diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..03098ad --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,5 @@ +export * from './types'; +export { VerstakPluginAPI, createPluginAPI } from './plugin-api'; +export { RPCServer, RPCClient } from './rpc'; +export { createTestManifest, createTestPluginState, createMockPluginAPI, validateManifest, } from './test-utils'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map new file mode 100644 index 0000000..39516a3 --- /dev/null +++ b/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,cAAc,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..d1f97ba --- /dev/null +++ b/dist/index.js @@ -0,0 +1,6 @@ +// Verstak Plugin SDK — Public API +export * from './types'; +export { VerstakPluginAPI, createPluginAPI } from './plugin-api'; +export { RPCServer, RPCClient } from './rpc'; +export { createTestManifest, createTestPluginState, createMockPluginAPI, validateManifest, } from './test-utils'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..6c29ae3 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,cAAc,CAAC"} \ No newline at end of file diff --git a/dist/plugin-api.d.ts b/dist/plugin-api.d.ts new file mode 100644 index 0000000..5093c6f --- /dev/null +++ b/dist/plugin-api.d.ts @@ -0,0 +1,79 @@ +import type { PluginSettings } from './types'; +/** + * VerstakPluginAPI — единственный способ для frontend плагина + * общаться с core платформы. + * + * Экземпляр API передаётся плагину при активации через глобальную + * переменную `window.__VERSTAK_PLUGIN_API__`. + */ +export declare class VerstakPluginAPI { + private pluginId; + private capabilities; + constructor(pluginId: string); + /** + * Инициализация API — вызывается core после загрузки frontend bundle. + * @internal + */ + _init(capabilities: string[]): void; + /** + * Зарегистрировать view для отображения в UI Shell. + */ + registerView(id: string, component: unknown): void; + /** + * Зарегистрировать панель настроек плагина. + */ + registerSettingsPanel(id: string, title: string, component: unknown): void; + /** + * Зарегистрировать команду для command palette. + */ + registerCommand(id: string, title: string, handler: () => void, keybinding?: string): void; + /** + * Зарегистрировать действия для файлов. + */ + registerFileAction(id: string, label: string, handler: (filePath: string) => void, capability?: string): void; + /** + * Зарегистрировать действия для заметок. + */ + registerNoteAction(id: string, label: string, handler: (noteId: string) => void, capability?: string): void; + /** + * Зарегистрировать provider поиска. + */ + registerSearchProvider(id: string, label: string, handler: (query: string) => unknown[]): void; + /** + * Проверить, доступна ли capability. + */ + hasCapability(name: string): boolean; + /** + * Получить список всех доступных capabilities. + */ + getAvailableCapabilities(): string[]; + /** + * Вызвать backend метод плагина через RPC. + */ + callBackend(method: string, args?: unknown[]): Promise; + /** + * Прочитать настройки плагина. + */ + readSettings(): Promise; + /** + * Записать настройки плагина. + */ + writeSettings(settings: PluginSettings): Promise; + /** + * Подписаться на событие event bus. + */ + subscribe(event: string, handler: (payload: unknown) => void): void; + /** + * Опубликовать событие в event bus. + */ + publish(event: string, payload: unknown): void; + private _postMessage; + private _rpcCall; +} +/** + * Создать экземпляр VerstakPluginAPI. + * Core вызывает эту функцию после загрузки frontend bundle, + * передавая pluginId и список доступных capabilities. + */ +export declare function createPluginAPI(pluginId: string): VerstakPluginAPI; +//# sourceMappingURL=plugin-api.d.ts.map \ No newline at end of file diff --git a/dist/plugin-api.d.ts.map b/dist/plugin-api.d.ts.map new file mode 100644 index 0000000..0391324 --- /dev/null +++ b/dist/plugin-api.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"plugin-api.d.ts","sourceRoot":"","sources":["../src/plugin-api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAqB;gBAE7B,QAAQ,EAAE,MAAM;IAI5B;;;OAGG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI;IAMnC;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI;IAIlD;;OAEG;IACH,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI;IAI1E;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAI1F;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAI7G;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3G;;OAEG;IACH,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,GAAG,IAAI;IAM9F;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIpC;;OAEG;IACH,wBAAwB,IAAI,MAAM,EAAE;IAMpC;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAMzE;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC;IAK7C;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAInE;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAM9C,OAAO,CAAC,YAAY;YAMN,QAAQ;CAiBvB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAGlE"} \ No newline at end of file diff --git a/dist/plugin-api.js b/dist/plugin-api.js new file mode 100644 index 0000000..671f7b4 --- /dev/null +++ b/dist/plugin-api.js @@ -0,0 +1,141 @@ +// Verstak Plugin SDK — VerstakPluginAPI +// The official runtime API available to all plugins in the frontend context. +/** + * VerstakPluginAPI — единственный способ для frontend плагина + * общаться с core платформы. + * + * Экземпляр API передаётся плагину при активации через глобальную + * переменную `window.__VERSTAK_PLUGIN_API__`. + */ +export class VerstakPluginAPI { + pluginId; + capabilities = new Set(); + constructor(pluginId) { + this.pluginId = pluginId; + } + /** + * Инициализация API — вызывается core после загрузки frontend bundle. + * @internal + */ + _init(capabilities) { + this.capabilities = new Set(capabilities); + } + // ─── View Registration ───────────────────────────────────── + /** + * Зарегистрировать view для отображения в UI Shell. + */ + registerView(id, component) { + this._postMessage('register.view', { id, component }); + } + /** + * Зарегистрировать панель настроек плагина. + */ + registerSettingsPanel(id, title, component) { + this._postMessage('register.settingsPanel', { id, title, component }); + } + /** + * Зарегистрировать команду для command palette. + */ + registerCommand(id, title, handler, keybinding) { + this._postMessage('register.command', { id, title, keybinding, handler: handler.toString() }); + } + /** + * Зарегистрировать действия для файлов. + */ + registerFileAction(id, label, handler, capability) { + this._postMessage('register.fileAction', { id, label, handler: handler.toString(), capability }); + } + /** + * Зарегистрировать действия для заметок. + */ + registerNoteAction(id, label, handler, capability) { + this._postMessage('register.noteAction', { id, label, handler: handler.toString(), capability }); + } + /** + * Зарегистрировать provider поиска. + */ + registerSearchProvider(id, label, handler) { + this._postMessage('register.searchProvider', { id, label, handler: handler.toString() }); + } + // ─── Capabilities ────────────────────────────────────────── + /** + * Проверить, доступна ли capability. + */ + hasCapability(name) { + return this.capabilities.has(name); + } + /** + * Получить список всех доступных capabilities. + */ + getAvailableCapabilities() { + return Array.from(this.capabilities); + } + // ─── Backend Communication ───────────────────────────────── + /** + * Вызвать backend метод плагина через RPC. + */ + async callBackend(method, args = []) { + return this._rpcCall(method, args); + } + // ─── Settings ────────────────────────────────────────────── + /** + * Прочитать настройки плагина. + */ + async readSettings() { + const result = await this._rpcCall('readSettings', []); + return result; + } + /** + * Записать настройки плагина. + */ + async writeSettings(settings) { + await this._rpcCall('writeSettings', [settings]); + } + // ─── Event Bus ───────────────────────────────────────────── + /** + * Подписаться на событие event bus. + */ + subscribe(event, handler) { + this._postMessage('subscribe', { event, handler: handler.toString() }); + } + /** + * Опубликовать событие в event bus. + */ + publish(event, payload) { + this._postMessage('publish', { event, payload }); + } + // ─── Internal ────────────────────────────────────────────── + _postMessage(type, data) { + window.dispatchEvent(new CustomEvent('verstak:plugin', { + detail: { pluginId: this.pluginId, type, data } + })); + } + async _rpcCall(method, args) { + return new Promise((resolve, reject) => { + const callId = `${this.pluginId}:${Date.now()}:${Math.random()}`; + const handler = (event) => { + if (event.detail.callId === callId) { + window.removeEventListener('verstak:rpc:response', handler); + if (event.detail.error) { + reject(new Error(event.detail.error)); + } + else { + resolve(event.detail.result); + } + } + }; + window.addEventListener('verstak:rpc:response', handler); + this._postMessage('rpc', { callId, method, args }); + }); + } +} +/** + * Создать экземпляр VerstakPluginAPI. + * Core вызывает эту функцию после загрузки frontend bundle, + * передавая pluginId и список доступных capabilities. + */ +export function createPluginAPI(pluginId) { + const api = new VerstakPluginAPI(pluginId); + return api; +} +//# sourceMappingURL=plugin-api.js.map \ No newline at end of file diff --git a/dist/plugin-api.js.map b/dist/plugin-api.js.map new file mode 100644 index 0000000..706f4a2 --- /dev/null +++ b/dist/plugin-api.js.map @@ -0,0 +1 @@ +{"version":3,"file":"plugin-api.js","sourceRoot":"","sources":["../src/plugin-api.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/rpc.d.ts b/dist/rpc.d.ts new file mode 100644 index 0000000..3f5168f --- /dev/null +++ b/dist/rpc.d.ts @@ -0,0 +1,57 @@ +export type RPCTransport = 'stdio' | 'tcp'; +export interface RPCRequest { + jsonrpc: '2.0'; + id: string; + method: string; + params: unknown[]; +} +export interface RPCResponse { + jsonrpc: '2.0'; + id: string; + result?: unknown; + error?: RPCError; +} +export interface RPCError { + code: number; + message: string; + data?: unknown; +} +/** + * RPC клиент для общения backend sidecar с core платформы. + * Использует JSON-RPC 2.0 протокол. + */ +export declare class RPCServer { + private handlers; + constructor(); + /** + * Зарегистрировать обработчик RPC метода. + */ + registerMethod(method: string, handler: (params: unknown[]) => Promise): void; + /** + * Обработать входящий RPC запрос. + */ + handleRequest(request: RPCRequest): Promise; + /** + * Создать RPC запрос. + */ + createRequest(method: string, params?: unknown[]): RPCRequest; + /** + * Разобрать RPC ответ. + */ + parseResponse(data: string): RPCResponse; +} +/** + * RPC клиент (для core, вызывает методы sidecar). + */ +export declare class RPCClient { + private requestId; + /** + * Создать JSON-RPC запрос. + */ + call(method: string, params?: unknown[]): string; + /** + * Разобрать ответ. + */ + parseResponse(data: string): RPCResponse; +} +//# sourceMappingURL=rpc.d.ts.map \ No newline at end of file diff --git a/dist/rpc.d.ts.map b/dist/rpc.d.ts.map new file mode 100644 index 0000000..ca6758d --- /dev/null +++ b/dist/rpc.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAA8D;;IAK9E;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAItF;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAsB9D;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,UAAU;IASjE;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;CAGzC;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAK;IAEtB;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,MAAM;IAUpD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;CAGzC"} \ No newline at end of file diff --git a/dist/rpc.js b/dist/rpc.js new file mode 100644 index 0000000..3d6b3b5 --- /dev/null +++ b/dist/rpc.js @@ -0,0 +1,82 @@ +// Verstak Plugin SDK — RPC Client for Sidecar Communication +/** + * RPC клиент для общения backend sidecar с core платформы. + * Использует JSON-RPC 2.0 протокол. + */ +export class RPCServer { + handlers = new Map(); + constructor() { + } + /** + * Зарегистрировать обработчик RPC метода. + */ + registerMethod(method, handler) { + this.handlers.set(method, handler); + } + /** + * Обработать входящий RPC запрос. + */ + async handleRequest(request) { + const handler = this.handlers.get(request.method); + if (!handler) { + return { + jsonrpc: '2.0', + id: request.id, + error: { code: -32601, message: `Method not found: ${request.method}` } + }; + } + try { + const result = await handler(request.params); + return { jsonrpc: '2.0', id: request.id, result }; + } + catch (err) { + return { + jsonrpc: '2.0', + id: request.id, + error: { code: -32000, message: err instanceof Error ? err.message : String(err) } + }; + } + } + /** + * Создать RPC запрос. + */ + createRequest(method, params = []) { + return { + jsonrpc: '2.0', + id: `${Date.now()}:${Math.random()}`, + method, + params + }; + } + /** + * Разобрать RPC ответ. + */ + parseResponse(data) { + return JSON.parse(data); + } +} +/** + * RPC клиент (для core, вызывает методы sidecar). + */ +export class RPCClient { + requestId = 0; + /** + * Создать JSON-RPC запрос. + */ + call(method, params = []) { + const request = { + jsonrpc: '2.0', + id: `${++this.requestId}`, + method, + params + }; + return JSON.stringify(request) + '\n'; + } + /** + * Разобрать ответ. + */ + parseResponse(data) { + return JSON.parse(data.trim()); + } +} +//# sourceMappingURL=rpc.js.map \ No newline at end of file diff --git a/dist/rpc.js.map b/dist/rpc.js.map new file mode 100644 index 0000000..86d3f2d --- /dev/null +++ b/dist/rpc.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAwB5D;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,QAAQ,GAAG,IAAI,GAAG,EAAmD,CAAC;IAE9E;IACA,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,MAAc,EAAE,OAAgD;QAC7E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,OAAmB;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,qBAAqB,OAAO,CAAC,MAAM,EAAE,EAAE;aACxE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACnF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,MAAc,EAAE,SAAoB,EAAE;QAClD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACpC,MAAM;YACN,MAAM;SACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;IACzC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,SAAS;IACZ,SAAS,GAAG,CAAC,CAAC;IAEtB;;OAEG;IACH,IAAI,CAAC,MAAc,EAAE,SAAoB,EAAE;QACzC,MAAM,OAAO,GAAe;YAC1B,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE;YACzB,MAAM;YACN,MAAM;SACP,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAgB,CAAC;IAChD,CAAC;CACF"} \ No newline at end of file diff --git a/dist/test-utils.d.ts b/dist/test-utils.d.ts new file mode 100644 index 0000000..d0ae995 --- /dev/null +++ b/dist/test-utils.d.ts @@ -0,0 +1,31 @@ +import type { PluginManifest, PluginState } from './types'; +/** + * Создать тестовый manifest для unit-тестов. + */ +export declare function createTestManifest(overrides?: Partial): PluginManifest; +/** + * Создать тестовое состояние плагина. + */ +export declare function createTestPluginState(overrides?: Partial): PluginState; +/** + * Создать заглушку VerstakPluginAPI для тестов. + */ +export declare function createMockPluginAPI(): { + registerView: ReturnType; + registerCommand: ReturnType; + registerSettingsPanel: ReturnType; + hasCapability: ReturnType; + callBackend: ReturnType; + subscribe: ReturnType; + publish: ReturnType; +}; +/** + * Валидатор plugin manifest. + */ +export declare function validateManifest(manifest: unknown): { + valid: boolean; + errors: string[]; +}; +import { vi } from 'vitest'; +export { vi }; +//# sourceMappingURL=test-utils.d.ts.map \ No newline at end of file diff --git a/dist/test-utils.d.ts.map b/dist/test-utils.d.ts.map new file mode 100644 index 0000000..2f3d255 --- /dev/null +++ b/dist/test-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAetF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CASnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,YAAY,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACvC,eAAe,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1C,qBAAqB,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAChD,aAAa,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACxC,WAAW,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;CACnC,CAUA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAgCxF;AAGD,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,EAAE,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/test-utils.js b/dist/test-utils.js new file mode 100644 index 0000000..6b7407b --- /dev/null +++ b/dist/test-utils.js @@ -0,0 +1,83 @@ +// Verstak Plugin SDK — Test Utilities +/** + * Создать тестовый manifest для unit-тестов. + */ +export function createTestManifest(overrides) { + return { + schemaVersion: 1, + id: 'test.plugin', + name: 'Test Plugin', + version: '0.1.0', + apiVersion: '1', + description: 'A test plugin for platform verification', + source: 'local', + provides: ['test.capability'], + requires: [], + optionalRequires: [], + permissions: ['events.publish', 'events.subscribe'], + ...overrides + }; +} +/** + * Создать тестовое состояние плагина. + */ +export function createTestPluginState(overrides) { + return { + id: 'test.plugin', + manifest: createTestManifest(), + status: 'loaded', + enabled: true, + loadedAt: new Date().toISOString(), + ...overrides + }; +} +/** + * Создать заглушку VerstakPluginAPI для тестов. + */ +export function createMockPluginAPI() { + return { + registerView: vi.fn(), + registerCommand: vi.fn(), + registerSettingsPanel: vi.fn(), + hasCapability: vi.fn().mockReturnValue(false), + callBackend: vi.fn().mockResolvedValue(undefined), + subscribe: vi.fn(), + publish: vi.fn(), + }; +} +/** + * Валидатор plugin manifest. + */ +export function validateManifest(manifest) { + const errors = []; + if (!manifest || typeof manifest !== 'object') { + return { valid: false, errors: ['Manifest must be an object'] }; + } + const m = manifest; + if (m.schemaVersion !== 1) { + errors.push(`schemaVersion must be 1, got ${m.schemaVersion}`); + } + if (typeof m.id !== 'string' || !m.id) { + errors.push('id must be a non-empty string'); + } + if (typeof m.name !== 'string' || !m.name) { + errors.push('name must be a non-empty string'); + } + if (typeof m.version !== 'string' || !/^\d+\.\d+\.\d+/.test(m.version)) { + errors.push('version must be a valid semver (e.g. 0.1.0)'); + } + if (typeof m.apiVersion !== 'string' || !m.apiVersion) { + errors.push('apiVersion must be a non-empty string'); + } + if (!Array.isArray(m.provides) || m.provides.length === 0) { + errors.push('provides must be a non-empty array'); + } + if (!Array.isArray(m.permissions) || m.permissions.length === 0) { + errors.push('permissions must be a non-empty array'); + } + return { valid: errors.length === 0, errors }; +} +// Re-export vi for test files +import { vi } from 'vitest'; +export { vi }; +//# sourceMappingURL=test-utils.js.map \ No newline at end of file diff --git a/dist/test-utils.js.map b/dist/test-utils.js.map new file mode 100644 index 0000000..4ff6659 --- /dev/null +++ b/dist/test-utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types.d.ts b/dist/types.d.ts new file mode 100644 index 0000000..ae2cdd5 --- /dev/null +++ b/dist/types.d.ts @@ -0,0 +1,263 @@ +export type PluginSource = 'official' | 'local' | 'third-party'; +export interface PluginManifest { + schemaVersion: 1; + id: string; + name: string; + version: string; + apiVersion: string; + description?: string; + source?: PluginSource; + icon?: string; + provides: string[]; + requires?: string[]; + optionalRequires?: string[]; + permissions: Permission[]; + frontend?: FrontendConfig; + backend?: BackendConfig; + migrations?: MigrationConfig; + contributes?: ContributionPoints; + sync?: SyncConfig; +} +export interface FrontendConfig { + entry: string; + style?: string; +} +export interface BackendConfig { + type: 'sidecar'; + entry: Record; + healthCheck?: HealthCheckConfig; +} +export interface HealthCheckConfig { + type?: 'rpc' | 'stdio' | 'tcp'; + timeout?: number; +} +export interface MigrationConfig { + path: string; +} +export interface SyncConfig { + namespaces?: string[]; + participate?: boolean; +} +export type CapabilityName = string; +export interface CapabilityEntry { + name: CapabilityName; + description: string; + status: 'stable' | 'draft' | 'deprecated'; +} +export type Permission = 'vault.read' | 'vault.write' | 'vault.watch' | 'storage.namespace' | 'storage.migrations' | 'events.publish' | 'events.subscribe' | 'ui.register' | 'commands.register' | 'network.local' | 'network.remote' | 'process.spawn' | 'secrets.read' | 'secrets.write' | 'sync.participate'; +export interface PermissionEntry { + name: Permission; + description: string; + dangerous: boolean; +} +export interface ContributionPoints { + views?: ContributionView[]; + commands?: ContributionCommand[]; + settingsPanels?: ContributionSettingsPanel[]; + sidebarItems?: ContributionSidebarItem[]; + fileActions?: ContributionAction[]; + noteActions?: ContributionAction[]; + contextMenuEntries?: ContributionContextMenuEntry[]; + searchProviders?: ContributionSearchProvider[]; + activityProviders?: ContributionActivityProvider[]; + statusBarItems?: ContributionStatusBarItem[]; +} +export interface ContributionView { + id: string; + title: string; + icon?: string; + component: string; +} +export interface ContributionCommand { + id: string; + title: string; + keybinding?: string; + icon?: string; + handler?: string; +} +export interface ContributionSettingsPanel { + id: string; + title: string; + component: string; + icon?: string; +} +export interface ContributionSidebarItem { + id: string; + title: string; + icon?: string; + view: string; + position?: number; +} +export interface ContributionAction { + id: string; + label: string; + icon?: string; + capability?: CapabilityName; + handler?: string; +} +export interface ContributionContextMenuEntry { + id: string; + label: string; + context: 'file' | 'note' | 'case' | 'folder'; + group?: string; + capability?: CapabilityName; + handler?: string; +} +export interface ContributionSearchProvider { + id: string; + label: string; + handler: string; +} +export interface ContributionActivityProvider { + id: string; + events?: string[]; + handler: string; +} +export interface ContributionStatusBarItem { + id: string; + label: string; + position?: 'left' | 'right'; + handler?: string; +} +export type PluginStatus = 'discovered' | 'disabled' | 'loading' | 'loaded' | 'degraded' | 'failed' | 'incompatible' | 'missing-required-capability'; +export interface PluginState { + id: string; + manifest: PluginManifest; + status: PluginStatus; + error?: string; + enabled: boolean; + loadedAt?: string; +} +export interface VerstakEvent { + name: string; + timestamp: string; + payload: Record; +} +export interface BrowserCapturePageEvent extends VerstakEvent { + name: 'browser.capture.page'; + payload: { + url: string; + title: string; + html?: string; + text?: string; + capturedAt: string; + domain?: string; + }; +} +export interface BrowserCaptureSelectionEvent extends VerstakEvent { + name: 'browser.capture.selection'; + payload: { + url: string; + title: string; + text: string; + capturedAt: string; + domain?: string; + }; +} +export interface BrowserCaptureLinkEvent extends VerstakEvent { + name: 'browser.capture.link'; + payload: { + url: string; + title?: string; + capturedAt: string; + domain?: string; + }; +} +export interface VaultOpenedEvent extends VerstakEvent { + name: 'vault.opened'; + payload: { + path: string; + version?: string; + openedAt: string; + }; +} +export interface CaseSelectedEvent extends VerstakEvent { + name: 'case.selected'; + payload: { + caseId: string; + casePath: string; + caseType?: string; + selectedAt: string; + }; +} +export interface FileChangedEvent extends VerstakEvent { + name: 'file.changed'; + payload: { + path: string; + size?: number; + changedAt: string; + }; +} +export interface NoteSavedEvent extends VerstakEvent { + name: 'note.saved'; + payload: { + noteId: string; + title?: string; + path: string; + caseId?: string; + savedAt: string; + }; +} +export interface PluginEnabledEvent extends VerstakEvent { + name: 'plugin.enabled'; + payload: { + pluginId: string; + version?: string; + enabledAt: string; + }; +} +export interface PluginDisabledEvent extends VerstakEvent { + name: 'plugin.disabled'; + payload: { + pluginId: string; + disabledAt: string; + }; +} +export type SyncOpType = 'add' | 'modify' | 'delete' | 'rename'; +export type SyncEntityType = 'file' | 'note' | 'plugin_state' | 'vault_meta'; +export interface SyncOperation { + op: SyncOpType; + id: string; + timestamp: string; + deviceId?: string; + entityType?: SyncEntityType; + entityPath?: string; + hash?: string; + size?: number; + mimeType?: string; + pluginNamespace?: string; + oldPath?: string; + metadata?: Record; +} +export interface SyncBatch { + batchId: string; + deviceId: string; + operations: SyncOperation[]; + timestamp: string; + lastSyncTimestamp?: string; + sequence?: number; +} +export interface SyncManifestEntry { + path: string; + hash: string; + size?: number; + updatedAt: string; + deleted?: boolean; +} +export interface SyncManifest { + deviceId: string; + entries: SyncManifestEntry[]; +} +export interface Conflict { + entityPath: string; + localHash: string; + remoteHash: string; + localTimestamp: string; + remoteTimestamp: string; + resolution?: 'local_wins' | 'remote_wins' | 'manual'; + resolvedAt?: string; +} +export interface PluginSettings { + [key: string]: unknown; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/dist/types.d.ts.map b/dist/types.d.ts.map new file mode 100644 index 0000000..0a25e30 --- /dev/null +++ b/dist/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAID,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;CAC3C;AAID,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,aAAa,GACb,aAAa,GACb,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,aAAa,GACb,mBAAmB,GACnB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,eAAe,GACf,kBAAkB,CAAC;AAEvB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACzC,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACnC,kBAAkB,CAAC,EAAE,4BAA4B,EAAE,CAAC;IACpD,eAAe,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC/C,iBAAiB,CAAC,EAAE,4BAA4B,EAAE,CAAC;IACnD,cAAc,CAAC,EAAE,yBAAyB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,cAAc,GACd,6BAA6B,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAGD,MAAM,WAAW,uBAAwB,SAAQ,YAAY;IAC3D,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,4BAA6B,SAAQ,YAAY;IAChE,IAAI,EAAE,2BAA2B,CAAC;IAClC,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,uBAAwB,SAAQ,YAAY;IAC3D,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAGD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAGD,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAID,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,YAAY,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,UAAU,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,YAAY,GAAG,aAAa,GAAG,QAAQ,CAAC;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"} \ No newline at end of file diff --git a/dist/types.js b/dist/types.js new file mode 100644 index 0000000..89de684 --- /dev/null +++ b/dist/types.js @@ -0,0 +1,3 @@ +// Verstak Plugin SDK — Core TypeScript Types +export {}; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/types.js.map b/dist/types.js.map new file mode 100644 index 0000000..b7dfa57 --- /dev/null +++ b/dist/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,6CAA6C"} \ No newline at end of file diff --git a/node_modules/.bin/acorn b/node_modules/.bin/acorn new file mode 120000 index 0000000..cf76760 --- /dev/null +++ b/node_modules/.bin/acorn @@ -0,0 +1 @@ +../acorn/bin/acorn \ No newline at end of file diff --git a/node_modules/.bin/esbuild b/node_modules/.bin/esbuild new file mode 120000 index 0000000..c83ac07 --- /dev/null +++ b/node_modules/.bin/esbuild @@ -0,0 +1 @@ +../esbuild/bin/esbuild \ No newline at end of file diff --git a/node_modules/.bin/nanoid b/node_modules/.bin/nanoid new file mode 120000 index 0000000..e2be547 --- /dev/null +++ b/node_modules/.bin/nanoid @@ -0,0 +1 @@ +../nanoid/bin/nanoid.cjs \ No newline at end of file diff --git a/node_modules/.bin/node-which b/node_modules/.bin/node-which new file mode 120000 index 0000000..6f8415e --- /dev/null +++ b/node_modules/.bin/node-which @@ -0,0 +1 @@ +../which/bin/node-which \ No newline at end of file diff --git a/node_modules/.bin/rollup b/node_modules/.bin/rollup new file mode 120000 index 0000000..5939621 --- /dev/null +++ b/node_modules/.bin/rollup @@ -0,0 +1 @@ +../rollup/dist/bin/rollup \ No newline at end of file diff --git a/node_modules/.bin/tsc b/node_modules/.bin/tsc new file mode 120000 index 0000000..0863208 --- /dev/null +++ b/node_modules/.bin/tsc @@ -0,0 +1 @@ +../typescript/bin/tsc \ No newline at end of file diff --git a/node_modules/.bin/tsserver b/node_modules/.bin/tsserver new file mode 120000 index 0000000..f8f8f1a --- /dev/null +++ b/node_modules/.bin/tsserver @@ -0,0 +1 @@ +../typescript/bin/tsserver \ No newline at end of file diff --git a/node_modules/.bin/vite b/node_modules/.bin/vite new file mode 120000 index 0000000..6d1e3be --- /dev/null +++ b/node_modules/.bin/vite @@ -0,0 +1 @@ +../vite/bin/vite.js \ No newline at end of file diff --git a/node_modules/.bin/vite-node b/node_modules/.bin/vite-node new file mode 120000 index 0000000..d68f74c --- /dev/null +++ b/node_modules/.bin/vite-node @@ -0,0 +1 @@ +../vite-node/vite-node.mjs \ No newline at end of file diff --git a/node_modules/.bin/vitest b/node_modules/.bin/vitest new file mode 120000 index 0000000..2273497 --- /dev/null +++ b/node_modules/.bin/vitest @@ -0,0 +1 @@ +../vitest/vitest.mjs \ No newline at end of file diff --git a/node_modules/.bin/why-is-node-running b/node_modules/.bin/why-is-node-running new file mode 120000 index 0000000..f08a594 --- /dev/null +++ b/node_modules/.bin/why-is-node-running @@ -0,0 +1 @@ +../why-is-node-running/cli.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..1def267 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,1030 @@ +{ + "name": "@verstak/plugin-sdk", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", + "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", + "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true + }, + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true + }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", + "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.0", + "@rollup/rollup-android-arm64": "4.62.0", + "@rollup/rollup-darwin-arm64": "4.62.0", + "@rollup/rollup-darwin-x64": "4.62.0", + "@rollup/rollup-freebsd-arm64": "4.62.0", + "@rollup/rollup-freebsd-x64": "4.62.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", + "@rollup/rollup-linux-arm-musleabihf": "4.62.0", + "@rollup/rollup-linux-arm64-gnu": "4.62.0", + "@rollup/rollup-linux-arm64-musl": "4.62.0", + "@rollup/rollup-linux-loong64-gnu": "4.62.0", + "@rollup/rollup-linux-loong64-musl": "4.62.0", + "@rollup/rollup-linux-ppc64-gnu": "4.62.0", + "@rollup/rollup-linux-ppc64-musl": "4.62.0", + "@rollup/rollup-linux-riscv64-gnu": "4.62.0", + "@rollup/rollup-linux-riscv64-musl": "4.62.0", + "@rollup/rollup-linux-s390x-gnu": "4.62.0", + "@rollup/rollup-linux-x64-gnu": "4.62.0", + "@rollup/rollup-linux-x64-musl": "4.62.0", + "@rollup/rollup-openbsd-x64": "4.62.0", + "@rollup/rollup-openharmony-arm64": "4.62.0", + "@rollup/rollup-win32-arm64-msvc": "4.62.0", + "@rollup/rollup-win32-ia32-msvc": "4.62.0", + "@rollup/rollup-win32-x64-gnu": "4.62.0", + "@rollup/rollup-win32-x64-msvc": "4.62.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz", + "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/node_modules/@esbuild/linux-x64/README.md b/node_modules/@esbuild/linux-x64/README.md new file mode 100644 index 0000000..b2f1930 --- /dev/null +++ b/node_modules/@esbuild/linux-x64/README.md @@ -0,0 +1,3 @@ +# esbuild + +This is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details. diff --git a/node_modules/@esbuild/linux-x64/bin/esbuild b/node_modules/@esbuild/linux-x64/bin/esbuild new file mode 100755 index 0000000..288f768 Binary files /dev/null and b/node_modules/@esbuild/linux-x64/bin/esbuild differ diff --git a/node_modules/@esbuild/linux-x64/package.json b/node_modules/@esbuild/linux-x64/package.json new file mode 100644 index 0000000..b70b09e --- /dev/null +++ b/node_modules/@esbuild/linux-x64/package.json @@ -0,0 +1,20 @@ +{ + "name": "@esbuild/linux-x64", + "version": "0.21.5", + "description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.", + "repository": { + "type": "git", + "url": "git+https://github.com/evanw/esbuild.git" + }, + "license": "MIT", + "preferUnplugged": true, + "engines": { + "node": ">=12" + }, + "os": [ + "linux" + ], + "cpu": [ + "x64" + ] +} diff --git a/node_modules/@jest/schemas/LICENSE b/node_modules/@jest/schemas/LICENSE new file mode 100644 index 0000000..b93be90 --- /dev/null +++ b/node_modules/@jest/schemas/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jest/schemas/README.md b/node_modules/@jest/schemas/README.md new file mode 100644 index 0000000..b2a1d12 --- /dev/null +++ b/node_modules/@jest/schemas/README.md @@ -0,0 +1,3 @@ +# `@jest/schemas` + +Experimental and currently incomplete module for JSON schemas for [Jest's](https://jestjs.io/) configuration. diff --git a/node_modules/@jest/schemas/build/index.d.ts b/node_modules/@jest/schemas/build/index.d.ts new file mode 100644 index 0000000..156f197 --- /dev/null +++ b/node_modules/@jest/schemas/build/index.d.ts @@ -0,0 +1,63 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import {Static} from '@sinclair/typebox'; +import {TBoolean} from '@sinclair/typebox'; +import {TNull} from '@sinclair/typebox'; +import {TNumber} from '@sinclair/typebox'; +import {TObject} from '@sinclair/typebox'; +import {TReadonlyOptional} from '@sinclair/typebox'; +import {TString} from '@sinclair/typebox'; + +declare const RawSnapshotFormat: TObject<{ + callToJSON: TReadonlyOptional; + compareKeys: TReadonlyOptional; + escapeRegex: TReadonlyOptional; + escapeString: TReadonlyOptional; + highlight: TReadonlyOptional; + indent: TReadonlyOptional; + maxDepth: TReadonlyOptional; + maxWidth: TReadonlyOptional; + min: TReadonlyOptional; + printBasicPrototype: TReadonlyOptional; + printFunctionName: TReadonlyOptional; + theme: TReadonlyOptional< + TObject<{ + comment: TReadonlyOptional>; + content: TReadonlyOptional>; + prop: TReadonlyOptional>; + tag: TReadonlyOptional>; + value: TReadonlyOptional>; + }> + >; +}>; + +export declare const SnapshotFormat: TObject<{ + callToJSON: TReadonlyOptional; + compareKeys: TReadonlyOptional; + escapeRegex: TReadonlyOptional; + escapeString: TReadonlyOptional; + highlight: TReadonlyOptional; + indent: TReadonlyOptional; + maxDepth: TReadonlyOptional; + maxWidth: TReadonlyOptional; + min: TReadonlyOptional; + printBasicPrototype: TReadonlyOptional; + printFunctionName: TReadonlyOptional; + theme: TReadonlyOptional< + TObject<{ + comment: TReadonlyOptional>; + content: TReadonlyOptional>; + prop: TReadonlyOptional>; + tag: TReadonlyOptional>; + value: TReadonlyOptional>; + }> + >; +}>; + +export declare type SnapshotFormat = Static; + +export {}; diff --git a/node_modules/@jest/schemas/build/index.js b/node_modules/@jest/schemas/build/index.js new file mode 100644 index 0000000..870c184 --- /dev/null +++ b/node_modules/@jest/schemas/build/index.js @@ -0,0 +1,60 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.SnapshotFormat = void 0; +function _typebox() { + const data = require('@sinclair/typebox'); + _typebox = function () { + return data; + }; + return data; +} +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const RawSnapshotFormat = _typebox().Type.Partial( + _typebox().Type.Object({ + callToJSON: _typebox().Type.Readonly(_typebox().Type.Boolean()), + compareKeys: _typebox().Type.Readonly(_typebox().Type.Null()), + escapeRegex: _typebox().Type.Readonly(_typebox().Type.Boolean()), + escapeString: _typebox().Type.Readonly(_typebox().Type.Boolean()), + highlight: _typebox().Type.Readonly(_typebox().Type.Boolean()), + indent: _typebox().Type.Readonly( + _typebox().Type.Number({ + minimum: 0 + }) + ), + maxDepth: _typebox().Type.Readonly( + _typebox().Type.Number({ + minimum: 0 + }) + ), + maxWidth: _typebox().Type.Readonly( + _typebox().Type.Number({ + minimum: 0 + }) + ), + min: _typebox().Type.Readonly(_typebox().Type.Boolean()), + printBasicPrototype: _typebox().Type.Readonly(_typebox().Type.Boolean()), + printFunctionName: _typebox().Type.Readonly(_typebox().Type.Boolean()), + theme: _typebox().Type.Readonly( + _typebox().Type.Partial( + _typebox().Type.Object({ + comment: _typebox().Type.Readonly(_typebox().Type.String()), + content: _typebox().Type.Readonly(_typebox().Type.String()), + prop: _typebox().Type.Readonly(_typebox().Type.String()), + tag: _typebox().Type.Readonly(_typebox().Type.String()), + value: _typebox().Type.Readonly(_typebox().Type.String()) + }) + ) + ) + }) +); +const SnapshotFormat = _typebox().Type.Strict(RawSnapshotFormat); +exports.SnapshotFormat = SnapshotFormat; diff --git a/node_modules/@jest/schemas/package.json b/node_modules/@jest/schemas/package.json new file mode 100644 index 0000000..db670bf --- /dev/null +++ b/node_modules/@jest/schemas/package.json @@ -0,0 +1,29 @@ +{ + "name": "@jest/schemas", + "version": "29.6.3", + "repository": { + "type": "git", + "url": "https://github.com/jestjs/jest.git", + "directory": "packages/jest-schemas" + }, + "license": "MIT", + "main": "./build/index.js", + "types": "./build/index.d.ts", + "exports": { + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, + "./package.json": "./package.json" + }, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "publishConfig": { + "access": "public" + }, + "gitHead": "fb7d95c8af6e0d65a8b65348433d8a0ea0725b5b" +} diff --git a/node_modules/@jridgewell/sourcemap-codec/LICENSE b/node_modules/@jridgewell/sourcemap-codec/LICENSE new file mode 100644 index 0000000..1f6ce94 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/sourcemap-codec/README.md b/node_modules/@jridgewell/sourcemap-codec/README.md new file mode 100644 index 0000000..b3e0708 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/README.md @@ -0,0 +1,264 @@ +# @jridgewell/sourcemap-codec + +Encode/decode the `mappings` property of a [sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit). + + +## Why? + +Sourcemaps are difficult to generate and manipulate, because the `mappings` property – the part that actually links the generated code back to the original source – is encoded using an obscure method called [Variable-length quantity](https://en.wikipedia.org/wiki/Variable-length_quantity). On top of that, each segment in the mapping contains offsets rather than absolute indices, which means that you can't look at a segment in isolation – you have to understand the whole sourcemap. + +This package makes the process slightly easier. + + +## Installation + +```bash +npm install @jridgewell/sourcemap-codec +``` + + +## Usage + +```js +import { encode, decode } from '@jridgewell/sourcemap-codec'; + +var decoded = decode( ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); + +assert.deepEqual( decoded, [ + // the first line (of the generated code) has no mappings, + // as shown by the starting semi-colon (which separates lines) + [], + + // the second line contains four (comma-separated) segments + [ + // segments are encoded as you'd expect: + // [ generatedCodeColumn, sourceIndex, sourceCodeLine, sourceCodeColumn, nameIndex ] + + // i.e. the first segment begins at column 2, and maps back to the second column + // of the second line (both zero-based) of the 0th source, and uses the 0th + // name in the `map.names` array + [ 2, 0, 2, 2, 0 ], + + // the remaining segments are 4-length rather than 5-length, + // because they don't map a name + [ 4, 0, 2, 4 ], + [ 6, 0, 2, 5 ], + [ 7, 0, 2, 7 ] + ], + + // the final line contains two segments + [ + [ 2, 1, 10, 19 ], + [ 12, 1, 11, 20 ] + ] +]); + +var encoded = encode( decoded ); +assert.equal( encoded, ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); +``` + +## Benchmarks + +``` +node v20.10.0 + +amp.js.map - 45120 segments + +Decode Memory Usage: +local code 5815135 bytes +@jridgewell/sourcemap-codec 1.4.15 5868160 bytes +sourcemap-codec 5492584 bytes +source-map-0.6.1 13569984 bytes +source-map-0.8.0 6390584 bytes +chrome dev tools 8011136 bytes +Smallest memory usage is sourcemap-codec + +Decode speed: +decode: local code x 492 ops/sec ±1.22% (90 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 499 ops/sec ±1.16% (89 runs sampled) +decode: sourcemap-codec x 376 ops/sec ±1.66% (89 runs sampled) +decode: source-map-0.6.1 x 34.99 ops/sec ±0.94% (48 runs sampled) +decode: source-map-0.8.0 x 351 ops/sec ±0.07% (95 runs sampled) +chrome dev tools x 165 ops/sec ±0.91% (86 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 444248 bytes +@jridgewell/sourcemap-codec 1.4.15 623024 bytes +sourcemap-codec 8696280 bytes +source-map-0.6.1 8745176 bytes +source-map-0.8.0 8736624 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 796 ops/sec ±0.11% (97 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 795 ops/sec ±0.25% (98 runs sampled) +encode: sourcemap-codec x 231 ops/sec ±0.83% (86 runs sampled) +encode: source-map-0.6.1 x 166 ops/sec ±0.57% (86 runs sampled) +encode: source-map-0.8.0 x 203 ops/sec ±0.45% (88 runs sampled) +Fastest is encode: local code,encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +babel.min.js.map - 347793 segments + +Decode Memory Usage: +local code 35424960 bytes +@jridgewell/sourcemap-codec 1.4.15 35424696 bytes +sourcemap-codec 36033464 bytes +source-map-0.6.1 62253704 bytes +source-map-0.8.0 43843920 bytes +chrome dev tools 45111400 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Decode speed: +decode: local code x 38.18 ops/sec ±5.44% (52 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 38.36 ops/sec ±5.02% (52 runs sampled) +decode: sourcemap-codec x 34.05 ops/sec ±4.45% (47 runs sampled) +decode: source-map-0.6.1 x 4.31 ops/sec ±2.76% (15 runs sampled) +decode: source-map-0.8.0 x 55.60 ops/sec ±0.13% (73 runs sampled) +chrome dev tools x 16.94 ops/sec ±3.78% (46 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 2606016 bytes +@jridgewell/sourcemap-codec 1.4.15 2626440 bytes +sourcemap-codec 21152576 bytes +source-map-0.6.1 25023928 bytes +source-map-0.8.0 25256448 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 127 ops/sec ±0.18% (83 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 128 ops/sec ±0.26% (83 runs sampled) +encode: sourcemap-codec x 29.31 ops/sec ±2.55% (53 runs sampled) +encode: source-map-0.6.1 x 18.85 ops/sec ±3.19% (36 runs sampled) +encode: source-map-0.8.0 x 19.34 ops/sec ±1.97% (36 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +preact.js.map - 1992 segments + +Decode Memory Usage: +local code 261696 bytes +@jridgewell/sourcemap-codec 1.4.15 244296 bytes +sourcemap-codec 302816 bytes +source-map-0.6.1 939176 bytes +source-map-0.8.0 336 bytes +chrome dev tools 587368 bytes +Smallest memory usage is source-map-0.8.0 + +Decode speed: +decode: local code x 17,782 ops/sec ±0.32% (97 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 17,863 ops/sec ±0.40% (100 runs sampled) +decode: sourcemap-codec x 12,453 ops/sec ±0.27% (101 runs sampled) +decode: source-map-0.6.1 x 1,288 ops/sec ±1.05% (96 runs sampled) +decode: source-map-0.8.0 x 9,289 ops/sec ±0.27% (101 runs sampled) +chrome dev tools x 4,769 ops/sec ±0.18% (100 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 262944 bytes +@jridgewell/sourcemap-codec 1.4.15 25544 bytes +sourcemap-codec 323048 bytes +source-map-0.6.1 507808 bytes +source-map-0.8.0 507480 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Encode speed: +encode: local code x 24,207 ops/sec ±0.79% (95 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 24,288 ops/sec ±0.48% (96 runs sampled) +encode: sourcemap-codec x 6,761 ops/sec ±0.21% (100 runs sampled) +encode: source-map-0.6.1 x 5,374 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 5,633 ops/sec ±0.32% (99 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15,encode: local code + + +*** + + +react.js.map - 5726 segments + +Decode Memory Usage: +local code 678816 bytes +@jridgewell/sourcemap-codec 1.4.15 678816 bytes +sourcemap-codec 816400 bytes +source-map-0.6.1 2288864 bytes +source-map-0.8.0 721360 bytes +chrome dev tools 1012512 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 6,178 ops/sec ±0.19% (98 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 6,261 ops/sec ±0.22% (100 runs sampled) +decode: sourcemap-codec x 4,472 ops/sec ±0.90% (99 runs sampled) +decode: source-map-0.6.1 x 449 ops/sec ±0.31% (95 runs sampled) +decode: source-map-0.8.0 x 3,219 ops/sec ±0.13% (100 runs sampled) +chrome dev tools x 1,743 ops/sec ±0.20% (99 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 140960 bytes +@jridgewell/sourcemap-codec 1.4.15 159808 bytes +sourcemap-codec 969304 bytes +source-map-0.6.1 930520 bytes +source-map-0.8.0 930248 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 8,013 ops/sec ±0.19% (100 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 7,989 ops/sec ±0.20% (101 runs sampled) +encode: sourcemap-codec x 2,472 ops/sec ±0.21% (99 runs sampled) +encode: source-map-0.6.1 x 2,200 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 2,220 ops/sec ±0.37% (99 runs sampled) +Fastest is encode: local code + + +*** + + +vscode.map - 2141001 segments + +Decode Memory Usage: +local code 198955264 bytes +@jridgewell/sourcemap-codec 1.4.15 199175352 bytes +sourcemap-codec 199102688 bytes +source-map-0.6.1 386323432 bytes +source-map-0.8.0 244116432 bytes +chrome dev tools 293734280 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 3.90 ops/sec ±22.21% (15 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 3.95 ops/sec ±23.53% (15 runs sampled) +decode: sourcemap-codec x 3.82 ops/sec ±17.94% (14 runs sampled) +decode: source-map-0.6.1 x 0.61 ops/sec ±7.81% (6 runs sampled) +decode: source-map-0.8.0 x 9.54 ops/sec ±0.28% (28 runs sampled) +chrome dev tools x 2.18 ops/sec ±10.58% (10 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 13509880 bytes +@jridgewell/sourcemap-codec 1.4.15 13537648 bytes +sourcemap-codec 32540104 bytes +source-map-0.6.1 127531040 bytes +source-map-0.8.0 127535312 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 20.10 ops/sec ±0.19% (38 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 20.26 ops/sec ±0.32% (38 runs sampled) +encode: sourcemap-codec x 5.44 ops/sec ±1.64% (18 runs sampled) +encode: source-map-0.6.1 x 2.30 ops/sec ±4.79% (10 runs sampled) +encode: source-map-0.8.0 x 2.46 ops/sec ±6.53% (10 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 +``` + +# License + +MIT diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs new file mode 100644 index 0000000..532bab3 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs @@ -0,0 +1,423 @@ +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +export { + decode, + decodeGeneratedRanges, + decodeOriginalScopes, + encode, + encodeGeneratedRanges, + encodeOriginalScopes +}; +//# sourceMappingURL=sourcemap-codec.mjs.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map new file mode 100644 index 0000000..c276844 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts", "../src/sourcemap-codec.ts"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js new file mode 100644 index 0000000..2d8e459 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js @@ -0,0 +1,464 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.sourcemapCodec = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module) { +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/sourcemap-codec.ts +var sourcemap_codec_exports = {}; +__export(sourcemap_codec_exports, { + decode: () => decode, + decodeGeneratedRanges: () => decodeGeneratedRanges, + decodeOriginalScopes: () => decodeOriginalScopes, + encode: () => encode, + encodeGeneratedRanges: () => encodeGeneratedRanges, + encodeOriginalScopes: () => encodeOriginalScopes +}); +module.exports = __toCommonJS(sourcemap_codec_exports); + +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +})); +//# sourceMappingURL=sourcemap-codec.umd.js.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map new file mode 100644 index 0000000..abc18d2 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/sourcemap-codec.ts", "../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/package.json b/node_modules/@jridgewell/sourcemap-codec/package.json new file mode 100644 index 0000000..da55137 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/package.json @@ -0,0 +1,63 @@ +{ + "name": "@jridgewell/sourcemap-codec", + "version": "1.5.5", + "description": "Encode/decode sourcemap mappings", + "keywords": [ + "sourcemap", + "vlq" + ], + "main": "dist/sourcemap-codec.umd.js", + "module": "dist/sourcemap-codec.mjs", + "types": "types/sourcemap-codec.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/sourcemap-codec.d.mts", + "default": "./dist/sourcemap-codec.mjs" + }, + "default": { + "types": "./types/sourcemap-codec.d.cts", + "default": "./dist/sourcemap-codec.umd.js" + } + }, + "./dist/sourcemap-codec.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.js", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs sourcemap-codec.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/sourcemap-codec", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/sourcemap-codec" + }, + "author": "Justin Ridgewell ", + "license": "MIT" +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts new file mode 100644 index 0000000..d194c2f --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts @@ -0,0 +1,345 @@ +import { StringReader, StringWriter } from './strings'; +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; + +const EMPTY: any[] = []; + +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; + +type Mix = (A & O) | (B & O); + +export type OriginalScope = Mix< + [Line, Column, Line, Column, Kind], + [Line, Column, Line, Column, Kind, Name], + { vars: Var[] } +>; + +export type GeneratedRange = Mix< + [Line, Column, Line, Column], + [Line, Column, Line, Column, SourcesIndex, ScopesIndex], + { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; + } +>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; + +export function decodeOriginalScopes(input: string): OriginalScope[] { + const { length } = input; + const reader = new StringReader(input); + const scopes: OriginalScope[] = []; + const stack: OriginalScope[] = []; + let line = 0; + + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + + if (!hasMoreVlq(reader, length)) { + const last = stack.pop()!; + last[2] = line; + last[3] = column; + continue; + } + + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 0b0001; + + const scope: OriginalScope = ( + hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind] + ) as OriginalScope; + + let vars: Var[] = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + + scopes.push(scope); + stack.push(scope); + } + + return scopes; +} + +export function encodeOriginalScopes(scopes: OriginalScope[]): string { + const writer = new StringWriter(); + + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + + return writer.flush(); +} + +function _encodeOriginalScopes( + scopes: OriginalScope[], + index: number, + writer: StringWriter, + state: [ + number, // GenColumn + ], +): number { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + + if (index > 0) writer.write(comma); + + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + + const fields = scope.length === 6 ? 0b0001 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + + for (const v of vars) { + encodeInteger(writer, v, 0); + } + + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + + return index; +} + +export function decodeGeneratedRanges(input: string): GeneratedRange[] { + const { length } = input; + const reader = new StringReader(input); + const ranges: GeneratedRange[] = []; + const stack: GeneratedRange[] = []; + + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + + do { + const semi = reader.indexOf(';'); + let genColumn = 0; + + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop()!; + last[2] = genLine; + last[3] = genColumn; + continue; + } + + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 0b0001; + const hasCallsite = fields & 0b0010; + const hasScope = fields & 0b0100; + + let callsite: CallSite | null = null; + let bindings: Binding[] = EMPTY; + let range: GeneratedRange; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0, + ); + + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange; + } else { + range = [genLine, genColumn, 0, 0] as GeneratedRange; + } + + range.isScope = !!hasScope; + + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0, + ); + + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges: BindingExpressionRange[]; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + + ranges.push(range); + stack.push(range); + } + + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + + return ranges; +} + +export function encodeGeneratedRanges(ranges: GeneratedRange[]): string { + if (ranges.length === 0) return ''; + + const writer = new StringWriter(); + + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + + return writer.flush(); +} + +function _encodeGeneratedRanges( + ranges: GeneratedRange[], + index: number, + writer: StringWriter, + state: [ + number, // GenLine + number, // GenColumn + number, // DefSourcesIndex + number, // DefScopesIndex + number, // CallSourcesIndex + number, // CallLine + number, // CallColumn + ], +): number { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings, + } = range; + + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + + state[1] = encodeInteger(writer, range[1], state[1]); + + const fields = + (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0); + encodeInteger(writer, fields, 0); + + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn); + encodeInteger(writer, expRange[0]!, 0); + } + } + } + + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + + return index; +} + +function catchupLine(writer: StringWriter, lastLine: number, line: number) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts new file mode 100644 index 0000000..a81f894 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts @@ -0,0 +1,111 @@ +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; +import { StringWriter, StringReader } from './strings'; + +export { + decodeOriginalScopes, + encodeOriginalScopes, + decodeGeneratedRanges, + encodeGeneratedRanges, +} from './scopes'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes'; + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; + +export function decode(mappings: string): SourceMapMappings { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded: SourceMapMappings = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + do { + const semi = reader.indexOf(';'); + const line: SourceMapLine = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + + while (reader.pos < semi) { + let seg: SourceMapSegment; + + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + + line.push(seg); + reader.pos++; + } + + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + + return decoded; +} + +function sort(line: SourceMapSegment[]) { + line.sort(sortComparator); +} + +function sortComparator(a: SourceMapSegment, b: SourceMapSegment): number { + return a[0] - b[0]; +} + +export function encode(decoded: SourceMapMappings): string; +export function encode(decoded: Readonly): string; +export function encode(decoded: Readonly): string { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + + let genColumn = 0; + + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + + genColumn = encodeInteger(writer, segment[0], genColumn); + + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + + return writer.flush(); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/strings.ts b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts new file mode 100644 index 0000000..d161965 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts @@ -0,0 +1,65 @@ +const bufLength = 1024 * 16; + +// Provide a fallback for older environments. +const td = + typeof TextDecoder !== 'undefined' + ? /* #__PURE__ */ new TextDecoder() + : typeof Buffer !== 'undefined' + ? { + decode(buf: Uint8Array): string { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + }, + } + : { + decode(buf: Uint8Array): string { + let out = ''; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + }, + }; + +export class StringWriter { + pos = 0; + private out = ''; + private buffer = new Uint8Array(bufLength); + + write(v: number): void { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + + flush(): string { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +} + +export class StringReader { + pos = 0; + declare private buffer: string; + + constructor(buffer: string) { + this.buffer = buffer; + } + + next(): number { + return this.buffer.charCodeAt(this.pos++); + } + + peek(): number { + return this.buffer.charCodeAt(this.pos); + } + + indexOf(char: string): number { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts new file mode 100644 index 0000000..a42c681 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts @@ -0,0 +1,55 @@ +import type { StringReader, StringWriter } from './strings'; + +export const comma = ','.charCodeAt(0); +export const semicolon = ';'.charCodeAt(0); + +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII + +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} + +export function decodeInteger(reader: StringReader, relative: number): number { + let value = 0; + let shift = 0; + let integer = 0; + + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + + const shouldNegate = value & 1; + value >>>= 1; + + if (shouldNegate) { + value = -0x80000000 | -value; + } + + return relative + value; +} + +export function encodeInteger(builder: StringWriter, num: number, relative: number): number { + let delta = num - relative; + + delta = delta < 0 ? (-delta << 1) | 1 : delta << 1; + do { + let clamped = delta & 0b011111; + delta >>>= 5; + if (delta > 0) clamped |= 0b100000; + builder.write(intToChar[clamped]); + } while (delta > 0); + + return num; +} + +export function hasMoreVlq(reader: StringReader, max: number) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts new file mode 100644 index 0000000..c583c75 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map new file mode 100644 index 0000000..630e647 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts new file mode 100644 index 0000000..c583c75 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map new file mode 100644 index 0000000..630e647 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts new file mode 100644 index 0000000..5f35e22 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.cts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.cts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map new file mode 100644 index 0000000..7123d52 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts new file mode 100644 index 0000000..199fb9f --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.mts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.mts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map new file mode 100644 index 0000000..7123d52 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts new file mode 100644 index 0000000..62faceb --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map new file mode 100644 index 0000000..d3602da --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts new file mode 100644 index 0000000..62faceb --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map new file mode 100644 index 0000000..d3602da --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts new file mode 100644 index 0000000..dbd6602 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.cts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map new file mode 100644 index 0000000..6fdc356 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts new file mode 100644 index 0000000..2c739bc --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.mts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map new file mode 100644 index 0000000..6fdc356 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/README.md b/node_modules/@rollup/rollup-linux-x64-gnu/README.md new file mode 100644 index 0000000..cabe280 --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-gnu/README.md @@ -0,0 +1,3 @@ +# `@rollup/rollup-linux-x64-gnu` + +This is the **x86_64-unknown-linux-gnu** binary for `rollup` diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/package.json b/node_modules/@rollup/rollup-linux-x64-gnu/package.json new file mode 100644 index 0000000..ab6dd22 --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-gnu/package.json @@ -0,0 +1,25 @@ +{ + "name": "@rollup/rollup-linux-x64-gnu", + "version": "4.62.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "files": [ + "rollup.linux-x64-gnu.node" + ], + "description": "Native bindings for Rollup", + "author": "Lukas Taegert-Atkinson", + "homepage": "https://rollupjs.org/", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/rollup/rollup.git" + }, + "libc": [ + "glibc" + ], + "main": "./rollup.linux-x64-gnu.node" +} \ No newline at end of file diff --git a/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node b/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node new file mode 100644 index 0000000..0eb2af3 Binary files /dev/null and b/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node differ diff --git a/node_modules/@rollup/rollup-linux-x64-musl/README.md b/node_modules/@rollup/rollup-linux-x64-musl/README.md new file mode 100644 index 0000000..5848a6c --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-musl/README.md @@ -0,0 +1,3 @@ +# `@rollup/rollup-linux-x64-musl` + +This is the **x86_64-unknown-linux-musl** binary for `rollup` diff --git a/node_modules/@rollup/rollup-linux-x64-musl/package.json b/node_modules/@rollup/rollup-linux-x64-musl/package.json new file mode 100644 index 0000000..80f0e28 --- /dev/null +++ b/node_modules/@rollup/rollup-linux-x64-musl/package.json @@ -0,0 +1,25 @@ +{ + "name": "@rollup/rollup-linux-x64-musl", + "version": "4.62.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "files": [ + "rollup.linux-x64-musl.node" + ], + "description": "Native bindings for Rollup", + "author": "Lukas Taegert-Atkinson", + "homepage": "https://rollupjs.org/", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/rollup/rollup.git" + }, + "libc": [ + "musl" + ], + "main": "./rollup.linux-x64-musl.node" +} \ No newline at end of file diff --git a/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node b/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node new file mode 100644 index 0000000..e1b9a9a Binary files /dev/null and b/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node differ diff --git a/node_modules/@sinclair/typebox/compiler/compiler.d.ts b/node_modules/@sinclair/typebox/compiler/compiler.d.ts new file mode 100644 index 0000000..f35f75f --- /dev/null +++ b/node_modules/@sinclair/typebox/compiler/compiler.d.ts @@ -0,0 +1,35 @@ +import * as Types from '../typebox'; +import { ValueErrorIterator } from '../errors/index'; +export type CheckFunction = (value: unknown) => boolean; +export declare class TypeCheck { + private readonly schema; + private readonly references; + private readonly checkFunc; + private readonly code; + constructor(schema: T, references: Types.TSchema[], checkFunc: CheckFunction, code: string); + /** Returns the generated assertion code used to validate this type. */ + Code(): string; + /** Returns an iterator for each error in this value. */ + Errors(value: unknown): ValueErrorIterator; + /** Returns true if the value matches the compiled type. */ + Check(value: unknown): value is Types.Static; +} +export declare class TypeCompilerUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class TypeCompilerDereferenceError extends Error { + readonly schema: Types.TRef; + constructor(schema: Types.TRef); +} +export declare class TypeCompilerTypeGuardError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +/** Compiles Types for Runtime Type Checking */ +export declare namespace TypeCompiler { + /** Returns the generated assertion code used to validate this type. */ + function Code(schema: T, references?: Types.TSchema[]): string; + /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */ + function Compile(schema: T, references?: Types.TSchema[]): TypeCheck; +} diff --git a/node_modules/@sinclair/typebox/compiler/compiler.js b/node_modules/@sinclair/typebox/compiler/compiler.js new file mode 100644 index 0000000..b318e7d --- /dev/null +++ b/node_modules/@sinclair/typebox/compiler/compiler.js @@ -0,0 +1,577 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/compiler + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TypeCompiler = exports.TypeCompilerTypeGuardError = exports.TypeCompilerDereferenceError = exports.TypeCompilerUnknownTypeError = exports.TypeCheck = void 0; +const Types = require("../typebox"); +const index_1 = require("../errors/index"); +const index_2 = require("../system/index"); +const hash_1 = require("../value/hash"); +// ------------------------------------------------------------------- +// TypeCheck +// ------------------------------------------------------------------- +class TypeCheck { + constructor(schema, references, checkFunc, code) { + this.schema = schema; + this.references = references; + this.checkFunc = checkFunc; + this.code = code; + } + /** Returns the generated assertion code used to validate this type. */ + Code() { + return this.code; + } + /** Returns an iterator for each error in this value. */ + Errors(value) { + return index_1.ValueErrors.Errors(this.schema, this.references, value); + } + /** Returns true if the value matches the compiled type. */ + Check(value) { + return this.checkFunc(value); + } +} +exports.TypeCheck = TypeCheck; +// ------------------------------------------------------------------- +// Character +// ------------------------------------------------------------------- +var Character; +(function (Character) { + function DollarSign(code) { + return code === 36; + } + Character.DollarSign = DollarSign; + function IsUnderscore(code) { + return code === 95; + } + Character.IsUnderscore = IsUnderscore; + function IsAlpha(code) { + return (code >= 65 && code <= 90) || (code >= 97 && code <= 122); + } + Character.IsAlpha = IsAlpha; + function IsNumeric(code) { + return code >= 48 && code <= 57; + } + Character.IsNumeric = IsNumeric; +})(Character || (Character = {})); +// ------------------------------------------------------------------- +// MemberExpression +// ------------------------------------------------------------------- +var MemberExpression; +(function (MemberExpression) { + function IsFirstCharacterNumeric(value) { + if (value.length === 0) + return false; + return Character.IsNumeric(value.charCodeAt(0)); + } + function IsAccessor(value) { + if (IsFirstCharacterNumeric(value)) + return false; + for (let i = 0; i < value.length; i++) { + const code = value.charCodeAt(i); + const check = Character.IsAlpha(code) || Character.IsNumeric(code) || Character.DollarSign(code) || Character.IsUnderscore(code); + if (!check) + return false; + } + return true; + } + function EscapeHyphen(key) { + return key.replace(/'/g, "\\'"); + } + function Encode(object, key) { + return IsAccessor(key) ? `${object}.${key}` : `${object}['${EscapeHyphen(key)}']`; + } + MemberExpression.Encode = Encode; +})(MemberExpression || (MemberExpression = {})); +// ------------------------------------------------------------------- +// Identifier +// ------------------------------------------------------------------- +var Identifier; +(function (Identifier) { + function Encode($id) { + const buffer = []; + for (let i = 0; i < $id.length; i++) { + const code = $id.charCodeAt(i); + if (Character.IsNumeric(code) || Character.IsAlpha(code)) { + buffer.push($id.charAt(i)); + } + else { + buffer.push(`_${code}_`); + } + } + return buffer.join('').replace(/__/g, '_'); + } + Identifier.Encode = Encode; +})(Identifier || (Identifier = {})); +// ------------------------------------------------------------------- +// TypeCompiler +// ------------------------------------------------------------------- +class TypeCompilerUnknownTypeError extends Error { + constructor(schema) { + super('TypeCompiler: Unknown type'); + this.schema = schema; + } +} +exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError; +class TypeCompilerDereferenceError extends Error { + constructor(schema) { + super(`TypeCompiler: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.TypeCompilerDereferenceError = TypeCompilerDereferenceError; +class TypeCompilerTypeGuardError extends Error { + constructor(schema) { + super('TypeCompiler: Preflight validation check failed to guard for the given schema'); + this.schema = schema; + } +} +exports.TypeCompilerTypeGuardError = TypeCompilerTypeGuardError; +/** Compiles Types for Runtime Type Checking */ +var TypeCompiler; +(function (TypeCompiler) { + // ------------------------------------------------------------------- + // Guards + // ------------------------------------------------------------------- + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsNumber(value) { + return typeof value === 'number' && globalThis.Number.isFinite(value); + } + function IsString(value) { + return typeof value === 'string'; + } + // ------------------------------------------------------------------- + // Polices + // ------------------------------------------------------------------- + function IsExactOptionalProperty(value, key, expression) { + return index_2.TypeSystem.ExactOptionalPropertyTypes ? `('${key}' in ${value} ? ${expression} : true)` : `(${MemberExpression.Encode(value, key)} !== undefined ? ${expression} : true)`; + } + function IsObjectCheck(value) { + return !index_2.TypeSystem.AllowArrayObjects ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)`; + } + function IsRecordCheck(value) { + return !index_2.TypeSystem.AllowArrayObjects + ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))` + : `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`; + } + function IsNumberCheck(value) { + return !index_2.TypeSystem.AllowNaN ? `(typeof ${value} === 'number' && Number.isFinite(${value}))` : `typeof ${value} === 'number'`; + } + function IsVoidCheck(value) { + return index_2.TypeSystem.AllowVoidNull ? `(${value} === undefined || ${value} === null)` : `${value} === undefined`; + } + // ------------------------------------------------------------------- + // Types + // ------------------------------------------------------------------- + function* Any(schema, references, value) { + yield 'true'; + } + function* Array(schema, references, value) { + const expression = CreateExpression(schema.items, references, 'value'); + yield `Array.isArray(${value}) && ${value}.every(value => ${expression})`; + if (IsNumber(schema.minItems)) + yield `${value}.length >= ${schema.minItems}`; + if (IsNumber(schema.maxItems)) + yield `${value}.length <= ${schema.maxItems}`; + if (schema.uniqueItems === true) + yield `((function() { const set = new Set(); for(const element of ${value}) { const hashed = hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true })())`; + } + function* BigInt(schema, references, value) { + yield `(typeof ${value} === 'bigint')`; + if (IsBigInt(schema.multipleOf)) + yield `(${value} % BigInt(${schema.multipleOf})) === 0`; + if (IsBigInt(schema.exclusiveMinimum)) + yield `${value} > BigInt(${schema.exclusiveMinimum})`; + if (IsBigInt(schema.exclusiveMaximum)) + yield `${value} < BigInt(${schema.exclusiveMaximum})`; + if (IsBigInt(schema.minimum)) + yield `${value} >= BigInt(${schema.minimum})`; + if (IsBigInt(schema.maximum)) + yield `${value} <= BigInt(${schema.maximum})`; + } + function* Boolean(schema, references, value) { + yield `typeof ${value} === 'boolean'`; + } + function* Constructor(schema, references, value) { + yield* Visit(schema.returns, references, `${value}.prototype`); + } + function* Date(schema, references, value) { + yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`; + if (IsNumber(schema.exclusiveMinimumTimestamp)) + yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`; + if (IsNumber(schema.exclusiveMaximumTimestamp)) + yield `${value}.getTime() < ${schema.exclusiveMaximumTimestamp}`; + if (IsNumber(schema.minimumTimestamp)) + yield `${value}.getTime() >= ${schema.minimumTimestamp}`; + if (IsNumber(schema.maximumTimestamp)) + yield `${value}.getTime() <= ${schema.maximumTimestamp}`; + } + function* Function(schema, references, value) { + yield `typeof ${value} === 'function'`; + } + function* Integer(schema, references, value) { + yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`; + if (IsNumber(schema.multipleOf)) + yield `(${value} % ${schema.multipleOf}) === 0`; + if (IsNumber(schema.exclusiveMinimum)) + yield `${value} > ${schema.exclusiveMinimum}`; + if (IsNumber(schema.exclusiveMaximum)) + yield `${value} < ${schema.exclusiveMaximum}`; + if (IsNumber(schema.minimum)) + yield `${value} >= ${schema.minimum}`; + if (IsNumber(schema.maximum)) + yield `${value} <= ${schema.maximum}`; + } + function* Intersect(schema, references, value) { + if (schema.unevaluatedProperties === undefined) { + const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value)); + yield `${expressions.join(' && ')}`; + } + else if (schema.unevaluatedProperties === false) { + // prettier-ignore + const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', '); + const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value)); + const expression1 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key))`; + yield `${expressions.join(' && ')} && ${expression1}`; + } + else if (typeof schema.unevaluatedProperties === 'object') { + // prettier-ignore + const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', '); + const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value)); + const expression1 = CreateExpression(schema.unevaluatedProperties, references, 'value[key]'); + const expression2 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key) || ${expression1})`; + yield `${expressions.join(' && ')} && ${expression2}`; + } + } + function* Literal(schema, references, value) { + if (typeof schema.const === 'number' || typeof schema.const === 'boolean') { + yield `${value} === ${schema.const}`; + } + else { + yield `${value} === '${schema.const}'`; + } + } + function* Never(schema, references, value) { + yield `false`; + } + function* Not(schema, references, value) { + const left = CreateExpression(schema.allOf[0].not, references, value); + const right = CreateExpression(schema.allOf[1], references, value); + yield `!${left} && ${right}`; + } + function* Null(schema, references, value) { + yield `${value} === null`; + } + function* Number(schema, references, value) { + yield IsNumberCheck(value); + if (IsNumber(schema.multipleOf)) + yield `(${value} % ${schema.multipleOf}) === 0`; + if (IsNumber(schema.exclusiveMinimum)) + yield `${value} > ${schema.exclusiveMinimum}`; + if (IsNumber(schema.exclusiveMaximum)) + yield `${value} < ${schema.exclusiveMaximum}`; + if (IsNumber(schema.minimum)) + yield `${value} >= ${schema.minimum}`; + if (IsNumber(schema.maximum)) + yield `${value} <= ${schema.maximum}`; + } + function* Object(schema, references, value) { + yield IsObjectCheck(value); + if (IsNumber(schema.minProperties)) + yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`; + if (IsNumber(schema.maxProperties)) + yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`; + const knownKeys = globalThis.Object.getOwnPropertyNames(schema.properties); + for (const knownKey of knownKeys) { + const memberExpression = MemberExpression.Encode(value, knownKey); + const property = schema.properties[knownKey]; + if (schema.required && schema.required.includes(knownKey)) { + yield* Visit(property, references, memberExpression); + if (Types.ExtendsUndefined.Check(property)) + yield `('${knownKey}' in ${value})`; + } + else { + const expression = CreateExpression(property, references, memberExpression); + yield IsExactOptionalProperty(value, knownKey, expression); + } + } + if (schema.additionalProperties === false) { + if (schema.required && schema.required.length === knownKeys.length) { + yield `Object.getOwnPropertyNames(${value}).length === ${knownKeys.length}`; + } + else { + const keys = `[${knownKeys.map((key) => `'${key}'`).join(', ')}]`; + yield `Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key))`; + } + } + if (typeof schema.additionalProperties === 'object') { + const expression = CreateExpression(schema.additionalProperties, references, 'value[key]'); + const keys = `[${knownKeys.map((key) => `'${key}'`).join(', ')}]`; + yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`; + } + } + function* Promise(schema, references, value) { + yield `(typeof value === 'object' && typeof ${value}.then === 'function')`; + } + function* Record(schema, references, value) { + yield IsRecordCheck(value); + if (IsNumber(schema.minProperties)) + yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`; + if (IsNumber(schema.maxProperties)) + yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`; + const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0]; + const local = PushLocal(`new RegExp(/${keyPattern}/)`); + yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`; + const expression = CreateExpression(valueSchema, references, 'value'); + yield `Object.values(${value}).every(value => ${expression})`; + } + function* Ref(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new TypeCompilerDereferenceError(schema); + const target = references[index]; + // Reference: If we have seen this reference before we can just yield and return + // the function call. If this isn't the case we defer to visit to generate and + // set the function for subsequent passes. Consider for refactor. + if (state_local_function_names.has(schema.$ref)) + return yield `${CreateFunctionName(schema.$ref)}(${value})`; + yield* Visit(target, references, value); + } + function* String(schema, references, value) { + yield `(typeof ${value} === 'string')`; + if (IsNumber(schema.minLength)) + yield `${value}.length >= ${schema.minLength}`; + if (IsNumber(schema.maxLength)) + yield `${value}.length <= ${schema.maxLength}`; + if (schema.pattern !== undefined) { + const local = PushLocal(`${new RegExp(schema.pattern)};`); + yield `${local}.test(${value})`; + } + if (schema.format !== undefined) { + yield `format('${schema.format}', ${value})`; + } + } + function* Symbol(schema, references, value) { + yield `(typeof ${value} === 'symbol')`; + } + function* TemplateLiteral(schema, references, value) { + yield `(typeof ${value} === 'string')`; + const local = PushLocal(`${new RegExp(schema.pattern)};`); + yield `${local}.test(${value})`; + } + function* This(schema, references, value) { + const func = CreateFunctionName(schema.$ref); + yield `${func}(${value})`; + } + function* Tuple(schema, references, value) { + yield `(Array.isArray(${value}))`; + if (schema.items === undefined) + return yield `${value}.length === 0`; + yield `(${value}.length === ${schema.maxItems})`; + for (let i = 0; i < schema.items.length; i++) { + const expression = CreateExpression(schema.items[i], references, `${value}[${i}]`); + yield `${expression}`; + } + } + function* Undefined(schema, references, value) { + yield `${value} === undefined`; + } + function* Union(schema, references, value) { + const expressions = schema.anyOf.map((schema) => CreateExpression(schema, references, value)); + yield `(${expressions.join(' || ')})`; + } + function* Uint8Array(schema, references, value) { + yield `${value} instanceof Uint8Array`; + if (IsNumber(schema.maxByteLength)) + yield `(${value}.length <= ${schema.maxByteLength})`; + if (IsNumber(schema.minByteLength)) + yield `(${value}.length >= ${schema.minByteLength})`; + } + function* Unknown(schema, references, value) { + yield 'true'; + } + function* Void(schema, references, value) { + yield IsVoidCheck(value); + } + function* UserDefined(schema, references, value) { + const schema_key = `schema_key_${state_remote_custom_types.size}`; + state_remote_custom_types.set(schema_key, schema); + yield `custom('${schema[Types.Kind]}', '${schema_key}', ${value})`; + } + function* Visit(schema, references, value) { + const references_ = IsString(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + // Reference: Referenced schemas can originate from either additional schemas + // or inline in the schema itself. Ideally the recursive path should align to + // reference path. Consider for refactor. + if (IsString(schema.$id) && !state_local_function_names.has(schema.$id)) { + state_local_function_names.add(schema.$id); + const name = CreateFunctionName(schema.$id); + const body = CreateFunction(name, schema, references, 'value'); + PushFunction(body); + yield `${name}(${value})`; + return; + } + switch (schema_[Types.Kind]) { + case 'Any': + return yield* Any(schema_, references_, value); + case 'Array': + return yield* Array(schema_, references_, value); + case 'BigInt': + return yield* BigInt(schema_, references_, value); + case 'Boolean': + return yield* Boolean(schema_, references_, value); + case 'Constructor': + return yield* Constructor(schema_, references_, value); + case 'Date': + return yield* Date(schema_, references_, value); + case 'Function': + return yield* Function(schema_, references_, value); + case 'Integer': + return yield* Integer(schema_, references_, value); + case 'Intersect': + return yield* Intersect(schema_, references_, value); + case 'Literal': + return yield* Literal(schema_, references_, value); + case 'Never': + return yield* Never(schema_, references_, value); + case 'Not': + return yield* Not(schema_, references_, value); + case 'Null': + return yield* Null(schema_, references_, value); + case 'Number': + return yield* Number(schema_, references_, value); + case 'Object': + return yield* Object(schema_, references_, value); + case 'Promise': + return yield* Promise(schema_, references_, value); + case 'Record': + return yield* Record(schema_, references_, value); + case 'Ref': + return yield* Ref(schema_, references_, value); + case 'String': + return yield* String(schema_, references_, value); + case 'Symbol': + return yield* Symbol(schema_, references_, value); + case 'TemplateLiteral': + return yield* TemplateLiteral(schema_, references_, value); + case 'This': + return yield* This(schema_, references_, value); + case 'Tuple': + return yield* Tuple(schema_, references_, value); + case 'Undefined': + return yield* Undefined(schema_, references_, value); + case 'Union': + return yield* Union(schema_, references_, value); + case 'Uint8Array': + return yield* Uint8Array(schema_, references_, value); + case 'Unknown': + return yield* Unknown(schema_, references_, value); + case 'Void': + return yield* Void(schema_, references_, value); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new TypeCompilerUnknownTypeError(schema); + return yield* UserDefined(schema_, references_, value); + } + } + // ------------------------------------------------------------------- + // Compiler State + // ------------------------------------------------------------------- + const state_local_variables = new Set(); // local variables and functions + const state_local_function_names = new Set(); // local function names used call ref validators + const state_remote_custom_types = new Map(); // remote custom types used during compilation + function ResetCompiler() { + state_local_variables.clear(); + state_local_function_names.clear(); + state_remote_custom_types.clear(); + } + function CreateExpression(schema, references, value) { + return `(${[...Visit(schema, references, value)].join(' && ')})`; + } + function CreateFunctionName($id) { + return `check_${Identifier.Encode($id)}`; + } + function CreateFunction(name, schema, references, value) { + const expression = [...Visit(schema, references, value)].map((condition) => ` ${condition}`).join(' &&\n'); + return `function ${name}(value) {\n return (\n${expression}\n )\n}`; + } + function PushFunction(functionBody) { + state_local_variables.add(functionBody); + } + function PushLocal(expression) { + const local = `local_${state_local_variables.size}`; + state_local_variables.add(`const ${local} = ${expression}`); + return local; + } + function GetLocals() { + return [...state_local_variables.values()]; + } + // ------------------------------------------------------------------- + // Compile + // ------------------------------------------------------------------- + function Build(schema, references) { + ResetCompiler(); + const check = CreateFunction('check', schema, references, 'value'); + const locals = GetLocals(); + return `${locals.join('\n')}\nreturn ${check}`; + } + /** Returns the generated assertion code used to validate this type. */ + function Code(schema, references = []) { + if (!Types.TypeGuard.TSchema(schema)) + throw new TypeCompilerTypeGuardError(schema); + for (const schema of references) + if (!Types.TypeGuard.TSchema(schema)) + throw new TypeCompilerTypeGuardError(schema); + return Build(schema, references); + } + TypeCompiler.Code = Code; + /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */ + function Compile(schema, references = []) { + const code = Code(schema, references); + const custom_schemas = new Map(state_remote_custom_types); + const compiledFunction = globalThis.Function('custom', 'format', 'hash', code); + const checkFunction = compiledFunction((kind, schema_key, value) => { + if (!Types.TypeRegistry.Has(kind) || !custom_schemas.has(schema_key)) + return false; + const schema = custom_schemas.get(schema_key); + const func = Types.TypeRegistry.Get(kind); + return func(schema, value); + }, (format, value) => { + if (!Types.FormatRegistry.Has(format)) + return false; + const func = Types.FormatRegistry.Get(format); + return func(value); + }, (value) => { + return hash_1.ValueHash.Create(value); + }); + return new TypeCheck(schema, references, checkFunction, code); + } + TypeCompiler.Compile = Compile; +})(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {})); diff --git a/node_modules/@sinclair/typebox/compiler/index.d.ts b/node_modules/@sinclair/typebox/compiler/index.d.ts new file mode 100644 index 0000000..4062a62 --- /dev/null +++ b/node_modules/@sinclair/typebox/compiler/index.d.ts @@ -0,0 +1,2 @@ +export { ValueError, ValueErrorType } from '../errors/index'; +export * from './compiler'; diff --git a/node_modules/@sinclair/typebox/compiler/index.js b/node_modules/@sinclair/typebox/compiler/index.js new file mode 100644 index 0000000..7a013c3 --- /dev/null +++ b/node_modules/@sinclair/typebox/compiler/index.js @@ -0,0 +1,47 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/compiler + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueErrorType = void 0; +var index_1 = require("../errors/index"); +Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } }); +__exportStar(require("./compiler"), exports); diff --git a/node_modules/@sinclair/typebox/errors/errors.d.ts b/node_modules/@sinclair/typebox/errors/errors.d.ts new file mode 100644 index 0000000..89786c6 --- /dev/null +++ b/node_modules/@sinclair/typebox/errors/errors.d.ts @@ -0,0 +1,88 @@ +import * as Types from '../typebox'; +export declare enum ValueErrorType { + Array = 0, + ArrayMinItems = 1, + ArrayMaxItems = 2, + ArrayUniqueItems = 3, + BigInt = 4, + BigIntMultipleOf = 5, + BigIntExclusiveMinimum = 6, + BigIntExclusiveMaximum = 7, + BigIntMinimum = 8, + BigIntMaximum = 9, + Boolean = 10, + Date = 11, + DateExclusiveMinimumTimestamp = 12, + DateExclusiveMaximumTimestamp = 13, + DateMinimumTimestamp = 14, + DateMaximumTimestamp = 15, + Function = 16, + Integer = 17, + IntegerMultipleOf = 18, + IntegerExclusiveMinimum = 19, + IntegerExclusiveMaximum = 20, + IntegerMinimum = 21, + IntegerMaximum = 22, + Intersect = 23, + IntersectUnevaluatedProperties = 24, + Literal = 25, + Never = 26, + Not = 27, + Null = 28, + Number = 29, + NumberMultipleOf = 30, + NumberExclusiveMinimum = 31, + NumberExclusiveMaximum = 32, + NumberMinumum = 33, + NumberMaximum = 34, + Object = 35, + ObjectMinProperties = 36, + ObjectMaxProperties = 37, + ObjectAdditionalProperties = 38, + ObjectRequiredProperties = 39, + Promise = 40, + RecordKeyNumeric = 41, + RecordKeyString = 42, + String = 43, + StringMinLength = 44, + StringMaxLength = 45, + StringPattern = 46, + StringFormatUnknown = 47, + StringFormat = 48, + Symbol = 49, + TupleZeroLength = 50, + TupleLength = 51, + Undefined = 52, + Union = 53, + Uint8Array = 54, + Uint8ArrayMinByteLength = 55, + Uint8ArrayMaxByteLength = 56, + Void = 57, + Custom = 58 +} +export interface ValueError { + type: ValueErrorType; + schema: Types.TSchema; + path: string; + value: unknown; + message: string; +} +export declare class ValueErrorIterator { + private readonly iterator; + constructor(iterator: IterableIterator); + [Symbol.iterator](): IterableIterator; + /** Returns the first value error or undefined if no errors */ + First(): ValueError | undefined; +} +export declare class ValueErrorsUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueErrorsDereferenceError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +/** Provides functionality to generate a sequence of errors against a TypeBox type. */ +export declare namespace ValueErrors { + function Errors(schema: T, references: Types.TSchema[], value: any): ValueErrorIterator; +} diff --git a/node_modules/@sinclair/typebox/errors/errors.js b/node_modules/@sinclair/typebox/errors/errors.js new file mode 100644 index 0000000..4f7210b --- /dev/null +++ b/node_modules/@sinclair/typebox/errors/errors.js @@ -0,0 +1,609 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueErrors = exports.ValueErrorsDereferenceError = exports.ValueErrorsUnknownTypeError = exports.ValueErrorIterator = exports.ValueErrorType = void 0; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/errors + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +const Types = require("../typebox"); +const index_1 = require("../system/index"); +const hash_1 = require("../value/hash"); +// ------------------------------------------------------------------- +// ValueErrorType +// ------------------------------------------------------------------- +var ValueErrorType; +(function (ValueErrorType) { + ValueErrorType[ValueErrorType["Array"] = 0] = "Array"; + ValueErrorType[ValueErrorType["ArrayMinItems"] = 1] = "ArrayMinItems"; + ValueErrorType[ValueErrorType["ArrayMaxItems"] = 2] = "ArrayMaxItems"; + ValueErrorType[ValueErrorType["ArrayUniqueItems"] = 3] = "ArrayUniqueItems"; + ValueErrorType[ValueErrorType["BigInt"] = 4] = "BigInt"; + ValueErrorType[ValueErrorType["BigIntMultipleOf"] = 5] = "BigIntMultipleOf"; + ValueErrorType[ValueErrorType["BigIntExclusiveMinimum"] = 6] = "BigIntExclusiveMinimum"; + ValueErrorType[ValueErrorType["BigIntExclusiveMaximum"] = 7] = "BigIntExclusiveMaximum"; + ValueErrorType[ValueErrorType["BigIntMinimum"] = 8] = "BigIntMinimum"; + ValueErrorType[ValueErrorType["BigIntMaximum"] = 9] = "BigIntMaximum"; + ValueErrorType[ValueErrorType["Boolean"] = 10] = "Boolean"; + ValueErrorType[ValueErrorType["Date"] = 11] = "Date"; + ValueErrorType[ValueErrorType["DateExclusiveMinimumTimestamp"] = 12] = "DateExclusiveMinimumTimestamp"; + ValueErrorType[ValueErrorType["DateExclusiveMaximumTimestamp"] = 13] = "DateExclusiveMaximumTimestamp"; + ValueErrorType[ValueErrorType["DateMinimumTimestamp"] = 14] = "DateMinimumTimestamp"; + ValueErrorType[ValueErrorType["DateMaximumTimestamp"] = 15] = "DateMaximumTimestamp"; + ValueErrorType[ValueErrorType["Function"] = 16] = "Function"; + ValueErrorType[ValueErrorType["Integer"] = 17] = "Integer"; + ValueErrorType[ValueErrorType["IntegerMultipleOf"] = 18] = "IntegerMultipleOf"; + ValueErrorType[ValueErrorType["IntegerExclusiveMinimum"] = 19] = "IntegerExclusiveMinimum"; + ValueErrorType[ValueErrorType["IntegerExclusiveMaximum"] = 20] = "IntegerExclusiveMaximum"; + ValueErrorType[ValueErrorType["IntegerMinimum"] = 21] = "IntegerMinimum"; + ValueErrorType[ValueErrorType["IntegerMaximum"] = 22] = "IntegerMaximum"; + ValueErrorType[ValueErrorType["Intersect"] = 23] = "Intersect"; + ValueErrorType[ValueErrorType["IntersectUnevaluatedProperties"] = 24] = "IntersectUnevaluatedProperties"; + ValueErrorType[ValueErrorType["Literal"] = 25] = "Literal"; + ValueErrorType[ValueErrorType["Never"] = 26] = "Never"; + ValueErrorType[ValueErrorType["Not"] = 27] = "Not"; + ValueErrorType[ValueErrorType["Null"] = 28] = "Null"; + ValueErrorType[ValueErrorType["Number"] = 29] = "Number"; + ValueErrorType[ValueErrorType["NumberMultipleOf"] = 30] = "NumberMultipleOf"; + ValueErrorType[ValueErrorType["NumberExclusiveMinimum"] = 31] = "NumberExclusiveMinimum"; + ValueErrorType[ValueErrorType["NumberExclusiveMaximum"] = 32] = "NumberExclusiveMaximum"; + ValueErrorType[ValueErrorType["NumberMinumum"] = 33] = "NumberMinumum"; + ValueErrorType[ValueErrorType["NumberMaximum"] = 34] = "NumberMaximum"; + ValueErrorType[ValueErrorType["Object"] = 35] = "Object"; + ValueErrorType[ValueErrorType["ObjectMinProperties"] = 36] = "ObjectMinProperties"; + ValueErrorType[ValueErrorType["ObjectMaxProperties"] = 37] = "ObjectMaxProperties"; + ValueErrorType[ValueErrorType["ObjectAdditionalProperties"] = 38] = "ObjectAdditionalProperties"; + ValueErrorType[ValueErrorType["ObjectRequiredProperties"] = 39] = "ObjectRequiredProperties"; + ValueErrorType[ValueErrorType["Promise"] = 40] = "Promise"; + ValueErrorType[ValueErrorType["RecordKeyNumeric"] = 41] = "RecordKeyNumeric"; + ValueErrorType[ValueErrorType["RecordKeyString"] = 42] = "RecordKeyString"; + ValueErrorType[ValueErrorType["String"] = 43] = "String"; + ValueErrorType[ValueErrorType["StringMinLength"] = 44] = "StringMinLength"; + ValueErrorType[ValueErrorType["StringMaxLength"] = 45] = "StringMaxLength"; + ValueErrorType[ValueErrorType["StringPattern"] = 46] = "StringPattern"; + ValueErrorType[ValueErrorType["StringFormatUnknown"] = 47] = "StringFormatUnknown"; + ValueErrorType[ValueErrorType["StringFormat"] = 48] = "StringFormat"; + ValueErrorType[ValueErrorType["Symbol"] = 49] = "Symbol"; + ValueErrorType[ValueErrorType["TupleZeroLength"] = 50] = "TupleZeroLength"; + ValueErrorType[ValueErrorType["TupleLength"] = 51] = "TupleLength"; + ValueErrorType[ValueErrorType["Undefined"] = 52] = "Undefined"; + ValueErrorType[ValueErrorType["Union"] = 53] = "Union"; + ValueErrorType[ValueErrorType["Uint8Array"] = 54] = "Uint8Array"; + ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 55] = "Uint8ArrayMinByteLength"; + ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 56] = "Uint8ArrayMaxByteLength"; + ValueErrorType[ValueErrorType["Void"] = 57] = "Void"; + ValueErrorType[ValueErrorType["Custom"] = 58] = "Custom"; +})(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {})); +// ------------------------------------------------------------------- +// ValueErrorIterator +// ------------------------------------------------------------------- +class ValueErrorIterator { + constructor(iterator) { + this.iterator = iterator; + } + [Symbol.iterator]() { + return this.iterator; + } + /** Returns the first value error or undefined if no errors */ + First() { + const next = this.iterator.next(); + return next.done ? undefined : next.value; + } +} +exports.ValueErrorIterator = ValueErrorIterator; +// ------------------------------------------------------------------- +// ValueErrors +// ------------------------------------------------------------------- +class ValueErrorsUnknownTypeError extends Error { + constructor(schema) { + super('ValueErrors: Unknown type'); + this.schema = schema; + } +} +exports.ValueErrorsUnknownTypeError = ValueErrorsUnknownTypeError; +class ValueErrorsDereferenceError extends Error { + constructor(schema) { + super(`ValueErrors: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueErrorsDereferenceError = ValueErrorsDereferenceError; +/** Provides functionality to generate a sequence of errors against a TypeBox type. */ +var ValueErrors; +(function (ValueErrors) { + // ---------------------------------------------------------------------- + // Guards + // ---------------------------------------------------------------------- + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsInteger(value) { + return globalThis.Number.isInteger(value); + } + function IsString(value) { + return typeof value === 'string'; + } + function IsDefined(value) { + return value !== undefined; + } + // ---------------------------------------------------------------------- + // Policies + // ---------------------------------------------------------------------- + function IsExactOptionalProperty(value, key) { + return index_1.TypeSystem.ExactOptionalPropertyTypes ? key in value : value[key] !== undefined; + } + function IsObject(value) { + const result = typeof value === 'object' && value !== null; + return index_1.TypeSystem.AllowArrayObjects ? result : result && !globalThis.Array.isArray(value); + } + function IsRecordObject(value) { + return IsObject(value) && !(value instanceof globalThis.Date) && !(value instanceof globalThis.Uint8Array); + } + function IsNumber(value) { + const result = typeof value === 'number'; + return index_1.TypeSystem.AllowNaN ? result : result && globalThis.Number.isFinite(value); + } + function IsVoid(value) { + const result = value === undefined; + return index_1.TypeSystem.AllowVoidNull ? result || value === null : result; + } + // ---------------------------------------------------------------------- + // Types + // ---------------------------------------------------------------------- + function* Any(schema, references, path, value) { } + function* Array(schema, references, path, value) { + if (!globalThis.Array.isArray(value)) { + return yield { type: ValueErrorType.Array, schema, path, value, message: `Expected array` }; + } + if (IsDefined(schema.minItems) && !(value.length >= schema.minItems)) { + yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be greater or equal to ${schema.minItems}` }; + } + if (IsDefined(schema.maxItems) && !(value.length <= schema.maxItems)) { + yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be less or equal to ${schema.maxItems}` }; + } + // prettier-ignore + if (schema.uniqueItems === true && !((function () { const set = new Set(); for (const element of value) { + const hashed = hash_1.ValueHash.Create(element); + if (set.has(hashed)) { + return false; + } + else { + set.add(hashed); + } + } return true; })())) { + yield { type: ValueErrorType.ArrayUniqueItems, schema, path, value, message: `Expected array elements to be unique` }; + } + for (let i = 0; i < value.length; i++) { + yield* Visit(schema.items, references, `${path}/${i}`, value[i]); + } + } + function* BigInt(schema, references, path, value) { + if (!IsBigInt(value)) { + return yield { type: ValueErrorType.BigInt, schema, path, value, message: `Expected bigint` }; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === globalThis.BigInt(0))) { + yield { type: ValueErrorType.BigIntMultipleOf, schema, path, value, message: `Expected bigint to be a multiple of ${schema.multipleOf}` }; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + yield { type: ValueErrorType.BigIntExclusiveMinimum, schema, path, value, message: `Expected bigint to be greater than ${schema.exclusiveMinimum}` }; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + yield { type: ValueErrorType.BigIntExclusiveMaximum, schema, path, value, message: `Expected bigint to be less than ${schema.exclusiveMaximum}` }; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + yield { type: ValueErrorType.BigIntMinimum, schema, path, value, message: `Expected bigint to be greater or equal to ${schema.minimum}` }; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + yield { type: ValueErrorType.BigIntMaximum, schema, path, value, message: `Expected bigint to be less or equal to ${schema.maximum}` }; + } + } + function* Boolean(schema, references, path, value) { + if (!(typeof value === 'boolean')) { + return yield { type: ValueErrorType.Boolean, schema, path, value, message: `Expected boolean` }; + } + } + function* Constructor(schema, references, path, value) { + yield* Visit(schema.returns, references, path, value.prototype); + } + function* Date(schema, references, path, value) { + if (!(value instanceof globalThis.Date)) { + return yield { type: ValueErrorType.Date, schema, path, value, message: `Expected Date object` }; + } + if (!globalThis.isFinite(value.getTime())) { + return yield { type: ValueErrorType.Date, schema, path, value, message: `Invalid Date` }; + } + if (IsDefined(schema.exclusiveMinimumTimestamp) && !(value.getTime() > schema.exclusiveMinimumTimestamp)) { + yield { type: ValueErrorType.DateExclusiveMinimumTimestamp, schema, path, value, message: `Expected Date timestamp to be greater than ${schema.exclusiveMinimum}` }; + } + if (IsDefined(schema.exclusiveMaximumTimestamp) && !(value.getTime() < schema.exclusiveMaximumTimestamp)) { + yield { type: ValueErrorType.DateExclusiveMaximumTimestamp, schema, path, value, message: `Expected Date timestamp to be less than ${schema.exclusiveMaximum}` }; + } + if (IsDefined(schema.minimumTimestamp) && !(value.getTime() >= schema.minimumTimestamp)) { + yield { type: ValueErrorType.DateMinimumTimestamp, schema, path, value, message: `Expected Date timestamp to be greater or equal to ${schema.minimum}` }; + } + if (IsDefined(schema.maximumTimestamp) && !(value.getTime() <= schema.maximumTimestamp)) { + yield { type: ValueErrorType.DateMaximumTimestamp, schema, path, value, message: `Expected Date timestamp to be less or equal to ${schema.maximum}` }; + } + } + function* Function(schema, references, path, value) { + if (!(typeof value === 'function')) { + return yield { type: ValueErrorType.Function, schema, path, value, message: `Expected function` }; + } + } + function* Integer(schema, references, path, value) { + if (!IsInteger(value)) { + return yield { type: ValueErrorType.Integer, schema, path, value, message: `Expected integer` }; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { + yield { type: ValueErrorType.IntegerMultipleOf, schema, path, value, message: `Expected integer to be a multiple of ${schema.multipleOf}` }; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + yield { type: ValueErrorType.IntegerExclusiveMinimum, schema, path, value, message: `Expected integer to be greater than ${schema.exclusiveMinimum}` }; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + yield { type: ValueErrorType.IntegerExclusiveMaximum, schema, path, value, message: `Expected integer to be less than ${schema.exclusiveMaximum}` }; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + yield { type: ValueErrorType.IntegerMinimum, schema, path, value, message: `Expected integer to be greater or equal to ${schema.minimum}` }; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + yield { type: ValueErrorType.IntegerMaximum, schema, path, value, message: `Expected integer to be less or equal to ${schema.maximum}` }; + } + } + function* Intersect(schema, references, path, value) { + for (const subschema of schema.allOf) { + const next = Visit(subschema, references, path, value).next(); + if (!next.done) { + yield next.value; + yield { type: ValueErrorType.Intersect, schema, path, value, message: `Expected all sub schemas to be valid` }; + return; + } + } + if (schema.unevaluatedProperties === false) { + const schemaKeys = Types.KeyResolver.Resolve(schema); + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + for (const valueKey of valueKeys) { + if (!schemaKeys.includes(valueKey)) { + yield { type: ValueErrorType.IntersectUnevaluatedProperties, schema, path: `${path}/${valueKey}`, value, message: `Unexpected property` }; + } + } + } + if (typeof schema.unevaluatedProperties === 'object') { + const schemaKeys = Types.KeyResolver.Resolve(schema); + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + for (const valueKey of valueKeys) { + if (!schemaKeys.includes(valueKey)) { + const next = Visit(schema.unevaluatedProperties, references, `${path}/${valueKey}`, value[valueKey]).next(); + if (!next.done) { + yield next.value; + yield { type: ValueErrorType.IntersectUnevaluatedProperties, schema, path: `${path}/${valueKey}`, value, message: `Invalid additional property` }; + return; + } + } + } + } + } + function* Literal(schema, references, path, value) { + if (!(value === schema.const)) { + const error = typeof schema.const === 'string' ? `'${schema.const}'` : schema.const; + return yield { type: ValueErrorType.Literal, schema, path, value, message: `Expected ${error}` }; + } + } + function* Never(schema, references, path, value) { + yield { type: ValueErrorType.Never, schema, path, value, message: `Value cannot be validated` }; + } + function* Not(schema, references, path, value) { + if (Visit(schema.allOf[0].not, references, path, value).next().done === true) { + yield { type: ValueErrorType.Not, schema, path, value, message: `Value should not validate` }; + } + yield* Visit(schema.allOf[1], references, path, value); + } + function* Null(schema, references, path, value) { + if (!(value === null)) { + return yield { type: ValueErrorType.Null, schema, path, value, message: `Expected null` }; + } + } + function* Number(schema, references, path, value) { + if (!IsNumber(value)) { + return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` }; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { + yield { type: ValueErrorType.NumberMultipleOf, schema, path, value, message: `Expected number to be a multiple of ${schema.multipleOf}` }; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + yield { type: ValueErrorType.NumberExclusiveMinimum, schema, path, value, message: `Expected number to be greater than ${schema.exclusiveMinimum}` }; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + yield { type: ValueErrorType.NumberExclusiveMaximum, schema, path, value, message: `Expected number to be less than ${schema.exclusiveMaximum}` }; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + yield { type: ValueErrorType.NumberMaximum, schema, path, value, message: `Expected number to be greater or equal to ${schema.minimum}` }; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + yield { type: ValueErrorType.NumberMinumum, schema, path, value, message: `Expected number to be less or equal to ${schema.maximum}` }; + } + } + function* Object(schema, references, path, value) { + if (!IsObject(value)) { + return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` }; + } + if (IsDefined(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) { + yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` }; + } + if (IsDefined(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { + yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` }; + } + const requiredKeys = globalThis.Array.isArray(schema.required) ? schema.required : []; + const knownKeys = globalThis.Object.getOwnPropertyNames(schema.properties); + const unknownKeys = globalThis.Object.getOwnPropertyNames(value); + for (const knownKey of knownKeys) { + const property = schema.properties[knownKey]; + if (schema.required && schema.required.includes(knownKey)) { + yield* Visit(property, references, `${path}/${knownKey}`, value[knownKey]); + if (Types.ExtendsUndefined.Check(schema) && !(knownKey in value)) { + yield { type: ValueErrorType.ObjectRequiredProperties, schema: property, path: `${path}/${knownKey}`, value: undefined, message: `Expected required property` }; + } + } + else { + if (IsExactOptionalProperty(value, knownKey)) { + yield* Visit(property, references, `${path}/${knownKey}`, value[knownKey]); + } + } + } + for (const requiredKey of requiredKeys) { + if (unknownKeys.includes(requiredKey)) + continue; + yield { type: ValueErrorType.ObjectRequiredProperties, schema: schema.properties[requiredKey], path: `${path}/${requiredKey}`, value: undefined, message: `Expected required property` }; + } + if (schema.additionalProperties === false) { + for (const valueKey of unknownKeys) { + if (!knownKeys.includes(valueKey)) { + yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${valueKey}`, value: value[valueKey], message: `Unexpected property` }; + } + } + } + if (typeof schema.additionalProperties === 'object') { + for (const valueKey of unknownKeys) { + if (knownKeys.includes(valueKey)) + continue; + yield* Visit(schema.additionalProperties, references, `${path}/${valueKey}`, value[valueKey]); + } + } + } + function* Promise(schema, references, path, value) { + if (!(typeof value === 'object' && typeof value.then === 'function')) { + yield { type: ValueErrorType.Promise, schema, path, value, message: `Expected Promise` }; + } + } + function* Record(schema, references, path, value) { + if (!IsRecordObject(value)) { + return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected record object` }; + } + if (IsDefined(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) { + yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` }; + } + if (IsDefined(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { + yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` }; + } + const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0]; + const regex = new RegExp(keyPattern); + if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) { + const numeric = keyPattern === Types.PatternNumberExact; + const type = numeric ? ValueErrorType.RecordKeyNumeric : ValueErrorType.RecordKeyString; + const message = numeric ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings'; + return yield { type, schema, path, value, message }; + } + for (const [propKey, propValue] of globalThis.Object.entries(value)) { + yield* Visit(valueSchema, references, `${path}/${propKey}`, propValue); + } + } + function* Ref(schema, references, path, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueErrorsDereferenceError(schema); + const target = references[index]; + yield* Visit(target, references, path, value); + } + function* String(schema, references, path, value) { + if (!IsString(value)) { + return yield { type: ValueErrorType.String, schema, path, value, message: 'Expected string' }; + } + if (IsDefined(schema.minLength) && !(value.length >= schema.minLength)) { + yield { type: ValueErrorType.StringMinLength, schema, path, value, message: `Expected string length greater or equal to ${schema.minLength}` }; + } + if (IsDefined(schema.maxLength) && !(value.length <= schema.maxLength)) { + yield { type: ValueErrorType.StringMaxLength, schema, path, value, message: `Expected string length less or equal to ${schema.maxLength}` }; + } + if (schema.pattern !== undefined) { + const regex = new RegExp(schema.pattern); + if (!regex.test(value)) { + yield { type: ValueErrorType.StringPattern, schema, path, value, message: `Expected string to match pattern ${schema.pattern}` }; + } + } + if (schema.format !== undefined) { + if (!Types.FormatRegistry.Has(schema.format)) { + yield { type: ValueErrorType.StringFormatUnknown, schema, path, value, message: `Unknown string format '${schema.format}'` }; + } + else { + const format = Types.FormatRegistry.Get(schema.format); + if (!format(value)) { + yield { type: ValueErrorType.StringFormat, schema, path, value, message: `Expected string to match format '${schema.format}'` }; + } + } + } + } + function* Symbol(schema, references, path, value) { + if (!(typeof value === 'symbol')) { + return yield { type: ValueErrorType.Symbol, schema, path, value, message: 'Expected symbol' }; + } + } + function* TemplateLiteral(schema, references, path, value) { + if (!IsString(value)) { + return yield { type: ValueErrorType.String, schema, path, value, message: 'Expected string' }; + } + const regex = new RegExp(schema.pattern); + if (!regex.test(value)) { + yield { type: ValueErrorType.StringPattern, schema, path, value, message: `Expected string to match pattern ${schema.pattern}` }; + } + } + function* This(schema, references, path, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueErrorsDereferenceError(schema); + const target = references[index]; + yield* Visit(target, references, path, value); + } + function* Tuple(schema, references, path, value) { + if (!globalThis.Array.isArray(value)) { + return yield { type: ValueErrorType.Array, schema, path, value, message: 'Expected Array' }; + } + if (schema.items === undefined && !(value.length === 0)) { + return yield { type: ValueErrorType.TupleZeroLength, schema, path, value, message: 'Expected tuple to have 0 elements' }; + } + if (!(value.length === schema.maxItems)) { + yield { type: ValueErrorType.TupleLength, schema, path, value, message: `Expected tuple to have ${schema.maxItems} elements` }; + } + if (!schema.items) { + return; + } + for (let i = 0; i < schema.items.length; i++) { + yield* Visit(schema.items[i], references, `${path}/${i}`, value[i]); + } + } + function* Undefined(schema, references, path, value) { + if (!(value === undefined)) { + yield { type: ValueErrorType.Undefined, schema, path, value, message: `Expected undefined` }; + } + } + function* Union(schema, references, path, value) { + const errors = []; + for (const inner of schema.anyOf) { + const variantErrors = [...Visit(inner, references, path, value)]; + if (variantErrors.length === 0) + return; + errors.push(...variantErrors); + } + if (errors.length > 0) { + yield { type: ValueErrorType.Union, schema, path, value, message: 'Expected value of union' }; + } + for (const error of errors) { + yield error; + } + } + function* Uint8Array(schema, references, path, value) { + if (!(value instanceof globalThis.Uint8Array)) { + return yield { type: ValueErrorType.Uint8Array, schema, path, value, message: `Expected Uint8Array` }; + } + if (IsDefined(schema.maxByteLength) && !(value.length <= schema.maxByteLength)) { + yield { type: ValueErrorType.Uint8ArrayMaxByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length less or equal to ${schema.maxByteLength}` }; + } + if (IsDefined(schema.minByteLength) && !(value.length >= schema.minByteLength)) { + yield { type: ValueErrorType.Uint8ArrayMinByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length greater or equal to ${schema.maxByteLength}` }; + } + } + function* Unknown(schema, references, path, value) { } + function* Void(schema, references, path, value) { + if (!IsVoid(value)) { + return yield { type: ValueErrorType.Void, schema, path, value, message: `Expected void` }; + } + } + function* UserDefined(schema, references, path, value) { + const check = Types.TypeRegistry.Get(schema[Types.Kind]); + if (!check(schema, value)) { + return yield { type: ValueErrorType.Custom, schema, path, value, message: `Expected kind ${schema[Types.Kind]}` }; + } + } + function* Visit(schema, references, path, value) { + const references_ = IsDefined(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + switch (schema_[Types.Kind]) { + case 'Any': + return yield* Any(schema_, references_, path, value); + case 'Array': + return yield* Array(schema_, references_, path, value); + case 'BigInt': + return yield* BigInt(schema_, references_, path, value); + case 'Boolean': + return yield* Boolean(schema_, references_, path, value); + case 'Constructor': + return yield* Constructor(schema_, references_, path, value); + case 'Date': + return yield* Date(schema_, references_, path, value); + case 'Function': + return yield* Function(schema_, references_, path, value); + case 'Integer': + return yield* Integer(schema_, references_, path, value); + case 'Intersect': + return yield* Intersect(schema_, references_, path, value); + case 'Literal': + return yield* Literal(schema_, references_, path, value); + case 'Never': + return yield* Never(schema_, references_, path, value); + case 'Not': + return yield* Not(schema_, references_, path, value); + case 'Null': + return yield* Null(schema_, references_, path, value); + case 'Number': + return yield* Number(schema_, references_, path, value); + case 'Object': + return yield* Object(schema_, references_, path, value); + case 'Promise': + return yield* Promise(schema_, references_, path, value); + case 'Record': + return yield* Record(schema_, references_, path, value); + case 'Ref': + return yield* Ref(schema_, references_, path, value); + case 'String': + return yield* String(schema_, references_, path, value); + case 'Symbol': + return yield* Symbol(schema_, references_, path, value); + case 'TemplateLiteral': + return yield* TemplateLiteral(schema_, references_, path, value); + case 'This': + return yield* This(schema_, references_, path, value); + case 'Tuple': + return yield* Tuple(schema_, references_, path, value); + case 'Undefined': + return yield* Undefined(schema_, references_, path, value); + case 'Union': + return yield* Union(schema_, references_, path, value); + case 'Uint8Array': + return yield* Uint8Array(schema_, references_, path, value); + case 'Unknown': + return yield* Unknown(schema_, references_, path, value); + case 'Void': + return yield* Void(schema_, references_, path, value); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new ValueErrorsUnknownTypeError(schema); + return yield* UserDefined(schema_, references_, path, value); + } + } + function Errors(schema, references, value) { + const iterator = Visit(schema, references, '', value); + return new ValueErrorIterator(iterator); + } + ValueErrors.Errors = Errors; +})(ValueErrors = exports.ValueErrors || (exports.ValueErrors = {})); diff --git a/node_modules/@sinclair/typebox/errors/index.d.ts b/node_modules/@sinclair/typebox/errors/index.d.ts new file mode 100644 index 0000000..f72bc43 --- /dev/null +++ b/node_modules/@sinclair/typebox/errors/index.d.ts @@ -0,0 +1 @@ +export * from './errors'; diff --git a/node_modules/@sinclair/typebox/errors/index.js b/node_modules/@sinclair/typebox/errors/index.js new file mode 100644 index 0000000..9637155 --- /dev/null +++ b/node_modules/@sinclair/typebox/errors/index.js @@ -0,0 +1,44 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/errors + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./errors"), exports); diff --git a/node_modules/@sinclair/typebox/license b/node_modules/@sinclair/typebox/license new file mode 100644 index 0000000..08641fd --- /dev/null +++ b/node_modules/@sinclair/typebox/license @@ -0,0 +1,23 @@ +TypeBox: JSON Schema Type Builder with Static Type Resolution for TypeScript + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/@sinclair/typebox/package.json b/node_modules/@sinclair/typebox/package.json new file mode 100644 index 0000000..5d24c50 --- /dev/null +++ b/node_modules/@sinclair/typebox/package.json @@ -0,0 +1,49 @@ +{ + "name": "@sinclair/typebox", + "version": "0.27.10", + "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript", + "keywords": [ + "typescript", + "json-schema", + "validate", + "typecheck" + ], + "author": "sinclairzx81", + "license": "MIT", + "main": "./typebox.js", + "types": "./typebox.d.ts", + "exports": { + "./compiler": "./compiler/index.js", + "./errors": "./errors/index.js", + "./system": "./system/index.js", + "./value": "./value/index.js", + ".": "./typebox.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/sinclairzx81/typebox-legacy" + }, + "scripts": { + "clean": "hammer task clean", + "format": "hammer task format", + "start": "hammer task start", + "test": "hammer task test", + "benchmark": "hammer task benchmark", + "build": "hammer task build", + "build:native": "hammer task build_native", + "publish": "hammer task publish" + }, + "devDependencies": { + "@sinclair/hammer": "^0.17.1", + "@typescript/native-preview": "^7.0.0-dev.20260203.1", + "@types/chai": "^4.3.3", + "@types/mocha": "^9.1.1", + "@types/node": "^18.19.130", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "chai": "^4.3.6", + "mocha": "^9.2.2", + "prettier": "^2.7.1", + "typescript": "5.0.2" + } +} diff --git a/node_modules/@sinclair/typebox/readme.md b/node_modules/@sinclair/typebox/readme.md new file mode 100644 index 0000000..c5120a9 --- /dev/null +++ b/node_modules/@sinclair/typebox/readme.md @@ -0,0 +1,1424 @@ +
+ +

TypeBox

+ +

JSON Schema Type Builder with Static Type Resolution for TypeScript

+ + + +
+
+ +[![npm version](https://badge.fury.io/js/%40sinclair%2Ftypebox.svg)](https://badge.fury.io/js/%40sinclair%2Ftypebox) +[![Downloads](https://img.shields.io/npm/dm/%40sinclair%2Ftypebox.svg)](https://www.npmjs.com/package/%40sinclair%2Ftypebox) +[![GitHub CI](https://github.com/sinclairzx81/typebox/workflows/GitHub%20CI/badge.svg)](https://github.com/sinclairzx81/typebox/actions) + +
+ + + +## Install + +#### Npm +```bash +$ npm install @sinclair/typebox --save +``` + +#### Deno +```typescript +import { Static, Type } from 'npm:@sinclair/typebox' +``` + +#### Esm + +```typescript +import { Static, Type } from 'https://esm.sh/@sinclair/typebox' +``` + +## Example + +```typescript +import { Static, Type } from '@sinclair/typebox' + +const T = Type.Object({ // const T = { + x: Type.Number(), // type: 'object', + y: Type.Number(), // required: ['x', 'y', 'z'], + z: Type.Number() // properties: { +}) // x: { type: 'number' }, + // y: { type: 'number' }, + // z: { type: 'number' } + // } + // } + +type T = Static // type T = { + // x: number, + // y: number, + // z: number + // } +``` + + + + +## Overview + +TypeBox is a runtime type builder that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type assertion rules of the TypeScript compiler. TypeBox enables one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation. + +This library is designed to enable JSON schema to compose with the same flexibility as TypeScript's type system. It can be used as a simple tool to build up complex schemas or integrated into REST or RPC services to help validate data received over the wire. + +License MIT + +## Contents +- [Install](#install) +- [Overview](#overview) +- [Usage](#usage) +- [Types](#types) + - [Standard](#types-standard) + - [Extended](#types-extended) + - [Modifiers](#types-modifiers) + - [Options](#types-options) + - [Generics](#types-generics) + - [References](#types-references) + - [Recursive](#types-recursive) + - [Conditional](#types-conditional) + - [Template Literal](#types-template-literal) + - [Guards](#types-guards) + - [Unsafe](#types-unsafe) + - [Strict](#types-strict) +- [Values](#values) + - [Create](#values-create) + - [Clone](#values-clone) + - [Check](#values-check) + - [Convert](#values-convert) + - [Cast](#values-cast) + - [Equal](#values-equal) + - [Hash](#values-hash) + - [Diff](#values-diff) + - [Patch](#values-patch) + - [Errors](#values-errors) + - [Mutate](#values-mutate) + - [Pointer](#values-pointer) +- [TypeCheck](#typecheck) + - [Ajv](#typecheck-ajv) + - [TypeCompiler](#typecheck-typecompiler) +- [TypeSystem](#typesystem) + - [Types](#typesystem-types) + - [Formats](#typesystem-formats) + - [Policies](#typesystem-policies) +- [Benchmark](#benchmark) + - [Compile](#benchmark-compile) + - [Validate](#benchmark-validate) + - [Compression](#benchmark-compression) +- [Contribute](#contribute) + + + +## Usage + +The following shows general usage. + +```typescript +import { Static, Type } from '@sinclair/typebox' + +//-------------------------------------------------------------------------------------------- +// +// Let's say you have the following type ... +// +//-------------------------------------------------------------------------------------------- + +type T = { + id: string, + name: string, + timestamp: number +} + +//-------------------------------------------------------------------------------------------- +// +// ... you can express this type in the following way. +// +//-------------------------------------------------------------------------------------------- + +const T = Type.Object({ // const T = { + id: Type.String(), // type: 'object', + name: Type.String(), // properties: { + timestamp: Type.Integer() // id: { +}) // type: 'string' + // }, + // name: { + // type: 'string' + // }, + // timestamp: { + // type: 'integer' + // } + // }, + // required: [ + // 'id', + // 'name', + // 'timestamp' + // ] + // } + +//-------------------------------------------------------------------------------------------- +// +// ... then infer back to the original static type this way. +// +//-------------------------------------------------------------------------------------------- + +type T = Static // type T = { + // id: string, + // name: string, + // timestamp: number + // } + +//-------------------------------------------------------------------------------------------- +// +// ... then use the type both as JSON schema and as a TypeScript type. +// +//-------------------------------------------------------------------------------------------- + +import { Value } from '@sinclair/typebox/value' + +function receive(value: T) { // ... as a Static Type + + if(Value.Check(T, value)) { // ... as a JSON Schema + + // ok... + } +} +``` + + + +## Types + +TypeBox types are JSON schema fragments that can be composed into more complex types. Each fragment is structured such that a JSON schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox provides a set of Standard types which are used create JSON schema compliant schematics as well as an Extended type set used to create schematics for constructs native to JavaScript. + + + +### Standard Types + +The following table lists the Standard TypeBox types. These types are fully compatible with the JSON Schema Draft 6 specification. + +```typescript +┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ +│ TypeBox │ TypeScript │ JSON Schema │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Any() │ type T = any │ const T = { } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Unknown() │ type T = unknown │ const T = { } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.String() │ type T = string │ const T = { │ +│ │ │ type: 'string' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Number() │ type T = number │ const T = { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Integer() │ type T = number │ const T = { │ +│ │ │ type: 'integer' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Boolean() │ type T = boolean │ const T = { │ +│ │ │ type: 'boolean' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Null() │ type T = null │ const T = { │ +│ │ │ type: 'null' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Literal(42) │ type T = 42 │ const T = { │ +│ │ │ const: 42, │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Array( │ type T = number[] │ const T = { │ +│ Type.Number() │ │ type: 'array', │ +│ ) │ │ items: { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Object({ │ type T = { │ const T = { │ +│ x: Type.Number(), │ x: number, │ type: 'object', │ +│ y: Type.Number() │ y: number │ required: ['x', 'y'], │ +│ }) │ } │ properties: { │ +│ │ │ x: { │ +│ │ │ type: 'number' │ +│ │ │ }, { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Tuple([ │ type T = [number, number] │ const T = { │ +│ Type.Number(), │ │ type: 'array', │ +│ Type.Number() │ │ items: [{ │ +│ ]) │ │ type: 'number' │ +│ │ │ }, { │ +│ │ │ type: 'number' │ +│ │ │ }], │ +│ │ │ additionalItems: false, │ +│ │ │ minItems: 2, │ +│ │ │ maxItems: 2 │ +│ │ │ } │ +│ │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ enum Foo { │ enum Foo { │ const T = { │ +│ A, │ A, │ anyOf: [{ │ +│ B │ B │ type: 'number', │ +│ } │ } │ const: 0 │ +│ │ │ }, { │ +│ const T = Type.Enum(Foo) │ type T = Foo │ type: 'number', │ +│ │ │ const: 1 │ +│ │ │ }] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.KeyOf( │ type T = keyof { │ const T = { │ +│ Type.Object({ │ x: number, │ anyOf: [{ │ +│ x: Type.Number(), │ y: number │ type: 'string', │ +│ y: Type.Number() │ } │ const: 'x' │ +│ }) │ │ }, { │ +│ ) │ │ type: 'string', │ +│ │ │ const: 'y' │ +│ │ │ }] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Union([ │ type T = string | number │ const T = { │ +│ Type.String(), │ │ anyOf: [{ │ +│ Type.Number() │ │ type: 'string' │ +│ ]) │ │ }, { │ +│ │ │ type: 'number' │ +│ │ │ }] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Intersect([ │ type T = { │ const T = { │ +│ Type.Object({ │ x: number │ allOf: [{ │ +│ x: Type.Number() │ } & { │ type: 'object', │ +│ }), │ y: number │ required: ['x'], │ +│ Type.Object({ │ } │ properties: { │ +│ y: Type.Number() │ │ x: { │ +│ ]) │ │ type: 'number' │ +│ ]) │ │ } │ +│ │ │ } │ +│ │ │ }, { │ +│ │ │ type: 'object', | +│ │ │ required: ['y'], │ +│ │ │ properties: { │ +│ │ │ y: { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ }] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Composite([ │ type I = { │ const T = { │ +│ Type.Object({ │ x: number │ type: 'object', │ +│ x: Type.Number() │ } & { │ required: ['x', 'y'], │ +│ }), │ y: number │ properties: { │ +│ Type.Object({ │ } │ x: { │ +│ y: Type.Number() │ │ type: 'number' │ +│ }) │ type T = { │ }, │ +│ ]) │ [K in keyof I]: I[K] │ y: { │ +│ │ } │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Never() │ type T = never │ const T = { │ +│ │ │ not: {} │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Not( | type T = string │ const T = { │ +| Type.Union([ │ │ allOf: [{ │ +│ Type.Literal('x'), │ │ not: { │ +│ Type.Literal('y'), │ │ anyOf: [ │ +│ Type.Literal('z') │ │ { const: 'x' }, │ +│ ]), │ │ { const: 'y' }, │ +│ Type.String() │ │ { const: 'z' } │ +│ ) │ │ ] │ +│ │ │ } │ +│ │ │ }, { │ +│ │ │ type: 'string' │ +│ │ │ }] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Extends( │ type T = │ const T = { │ +│ Type.String(), │ string extends number │ const: false, │ +│ Type.Number(), │ true : false │ type: 'boolean' │ +│ Type.Literal(true), │ │ } │ +│ Type.Literal(false) │ │ │ +│ ) │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Extract( │ type T = Extract< │ const T = { │ +│ Type.Union([ │ string | number, │ type: 'string' │ +│ Type.String(), │ string │ } │ +│ Type.Number(), │ > │ │ +│ ]), │ │ │ +│ Type.String() │ │ │ +│ ) │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Exclude( │ type T = Exclude< │ const T = { │ +│ Type.Union([ │ string | number, │ type: 'number' │ +│ Type.String(), │ string │ } │ +│ Type.Number(), │ > │ │ +│ ]), │ │ │ +│ Type.String() │ │ │ +│ ) │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const U = Type.Union([ │ type U = 'open' | 'close' │ const T = { │ +│ Type.Literal('open'), │ │ type: 'string', │ +│ Type.Literal('close') │ type T = `on${U}` │ pattern: '^on(open|close)$' │ +│ ]) │ │ } │ +│ │ │ │ +│ const T = Type │ │ │ +│ .TemplateLiteral([ │ │ │ +│ Type.Literal('on'), │ │ │ +│ U │ │ │ +│ ]) │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Record( │ type T = Record< │ const T = { │ +│ Type.String(), │ string, │ type: 'object', │ +│ Type.Number() │ number │ patternProperties: { │ +│ ) │ > │ '^.*$': { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Partial( │ type T = Partial<{ │ const T = { │ +│ Type.Object({ │ x: number, │ type: 'object', │ +│ x: Type.Number(), │ y: number │ properties: { │ +│ y: Type.Number() | }> │ x: { │ +│ }) │ │ type: 'number' │ +│ ) │ │ }, │ +│ │ │ y: { │ +│ │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Required( │ type T = Required<{ │ const T = { │ +│ Type.Object({ │ x?: number, │ type: 'object', │ +│ x: Type.Optional( │ y?: number │ required: ['x', 'y'], │ +│ Type.Number() | }> │ properties: { │ +│ ), │ │ x: { │ +│ y: Type.Optional( │ │ type: 'number' │ +│ Type.Number() │ │ }, │ +│ ) │ │ y: { │ +│ }) │ │ type: 'number' │ +│ ) │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Pick( │ type T = Pick<{ │ const T = { │ +│ Type.Object({ │ x: number, │ type: 'object', │ +│ x: Type.Number(), │ y: number │ required: ['x'], │ +│ y: Type.Number() │ }, 'x'> │ properties: { │ +│ }), ['x'] | │ x: { │ +│ ) │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Omit( │ type T = Omit<{ │ const T = { │ +│ Type.Object({ │ x: number, │ type: 'object', │ +│ x: Type.Number(), │ y: number │ required: ['y'], │ +│ y: Type.Number() │ }, 'x'> │ properties: { │ +│ }), ['x'] | │ y: { │ +│ ) │ │ type: 'number' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Object({ │ type T = { │ const R = { │ +│ x: Type.Number(), │ x: number, │ $ref: 'T' │ +│ y: Type.Number() │ y: number │ } │ +│ }, { $id: 'T' }) | } │ │ +│ │ │ │ +│ const R = Type.Ref(T) │ type R = T │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ +``` + + + +### Extended Types + +TypeBox provides several extended types that can be used to produce schematics for common JavaScript constructs. These types can not be used with standard JSON schema validators; but are useful to help frame schematics for RPC interfaces that may receive JSON validated data. Extended types are prefixed with the `[Extended]` doc comment for convenience. The following table lists the supported types. + +```typescript +┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ +│ TypeBox │ TypeScript │ Extended Schema │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Constructor([ │ type T = new ( │ const T = { │ +│ Type.String(), │ arg0: string, │ type: 'object', │ +│ Type.Number() │ arg1: number │ instanceOf: 'Constructor', │ +│ ], Type.Boolean()) │ ) => boolean │ parameters: [{ │ +│ │ │ type: 'string' │ +│ │ │ }, { │ +│ │ │ type: 'number' │ +│ │ │ }], │ +│ │ │ return: { │ +│ │ │ type: 'boolean' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Function([ │ type T = ( │ const T = { │ +| Type.String(), │ arg0: string, │ type : 'object', │ +│ Type.Number() │ arg1: number │ instanceOf: 'Function', │ +│ ], Type.Boolean()) │ ) => boolean │ parameters: [{ │ +│ │ │ type: 'string' │ +│ │ │ }, { │ +│ │ │ type: 'number' │ +│ │ │ }], │ +│ │ │ return: { │ +│ │ │ type: 'boolean' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Promise( │ type T = Promise │ const T = { │ +│ Type.String() │ │ type: 'object', │ +│ ) │ │ instanceOf: 'Promise', │ +│ │ │ item: { │ +│ │ │ type: 'string' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │ +│ │ │ type: 'object', │ +│ │ │ instanceOf: 'Uint8Array' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Date() │ type T = Date │ const T = { │ +│ │ │ type: 'object', │ +│ │ │ instanceOf: 'Date' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Undefined() │ type T = undefined │ const T = { │ +│ │ │ type: 'null', │ +│ │ │ typeOf: 'Undefined' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.RegEx(/foo/) │ type T = string │ const T = { │ +│ │ │ type: 'string', │ +│ │ │ pattern: 'foo' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Symbol() │ type T = symbol │ const T = { │ +│ │ │ type: 'null', │ +│ │ │ typeOf: 'Symbol' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.BigInt() │ type T = bigint │ const T = { │ +│ │ │ type: 'null', │ +│ │ │ typeOf: 'BigInt' │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Void() │ type T = void │ const T = { │ +│ │ │ type: 'null' │ +│ │ │ typeOf: 'Void' │ +│ │ │ } │ +│ │ │ │ +└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ +``` + + + +### Modifiers + +TypeBox provides modifiers that allow schema properties to be statically inferred as `readonly` or `optional`. The following table shows the supported modifiers and how they map between TypeScript and JSON Schema. + +```typescript +┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ +│ TypeBox │ TypeScript │ JSON Schema │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Object({ │ type T = { │ const T = { │ +│ name: Type.Optional( │ name?: string │ type: 'object', │ +│ Type.String() │ } │ properties: { │ +│ ) │ │ name: { │ +│ }) │ │ type: 'string' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Object({ │ type T = { │ const T = { │ +│ name: Type.Readonly( │ readonly name: string │ type: 'object', │ +│ Type.String() │ } │ properties: { │ +│ ) │ │ name: { │ +│ }) │ │ type: 'string' │ +│ │ │ } │ +│ │ │ }, │ +│ │ │ required: ['name'] │ +│ │ │ } │ +│ │ │ │ +├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ +│ const T = Type.Object({ │ type T = { │ const T = { │ +│ name: Type.ReadonlyOptional( │ readonly name?: string │ type: 'object', │ +│ Type.String() │ } │ properties: { │ +│ ) │ │ name: { │ +│ }) │ │ type: 'string' │ +│ │ │ } │ +│ │ │ } │ +│ │ │ } │ +│ │ │ │ +└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ +``` + + + +### Options + +You can pass JSON Schema options on the last argument of any type. Option hints specific to each type are provided for convenience. + +```typescript +// String must be an email +const T = Type.String({ // const T = { + format: 'email' // type: 'string', +}) // format: 'email' + // } + +// Mumber must be a multiple of 2 +const T = Type.Number({ // const T = { + multipleOf: 2 // type: 'number', +}) // multipleOf: 2 + // } + +// Array must have at least 5 integer values +const T = Type.Array(Type.Integer(), { // const T = { + minItems: 5 // type: 'array', +}) // minItems: 5, + // items: { + // type: 'integer' + // } + // } + +``` + + + +### Generic Types + +Generic types can be created with generic functions constrained to type `TSchema`. The following creates a generic `Vector` type. + +```typescript +import { Type, Static, TSchema } from '@sinclair/typebox' + +const Vector = (t: T) => Type.Object({ x: t, y: t, z: t }) + +const NumberVector = Vector(Type.Number()) // const NumberVector = { + // type: 'object', + // required: ['x', 'y', 'z'], + // properties: { + // x: { type: 'number' }, + // y: { type: 'number' }, + // z: { type: 'number' } + // } + // } + +type NumberVector = Static // type NumberVector = { + // x: number, + // y: number, + // z: number + // } + +const BooleanVector = Vector(Type.Boolean()) // const BooleanVector = { + // type: 'object', + // required: ['x', 'y', 'z'], + // properties: { + // x: { type: 'boolean' }, + // y: { type: 'boolean' }, + // z: { type: 'boolean' } + // } + // } + +type BooleanVector = Static // type BooleanVector = { + // x: boolean, + // y: boolean, + // z: boolean + // } +``` + +The following creates a generic `Nullable` type. + +```typescript +const Nullable = (schema: T) => Type.Union([schema, Type.Null()]) + +const T = Nullable(Type.String()) // const T = { + // anyOf: [ + // { type: 'string' }, + // { type: 'null' } + // ] + // } + +type T = Static // type T = string | null +``` + + + +### Reference Types + +Reference types are supported with `Type.Ref`. The target type must specify a valid `$id`. + +```typescript +const T = Type.String({ $id: 'T' }) // const T = { + // $id: 'T', + // type: 'string' + // } + +const R = Type.Ref(T) // const R = { + // $ref: 'T' + // } +``` + + + +### Recursive Types + +Recursive types are supported with `Type.Recursive` + +```typescript +const Node = Type.Recursive(Node => Type.Object({ // const Node = { + id: Type.String(), // $id: 'Node', + nodes: Type.Array(Node) // type: 'object', +}), { $id: 'Node' }) // properties: { + // id: { + // type: 'string' + // }, + // nodes: { + // type: 'array', + // items: { + // $ref: 'Node' + // } + // } + // }, + // required: [ + // 'id', + // 'nodes' + // ] + // } + +type Node = Static // type Node = { + // id: string + // nodes: Node[] + // } + +function test(node: Node) { + const id = node.nodes[0].nodes[0].id // id is string +} +``` + + + +### Conditional Types + +Conditional types are supported with `Type.Extends`, `Type.Exclude` and `Type.Extract` + +```typescript +// TypeScript + +type T0 = string extends number ? true : false // type T0 = false + +type T1 = Extract // type T1 = number + +type T2 = Exclude // type T2 = string + +// TypeBox + +const T0 = Type.Extends(Type.String(), Type.Number(), Type.Literal(true), Type.Literal(false)) + +const T1 = Type.Extract(Type.Union([Type.String(), Type.Number()]), Type.Number()) + +const T2 = Type.Exclude(Type.Union([Type.String(), Type.Number()]), Type.Number()) + + +type T0 = Static // type T0 = false + +type T1 = Static // type T1 = number + +type T2 = Static // type T2 = string +``` + + + +### Template Literal Types + +Template Literal types are supported with `Type.TemplateLiteral` + +```typescript +// TypeScript + +type T = `option${'A'|'B'}` // type T = 'optionA' | 'optionB' + +type R = Record // type R = { + // optionA: string + // optionB: string + // } + +// TypeBox + +const T = Type.TemplateLiteral([ // const T = { + Type.Literal('option'), // pattern: '^option(A|B)$', + Type.Union([ // type: 'string' + Type.Literal('A'), // } + Type.Literal('B') + ]) +]) + +const R = Type.Record(T, Type.String()) // const R = { + // type: 'object', + // required: ['optionA', 'optionB'], + // properties: { + // optionA: { + // type: 'string' + // }, + // optionB: { + // type: 'string' + // } + // } + // } + +type T = Static // type T = 'optionA' | 'optionB' + +type R = Static // type R = { + // optionA: string + // optionB: string + // } +``` + + + +### Unsafe + +Use `Type.Unsafe` to create custom schematics with user defined inference rules. + +```typescript +const T = Type.Unsafe({ type: 'number' }) // const T = { + // type: 'number' + // } + +type T = Static // type T = string +``` + +The `Type.Unsafe` type can be useful to express specific OpenAPI schema representations. + +```typescript +import { Type, Static, TSchema } from '@sinclair/typebox' + +// Nullable + +function Nullable(schema: T) { + return Type.Unsafe | null>({ ...schema, nullable: true }) +} + +const T = Nullable(Type.String()) // const T = { + // type: 'string', + // nullable: true + // } + +type T = Static // type T = string | null + +// StringEnum + +function StringEnum(values: [...T]) { + return Type.Unsafe({ type: 'string', enum: values }) +} + +const T = StringEnum(['A', 'B', 'C']) // const T = { + // enum: ['A', 'B', 'C'] + // } + +type T = Static // type T = 'A' | 'B' | 'C' +``` + + + +### Guards + +TypeBox provides a `TypeGuard` module that can be used for reflection and asserting values as types. + +```typescript +import { Type, TypeGuard } from '@sinclair/typebox' + +const T = Type.String() + +if(TypeGuard.TString(T)) { + + // T is TString +} +``` + + + +### Strict + +TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are used for type composition and reflection. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict` function that will omit these properties if necessary. + +```typescript +const T = Type.Object({ // const T = { + name: Type.Optional(Type.String()) // [Kind]: 'Object', +}) // type: 'object', + // properties: { + // name: { + // [Kind]: 'String', + // type: 'string', + // [Modifier]: 'Optional' + // } + // } + // } + +const U = Type.Strict(T) // const U = { + // type: 'object', + // properties: { + // name: { + // type: 'string' + // } + // } + // } +``` + + + +## Values + +TypeBox provides an optional utility module that can be used to perform common operations on JavaScript values. This module includes functionality to create, check and cast values from types as well as check equality, clone, diff and patch JavaScript values. This module is provided via optional import. + +```typescript +import { Value } from '@sinclair/typebox/value' +``` + + + +### Create + +Use the Create function to create a value from a type. TypeBox will use default values if specified. + +```typescript +const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) }) + +const A = Value.Create(T) // const A = { x: 0, y: 42 } +``` + + + +### Clone + +Use the Clone function to deeply clone a value + +```typescript +const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 } +``` + + + +### Check + +Use the Check function to type check a value + +```typescript +const T = Type.Object({ x: Type.Number() }) + +const R = Value.Check(T, { x: 1 }) // const R = true +``` + + + +### Convert + +Use the Convert function to convert a value into its target type if a reasonable conversion is possible. + +```typescript +const T = Type.Object({ x: Type.Number() }) + +const R1 = Value.Convert(T, { x: '3.14' }) // const R1 = { x: 3.14 } + +const R2 = Value.Convert(T, { x: 'not a number' }) // const R2 = { x: 'not a number' } +``` + + + +### Cast + +Use the Cast function to cast a value into a type. The cast function will retain as much information as possible from the original value. + +```typescript +const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false }) + +const X = Value.Cast(T, null) // const X = { x: 0, y: 0 } + +const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 } + +const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 } +``` + + + +### Equal + +Use the Equal function to deeply check for value equality. + +```typescript +const R = Value.Equal( // const R = true + { x: 1, y: 2, z: 3 }, + { x: 1, y: 2, z: 3 } +) +``` + + + +### Hash + +Use the Hash function to create a [FNV1A-64](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) non cryptographic hash of a value. + +```typescript +const A = Value.Hash({ x: 1, y: 2, z: 3 }) // const A = 2910466848807138541n + +const B = Value.Hash({ x: 1, y: 4, z: 3 }) // const B = 1418369778807423581n +``` + + + +### Diff + +Use the Diff function to produce a sequence of edits to transform one value into another. + +```typescript +const E = Value.Diff( // const E = [ + { x: 1, y: 2, z: 3 }, // { type: 'update', path: '/y', value: 4 }, + { y: 4, z: 5, w: 6 } // { type: 'update', path: '/z', value: 5 }, +) // { type: 'insert', path: '/w', value: 6 }, + // { type: 'delete', path: '/x' } + // ] +``` + + + +### Patch + +Use the Patch function to apply edits + +```typescript +const A = { x: 1, y: 2 } + +const B = { x: 3 } + +const E = Value.Diff(A, B) // const E = [ + // { type: 'update', path: '/x', value: 3 }, + // { type: 'delete', path: '/y' } + // ] + +const C = Value.Patch(A, E) // const C = { x: 3 } +``` + + + +### Errors + +Use the Errors function enumerate validation errors. + +```typescript +const T = Type.Object({ x: Type.Number(), y: Type.Number() }) + +const R = [...Value.Errors(T, { x: '42' })] // const R = [{ + // schema: { type: 'number' }, + // path: '/x', + // value: '42', + // message: 'Expected number' + // }, { + // schema: { type: 'number' }, + // path: '/y', + // value: undefined, + // message: 'Expected number' + // }] +``` + + + +### Mutate + +Use the Mutate function to perform a deep mutable value assignment while retaining internal references. + +```typescript +const Y = { z: 1 } // const Y = { z: 1 } + +const X = { y: Y } // const X = { y: { z: 1 } } + +const A = { x: X } // const A = { x: { y: { z: 1 } } } + + +Value.Mutate(A, { x: { y: { z: 2 } } }) // const A' = { x: { y: { z: 2 } } } + +const R0 = A.x.y.z === 2 // const R0 = 2 + +const R1 = A.x.y === Y // const R1 = true + +const R2 = A.x === X // const R2 = true +``` + + + +### Pointer + +Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) JSON Pointers. + +```typescript +import { ValuePointer } from '@sinclair/typebox/value' + +const A = { x: 0, y: 0, z: 0 } + +ValuePointer.Set(A, '/x', 1) // const A' = { x: 1, y: 0, z: 0 } + +ValuePointer.Set(A, '/y', 1) // const A' = { x: 1, y: 1, z: 0 } + +ValuePointer.Set(A, '/z', 1) // const A' = { x: 1, y: 1, z: 1 } +``` + + + +## TypeCheck + +TypeBox types target JSON Schema draft 6 so are compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for high performance compilation and value assertion. + +The following sections detail using Ajv and TypeBox's compiler infrastructure. + + + +## Ajv + +The following shows the recommended setup for Ajv. + +```bash +$ npm install ajv ajv-formats --save +``` + +```typescript +import { Type } from '@sinclair/typebox' +import addFormats from 'ajv-formats' +import Ajv from 'ajv' + +const ajv = addFormats(new Ajv({}), [ + 'date-time', + 'time', + 'date', + 'email', + 'hostname', + 'ipv4', + 'ipv6', + 'uri', + 'uri-reference', + 'uuid', + 'uri-template', + 'json-pointer', + 'relative-json-pointer', + 'regex' +]) + +const C = ajv.compile(Type.Object({ + x: Type.Number(), + y: Type.Number(), + z: Type.Number() +})) + +const R = C({ x: 1, y: 2, z: 3 }) // const R = true +``` + + + +### TypeCompiler + +The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast value assertion. It is designed to serve as a validation backend that can be integrated into larger applications; but can also be used as a general purpose validator. + +The TypeCompiler is provided as an optional import. + +```typescript +import { TypeCompiler } from '@sinclair/typebox/compiler' +``` + +Use the `Compile(...)` function to compile a type. + +```typescript +const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck> + +const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true +``` + +Use the `Errors(...)` function to produce diagnostic errors for a value. The `Errors(...)` function will return an iterator that if enumerated; will perform an exhaustive check across the entire value and yield any error found. For performance, this function should only be called after failed `Check(...)`. Applications may also choose to yield only the first value to avoid exhaustive error generation. + +```typescript +const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck> + +const value = { } + +const errors = [...C.Errors(value)] // const errors = [{ + // schema: { type: 'number' }, + // path: '/x', + // value: undefined, + // message: 'Expected number' + // }, { + // schema: { type: 'number' }, + // path: '/y', + // value: undefined, + // message: 'Expected number' + // }, { + // schema: { type: 'number' }, + // path: '/z', + // value: undefined, + // message: 'Expected number' + // }] +``` + +Compiled routines can be inspected with the `.Code()` function. + +```typescript +const C = TypeCompiler.Compile(Type.String()) // const C: TypeCheck + +console.log(C.Code()) // return function check(value) { + // return ( + // (typeof value === 'string') + // ) + // } +``` + + + +## TypeSystem + +The TypeBox TypeSystem module provides functionality to define types above and beyond the Standard and Extended type sets as well as control various assertion polices. Configurations made to the TypeSystem module are observed by both `TypeCompiler` and `Value` modules. + +The TypeSystem module is provided as an optional import. + +```typescript +import { TypeSystem } from '@sinclair/typebox/system' +``` + + + +### Types + +Use the `Type(...)` function to create a custom type. This function will return a type factory function that can be used to construct the type. The following creates a Point type. + +```typescript +type PointOptions = { } // The Type Options + +type PointType = { x: number, y: number } // The Static Type + +const Point = TypeSystem.Type('Point', (options, value) => { + return ( + typeof value === 'object' && value !== null && + typeof value.x === 'number' && + typeof value.y === 'number' + ) +}) + +const T = Point() + +type T = Static // type T = { x: number, y: number } + +const R = Value.Check(T, { x: 1, y: 2 }) // const R = true +``` + + + +### Formats + +Use the `Format(...)` function to create a custom string format. The following creates a format that checks for lowercase strings. + +```typescript +TypeSystem.Format('lowercase', value => value === value.toLowerCase()) // format should be lowercase + +const T = Type.String({ format: 'lowercase' }) + +const A = Value.Check(T, 'Hello') // const A = false + +const B = Value.Check(T, 'hello') // const B = true +``` + + + +### Policies + +TypeBox validates using JSON Schema assertion policies by default. It is possible to override these policies and have TypeBox assert using TypeScript policies. The following overrides are available. + +```typescript +// Allow arrays to validate as object types (default is false) +// +// const A: {} = [] - allowed in TS + +TypeSystem.AllowArrayObjects = true + +// Allow numeric values to be NaN or + or - Infinity (default is false) +// +// const A: number = NaN - allowed in TS + +TypeSystem.AllowNaN = true +``` + + + +## Benchmark + +This project maintains a set of benchmarks that measure Ajv, Value and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.12.0. + +For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/). + + + +### Compile + +This benchmark measures compilation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/compile.ts). + +```typescript +┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┐ +│ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │ +├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┤ +│ Literal_String │ 1000 │ ' 257 ms' │ ' 8 ms' │ ' 32.13 x' │ +│ Literal_Number │ 1000 │ ' 203 ms' │ ' 4 ms' │ ' 50.75 x' │ +│ Literal_Boolean │ 1000 │ ' 183 ms' │ ' 4 ms' │ ' 45.75 x' │ +│ Primitive_Number │ 1000 │ ' 174 ms' │ ' 8 ms' │ ' 21.75 x' │ +│ Primitive_String │ 1000 │ ' 158 ms' │ ' 9 ms' │ ' 17.56 x' │ +│ Primitive_String_Pattern │ 1000 │ ' 213 ms' │ ' 13 ms' │ ' 16.38 x' │ +│ Primitive_Boolean │ 1000 │ ' 136 ms' │ ' 6 ms' │ ' 22.67 x' │ +│ Primitive_Null │ 1000 │ ' 144 ms' │ ' 6 ms' │ ' 24.00 x' │ +│ Object_Unconstrained │ 1000 │ ' 1176 ms' │ ' 38 ms' │ ' 30.95 x' │ +│ Object_Constrained │ 1000 │ ' 1181 ms' │ ' 31 ms' │ ' 38.10 x' │ +│ Object_Vector3 │ 1000 │ ' 387 ms' │ ' 8 ms' │ ' 48.38 x' │ +│ Object_Box3D │ 1000 │ ' 1693 ms' │ ' 25 ms' │ ' 67.72 x' │ +│ Tuple_Primitive │ 1000 │ ' 470 ms' │ ' 15 ms' │ ' 31.33 x' │ +│ Tuple_Object │ 1000 │ ' 1206 ms' │ ' 17 ms' │ ' 70.94 x' │ +│ Composite_Intersect │ 1000 │ ' 567 ms' │ ' 20 ms' │ ' 28.35 x' │ +│ Composite_Union │ 1000 │ ' 515 ms' │ ' 21 ms' │ ' 24.52 x' │ +│ Math_Vector4 │ 1000 │ ' 787 ms' │ ' 10 ms' │ ' 78.70 x' │ +│ Math_Matrix4 │ 1000 │ ' 386 ms' │ ' 8 ms' │ ' 48.25 x' │ +│ Array_Primitive_Number │ 1000 │ ' 349 ms' │ ' 7 ms' │ ' 49.86 x' │ +│ Array_Primitive_String │ 1000 │ ' 336 ms' │ ' 4 ms' │ ' 84.00 x' │ +│ Array_Primitive_Boolean │ 1000 │ ' 284 ms' │ ' 3 ms' │ ' 94.67 x' │ +│ Array_Object_Unconstrained │ 1000 │ ' 1704 ms' │ ' 19 ms' │ ' 89.68 x' │ +│ Array_Object_Constrained │ 1000 │ ' 1456 ms' │ ' 18 ms' │ ' 80.89 x' │ +│ Array_Tuple_Primitive │ 1000 │ ' 792 ms' │ ' 15 ms' │ ' 52.80 x' │ +│ Array_Tuple_Object │ 1000 │ ' 1552 ms' │ ' 17 ms' │ ' 91.29 x' │ +│ Array_Composite_Intersect │ 1000 │ ' 744 ms' │ ' 18 ms' │ ' 41.33 x' │ +│ Array_Composite_Union │ 1000 │ ' 783 ms' │ ' 15 ms' │ ' 52.20 x' │ +│ Array_Math_Vector4 │ 1000 │ ' 1093 ms' │ ' 14 ms' │ ' 78.07 x' │ +│ Array_Math_Matrix4 │ 1000 │ ' 684 ms' │ ' 6 ms' │ ' 114.00 x' │ +└────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┘ +``` + + + +### Validate + +This benchmark measures validation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/check.ts). + +```typescript +┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐ +│ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │ +├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ +│ Literal_String │ 1000000 │ ' 27 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │ +│ Literal_Number │ 1000000 │ ' 23 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │ +│ Literal_Boolean │ 1000000 │ ' 21 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │ +│ Primitive_Number │ 1000000 │ ' 26 ms' │ ' 19 ms' │ ' 11 ms' │ ' 1.73 x' │ +│ Primitive_String │ 1000000 │ ' 25 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │ +│ Primitive_String_Pattern │ 1000000 │ ' 155 ms' │ ' 49 ms' │ ' 43 ms' │ ' 1.14 x' │ +│ Primitive_Boolean │ 1000000 │ ' 23 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │ +│ Primitive_Null │ 1000000 │ ' 24 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │ +│ Object_Unconstrained │ 1000000 │ ' 804 ms' │ ' 35 ms' │ ' 28 ms' │ ' 1.25 x' │ +│ Object_Constrained │ 1000000 │ ' 1041 ms' │ ' 55 ms' │ ' 41 ms' │ ' 1.34 x' │ +│ Object_Vector3 │ 1000000 │ ' 380 ms' │ ' 26 ms' │ ' 20 ms' │ ' 1.30 x' │ +│ Object_Box3D │ 1000000 │ ' 1785 ms' │ ' 65 ms' │ ' 52 ms' │ ' 1.25 x' │ +│ Object_Recursive │ 1000000 │ ' 4984 ms' │ ' 396 ms' │ ' 114 ms' │ ' 3.47 x' │ +│ Tuple_Primitive │ 1000000 │ ' 168 ms' │ ' 24 ms' │ ' 16 ms' │ ' 1.50 x' │ +│ Tuple_Object │ 1000000 │ ' 673 ms' │ ' 30 ms' │ ' 26 ms' │ ' 1.15 x' │ +│ Composite_Intersect │ 1000000 │ ' 751 ms' │ ' 28 ms' │ ' 20 ms' │ ' 1.40 x' │ +│ Composite_Union │ 1000000 │ ' 489 ms' │ ' 24 ms' │ ' 16 ms' │ ' 1.50 x' │ +│ Math_Vector4 │ 1000000 │ ' 259 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │ +│ Math_Matrix4 │ 1000000 │ ' 1002 ms' │ ' 40 ms' │ ' 30 ms' │ ' 1.33 x' │ +│ Array_Primitive_Number │ 1000000 │ ' 252 ms' │ ' 22 ms' │ ' 15 ms' │ ' 1.47 x' │ +│ Array_Primitive_String │ 1000000 │ ' 227 ms' │ ' 22 ms' │ ' 18 ms' │ ' 1.22 x' │ +│ Array_Primitive_Boolean │ 1000000 │ ' 150 ms' │ ' 23 ms' │ ' 22 ms' │ ' 1.05 x' │ +│ Array_Object_Unconstrained │ 1000000 │ ' 4754 ms' │ ' 71 ms' │ ' 64 ms' │ ' 1.11 x' │ +│ Array_Object_Constrained │ 1000000 │ ' 4787 ms' │ ' 142 ms' │ ' 123 ms' │ ' 1.15 x' │ +│ Array_Object_Recursive │ 1000000 │ ' 19088 ms' │ ' 1735 ms' │ ' 314 ms' │ ' 5.53 x' │ +│ Array_Tuple_Primitive │ 1000000 │ ' 650 ms' │ ' 41 ms' │ ' 31 ms' │ ' 1.32 x' │ +│ Array_Tuple_Object │ 1000000 │ ' 2770 ms' │ ' 67 ms' │ ' 55 ms' │ ' 1.22 x' │ +│ Array_Composite_Intersect │ 1000000 │ ' 2693 ms' │ ' 50 ms' │ ' 39 ms' │ ' 1.28 x' │ +│ Array_Composite_Union │ 1000000 │ ' 1982 ms' │ ' 72 ms' │ ' 33 ms' │ ' 2.18 x' │ +│ Array_Math_Vector4 │ 1000000 │ ' 1068 ms' │ ' 40 ms' │ ' 26 ms' │ ' 1.54 x' │ +│ Array_Math_Matrix4 │ 1000000 │ ' 4609 ms' │ ' 115 ms' │ ' 88 ms' │ ' 1.31 x' │ +└────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘ +``` + + + +### Compression + +The following table lists esbuild compiled and minified sizes for each TypeBox module. + +```typescript +┌──────────────────────┬────────────┬────────────┬─────────────┐ +│ (index) │ Compiled │ Minified │ Compression │ +├──────────────────────┼────────────┼────────────┼─────────────┤ +│ typebox/compiler │ '124.3 kb' │ ' 55.7 kb' │ '2.23 x' │ +│ typebox/errors │ '107.8 kb' │ ' 47.9 kb' │ '2.25 x' │ +│ typebox/system │ ' 73.3 kb' │ ' 30.2 kb' │ '2.43 x' │ +│ typebox/value │ '170.7 kb' │ ' 74.2 kb' │ '2.30 x' │ +│ typebox │ ' 72.0 kb' │ ' 29.7 kb' │ '2.43 x' │ +└──────────────────────┴────────────┴────────────┴─────────────┘ +``` + + + +## Contribute + +TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features. diff --git a/node_modules/@sinclair/typebox/system/index.d.ts b/node_modules/@sinclair/typebox/system/index.d.ts new file mode 100644 index 0000000..4b58cda --- /dev/null +++ b/node_modules/@sinclair/typebox/system/index.d.ts @@ -0,0 +1 @@ +export * from './system'; diff --git a/node_modules/@sinclair/typebox/system/index.js b/node_modules/@sinclair/typebox/system/index.js new file mode 100644 index 0000000..3c5107f --- /dev/null +++ b/node_modules/@sinclair/typebox/system/index.js @@ -0,0 +1,44 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/system + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./system"), exports); diff --git a/node_modules/@sinclair/typebox/system/system.d.ts b/node_modules/@sinclair/typebox/system/system.d.ts new file mode 100644 index 0000000..4308454 --- /dev/null +++ b/node_modules/@sinclair/typebox/system/system.d.ts @@ -0,0 +1,26 @@ +import * as Types from '../typebox'; +export declare class TypeSystemDuplicateTypeKind extends Error { + constructor(kind: string); +} +export declare class TypeSystemDuplicateFormat extends Error { + constructor(kind: string); +} +/** Creates user defined types and formats and provides overrides for value checking behaviours */ +export declare namespace TypeSystem { + /** Sets whether TypeBox should assert optional properties using the TypeScript `exactOptionalPropertyTypes` assertion policy. The default is `false` */ + let ExactOptionalPropertyTypes: boolean; + /** Sets whether arrays should be treated as a kind of objects. The default is `false` */ + let AllowArrayObjects: boolean; + /** Sets whether `NaN` or `Infinity` should be treated as valid numeric values. The default is `false` */ + let AllowNaN: boolean; + /** Sets whether `null` should validate for void types. The default is `false` */ + let AllowVoidNull: boolean; + /** Creates a new type */ + function Type(kind: string, check: (options: Options, value: unknown) => boolean): (options?: Partial) => Types.TUnsafe; + /** Creates a new string format */ + function Format(format: F, check: (value: string) => boolean): F; + /** @deprecated Use `TypeSystem.Type()` instead. */ + function CreateType(kind: string, check: (options: Options, value: unknown) => boolean): (options?: Partial) => Types.TUnsafe; + /** @deprecated Use `TypeSystem.Format()` instead. */ + function CreateFormat(format: F, check: (value: string) => boolean): F; +} diff --git a/node_modules/@sinclair/typebox/system/system.js b/node_modules/@sinclair/typebox/system/system.js new file mode 100644 index 0000000..44911a4 --- /dev/null +++ b/node_modules/@sinclair/typebox/system/system.js @@ -0,0 +1,90 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/system + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TypeSystem = exports.TypeSystemDuplicateFormat = exports.TypeSystemDuplicateTypeKind = void 0; +const Types = require("../typebox"); +class TypeSystemDuplicateTypeKind extends Error { + constructor(kind) { + super(`Duplicate type kind '${kind}' detected`); + } +} +exports.TypeSystemDuplicateTypeKind = TypeSystemDuplicateTypeKind; +class TypeSystemDuplicateFormat extends Error { + constructor(kind) { + super(`Duplicate string format '${kind}' detected`); + } +} +exports.TypeSystemDuplicateFormat = TypeSystemDuplicateFormat; +/** Creates user defined types and formats and provides overrides for value checking behaviours */ +var TypeSystem; +(function (TypeSystem) { + // ------------------------------------------------------------------------ + // Assertion Policies + // ------------------------------------------------------------------------ + /** Sets whether TypeBox should assert optional properties using the TypeScript `exactOptionalPropertyTypes` assertion policy. The default is `false` */ + TypeSystem.ExactOptionalPropertyTypes = false; + /** Sets whether arrays should be treated as a kind of objects. The default is `false` */ + TypeSystem.AllowArrayObjects = false; + /** Sets whether `NaN` or `Infinity` should be treated as valid numeric values. The default is `false` */ + TypeSystem.AllowNaN = false; + /** Sets whether `null` should validate for void types. The default is `false` */ + TypeSystem.AllowVoidNull = false; + // ------------------------------------------------------------------------ + // String Formats and Types + // ------------------------------------------------------------------------ + /** Creates a new type */ + function Type(kind, check) { + if (Types.TypeRegistry.Has(kind)) + throw new TypeSystemDuplicateTypeKind(kind); + Types.TypeRegistry.Set(kind, check); + return (options = {}) => Types.Type.Unsafe({ ...options, [Types.Kind]: kind }); + } + TypeSystem.Type = Type; + /** Creates a new string format */ + function Format(format, check) { + if (Types.FormatRegistry.Has(format)) + throw new TypeSystemDuplicateFormat(format); + Types.FormatRegistry.Set(format, check); + return format; + } + TypeSystem.Format = Format; + // ------------------------------------------------------------------------ + // Deprecated + // ------------------------------------------------------------------------ + /** @deprecated Use `TypeSystem.Type()` instead. */ + function CreateType(kind, check) { + return Type(kind, check); + } + TypeSystem.CreateType = CreateType; + /** @deprecated Use `TypeSystem.Format()` instead. */ + function CreateFormat(format, check) { + return Format(format, check); + } + TypeSystem.CreateFormat = CreateFormat; +})(TypeSystem = exports.TypeSystem || (exports.TypeSystem = {})); diff --git a/node_modules/@sinclair/typebox/typebox.d.ts b/node_modules/@sinclair/typebox/typebox.d.ts new file mode 100644 index 0000000..9581b4a --- /dev/null +++ b/node_modules/@sinclair/typebox/typebox.d.ts @@ -0,0 +1,717 @@ +export declare const Modifier: unique symbol; +export declare const Hint: unique symbol; +export declare const Kind: unique symbol; +export declare const PatternBoolean = "(true|false)"; +export declare const PatternNumber = "(0|[1-9][0-9]*)"; +export declare const PatternString = "(.*)"; +export declare const PatternBooleanExact: string; +export declare const PatternNumberExact: string; +export declare const PatternStringExact: string; +export type TupleToIntersect = T extends [infer I] ? I : T extends [infer I, ...infer R] ? I & TupleToIntersect : never; +export type TupleToUnion = { + [K in keyof T]: T[K]; +}[number]; +export type UnionToIntersect = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never; +export type UnionLast = UnionToIntersect 0 : never> extends (x: infer L) => 0 ? L : never; +export type UnionToTuple> = [U] extends [never] ? [] : [...UnionToTuple>, L]; +export type Assert = T extends E ? T : never; +export type Evaluate = T extends infer O ? { + [K in keyof O]: O[K]; +} : never; +export type Ensure = T extends infer U ? U : never; +export type TModifier = TReadonlyOptional | TOptional | TReadonly; +export type TReadonly = T & { + [Modifier]: 'Readonly'; +}; +export type TOptional = T & { + [Modifier]: 'Optional'; +}; +export type TReadonlyOptional = T & { + [Modifier]: 'ReadonlyOptional'; +}; +export interface SchemaOptions { + $schema?: string; + /** Id for this schema */ + $id?: string; + /** Title of this schema */ + title?: string; + /** Description of this schema */ + description?: string; + /** Default value for this schema */ + default?: any; + /** Example values matching this schema */ + examples?: any; + [prop: string]: any; +} +export interface TKind { + [Kind]: string; +} +export interface TSchema extends SchemaOptions, TKind { + [Modifier]?: string; + [Hint]?: string; + params: unknown[]; + static: unknown; +} +export type TAnySchema = TSchema | TAny | TArray | TBigInt | TBoolean | TConstructor | TDate | TEnum | TFunction | TInteger | TIntersect | TLiteral | TNot | TNull | TNumber | TObject | TPromise | TRecord | TRef | TString | TSymbol | TTemplateLiteral | TThis | TTuple | TUndefined | TUnion | TUint8Array | TUnknown | TVoid; +export type TNumeric = TInteger | TNumber; +export interface NumericOptions extends SchemaOptions { + exclusiveMaximum?: N; + exclusiveMinimum?: N; + maximum?: N; + minimum?: N; + multipleOf?: N; +} +export interface TAny extends TSchema { + [Kind]: 'Any'; + static: any; +} +export interface ArrayOptions extends SchemaOptions { + uniqueItems?: boolean; + minItems?: number; + maxItems?: number; +} +export interface TArray extends TSchema, ArrayOptions { + [Kind]: 'Array'; + static: Static[]; + type: 'array'; + items: T; +} +export interface TBigInt extends TSchema, NumericOptions { + [Kind]: 'BigInt'; + static: bigint; + type: 'null'; + typeOf: 'BigInt'; +} +export interface TBoolean extends TSchema { + [Kind]: 'Boolean'; + static: boolean; + type: 'boolean'; +} +export type TConstructorParameters> = TTuple; +export type TInstanceType> = T['returns']; +export type TCompositeEvaluateArray = { + [K in keyof T]: T[K] extends TSchema ? Static : never; +}; +export type TCompositeArray = { + [K in keyof T]: T[K] extends TObject ? P : {}; +}; +export type TCompositeProperties = Evaluate : I extends object ? I : {}>; +export interface TComposite extends TObject { + [Hint]: 'Composite'; + static: Evaluate>>; + properties: TCompositeProperties>; +} +export type TConstructorParameterArray = [...{ + [K in keyof T]: Static, P>; +}]; +export interface TConstructor extends TSchema { + [Kind]: 'Constructor'; + static: new (...param: TConstructorParameterArray) => Static; + type: 'object'; + instanceOf: 'Constructor'; + parameters: T; + returns: U; +} +export interface DateOptions extends SchemaOptions { + exclusiveMaximumTimestamp?: number; + exclusiveMinimumTimestamp?: number; + maximumTimestamp?: number; + minimumTimestamp?: number; +} +export interface TDate extends TSchema, DateOptions { + [Kind]: 'Date'; + static: Date; + type: 'object'; + instanceOf: 'Date'; +} +export interface TEnumOption { + type: 'number' | 'string'; + const: T; +} +export interface TEnum = Record> extends TSchema { + [Kind]: 'Union'; + static: T[keyof T]; + anyOf: TLiteral[]; +} +export type TExtends = (Static extends Static ? T : U) extends infer O ? UnionToTuple extends [infer X, infer Y] ? TUnion<[Assert, Assert]> : Assert : never; +export type TExcludeTemplateLiteralResult = TString; +export type TExcludeTemplateLiteral = Exclude, Static> extends infer S ? TExcludeTemplateLiteralResult> : never; +export type TExcludeArray = Assert> extends Static ? never : T[K]; +}[number]>, TSchema[]> extends infer R ? TUnionResult> : never; +export type TExclude = T extends TTemplateLiteral ? TExcludeTemplateLiteral : T extends TUnion ? TExcludeArray : T extends U ? TNever : T; +export type TExtractTemplateLiteralResult = TString; +export type TExtractTemplateLiteral = Extract, Static> extends infer S ? TExtractTemplateLiteralResult> : never; +export type TExtractArray = Assert> extends Static ? T[K] : never; +}[number]>, TSchema[]> extends infer R ? TUnionResult> : never; +export type TExtract = T extends TTemplateLiteral ? TExtractTemplateLiteral : T extends TUnion ? TExtractArray : T extends U ? T : T; +export type TFunctionParameters = [...{ + [K in keyof T]: Static, P>; +}]; +export interface TFunction extends TSchema { + [Kind]: 'Function'; + static: (...param: TFunctionParameters) => Static; + type: 'object'; + instanceOf: 'Function'; + parameters: T; + returns: U; +} +export interface TInteger extends TSchema, NumericOptions { + [Kind]: 'Integer'; + static: number; + type: 'integer'; +} +export type TUnevaluatedProperties = undefined | TSchema | boolean; +export interface IntersectOptions extends SchemaOptions { + unevaluatedProperties?: TUnevaluatedProperties; +} +export interface TIntersect extends TSchema, IntersectOptions { + [Kind]: 'Intersect'; + static: TupleToIntersect<{ + [K in keyof T]: Static, this['params']>; + }>; + type?: 'object'; + allOf: [...T]; +} +export type TKeyOfTuple = { + [K in keyof Static]: TLiteral>; +} extends infer U ? UnionToTuple> : never; +export type TKeyOf = (T extends TRecursive ? TKeyOfTuple : T extends TComposite ? TKeyOfTuple : T extends TIntersect ? TKeyOfTuple : T extends TUnion ? TKeyOfTuple : T extends TObject ? TKeyOfTuple : T extends TRecord ? [K] : [ +]) extends infer R ? TUnionResult> : never; +export type TLiteralValue = string | number | boolean; +export interface TLiteral extends TSchema { + [Kind]: 'Literal'; + static: T; + const: T; +} +export interface TNever extends TSchema { + [Kind]: 'Never'; + static: never; + not: {}; +} +export interface TNot extends TSchema { + [Kind]: 'Not'; + static: Static; + allOf: [{ + not: Not; + }, T]; +} +export interface TNull extends TSchema { + [Kind]: 'Null'; + static: null; + type: 'null'; +} +export interface TNumber extends TSchema, NumericOptions { + [Kind]: 'Number'; + static: number; + type: 'number'; +} +export type ReadonlyOptionalPropertyKeys = { + [K in keyof T]: T[K] extends TReadonlyOptional ? K : never; +}[keyof T]; +export type ReadonlyPropertyKeys = { + [K in keyof T]: T[K] extends TReadonly ? K : never; +}[keyof T]; +export type OptionalPropertyKeys = { + [K in keyof T]: T[K] extends TOptional ? K : never; +}[keyof T]; +export type RequiredPropertyKeys = keyof Omit | ReadonlyPropertyKeys | OptionalPropertyKeys>; +export type PropertiesReducer> = Evaluate<(Readonly>>> & Readonly>> & Partial>> & Required>>)>; +export type PropertiesReduce = PropertiesReducer; +}>; +export type TProperties = Record; +export type ObjectProperties = T extends TObject ? U : never; +export type ObjectPropertyKeys = T extends TObject ? keyof U : never; +export type TAdditionalProperties = undefined | TSchema | boolean; +export interface ObjectOptions extends SchemaOptions { + additionalProperties?: TAdditionalProperties; + minProperties?: number; + maxProperties?: number; +} +export interface TObject extends TSchema, ObjectOptions { + [Kind]: 'Object'; + static: PropertiesReduce; + additionalProperties?: TAdditionalProperties; + type: 'object'; + properties: T; + required?: string[]; +} +export type TOmitArray = Assert<{ + [K2 in keyof T]: TOmit, K>; +}, TSchema[]>; +export type TOmitProperties = Evaluate, TProperties>>; +export type TOmit = T extends TRecursive ? TRecursive> : T extends TComposite ? TComposite> : T extends TIntersect ? TIntersect> : T extends TUnion ? TUnion> : T extends TObject ? TObject> : T; +export type TParameters = TTuple; +export type TPartialObjectArray = Assert<{ + [K in keyof T]: TPartial>; +}, TObject[]>; +export type TPartialArray = Assert<{ + [K in keyof T]: TPartial>; +}, TSchema[]>; +export type TPartialProperties = Evaluate ? TReadonlyOptional : T[K] extends TReadonly ? TReadonlyOptional : T[K] extends TOptional ? TOptional : TOptional; +}, TProperties>>; +export type TPartial = T extends TRecursive ? TRecursive> : T extends TComposite ? TComposite> : T extends TIntersect ? TIntersect> : T extends TUnion ? TUnion> : T extends TObject ? TObject> : T; +export type TPickArray = { + [K2 in keyof T]: TPick, K>; +}; +export type TPickProperties = Pick, keyof T>> extends infer R ? ({ + [K in keyof R]: Assert extends TSchema ? R[K] : never; +}) : never; +export type TPick = T extends TRecursive ? TRecursive> : T extends TComposite ? TComposite> : T extends TIntersect ? TIntersect> : T extends TUnion ? TUnion> : T extends TObject ? TObject> : T; +export interface TPromise extends TSchema { + [Kind]: 'Promise'; + static: Promise>; + type: 'object'; + instanceOf: 'Promise'; + item: TSchema; +} +export type RecordTemplateLiteralObjectType = Ensure]: T; +}>>>; +export type RecordTemplateLiteralType = IsTemplateLiteralFinite extends true ? RecordTemplateLiteralObjectType : TRecord; +export type RecordUnionLiteralType[]>, T extends TSchema> = Static extends string ? Ensure]: T; +}>> : never; +export type RecordLiteralType, T extends TSchema> = Ensure>; +export type RecordNumberType = Ensure>; +export type RecordStringType = Ensure>; +export type RecordKey = TUnion[]> | TLiteral | TTemplateLiteral | TInteger | TNumber | TString; +export interface TRecord extends TSchema { + [Kind]: 'Record'; + static: Record, Static>; + type: 'object'; + patternProperties: { + [pattern: string]: T; + }; + additionalProperties: false; +} +export interface TThis extends TSchema { + [Kind]: 'This'; + static: this['params'][0]; + $ref: string; +} +export type TRecursiveReduce = Static]>; +export interface TRecursive extends TSchema { + [Hint]: 'Recursive'; + static: TRecursiveReduce; +} +export interface TRef extends TSchema { + [Kind]: 'Ref'; + static: Static; + $ref: string; +} +export type TReturnType = T['returns']; +export type TRequiredArray = Assert<{ + [K in keyof T]: TRequired>; +}, TSchema[]>; +export type TRequiredProperties = Evaluate ? TReadonly : T[K] extends TReadonly ? TReadonly : T[K] extends TOptional ? U : T[K]; +}, TProperties>>; +export type TRequired = T extends TRecursive ? TRecursive> : T extends TComposite ? TComposite> : T extends TIntersect ? TIntersect> : T extends TUnion ? TUnion> : T extends TObject ? TObject> : T; +export type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex'; +export interface StringOptions extends SchemaOptions { + minLength?: number; + maxLength?: number; + pattern?: string; + format?: Format; + contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64'; + contentMediaType?: string; +} +export interface TString extends TSchema, StringOptions { + [Kind]: 'String'; + static: string; + type: 'string'; +} +export type SymbolValue = string | number | undefined; +export interface TSymbol extends TSchema, SchemaOptions { + [Kind]: 'Symbol'; + static: symbol; + type: 'null'; + typeOf: 'Symbol'; +} +export type IsTemplateLiteralFiniteCheck = T extends TTemplateLiteral ? IsTemplateLiteralFiniteArray> : T extends TUnion ? IsTemplateLiteralFiniteArray> : T extends TString ? false : T extends TBoolean ? false : T extends TNumber ? false : T extends TInteger ? false : T extends TBigInt ? false : T extends TLiteral ? true : false; +export type IsTemplateLiteralFiniteArray = T extends [infer L, ...infer R] ? IsTemplateLiteralFiniteCheck extends false ? false : IsTemplateLiteralFiniteArray> : T extends [infer L] ? IsTemplateLiteralFiniteCheck extends false ? false : true : true; +export type IsTemplateLiteralFinite = T extends TTemplateLiteral ? IsTemplateLiteralFiniteArray : false; +export type TTemplateLiteralKind = TUnion | TLiteral | TInteger | TTemplateLiteral | TNumber | TBigInt | TString | TBoolean | TNever; +export type TTemplateLiteralConst = T extends TUnion ? { + [K in keyof U]: TTemplateLiteralUnion, Acc>; +}[number] : T extends TTemplateLiteral ? `${Static}` : T extends TLiteral ? `${U}` : T extends TString ? `${string}` : T extends TNumber ? `${number}` : T extends TBigInt ? `${bigint}` : T extends TBoolean ? `${boolean}` : never; +export type TTemplateLiteralUnion = T extends [infer L, ...infer R] ? `${TTemplateLiteralConst}${TTemplateLiteralUnion, Acc>}` : T extends [infer L] ? `${TTemplateLiteralConst}${Acc}` : Acc; +export interface TTemplateLiteral extends TSchema { + [Kind]: 'TemplateLiteral'; + static: TTemplateLiteralUnion; + type: 'string'; + pattern: string; +} +export type TTupleIntoArray> = T extends TTuple ? Assert : never; +export interface TTuple extends TSchema { + [Kind]: 'Tuple'; + static: { + [K in keyof T]: T[K] extends TSchema ? Static : T[K]; + }; + type: 'array'; + items?: T; + additionalItems?: false; + minItems: number; + maxItems: number; +} +export interface TUndefined extends TSchema { + [Kind]: 'Undefined'; + static: undefined; + type: 'null'; + typeOf: 'Undefined'; +} +export type TUnionOfLiteralArray[]> = { + [K in keyof T]: Assert['const']; +}[number]; +export type TUnionOfLiteral[]>> = TUnionOfLiteralArray; +export type TUnionResult = T extends [] ? TNever : T extends [infer S] ? S : TUnion; +export type TUnionTemplateLiteral> = (string); +export interface TUnion extends TSchema { + [Kind]: 'Union'; + static: { + [K in keyof T]: T[K] extends TSchema ? Static : never; + }[number]; + anyOf: T; +} +export interface Uint8ArrayOptions extends SchemaOptions { + maxByteLength?: number; + minByteLength?: number; +} +export interface TUint8Array extends TSchema, Uint8ArrayOptions { + [Kind]: 'Uint8Array'; + static: Uint8Array; + instanceOf: 'Uint8Array'; + type: 'object'; +} +export interface TUnknown extends TSchema { + [Kind]: 'Unknown'; + static: unknown; +} +export interface UnsafeOptions extends SchemaOptions { + [Kind]?: string; +} +export interface TUnsafe extends TSchema { + [Kind]: string; + static: T; +} +export interface TVoid extends TSchema { + [Kind]: 'Void'; + static: void; + type: 'null'; + typeOf: 'Void'; +} +/** Creates a TypeScript static type from a TypeBox type */ +export type Static = (T & { + params: P; +})['static']; +export type TypeRegistryValidationFunction = (schema: TSchema, value: unknown) => boolean; +/** A registry for user defined types */ +export declare namespace TypeRegistry { + /** Returns the entries in this registry */ + function Entries(): Map>; + /** Clears all user defined types */ + function Clear(): void; + /** Returns true if this registry contains this kind */ + function Has(kind: string): boolean; + /** Sets a validation function for a user defined type */ + function Set(kind: string, func: TypeRegistryValidationFunction): void; + /** Gets a custom validation function for a user defined type */ + function Get(kind: string): TypeRegistryValidationFunction | undefined; +} +export type FormatRegistryValidationFunction = (value: string) => boolean; +/** A registry for user defined string formats */ +export declare namespace FormatRegistry { + /** Returns the entries in this registry */ + function Entries(): Map; + /** Clears all user defined string formats */ + function Clear(): void; + /** Returns true if the user defined string format exists */ + function Has(format: string): boolean; + /** Sets a validation function for a user defined string format */ + function Set(format: string, func: FormatRegistryValidationFunction): void; + /** Gets a validation function for a user defined string format */ + function Get(format: string): FormatRegistryValidationFunction | undefined; +} +export declare class TypeGuardUnknownTypeError extends Error { + readonly schema: unknown; + constructor(schema: unknown); +} +/** Provides functions to test if JavaScript values are TypeBox types */ +export declare namespace TypeGuard { + /** Returns true if the given schema is TAny */ + function TAny(schema: unknown): schema is TAny; + /** Returns true if the given schema is TArray */ + function TArray(schema: unknown): schema is TArray; + /** Returns true if the given schema is TBigInt */ + function TBigInt(schema: unknown): schema is TBigInt; + /** Returns true if the given schema is TBoolean */ + function TBoolean(schema: unknown): schema is TBoolean; + /** Returns true if the given schema is TConstructor */ + function TConstructor(schema: unknown): schema is TConstructor; + /** Returns true if the given schema is TDate */ + function TDate(schema: unknown): schema is TDate; + /** Returns true if the given schema is TFunction */ + function TFunction(schema: unknown): schema is TFunction; + /** Returns true if the given schema is TInteger */ + function TInteger(schema: unknown): schema is TInteger; + /** Returns true if the given schema is TIntersect */ + function TIntersect(schema: unknown): schema is TIntersect; + /** Returns true if the given schema is TKind */ + function TKind(schema: unknown): schema is Record; + /** Returns true if the given schema is TLiteral */ + function TLiteral(schema: unknown): schema is TLiteral; + /** Returns true if the given schema is TNever */ + function TNever(schema: unknown): schema is TNever; + /** Returns true if the given schema is TNot */ + function TNot(schema: unknown): schema is TNot; + /** Returns true if the given schema is TNull */ + function TNull(schema: unknown): schema is TNull; + /** Returns true if the given schema is TNumber */ + function TNumber(schema: unknown): schema is TNumber; + /** Returns true if the given schema is TObject */ + function TObject(schema: unknown): schema is TObject; + /** Returns true if the given schema is TPromise */ + function TPromise(schema: unknown): schema is TPromise; + /** Returns true if the given schema is TRecord */ + function TRecord(schema: unknown): schema is TRecord; + /** Returns true if the given schema is TRef */ + function TRef(schema: unknown): schema is TRef; + /** Returns true if the given schema is TString */ + function TString(schema: unknown): schema is TString; + /** Returns true if the given schema is TSymbol */ + function TSymbol(schema: unknown): schema is TSymbol; + /** Returns true if the given schema is TTemplateLiteral */ + function TTemplateLiteral(schema: unknown): schema is TTemplateLiteral; + /** Returns true if the given schema is TThis */ + function TThis(schema: unknown): schema is TThis; + /** Returns true if the given schema is TTuple */ + function TTuple(schema: unknown): schema is TTuple; + /** Returns true if the given schema is TUndefined */ + function TUndefined(schema: unknown): schema is TUndefined; + /** Returns true if the given schema is TUnion */ + function TUnion(schema: unknown): schema is TUnion; + /** Returns true if the given schema is TUnion[]> */ + function TUnionLiteral(schema: unknown): schema is TUnion[]>; + /** Returns true if the given schema is TUint8Array */ + function TUint8Array(schema: unknown): schema is TUint8Array; + /** Returns true if the given schema is TUnknown */ + function TUnknown(schema: unknown): schema is TUnknown; + /** Returns true if the given schema is a raw TUnsafe */ + function TUnsafe(schema: unknown): schema is TUnsafe; + /** Returns true if the given schema is TVoid */ + function TVoid(schema: unknown): schema is TVoid; + /** Returns true if this schema has the ReadonlyOptional modifier */ + function TReadonlyOptional(schema: T): schema is TReadonlyOptional; + /** Returns true if this schema has the Readonly modifier */ + function TReadonly(schema: T): schema is TReadonly; + /** Returns true if this schema has the Optional modifier */ + function TOptional(schema: T): schema is TOptional; + /** Returns true if the given schema is TSchema */ + function TSchema(schema: unknown): schema is TSchema; +} +/** Fast undefined check used for properties of type undefined */ +export declare namespace ExtendsUndefined { + function Check(schema: TSchema): boolean; +} +export declare enum TypeExtendsResult { + Union = 0, + True = 1, + False = 2 +} +export declare namespace TypeExtends { + function Extends(left: TSchema, right: TSchema): TypeExtendsResult; +} +/** Specialized Clone for Types */ +export declare namespace TypeClone { + /** Clones a type. */ + function Clone(schema: T, options: SchemaOptions): T; +} +export declare namespace ObjectMap { + function Map(schema: TSchema, callback: (object: TObject) => TObject, options: SchemaOptions): T; +} +export declare namespace KeyResolver { + function Resolve(schema: T): string[]; +} +export declare namespace TemplateLiteralPattern { + function Create(kinds: TTemplateLiteralKind[]): string; +} +export declare namespace TemplateLiteralResolver { + function Resolve(template: TTemplateLiteral): TString | TUnion | TLiteral; +} +export declare class TemplateLiteralParserError extends Error { + constructor(message: string); +} +export declare namespace TemplateLiteralParser { + type Expression = And | Or | Const; + type Const = { + type: 'const'; + const: string; + }; + type And = { + type: 'and'; + expr: Expression[]; + }; + type Or = { + type: 'or'; + expr: Expression[]; + }; + /** Parses a pattern and returns an expression tree */ + function Parse(pattern: string): Expression; + /** Parses a pattern and strips forward and trailing ^ and $ */ + function ParseExact(pattern: string): Expression; +} +export declare namespace TemplateLiteralFinite { + function Check(expression: TemplateLiteralParser.Expression): boolean; +} +export declare namespace TemplateLiteralGenerator { + function Generate(expression: TemplateLiteralParser.Expression): IterableIterator; +} +export declare class TypeBuilder { + /** `[Utility]` Creates a schema without `static` and `params` types */ + protected Create(schema: Omit): T; + /** `[Standard]` Omits compositing symbols from this schema */ + Strict(schema: T): T; +} +export declare class StandardTypeBuilder extends TypeBuilder { + /** `[Modifier]` Creates a Optional property */ + Optional(schema: T): TOptional; + /** `[Modifier]` Creates a ReadonlyOptional property */ + ReadonlyOptional(schema: T): TReadonlyOptional; + /** `[Modifier]` Creates a Readonly object or property */ + Readonly(schema: T): TReadonly; + /** `[Standard]` Creates an Any type */ + Any(options?: SchemaOptions): TAny; + /** `[Standard]` Creates an Array type */ + Array(items: T, options?: ArrayOptions): TArray; + /** `[Standard]` Creates a Boolean type */ + Boolean(options?: SchemaOptions): TBoolean; + /** `[Standard]` Creates a Composite object type. */ + Composite(objects: [...T], options?: ObjectOptions): TComposite; + /** `[Standard]` Creates a Enum type */ + Enum>(item: T, options?: SchemaOptions): TEnum; + /** `[Standard]` A conditional type expression that will return the true type if the left type extends the right */ + Extends(left: L, right: R, trueType: T, falseType: U, options?: SchemaOptions): TExtends; + /** `[Standard]` Excludes from the left type any type that is not assignable to the right */ + Exclude(left: L, right: R, options?: SchemaOptions): TExclude; + /** `[Standard]` Extracts from the left type any type that is assignable to the right */ + Extract(left: L, right: R, options?: SchemaOptions): TExtract; + /** `[Standard]` Creates an Integer type */ + Integer(options?: NumericOptions): TInteger; + /** `[Standard]` Creates a Intersect type */ + Intersect(allOf: [], options?: SchemaOptions): TNever; + /** `[Standard]` Creates a Intersect type */ + Intersect(allOf: [...T], options?: SchemaOptions): T[0]; + Intersect(allOf: [...T], options?: IntersectOptions): TIntersect; + /** `[Standard]` Creates a KeyOf type */ + KeyOf(schema: T, options?: SchemaOptions): TKeyOf; + /** `[Standard]` Creates a Literal type */ + Literal(value: T, options?: SchemaOptions): TLiteral; + /** `[Standard]` Creates a Never type */ + Never(options?: SchemaOptions): TNever; + /** `[Standard]` Creates a Not type. The first argument is the disallowed type, the second is the allowed. */ + Not(not: N, schema: T, options?: SchemaOptions): TNot; + /** `[Standard]` Creates a Null type */ + Null(options?: SchemaOptions): TNull; + /** `[Standard]` Creates a Number type */ + Number(options?: NumericOptions): TNumber; + /** `[Standard]` Creates an Object type */ + Object(properties: T, options?: ObjectOptions): TObject; + /** `[Standard]` Creates a mapped type whose keys are omitted from the given type */ + Omit)[]>(schema: T, keys: readonly [...K], options?: SchemaOptions): TOmit; + /** `[Standard]` Creates a mapped type whose keys are omitted from the given type */ + Omit[]>>(schema: T, keys: K, options?: SchemaOptions): TOmit>; + /** `[Standard]` Creates a mapped type whose keys are omitted from the given type */ + Omit>(schema: T, key: K, options?: SchemaOptions): TOmit; + /** `[Standard]` Creates a mapped type whose keys are omitted from the given type */ + Omit(schema: T, key: K, options?: SchemaOptions): TOmit; + /** `[Standard]` Creates a mapped type where all properties are Optional */ + Partial(schema: T, options?: ObjectOptions): TPartial; + /** `[Standard]` Creates a mapped type whose keys are picked from the given type */ + Pick)[]>(schema: T, keys: readonly [...K], options?: SchemaOptions): TPick; + /** `[Standard]` Creates a mapped type whose keys are picked from the given type */ + Pick[]>>(schema: T, keys: K, options?: SchemaOptions): TPick>; + /** `[Standard]` Creates a mapped type whose keys are picked from the given type */ + Pick>(schema: T, key: K, options?: SchemaOptions): TPick; + /** `[Standard]` Creates a mapped type whose keys are picked from the given type */ + Pick(schema: T, key: K, options?: SchemaOptions): TPick; + /** `[Standard]` Creates a Record type */ + Record[]>, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordUnionLiteralType; + /** `[Standard]` Creates a Record type */ + Record, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordLiteralType; + /** `[Standard]` Creates a Record type */ + Record(key: K, schema: T, options?: ObjectOptions): RecordTemplateLiteralType; + /** `[Standard]` Creates a Record type */ + Record(key: K, schema: T, options?: ObjectOptions): RecordNumberType; + /** `[Standard]` Creates a Record type */ + Record(key: K, schema: T, options?: ObjectOptions): RecordStringType; + /** `[Standard]` Creates a Recursive type */ + Recursive(callback: (thisType: TThis) => T, options?: SchemaOptions): TRecursive; + /** `[Standard]` Creates a Ref type. The referenced type must contain a $id */ + Ref(schema: T, options?: SchemaOptions): TRef; + /** `[Standard]` Creates a mapped type where all properties are Required */ + Required(schema: T, options?: SchemaOptions): TRequired; + /** `[Standard]` Creates a String type */ + String(options?: StringOptions): TString; + /** `[Standard]` Creates a template literal type */ + TemplateLiteral(kinds: [...T], options?: SchemaOptions): TTemplateLiteral; + /** `[Standard]` Creates a Tuple type */ + Tuple(items: [...T], options?: SchemaOptions): TTuple; + /** `[Standard]` Creates a Union type */ + Union(anyOf: [], options?: SchemaOptions): TNever; + /** `[Standard]` Creates a Union type */ + Union(anyOf: [...T], options?: SchemaOptions): T[0]; + /** `[Standard]` Creates a Union type */ + Union(anyOf: [...T], options?: SchemaOptions): TUnion; + /** `[Experimental]` Remaps a TemplateLiteral into a Union representation. This function is known to cause TS compiler crashes for finite templates with large generation counts. Use with caution. */ + Union(template: T): TUnionTemplateLiteral; + /** `[Standard]` Creates an Unknown type */ + Unknown(options?: SchemaOptions): TUnknown; + /** `[Standard]` Creates a Unsafe type that infers for the generic argument */ + Unsafe(options?: UnsafeOptions): TUnsafe; +} +export declare class ExtendedTypeBuilder extends StandardTypeBuilder { + /** `[Extended]` Creates a BigInt type */ + BigInt(options?: NumericOptions): TBigInt; + /** `[Extended]` Extracts the ConstructorParameters from the given Constructor type */ + ConstructorParameters>(schema: T, options?: SchemaOptions): TConstructorParameters; + /** `[Extended]` Creates a Constructor type */ + Constructor, U extends TSchema>(parameters: T, returns: U, options?: SchemaOptions): TConstructor, U>; + /** `[Extended]` Creates a Constructor type */ + Constructor(parameters: [...T], returns: U, options?: SchemaOptions): TConstructor; + /** `[Extended]` Creates a Date type */ + Date(options?: DateOptions): TDate; + /** `[Extended]` Creates a Function type */ + Function, U extends TSchema>(parameters: T, returns: U, options?: SchemaOptions): TFunction, U>; + /** `[Extended]` Creates a Function type */ + Function(parameters: [...T], returns: U, options?: SchemaOptions): TFunction; + /** `[Extended]` Extracts the InstanceType from the given Constructor */ + InstanceType>(schema: T, options?: SchemaOptions): TInstanceType; + /** `[Extended]` Extracts the Parameters from the given Function type */ + Parameters>(schema: T, options?: SchemaOptions): TParameters; + /** `[Extended]` Creates a Promise type */ + Promise(item: T, options?: SchemaOptions): TPromise; + /** `[Extended]` Creates a regular expression type */ + RegEx(regex: RegExp, options?: SchemaOptions): TString; + /** `[Extended]` Extracts the ReturnType from the given Function */ + ReturnType>(schema: T, options?: SchemaOptions): TReturnType; + /** `[Extended]` Creates a Symbol type */ + Symbol(options?: SchemaOptions): TSymbol; + /** `[Extended]` Creates a Undefined type */ + Undefined(options?: SchemaOptions): TUndefined; + /** `[Extended]` Creates a Uint8Array type */ + Uint8Array(options?: Uint8ArrayOptions): TUint8Array; + /** `[Extended]` Creates a Void type */ + Void(options?: SchemaOptions): TVoid; +} +/** JSON Schema TypeBuilder with Static Resolution for TypeScript */ +export declare const StandardType: StandardTypeBuilder; +/** JSON Schema TypeBuilder with Static Resolution for TypeScript */ +export declare const Type: ExtendedTypeBuilder; diff --git a/node_modules/@sinclair/typebox/typebox.js b/node_modules/@sinclair/typebox/typebox.js new file mode 100644 index 0000000..c8953c3 --- /dev/null +++ b/node_modules/@sinclair/typebox/typebox.js @@ -0,0 +1,2220 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Type = exports.StandardType = exports.ExtendedTypeBuilder = exports.StandardTypeBuilder = exports.TypeBuilder = exports.TemplateLiteralGenerator = exports.TemplateLiteralFinite = exports.TemplateLiteralParser = exports.TemplateLiteralParserError = exports.TemplateLiteralResolver = exports.TemplateLiteralPattern = exports.KeyResolver = exports.ObjectMap = exports.TypeClone = exports.TypeExtends = exports.TypeExtendsResult = exports.ExtendsUndefined = exports.TypeGuard = exports.TypeGuardUnknownTypeError = exports.FormatRegistry = exports.TypeRegistry = exports.PatternStringExact = exports.PatternNumberExact = exports.PatternBooleanExact = exports.PatternString = exports.PatternNumber = exports.PatternBoolean = exports.Kind = exports.Hint = exports.Modifier = void 0; +// -------------------------------------------------------------------------- +// Symbols +// -------------------------------------------------------------------------- +exports.Modifier = Symbol.for('TypeBox.Modifier'); +exports.Hint = Symbol.for('TypeBox.Hint'); +exports.Kind = Symbol.for('TypeBox.Kind'); +// -------------------------------------------------------------------------- +// Patterns +// -------------------------------------------------------------------------- +exports.PatternBoolean = '(true|false)'; +exports.PatternNumber = '(0|[1-9][0-9]*)'; +exports.PatternString = '(.*)'; +exports.PatternBooleanExact = `^${exports.PatternBoolean}$`; +exports.PatternNumberExact = `^${exports.PatternNumber}$`; +exports.PatternStringExact = `^${exports.PatternString}$`; +/** A registry for user defined types */ +var TypeRegistry; +(function (TypeRegistry) { + const map = new Map(); + /** Returns the entries in this registry */ + function Entries() { + return new Map(map); + } + TypeRegistry.Entries = Entries; + /** Clears all user defined types */ + function Clear() { + return map.clear(); + } + TypeRegistry.Clear = Clear; + /** Returns true if this registry contains this kind */ + function Has(kind) { + return map.has(kind); + } + TypeRegistry.Has = Has; + /** Sets a validation function for a user defined type */ + function Set(kind, func) { + map.set(kind, func); + } + TypeRegistry.Set = Set; + /** Gets a custom validation function for a user defined type */ + function Get(kind) { + return map.get(kind); + } + TypeRegistry.Get = Get; +})(TypeRegistry = exports.TypeRegistry || (exports.TypeRegistry = {})); +/** A registry for user defined string formats */ +var FormatRegistry; +(function (FormatRegistry) { + const map = new Map(); + /** Returns the entries in this registry */ + function Entries() { + return new Map(map); + } + FormatRegistry.Entries = Entries; + /** Clears all user defined string formats */ + function Clear() { + return map.clear(); + } + FormatRegistry.Clear = Clear; + /** Returns true if the user defined string format exists */ + function Has(format) { + return map.has(format); + } + FormatRegistry.Has = Has; + /** Sets a validation function for a user defined string format */ + function Set(format, func) { + map.set(format, func); + } + FormatRegistry.Set = Set; + /** Gets a validation function for a user defined string format */ + function Get(format) { + return map.get(format); + } + FormatRegistry.Get = Get; +})(FormatRegistry = exports.FormatRegistry || (exports.FormatRegistry = {})); +// -------------------------------------------------------------------------- +// TypeGuard +// -------------------------------------------------------------------------- +class TypeGuardUnknownTypeError extends Error { + constructor(schema) { + super('TypeGuard: Unknown type'); + this.schema = schema; + } +} +exports.TypeGuardUnknownTypeError = TypeGuardUnknownTypeError; +/** Provides functions to test if JavaScript values are TypeBox types */ +var TypeGuard; +(function (TypeGuard) { + function IsObject(value) { + return typeof value === 'object' && value !== null && !Array.isArray(value); + } + function IsArray(value) { + return typeof value === 'object' && value !== null && Array.isArray(value); + } + function IsPattern(value) { + try { + new RegExp(value); + return true; + } + catch { + return false; + } + } + function IsControlCharacterFree(value) { + if (typeof value !== 'string') + return false; + for (let i = 0; i < value.length; i++) { + const code = value.charCodeAt(i); + if ((code >= 7 && code <= 13) || code === 27 || code === 127) { + return false; + } + } + return true; + } + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsString(value) { + return typeof value === 'string'; + } + function IsNumber(value) { + return typeof value === 'number' && globalThis.Number.isFinite(value); + } + function IsBoolean(value) { + return typeof value === 'boolean'; + } + function IsOptionalBigInt(value) { + return value === undefined || (value !== undefined && IsBigInt(value)); + } + function IsOptionalNumber(value) { + return value === undefined || (value !== undefined && IsNumber(value)); + } + function IsOptionalBoolean(value) { + return value === undefined || (value !== undefined && IsBoolean(value)); + } + function IsOptionalString(value) { + return value === undefined || (value !== undefined && IsString(value)); + } + function IsOptionalPattern(value) { + return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value) && IsPattern(value)); + } + function IsOptionalFormat(value) { + return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value)); + } + function IsOptionalSchema(value) { + return value === undefined || TSchema(value); + } + /** Returns true if the given schema is TAny */ + function TAny(schema) { + return TKind(schema) && schema[exports.Kind] === 'Any' && IsOptionalString(schema.$id); + } + TypeGuard.TAny = TAny; + /** Returns true if the given schema is TArray */ + function TArray(schema) { + return (TKind(schema) && + schema[exports.Kind] === 'Array' && + schema.type === 'array' && + IsOptionalString(schema.$id) && + TSchema(schema.items) && + IsOptionalNumber(schema.minItems) && + IsOptionalNumber(schema.maxItems) && + IsOptionalBoolean(schema.uniqueItems)); + } + TypeGuard.TArray = TArray; + /** Returns true if the given schema is TBigInt */ + function TBigInt(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'BigInt' && + schema.type === 'null' && + schema.typeOf === 'BigInt' && + IsOptionalString(schema.$id) && + IsOptionalBigInt(schema.multipleOf) && + IsOptionalBigInt(schema.minimum) && + IsOptionalBigInt(schema.maximum) && + IsOptionalBigInt(schema.exclusiveMinimum) && + IsOptionalBigInt(schema.exclusiveMaximum)); + } + TypeGuard.TBigInt = TBigInt; + /** Returns true if the given schema is TBoolean */ + function TBoolean(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Boolean' && + schema.type === 'boolean' && + IsOptionalString(schema.$id)); + } + TypeGuard.TBoolean = TBoolean; + /** Returns true if the given schema is TConstructor */ + function TConstructor(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Constructor' && + schema.type === 'object' && + schema.instanceOf === 'Constructor' && + IsOptionalString(schema.$id) && + IsArray(schema.parameters) && + TSchema(schema.returns))) { + return false; + } + for (const parameter of schema.parameters) { + if (!TSchema(parameter)) + return false; + } + return true; + } + TypeGuard.TConstructor = TConstructor; + /** Returns true if the given schema is TDate */ + function TDate(schema) { + return (TKind(schema) && + schema[exports.Kind] === 'Date' && + schema.type === 'object' && + schema.instanceOf === 'Date' && + IsOptionalString(schema.$id) && + IsOptionalNumber(schema.minimumTimestamp) && + IsOptionalNumber(schema.maximumTimestamp) && + IsOptionalNumber(schema.exclusiveMinimumTimestamp) && + IsOptionalNumber(schema.exclusiveMaximumTimestamp)); + } + TypeGuard.TDate = TDate; + /** Returns true if the given schema is TFunction */ + function TFunction(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Function' && + schema.type === 'object' && + schema.instanceOf === 'Function' && + IsOptionalString(schema.$id) && + IsArray(schema.parameters) && + TSchema(schema.returns))) { + return false; + } + for (const parameter of schema.parameters) { + if (!TSchema(parameter)) + return false; + } + return true; + } + TypeGuard.TFunction = TFunction; + /** Returns true if the given schema is TInteger */ + function TInteger(schema) { + return (TKind(schema) && + schema[exports.Kind] === 'Integer' && + schema.type === 'integer' && + IsOptionalString(schema.$id) && + IsOptionalNumber(schema.multipleOf) && + IsOptionalNumber(schema.minimum) && + IsOptionalNumber(schema.maximum) && + IsOptionalNumber(schema.exclusiveMinimum) && + IsOptionalNumber(schema.exclusiveMaximum)); + } + TypeGuard.TInteger = TInteger; + /** Returns true if the given schema is TIntersect */ + function TIntersect(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Intersect' && + IsArray(schema.allOf) && + IsOptionalString(schema.type) && + (IsOptionalBoolean(schema.unevaluatedProperties) || IsOptionalSchema(schema.unevaluatedProperties)) && + IsOptionalString(schema.$id))) { + return false; + } + if ('type' in schema && schema.type !== 'object') { + return false; + } + for (const inner of schema.allOf) { + if (!TSchema(inner)) + return false; + } + return true; + } + TypeGuard.TIntersect = TIntersect; + /** Returns true if the given schema is TKind */ + function TKind(schema) { + return IsObject(schema) && exports.Kind in schema && typeof schema[exports.Kind] === 'string'; // TS 4.1.5: any required for symbol indexer + } + TypeGuard.TKind = TKind; + /** Returns true if the given schema is TLiteral */ + function TLiteral(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Literal' && + IsOptionalString(schema.$id) && + (IsString(schema.const) || + IsNumber(schema.const) || + IsBoolean(schema.const) || + IsBigInt(schema.const))); + } + TypeGuard.TLiteral = TLiteral; + /** Returns true if the given schema is TNever */ + function TNever(schema) { + return TKind(schema) && schema[exports.Kind] === 'Never' && IsObject(schema.not) && globalThis.Object.getOwnPropertyNames(schema.not).length === 0; + } + TypeGuard.TNever = TNever; + /** Returns true if the given schema is TNot */ + function TNot(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Not' && + IsArray(schema.allOf) && + schema.allOf.length === 2 && + IsObject(schema.allOf[0]) && + TSchema(schema.allOf[0].not) && + TSchema(schema.allOf[1])); + } + TypeGuard.TNot = TNot; + /** Returns true if the given schema is TNull */ + function TNull(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Null' && + schema.type === 'null' && + IsOptionalString(schema.$id)); + } + TypeGuard.TNull = TNull; + /** Returns true if the given schema is TNumber */ + function TNumber(schema) { + return (TKind(schema) && + schema[exports.Kind] === 'Number' && + schema.type === 'number' && + IsOptionalString(schema.$id) && + IsOptionalNumber(schema.multipleOf) && + IsOptionalNumber(schema.minimum) && + IsOptionalNumber(schema.maximum) && + IsOptionalNumber(schema.exclusiveMinimum) && + IsOptionalNumber(schema.exclusiveMaximum)); + } + TypeGuard.TNumber = TNumber; + /** Returns true if the given schema is TObject */ + function TObject(schema) { + if (!(TKind(schema) && + schema[exports.Kind] === 'Object' && + schema.type === 'object' && + IsOptionalString(schema.$id) && + IsObject(schema.properties) && + (IsOptionalBoolean(schema.additionalProperties) || IsOptionalSchema(schema.additionalProperties)) && + IsOptionalNumber(schema.minProperties) && + IsOptionalNumber(schema.maxProperties))) { + return false; + } + for (const [key, value] of Object.entries(schema.properties)) { + if (!IsControlCharacterFree(key)) + return false; + if (!TSchema(value)) + return false; + } + return true; + } + TypeGuard.TObject = TObject; + /** Returns true if the given schema is TPromise */ + function TPromise(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Promise' && + schema.type === 'object' && + schema.instanceOf === 'Promise' && + IsOptionalString(schema.$id) && + TSchema(schema.item)); + } + TypeGuard.TPromise = TPromise; + /** Returns true if the given schema is TRecord */ + function TRecord(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Record' && + schema.type === 'object' && + IsOptionalString(schema.$id) && + schema.additionalProperties === false && + IsObject(schema.patternProperties))) { + return false; + } + const keys = Object.keys(schema.patternProperties); + if (keys.length !== 1) { + return false; + } + if (!IsPattern(keys[0])) { + return false; + } + if (!TSchema(schema.patternProperties[keys[0]])) { + return false; + } + return true; + } + TypeGuard.TRecord = TRecord; + /** Returns true if the given schema is TRef */ + function TRef(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Ref' && + IsOptionalString(schema.$id) && + IsString(schema.$ref)); + } + TypeGuard.TRef = TRef; + /** Returns true if the given schema is TString */ + function TString(schema) { + return (TKind(schema) && + schema[exports.Kind] === 'String' && + schema.type === 'string' && + IsOptionalString(schema.$id) && + IsOptionalNumber(schema.minLength) && + IsOptionalNumber(schema.maxLength) && + IsOptionalPattern(schema.pattern) && + IsOptionalFormat(schema.format)); + } + TypeGuard.TString = TString; + /** Returns true if the given schema is TSymbol */ + function TSymbol(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Symbol' && + schema.type === 'null' && + schema.typeOf === 'Symbol' && + IsOptionalString(schema.$id)); + } + TypeGuard.TSymbol = TSymbol; + /** Returns true if the given schema is TTemplateLiteral */ + function TTemplateLiteral(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'TemplateLiteral' && + schema.type === 'string' && + IsString(schema.pattern) && + schema.pattern[0] === '^' && + schema.pattern[schema.pattern.length - 1] === '$'); + } + TypeGuard.TTemplateLiteral = TTemplateLiteral; + /** Returns true if the given schema is TThis */ + function TThis(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'This' && + IsOptionalString(schema.$id) && + IsString(schema.$ref)); + } + TypeGuard.TThis = TThis; + /** Returns true if the given schema is TTuple */ + function TTuple(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Tuple' && + schema.type === 'array' && + IsOptionalString(schema.$id) && + IsNumber(schema.minItems) && + IsNumber(schema.maxItems) && + schema.minItems === schema.maxItems)) { + return false; + } + if (schema.items === undefined && schema.additionalItems === undefined && schema.minItems === 0) { + return true; + } + if (!IsArray(schema.items)) { + return false; + } + for (const inner of schema.items) { + if (!TSchema(inner)) + return false; + } + return true; + } + TypeGuard.TTuple = TTuple; + /** Returns true if the given schema is TUndefined */ + function TUndefined(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Undefined' && + schema.type === 'null' && + schema.typeOf === 'Undefined' && + IsOptionalString(schema.$id)); + } + TypeGuard.TUndefined = TUndefined; + /** Returns true if the given schema is TUnion */ + function TUnion(schema) { + // prettier-ignore + if (!(TKind(schema) && + schema[exports.Kind] === 'Union' && + IsArray(schema.anyOf) && + IsOptionalString(schema.$id))) { + return false; + } + for (const inner of schema.anyOf) { + if (!TSchema(inner)) + return false; + } + return true; + } + TypeGuard.TUnion = TUnion; + /** Returns true if the given schema is TUnion[]> */ + function TUnionLiteral(schema) { + return TUnion(schema) && schema.anyOf.every((schema) => TLiteral(schema) && typeof schema.const === 'string'); + } + TypeGuard.TUnionLiteral = TUnionLiteral; + /** Returns true if the given schema is TUint8Array */ + function TUint8Array(schema) { + return TKind(schema) && schema[exports.Kind] === 'Uint8Array' && schema.type === 'object' && IsOptionalString(schema.$id) && schema.instanceOf === 'Uint8Array' && IsOptionalNumber(schema.minByteLength) && IsOptionalNumber(schema.maxByteLength); + } + TypeGuard.TUint8Array = TUint8Array; + /** Returns true if the given schema is TUnknown */ + function TUnknown(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Unknown' && + IsOptionalString(schema.$id)); + } + TypeGuard.TUnknown = TUnknown; + /** Returns true if the given schema is a raw TUnsafe */ + function TUnsafe(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Unsafe'); + } + TypeGuard.TUnsafe = TUnsafe; + /** Returns true if the given schema is TVoid */ + function TVoid(schema) { + // prettier-ignore + return (TKind(schema) && + schema[exports.Kind] === 'Void' && + schema.type === 'null' && + schema.typeOf === 'Void' && + IsOptionalString(schema.$id)); + } + TypeGuard.TVoid = TVoid; + /** Returns true if this schema has the ReadonlyOptional modifier */ + function TReadonlyOptional(schema) { + return IsObject(schema) && schema[exports.Modifier] === 'ReadonlyOptional'; + } + TypeGuard.TReadonlyOptional = TReadonlyOptional; + /** Returns true if this schema has the Readonly modifier */ + function TReadonly(schema) { + return IsObject(schema) && schema[exports.Modifier] === 'Readonly'; + } + TypeGuard.TReadonly = TReadonly; + /** Returns true if this schema has the Optional modifier */ + function TOptional(schema) { + return IsObject(schema) && schema[exports.Modifier] === 'Optional'; + } + TypeGuard.TOptional = TOptional; + /** Returns true if the given schema is TSchema */ + function TSchema(schema) { + return (typeof schema === 'object' && + (TAny(schema) || + TArray(schema) || + TBoolean(schema) || + TBigInt(schema) || + TConstructor(schema) || + TDate(schema) || + TFunction(schema) || + TInteger(schema) || + TIntersect(schema) || + TLiteral(schema) || + TNever(schema) || + TNot(schema) || + TNull(schema) || + TNumber(schema) || + TObject(schema) || + TPromise(schema) || + TRecord(schema) || + TRef(schema) || + TString(schema) || + TSymbol(schema) || + TTemplateLiteral(schema) || + TThis(schema) || + TTuple(schema) || + TUndefined(schema) || + TUnion(schema) || + TUint8Array(schema) || + TUnknown(schema) || + TUnsafe(schema) || + TVoid(schema) || + (TKind(schema) && TypeRegistry.Has(schema[exports.Kind])))); + } + TypeGuard.TSchema = TSchema; +})(TypeGuard = exports.TypeGuard || (exports.TypeGuard = {})); +// -------------------------------------------------------------------------- +// ExtendsUndefined +// -------------------------------------------------------------------------- +/** Fast undefined check used for properties of type undefined */ +var ExtendsUndefined; +(function (ExtendsUndefined) { + function Check(schema) { + if (schema[exports.Kind] === 'Undefined') + return true; + if (schema[exports.Kind] === 'Union') { + const union = schema; + return union.anyOf.some((schema) => Check(schema)); + } + return false; + } + ExtendsUndefined.Check = Check; +})(ExtendsUndefined = exports.ExtendsUndefined || (exports.ExtendsUndefined = {})); +// -------------------------------------------------------------------------- +// TypeExtends +// -------------------------------------------------------------------------- +var TypeExtendsResult; +(function (TypeExtendsResult) { + TypeExtendsResult[TypeExtendsResult["Union"] = 0] = "Union"; + TypeExtendsResult[TypeExtendsResult["True"] = 1] = "True"; + TypeExtendsResult[TypeExtendsResult["False"] = 2] = "False"; +})(TypeExtendsResult = exports.TypeExtendsResult || (exports.TypeExtendsResult = {})); +var TypeExtends; +(function (TypeExtends) { + // -------------------------------------------------------------------------- + // IntoBooleanResult + // -------------------------------------------------------------------------- + function IntoBooleanResult(result) { + return result === TypeExtendsResult.False ? TypeExtendsResult.False : TypeExtendsResult.True; + } + // -------------------------------------------------------------------------- + // Any + // -------------------------------------------------------------------------- + function AnyRight(left, right) { + return TypeExtendsResult.True; + } + function Any(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right) && right.anyOf.some((schema) => TypeGuard.TAny(schema) || TypeGuard.TUnknown(schema))) + return TypeExtendsResult.True; + if (TypeGuard.TUnion(right)) + return TypeExtendsResult.Union; + if (TypeGuard.TUnknown(right)) + return TypeExtendsResult.True; + if (TypeGuard.TAny(right)) + return TypeExtendsResult.True; + return TypeExtendsResult.Union; + } + // -------------------------------------------------------------------------- + // Array + // -------------------------------------------------------------------------- + function ArrayRight(left, right) { + if (TypeGuard.TUnknown(left)) + return TypeExtendsResult.False; + if (TypeGuard.TAny(left)) + return TypeExtendsResult.Union; + if (TypeGuard.TNever(left)) + return TypeExtendsResult.True; + return TypeExtendsResult.False; + } + function Array(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right) && IsObjectArrayLike(right)) + return TypeExtendsResult.True; + if (!TypeGuard.TArray(right)) + return TypeExtendsResult.False; + return IntoBooleanResult(Visit(left.items, right.items)); + } + // -------------------------------------------------------------------------- + // BigInt + // -------------------------------------------------------------------------- + function BigInt(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TBigInt(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Boolean + // -------------------------------------------------------------------------- + function BooleanRight(left, right) { + if (TypeGuard.TLiteral(left) && typeof left.const === 'boolean') + return TypeExtendsResult.True; + return TypeGuard.TBoolean(left) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Boolean(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TBoolean(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Constructor + // -------------------------------------------------------------------------- + function Constructor(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (!TypeGuard.TConstructor(right)) + return TypeExtendsResult.False; + if (left.parameters.length > right.parameters.length) + return TypeExtendsResult.False; + if (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === TypeExtendsResult.True)) { + return TypeExtendsResult.False; + } + return IntoBooleanResult(Visit(left.returns, right.returns)); + } + // -------------------------------------------------------------------------- + // Date + // -------------------------------------------------------------------------- + function Date(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TDate(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Function + // -------------------------------------------------------------------------- + function Function(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (!TypeGuard.TFunction(right)) + return TypeExtendsResult.False; + if (left.parameters.length > right.parameters.length) + return TypeExtendsResult.False; + if (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === TypeExtendsResult.True)) { + return TypeExtendsResult.False; + } + return IntoBooleanResult(Visit(left.returns, right.returns)); + } + // -------------------------------------------------------------------------- + // Integer + // -------------------------------------------------------------------------- + function IntegerRight(left, right) { + if (TypeGuard.TLiteral(left) && typeof left.const === 'number') + return TypeExtendsResult.True; + return TypeGuard.TNumber(left) || TypeGuard.TInteger(left) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Integer(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TInteger(right) || TypeGuard.TNumber(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Intersect + // -------------------------------------------------------------------------- + function IntersectRight(left, right) { + return right.allOf.every((schema) => Visit(left, schema) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Intersect(left, right) { + return left.allOf.some((schema) => Visit(schema, right) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Literal + // -------------------------------------------------------------------------- + function IsLiteralString(schema) { + return typeof schema.const === 'string'; + } + function IsLiteralNumber(schema) { + return typeof schema.const === 'number'; + } + function IsLiteralBoolean(schema) { + return typeof schema.const === 'boolean'; + } + function Literal(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + if (TypeGuard.TString(right)) + return StringRight(left, right); + if (TypeGuard.TNumber(right)) + return NumberRight(left, right); + if (TypeGuard.TInteger(right)) + return IntegerRight(left, right); + if (TypeGuard.TBoolean(right)) + return BooleanRight(left, right); + return TypeGuard.TLiteral(right) && right.const === left.const ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Never + // -------------------------------------------------------------------------- + function NeverRight(left, right) { + return TypeExtendsResult.False; + } + function Never(left, right) { + return TypeExtendsResult.True; + } + // -------------------------------------------------------------------------- + // Null + // -------------------------------------------------------------------------- + function Null(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TNull(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Number + // -------------------------------------------------------------------------- + function NumberRight(left, right) { + if (TypeGuard.TLiteral(left) && IsLiteralNumber(left)) + return TypeExtendsResult.True; + return TypeGuard.TNumber(left) || TypeGuard.TInteger(left) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Number(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TInteger(right) || TypeGuard.TNumber(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Object + // -------------------------------------------------------------------------- + function IsObjectPropertyCount(schema, count) { + return globalThis.Object.keys(schema.properties).length === count; + } + function IsObjectStringLike(schema) { + return IsObjectArrayLike(schema); + } + function IsObjectSymbolLike(schema) { + // prettier-ignore + return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'description' in schema.properties && TypeGuard.TUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && ((TypeGuard.TString(schema.properties.description.anyOf[0]) && + TypeGuard.TUndefined(schema.properties.description.anyOf[1])) || (TypeGuard.TString(schema.properties.description.anyOf[1]) && + TypeGuard.TUndefined(schema.properties.description.anyOf[0])))); + } + function IsObjectNumberLike(schema) { + return IsObjectPropertyCount(schema, 0); + } + function IsObjectBooleanLike(schema) { + return IsObjectPropertyCount(schema, 0); + } + function IsObjectBigIntLike(schema) { + return IsObjectPropertyCount(schema, 0); + } + function IsObjectDateLike(schema) { + return IsObjectPropertyCount(schema, 0); + } + function IsObjectUint8ArrayLike(schema) { + return IsObjectArrayLike(schema); + } + function IsObjectFunctionLike(schema) { + const length = exports.Type.Number(); + return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === TypeExtendsResult.True); + } + function IsObjectConstructorLike(schema) { + return IsObjectPropertyCount(schema, 0); + } + function IsObjectArrayLike(schema) { + const length = exports.Type.Number(); + return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === TypeExtendsResult.True); + } + function IsObjectPromiseLike(schema) { + const then = exports.Type.Function([exports.Type.Any()], exports.Type.Any()); + return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'then' in schema.properties && IntoBooleanResult(Visit(schema.properties['then'], then)) === TypeExtendsResult.True); + } + // -------------------------------------------------------------------------- + // Property + // -------------------------------------------------------------------------- + function Property(left, right) { + if (Visit(left, right) === TypeExtendsResult.False) + return TypeExtendsResult.False; + if (TypeGuard.TOptional(left) && !TypeGuard.TOptional(right)) + return TypeExtendsResult.False; + return TypeExtendsResult.True; + } + function ObjectRight(left, right) { + if (TypeGuard.TUnknown(left)) + return TypeExtendsResult.False; + if (TypeGuard.TAny(left)) + return TypeExtendsResult.Union; + if (TypeGuard.TNever(left)) + return TypeExtendsResult.True; + if (TypeGuard.TLiteral(left) && IsLiteralString(left) && IsObjectStringLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TLiteral(left) && IsLiteralNumber(left) && IsObjectNumberLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TLiteral(left) && IsLiteralBoolean(left) && IsObjectBooleanLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TSymbol(left) && IsObjectSymbolLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TBigInt(left) && IsObjectBigIntLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TString(left) && IsObjectStringLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TSymbol(left) && IsObjectSymbolLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TNumber(left) && IsObjectNumberLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TInteger(left) && IsObjectNumberLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TBoolean(left) && IsObjectBooleanLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TUint8Array(left) && IsObjectUint8ArrayLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TDate(left) && IsObjectDateLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TConstructor(left) && IsObjectConstructorLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TFunction(left) && IsObjectFunctionLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TRecord(left) && TypeGuard.TString(RecordKey(left))) { + // When expressing a Record with literal key values, the Record is converted into a Object with + // the Hint assigned as `Record`. This is used to invert the extends logic. + return right[exports.Hint] === 'Record' ? TypeExtendsResult.True : TypeExtendsResult.False; + } + if (TypeGuard.TRecord(left) && TypeGuard.TNumber(RecordKey(left))) { + return IsObjectPropertyCount(right, 0) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + return TypeExtendsResult.False; + } + function Object(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + if (!TypeGuard.TObject(right)) + return TypeExtendsResult.False; + for (const key of globalThis.Object.keys(right.properties)) { + if (!(key in left.properties)) + return TypeExtendsResult.False; + if (Property(left.properties[key], right.properties[key]) === TypeExtendsResult.False) { + return TypeExtendsResult.False; + } + } + return TypeExtendsResult.True; + } + // -------------------------------------------------------------------------- + // Promise + // -------------------------------------------------------------------------- + function Promise(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right) && IsObjectPromiseLike(right)) + return TypeExtendsResult.True; + if (!TypeGuard.TPromise(right)) + return TypeExtendsResult.False; + return IntoBooleanResult(Visit(left.item, right.item)); + } + // -------------------------------------------------------------------------- + // Record + // -------------------------------------------------------------------------- + function RecordKey(schema) { + if (exports.PatternNumberExact in schema.patternProperties) + return exports.Type.Number(); + if (exports.PatternStringExact in schema.patternProperties) + return exports.Type.String(); + throw Error('TypeExtends: Cannot get record key'); + } + function RecordValue(schema) { + if (exports.PatternNumberExact in schema.patternProperties) + return schema.patternProperties[exports.PatternNumberExact]; + if (exports.PatternStringExact in schema.patternProperties) + return schema.patternProperties[exports.PatternStringExact]; + throw Error('TypeExtends: Cannot get record value'); + } + function RecordRight(left, right) { + const Key = RecordKey(right); + const Value = RecordValue(right); + if (TypeGuard.TLiteral(left) && IsLiteralString(left) && TypeGuard.TNumber(Key) && IntoBooleanResult(Visit(left, Value)) === TypeExtendsResult.True) + return TypeExtendsResult.True; + if (TypeGuard.TUint8Array(left) && TypeGuard.TNumber(Key)) + return Visit(left, Value); + if (TypeGuard.TString(left) && TypeGuard.TNumber(Key)) + return Visit(left, Value); + if (TypeGuard.TArray(left) && TypeGuard.TNumber(Key)) + return Visit(left, Value); + if (TypeGuard.TObject(left)) { + for (const key of globalThis.Object.keys(left.properties)) { + if (Property(Value, left.properties[key]) === TypeExtendsResult.False) { + return TypeExtendsResult.False; + } + } + return TypeExtendsResult.True; + } + return TypeExtendsResult.False; + } + function Record(left, right) { + const Value = RecordValue(left); + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (!TypeGuard.TRecord(right)) + return TypeExtendsResult.False; + return Visit(Value, RecordValue(right)); + } + // -------------------------------------------------------------------------- + // String + // -------------------------------------------------------------------------- + function StringRight(left, right) { + if (TypeGuard.TLiteral(left) && typeof left.const === 'string') + return TypeExtendsResult.True; + return TypeGuard.TString(left) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function String(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TString(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Symbol + // -------------------------------------------------------------------------- + function Symbol(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TSymbol(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Tuple + // -------------------------------------------------------------------------- + function TupleRight(left, right) { + if (TypeGuard.TUnknown(left)) + return TypeExtendsResult.False; + if (TypeGuard.TAny(left)) + return TypeExtendsResult.Union; + if (TypeGuard.TNever(left)) + return TypeExtendsResult.True; + return TypeExtendsResult.False; + } + function IsArrayOfTuple(left, right) { + return TypeGuard.TArray(right) && left.items !== undefined && left.items.every((schema) => Visit(schema, right.items) === TypeExtendsResult.True); + } + function Tuple(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right) && IsObjectArrayLike(right)) + return TypeExtendsResult.True; + if (TypeGuard.TArray(right) && IsArrayOfTuple(left, right)) + return TypeExtendsResult.True; + if (!TypeGuard.TTuple(right)) + return TypeExtendsResult.False; + if ((left.items === undefined && right.items !== undefined) || (left.items !== undefined && right.items === undefined)) + return TypeExtendsResult.False; + if (left.items === undefined && right.items === undefined) + return TypeExtendsResult.True; + return left.items.every((schema, index) => Visit(schema, right.items[index]) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Uint8Array + // -------------------------------------------------------------------------- + function Uint8Array(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + return TypeGuard.TUint8Array(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Undefined + // -------------------------------------------------------------------------- + function Undefined(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TNever(right)) + return NeverRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + if (TypeGuard.TRecord(right)) + return RecordRight(left, right); + if (TypeGuard.TVoid(right)) + return VoidRight(left, right); + return TypeGuard.TUndefined(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Union + // -------------------------------------------------------------------------- + function UnionRight(left, right) { + return right.anyOf.some((schema) => Visit(left, schema) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Union(left, right) { + return left.anyOf.every((schema) => Visit(schema, right) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Unknown + // -------------------------------------------------------------------------- + function UnknownRight(left, right) { + return TypeExtendsResult.True; + } + function Unknown(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TString(right)) + return StringRight(left, right); + if (TypeGuard.TNumber(right)) + return NumberRight(left, right); + if (TypeGuard.TInteger(right)) + return IntegerRight(left, right); + if (TypeGuard.TBoolean(right)) + return BooleanRight(left, right); + if (TypeGuard.TArray(right)) + return ArrayRight(left, right); + if (TypeGuard.TTuple(right)) + return TupleRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + return TypeGuard.TUnknown(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + // -------------------------------------------------------------------------- + // Void + // -------------------------------------------------------------------------- + function VoidRight(left, right) { + if (TypeGuard.TUndefined(left)) + return TypeExtendsResult.True; + return TypeGuard.TUndefined(left) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Void(left, right) { + if (TypeGuard.TIntersect(right)) + return IntersectRight(left, right); + if (TypeGuard.TUnion(right)) + return UnionRight(left, right); + if (TypeGuard.TUnknown(right)) + return UnknownRight(left, right); + if (TypeGuard.TAny(right)) + return AnyRight(left, right); + if (TypeGuard.TObject(right)) + return ObjectRight(left, right); + return TypeGuard.TVoid(right) ? TypeExtendsResult.True : TypeExtendsResult.False; + } + function Visit(left, right) { + // template union remap + if (TypeGuard.TTemplateLiteral(left)) + return Visit(TemplateLiteralResolver.Resolve(left), right); + if (TypeGuard.TTemplateLiteral(right)) + return Visit(left, TemplateLiteralResolver.Resolve(right)); + // standard extends + if (TypeGuard.TAny(left)) + return Any(left, right); + if (TypeGuard.TArray(left)) + return Array(left, right); + if (TypeGuard.TBigInt(left)) + return BigInt(left, right); + if (TypeGuard.TBoolean(left)) + return Boolean(left, right); + if (TypeGuard.TConstructor(left)) + return Constructor(left, right); + if (TypeGuard.TDate(left)) + return Date(left, right); + if (TypeGuard.TFunction(left)) + return Function(left, right); + if (TypeGuard.TInteger(left)) + return Integer(left, right); + if (TypeGuard.TIntersect(left)) + return Intersect(left, right); + if (TypeGuard.TLiteral(left)) + return Literal(left, right); + if (TypeGuard.TNever(left)) + return Never(left, right); + if (TypeGuard.TNull(left)) + return Null(left, right); + if (TypeGuard.TNumber(left)) + return Number(left, right); + if (TypeGuard.TObject(left)) + return Object(left, right); + if (TypeGuard.TRecord(left)) + return Record(left, right); + if (TypeGuard.TString(left)) + return String(left, right); + if (TypeGuard.TSymbol(left)) + return Symbol(left, right); + if (TypeGuard.TTuple(left)) + return Tuple(left, right); + if (TypeGuard.TPromise(left)) + return Promise(left, right); + if (TypeGuard.TUint8Array(left)) + return Uint8Array(left, right); + if (TypeGuard.TUndefined(left)) + return Undefined(left, right); + if (TypeGuard.TUnion(left)) + return Union(left, right); + if (TypeGuard.TUnknown(left)) + return Unknown(left, right); + if (TypeGuard.TVoid(left)) + return Void(left, right); + throw Error(`TypeExtends: Unknown left type operand '${left[exports.Kind]}'`); + } + function Extends(left, right) { + return Visit(left, right); + } + TypeExtends.Extends = Extends; +})(TypeExtends = exports.TypeExtends || (exports.TypeExtends = {})); +// -------------------------------------------------------------------------- +// TypeClone +// -------------------------------------------------------------------------- +/** Specialized Clone for Types */ +var TypeClone; +(function (TypeClone) { + function IsObject(value) { + return typeof value === 'object' && value !== null; + } + function IsArray(value) { + return globalThis.Array.isArray(value); + } + function Array(value) { + return value.map((value) => Visit(value)); + } + function Object(value) { + const clonedProperties = globalThis.Object.getOwnPropertyNames(value).reduce((acc, key) => { + return { ...acc, [key]: Visit(value[key]) }; + }, {}); + const clonedSymbols = globalThis.Object.getOwnPropertySymbols(value).reduce((acc, key) => { + return { ...acc, [key]: Visit(value[key]) }; + }, {}); + return { ...clonedProperties, ...clonedSymbols }; + } + function Visit(value) { + if (IsArray(value)) + return Array(value); + if (IsObject(value)) + return Object(value); + return value; + } + /** Clones a type. */ + function Clone(schema, options) { + return { ...Visit(schema), ...options }; + } + TypeClone.Clone = Clone; +})(TypeClone = exports.TypeClone || (exports.TypeClone = {})); +// -------------------------------------------------------------------------- +// ObjectMap +// -------------------------------------------------------------------------- +var ObjectMap; +(function (ObjectMap) { + function Intersect(schema, callback) { + // prettier-ignore + return exports.Type.Intersect(schema.allOf.map((inner) => Visit(inner, callback)), { ...schema }); + } + function Union(schema, callback) { + // prettier-ignore + return exports.Type.Union(schema.anyOf.map((inner) => Visit(inner, callback)), { ...schema }); + } + function Object(schema, callback) { + return callback(schema); + } + function Visit(schema, callback) { + // There are cases where users need to map objects with unregistered kinds. Using a TypeGuard here would + // prevent sub schema mapping as unregistered kinds will not pass TSchema checks. This is notable in the + // case of TObject where unregistered property kinds cause the TObject check to fail. As mapping is only + // used for composition, we use explicit checks instead. + if (schema[exports.Kind] === 'Intersect') + return Intersect(schema, callback); + if (schema[exports.Kind] === 'Union') + return Union(schema, callback); + if (schema[exports.Kind] === 'Object') + return Object(schema, callback); + return schema; + } + function Map(schema, callback, options) { + return { ...Visit(TypeClone.Clone(schema, {}), callback), ...options }; + } + ObjectMap.Map = Map; +})(ObjectMap = exports.ObjectMap || (exports.ObjectMap = {})); +// -------------------------------------------------------------------------- +// KeyResolver +// -------------------------------------------------------------------------- +var KeyResolver; +(function (KeyResolver) { + function IsKeyable(schema) { + return TypeGuard.TIntersect(schema) || TypeGuard.TUnion(schema) || (TypeGuard.TObject(schema) && globalThis.Object.getOwnPropertyNames(schema.properties).length > 0); + } + function Intersect(schema) { + return [...schema.allOf.filter((schema) => IsKeyable(schema)).reduce((set, schema) => Visit(schema).map((key) => set.add(key))[0], new Set())]; + } + function Union(schema) { + const sets = schema.anyOf.filter((schema) => IsKeyable(schema)).map((inner) => Visit(inner)); + return [...sets.reduce((set, outer) => outer.map((key) => (sets.every((inner) => inner.includes(key)) ? set.add(key) : set))[0], new Set())]; + } + function Object(schema) { + return globalThis.Object.keys(schema.properties); + } + function Visit(schema) { + if (TypeGuard.TIntersect(schema)) + return Intersect(schema); + if (TypeGuard.TUnion(schema)) + return Union(schema); + if (TypeGuard.TObject(schema)) + return Object(schema); + return []; + } + function Resolve(schema) { + return Visit(schema); + } + KeyResolver.Resolve = Resolve; +})(KeyResolver = exports.KeyResolver || (exports.KeyResolver = {})); +// -------------------------------------------------------------------------- +// TemplateLiteralPattern +// -------------------------------------------------------------------------- +var TemplateLiteralPattern; +(function (TemplateLiteralPattern) { + function Escape(value) { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + function Visit(schema, acc) { + if (TypeGuard.TTemplateLiteral(schema)) { + const pattern = schema.pattern.slice(1, schema.pattern.length - 1); + return pattern; + } + else if (TypeGuard.TUnion(schema)) { + const tokens = schema.anyOf.map((schema) => Visit(schema, acc)).join('|'); + return `(${tokens})`; + } + else if (TypeGuard.TNumber(schema)) { + return `${acc}${exports.PatternNumber}`; + } + else if (TypeGuard.TInteger(schema)) { + return `${acc}${exports.PatternNumber}`; + } + else if (TypeGuard.TBigInt(schema)) { + return `${acc}${exports.PatternNumber}`; + } + else if (TypeGuard.TString(schema)) { + return `${acc}${exports.PatternString}`; + } + else if (TypeGuard.TLiteral(schema)) { + return `${acc}${Escape(schema.const.toString())}`; + } + else if (TypeGuard.TBoolean(schema)) { + return `${acc}${exports.PatternBoolean}`; + } + else if (TypeGuard.TNever(schema)) { + throw Error('TemplateLiteralPattern: TemplateLiteral cannot operate on types of TNever'); + } + else { + throw Error(`TemplateLiteralPattern: Unexpected Kind '${schema[exports.Kind]}'`); + } + } + function Create(kinds) { + return `^${kinds.map((schema) => Visit(schema, '')).join('')}\$`; + } + TemplateLiteralPattern.Create = Create; +})(TemplateLiteralPattern = exports.TemplateLiteralPattern || (exports.TemplateLiteralPattern = {})); +// -------------------------------------------------------------------------------------- +// TemplateLiteralResolver +// -------------------------------------------------------------------------------------- +var TemplateLiteralResolver; +(function (TemplateLiteralResolver) { + function Resolve(template) { + const expression = TemplateLiteralParser.ParseExact(template.pattern); + if (!TemplateLiteralFinite.Check(expression)) + return exports.Type.String(); + const literals = [...TemplateLiteralGenerator.Generate(expression)].map((value) => exports.Type.Literal(value)); + return exports.Type.Union(literals); + } + TemplateLiteralResolver.Resolve = Resolve; +})(TemplateLiteralResolver = exports.TemplateLiteralResolver || (exports.TemplateLiteralResolver = {})); +// -------------------------------------------------------------------------------------- +// TemplateLiteralParser +// -------------------------------------------------------------------------------------- +class TemplateLiteralParserError extends Error { + constructor(message) { + super(message); + } +} +exports.TemplateLiteralParserError = TemplateLiteralParserError; +var TemplateLiteralParser; +(function (TemplateLiteralParser) { + function IsNonEscaped(pattern, index, char) { + return pattern[index] === char && pattern.charCodeAt(index - 1) !== 92; + } + function IsOpenParen(pattern, index) { + return IsNonEscaped(pattern, index, '('); + } + function IsCloseParen(pattern, index) { + return IsNonEscaped(pattern, index, ')'); + } + function IsSeparator(pattern, index) { + return IsNonEscaped(pattern, index, '|'); + } + function IsGroup(pattern) { + if (!(IsOpenParen(pattern, 0) && IsCloseParen(pattern, pattern.length - 1))) + return false; + let count = 0; + for (let index = 0; index < pattern.length; index++) { + if (IsOpenParen(pattern, index)) + count += 1; + if (IsCloseParen(pattern, index)) + count -= 1; + if (count === 0 && index !== pattern.length - 1) + return false; + } + return true; + } + function InGroup(pattern) { + return pattern.slice(1, pattern.length - 1); + } + function IsPrecedenceOr(pattern) { + let count = 0; + for (let index = 0; index < pattern.length; index++) { + if (IsOpenParen(pattern, index)) + count += 1; + if (IsCloseParen(pattern, index)) + count -= 1; + if (IsSeparator(pattern, index) && count === 0) + return true; + } + return false; + } + function IsPrecedenceAnd(pattern) { + for (let index = 0; index < pattern.length; index++) { + if (IsOpenParen(pattern, index)) + return true; + } + return false; + } + function Or(pattern) { + let [count, start] = [0, 0]; + const expressions = []; + for (let index = 0; index < pattern.length; index++) { + if (IsOpenParen(pattern, index)) + count += 1; + if (IsCloseParen(pattern, index)) + count -= 1; + if (IsSeparator(pattern, index) && count === 0) { + const range = pattern.slice(start, index); + if (range.length > 0) + expressions.push(Parse(range)); + start = index + 1; + } + } + const range = pattern.slice(start); + if (range.length > 0) + expressions.push(Parse(range)); + if (expressions.length === 0) + return { type: 'const', const: '' }; + if (expressions.length === 1) + return expressions[0]; + return { type: 'or', expr: expressions }; + } + function And(pattern) { + function Group(value, index) { + if (!IsOpenParen(value, index)) + throw new TemplateLiteralParserError(`TemplateLiteralParser: Index must point to open parens`); + let count = 0; + for (let scan = index; scan < value.length; scan++) { + if (IsOpenParen(value, scan)) + count += 1; + if (IsCloseParen(value, scan)) + count -= 1; + if (count === 0) + return [index, scan]; + } + throw new TemplateLiteralParserError(`TemplateLiteralParser: Unclosed group parens in expression`); + } + function Range(pattern, index) { + for (let scan = index; scan < pattern.length; scan++) { + if (IsOpenParen(pattern, scan)) + return [index, scan]; + } + return [index, pattern.length]; + } + const expressions = []; + for (let index = 0; index < pattern.length; index++) { + if (IsOpenParen(pattern, index)) { + const [start, end] = Group(pattern, index); + const range = pattern.slice(start, end + 1); + expressions.push(Parse(range)); + index = end; + } + else { + const [start, end] = Range(pattern, index); + const range = pattern.slice(start, end); + if (range.length > 0) + expressions.push(Parse(range)); + index = end - 1; + } + } + if (expressions.length === 0) + return { type: 'const', const: '' }; + if (expressions.length === 1) + return expressions[0]; + return { type: 'and', expr: expressions }; + } + /** Parses a pattern and returns an expression tree */ + function Parse(pattern) { + if (IsGroup(pattern)) + return Parse(InGroup(pattern)); + if (IsPrecedenceOr(pattern)) + return Or(pattern); + if (IsPrecedenceAnd(pattern)) + return And(pattern); + return { type: 'const', const: pattern }; + } + TemplateLiteralParser.Parse = Parse; + /** Parses a pattern and strips forward and trailing ^ and $ */ + function ParseExact(pattern) { + return Parse(pattern.slice(1, pattern.length - 1)); + } + TemplateLiteralParser.ParseExact = ParseExact; +})(TemplateLiteralParser = exports.TemplateLiteralParser || (exports.TemplateLiteralParser = {})); +// -------------------------------------------------------------------------------------- +// TemplateLiteralFinite +// -------------------------------------------------------------------------------------- +var TemplateLiteralFinite; +(function (TemplateLiteralFinite) { + function IsNumber(expression) { + // prettier-ignore + return (expression.type === 'or' && + expression.expr.length === 2 && + expression.expr[0].type === 'const' && + expression.expr[0].const === '0' && + expression.expr[1].type === 'const' && + expression.expr[1].const === '[1-9][0-9]*'); + } + function IsBoolean(expression) { + // prettier-ignore + return (expression.type === 'or' && + expression.expr.length === 2 && + expression.expr[0].type === 'const' && + expression.expr[0].const === 'true' && + expression.expr[1].type === 'const' && + expression.expr[1].const === 'false'); + } + function IsString(expression) { + return expression.type === 'const' && expression.const === '.*'; + } + function Check(expression) { + if (IsBoolean(expression)) + return true; + if (IsNumber(expression) || IsString(expression)) + return false; + if (expression.type === 'and') + return expression.expr.every((expr) => Check(expr)); + if (expression.type === 'or') + return expression.expr.every((expr) => Check(expr)); + if (expression.type === 'const') + return true; + throw Error(`TemplateLiteralFinite: Unknown expression type`); + } + TemplateLiteralFinite.Check = Check; +})(TemplateLiteralFinite = exports.TemplateLiteralFinite || (exports.TemplateLiteralFinite = {})); +// -------------------------------------------------------------------------------------- +// TemplateLiteralGenerator +// -------------------------------------------------------------------------------------- +var TemplateLiteralGenerator; +(function (TemplateLiteralGenerator) { + function* Reduce(buffer) { + if (buffer.length === 1) + return yield* buffer[0]; + for (const left of buffer[0]) { + for (const right of Reduce(buffer.slice(1))) { + yield `${left}${right}`; + } + } + } + function* And(expression) { + return yield* Reduce(expression.expr.map((expr) => [...Generate(expr)])); + } + function* Or(expression) { + for (const expr of expression.expr) + yield* Generate(expr); + } + function* Const(expression) { + return yield expression.const; + } + function* Generate(expression) { + if (expression.type === 'and') + return yield* And(expression); + if (expression.type === 'or') + return yield* Or(expression); + if (expression.type === 'const') + return yield* Const(expression); + throw Error('TemplateLiteralGenerator: Unknown expression'); + } + TemplateLiteralGenerator.Generate = Generate; +})(TemplateLiteralGenerator = exports.TemplateLiteralGenerator || (exports.TemplateLiteralGenerator = {})); +// -------------------------------------------------------------------------- +// TypeOrdinal: Used for auto $id generation +// -------------------------------------------------------------------------- +let TypeOrdinal = 0; +// -------------------------------------------------------------------------- +// TypeBuilder +// -------------------------------------------------------------------------- +class TypeBuilder { + /** `[Utility]` Creates a schema without `static` and `params` types */ + Create(schema) { + return schema; + } + /** `[Standard]` Omits compositing symbols from this schema */ + Strict(schema) { + return JSON.parse(JSON.stringify(schema)); + } +} +exports.TypeBuilder = TypeBuilder; +// -------------------------------------------------------------------------- +// StandardTypeBuilder +// -------------------------------------------------------------------------- +class StandardTypeBuilder extends TypeBuilder { + // ------------------------------------------------------------------------ + // Modifiers + // ------------------------------------------------------------------------ + /** `[Modifier]` Creates a Optional property */ + Optional(schema) { + return { [exports.Modifier]: 'Optional', ...TypeClone.Clone(schema, {}) }; + } + /** `[Modifier]` Creates a ReadonlyOptional property */ + ReadonlyOptional(schema) { + return { [exports.Modifier]: 'ReadonlyOptional', ...TypeClone.Clone(schema, {}) }; + } + /** `[Modifier]` Creates a Readonly object or property */ + Readonly(schema) { + return { [exports.Modifier]: 'Readonly', ...schema }; + } + // ------------------------------------------------------------------------ + // Types + // ------------------------------------------------------------------------ + /** `[Standard]` Creates an Any type */ + Any(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Any' }); + } + /** `[Standard]` Creates an Array type */ + Array(items, options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Array', type: 'array', items: TypeClone.Clone(items, {}) }); + } + /** `[Standard]` Creates a Boolean type */ + Boolean(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Boolean', type: 'boolean' }); + } + /** `[Standard]` Creates a Composite object type. */ + Composite(objects, options) { + const isOptionalAll = (objects, key) => objects.every((object) => !(key in object.properties) || IsOptional(object.properties[key])); + const IsOptional = (schema) => TypeGuard.TOptional(schema) || TypeGuard.TReadonlyOptional(schema); + const [required, optional] = [new Set(), new Set()]; + for (const object of objects) { + for (const key of globalThis.Object.getOwnPropertyNames(object.properties)) { + if (isOptionalAll(objects, key)) + optional.add(key); + } + } + for (const object of objects) { + for (const key of globalThis.Object.getOwnPropertyNames(object.properties)) { + if (!optional.has(key)) + required.add(key); + } + } + const properties = {}; + for (const object of objects) { + for (const [key, schema] of Object.entries(object.properties)) { + const property = TypeClone.Clone(schema, {}); + if (!optional.has(key)) + delete property[exports.Modifier]; + if (key in properties) { + const left = TypeExtends.Extends(properties[key], property) !== TypeExtendsResult.False; + const right = TypeExtends.Extends(property, properties[key]) !== TypeExtendsResult.False; + if (!left && !right) + properties[key] = exports.Type.Never(); + if (!left && right) + properties[key] = property; + } + else { + properties[key] = property; + } + } + } + if (required.size > 0) { + return this.Create({ ...options, [exports.Kind]: 'Object', [exports.Hint]: 'Composite', type: 'object', properties, required: [...required] }); + } + else { + return this.Create({ ...options, [exports.Kind]: 'Object', [exports.Hint]: 'Composite', type: 'object', properties }); + } + } + /** `[Standard]` Creates a Enum type */ + Enum(item, options = {}) { + // prettier-ignore + const values = globalThis.Object.keys(item).filter((key) => isNaN(key)).map((key) => item[key]); + const anyOf = values.map((value) => (typeof value === 'string' ? { [exports.Kind]: 'Literal', type: 'string', const: value } : { [exports.Kind]: 'Literal', type: 'number', const: value })); + return this.Create({ ...options, [exports.Kind]: 'Union', anyOf }); + } + /** `[Standard]` A conditional type expression that will return the true type if the left type extends the right */ + Extends(left, right, trueType, falseType, options = {}) { + switch (TypeExtends.Extends(left, right)) { + case TypeExtendsResult.Union: + return this.Union([TypeClone.Clone(trueType, options), TypeClone.Clone(falseType, options)]); + case TypeExtendsResult.True: + return TypeClone.Clone(trueType, options); + case TypeExtendsResult.False: + return TypeClone.Clone(falseType, options); + } + } + /** `[Standard]` Excludes from the left type any type that is not assignable to the right */ + Exclude(left, right, options = {}) { + if (TypeGuard.TTemplateLiteral(left)) + return this.Exclude(TemplateLiteralResolver.Resolve(left), right, options); + if (TypeGuard.TTemplateLiteral(right)) + return this.Exclude(left, TemplateLiteralResolver.Resolve(right), options); + if (TypeGuard.TUnion(left)) { + const narrowed = left.anyOf.filter((inner) => TypeExtends.Extends(inner, right) === TypeExtendsResult.False); + return (narrowed.length === 1 ? TypeClone.Clone(narrowed[0], options) : this.Union(narrowed, options)); + } + else { + return (TypeExtends.Extends(left, right) !== TypeExtendsResult.False ? this.Never(options) : TypeClone.Clone(left, options)); + } + } + /** `[Standard]` Extracts from the left type any type that is assignable to the right */ + Extract(left, right, options = {}) { + if (TypeGuard.TTemplateLiteral(left)) + return this.Extract(TemplateLiteralResolver.Resolve(left), right, options); + if (TypeGuard.TTemplateLiteral(right)) + return this.Extract(left, TemplateLiteralResolver.Resolve(right), options); + if (TypeGuard.TUnion(left)) { + const narrowed = left.anyOf.filter((inner) => TypeExtends.Extends(inner, right) !== TypeExtendsResult.False); + return (narrowed.length === 1 ? TypeClone.Clone(narrowed[0], options) : this.Union(narrowed, options)); + } + else { + return (TypeExtends.Extends(left, right) !== TypeExtendsResult.False ? TypeClone.Clone(left, options) : this.Never(options)); + } + } + /** `[Standard]` Creates an Integer type */ + Integer(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Integer', type: 'integer' }); + } + Intersect(allOf, options = {}) { + if (allOf.length === 0) + return exports.Type.Never(); + if (allOf.length === 1) + return TypeClone.Clone(allOf[0], options); + const objects = allOf.every((schema) => TypeGuard.TObject(schema)); + const cloned = allOf.map((schema) => TypeClone.Clone(schema, {})); + const clonedUnevaluatedProperties = TypeGuard.TSchema(options.unevaluatedProperties) ? { unevaluatedProperties: TypeClone.Clone(options.unevaluatedProperties, {}) } : {}; + if (options.unevaluatedProperties === false || TypeGuard.TSchema(options.unevaluatedProperties) || objects) { + return this.Create({ ...options, ...clonedUnevaluatedProperties, [exports.Kind]: 'Intersect', type: 'object', allOf: cloned }); + } + else { + return this.Create({ ...options, ...clonedUnevaluatedProperties, [exports.Kind]: 'Intersect', allOf: cloned }); + } + } + /** `[Standard]` Creates a KeyOf type */ + KeyOf(schema, options = {}) { + if (TypeGuard.TRecord(schema)) { + const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0]; + if (pattern === exports.PatternNumberExact) + return this.Number(options); + if (pattern === exports.PatternStringExact) + return this.String(options); + throw Error('StandardTypeBuilder: Unable to resolve key type from Record key pattern'); + } + else { + const resolved = KeyResolver.Resolve(schema); + if (resolved.length === 0) + return this.Never(options); + const literals = resolved.map((key) => this.Literal(key)); + return this.Union(literals, options); + } + } + /** `[Standard]` Creates a Literal type */ + Literal(value, options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Literal', const: value, type: typeof value }); + } + /** `[Standard]` Creates a Never type */ + Never(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Never', not: {} }); + } + /** `[Standard]` Creates a Not type. The first argument is the disallowed type, the second is the allowed. */ + Not(not, schema, options) { + return this.Create({ ...options, [exports.Kind]: 'Not', allOf: [{ not: TypeClone.Clone(not, {}) }, TypeClone.Clone(schema, {})] }); + } + /** `[Standard]` Creates a Null type */ + Null(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Null', type: 'null' }); + } + /** `[Standard]` Creates a Number type */ + Number(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Number', type: 'number' }); + } + /** `[Standard]` Creates an Object type */ + Object(properties, options = {}) { + const propertyKeys = globalThis.Object.getOwnPropertyNames(properties); + const optionalKeys = propertyKeys.filter((key) => TypeGuard.TOptional(properties[key]) || TypeGuard.TReadonlyOptional(properties[key])); + const requiredKeys = propertyKeys.filter((name) => !optionalKeys.includes(name)); + const clonedAdditionalProperties = TypeGuard.TSchema(options.additionalProperties) ? { additionalProperties: TypeClone.Clone(options.additionalProperties, {}) } : {}; + const clonedProperties = propertyKeys.reduce((acc, key) => ({ ...acc, [key]: TypeClone.Clone(properties[key], {}) }), {}); + if (requiredKeys.length > 0) { + return this.Create({ ...options, ...clonedAdditionalProperties, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties, required: requiredKeys }); + } + else { + return this.Create({ ...options, ...clonedAdditionalProperties, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties }); + } + } + Omit(schema, unresolved, options = {}) { + // prettier-ignore + const keys = TypeGuard.TUnionLiteral(unresolved) ? unresolved.anyOf.map((schema) => schema.const) : + TypeGuard.TLiteral(unresolved) ? [unresolved.const] : + TypeGuard.TNever(unresolved) ? [] : + unresolved; + // prettier-ignore + return ObjectMap.Map(TypeClone.Clone(schema, {}), (schema) => { + if (schema.required) { + schema.required = schema.required.filter((key) => !keys.includes(key)); + if (schema.required.length === 0) + delete schema.required; + } + for (const key of globalThis.Object.keys(schema.properties)) { + if (keys.includes(key)) + delete schema.properties[key]; + } + return this.Create(schema); + }, options); + } + /** `[Standard]` Creates a mapped type where all properties are Optional */ + Partial(schema, options = {}) { + function Apply(schema) { + // prettier-ignore + switch (schema[exports.Modifier]) { + case 'ReadonlyOptional': + schema[exports.Modifier] = 'ReadonlyOptional'; + break; + case 'Readonly': + schema[exports.Modifier] = 'ReadonlyOptional'; + break; + case 'Optional': + schema[exports.Modifier] = 'Optional'; + break; + default: + schema[exports.Modifier] = 'Optional'; + break; + } + } + // prettier-ignore + return ObjectMap.Map(TypeClone.Clone(schema, {}), (schema) => { + delete schema.required; + globalThis.Object.keys(schema.properties).forEach(key => Apply(schema.properties[key])); + return schema; + }, options); + } + Pick(schema, unresolved, options = {}) { + // prettier-ignore + const keys = TypeGuard.TUnionLiteral(unresolved) ? unresolved.anyOf.map((schema) => schema.const) : + TypeGuard.TLiteral(unresolved) ? [unresolved.const] : + TypeGuard.TNever(unresolved) ? [] : + unresolved; + // prettier-ignore + return ObjectMap.Map(TypeClone.Clone(schema, {}), (schema) => { + if (schema.required) { + schema.required = schema.required.filter((key) => keys.includes(key)); + if (schema.required.length === 0) + delete schema.required; + } + for (const key of globalThis.Object.keys(schema.properties)) { + if (!keys.includes(key)) + delete schema.properties[key]; + } + return this.Create(schema); + }, options); + } + /** `[Standard]` Creates a Record type */ + Record(key, schema, options = {}) { + if (TypeGuard.TTemplateLiteral(key)) { + const expression = TemplateLiteralParser.ParseExact(key.pattern); + // prettier-ignore + return TemplateLiteralFinite.Check(expression) + ? (this.Object([...TemplateLiteralGenerator.Generate(expression)].reduce((acc, key) => ({ ...acc, [key]: TypeClone.Clone(schema, {}) }), {}), options)) + : this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [key.pattern]: TypeClone.Clone(schema, {}) }, additionalProperties: false }); + } + else if (TypeGuard.TUnionLiteral(key)) { + if (key.anyOf.every((schema) => TypeGuard.TLiteral(schema) && (typeof schema.const === 'string' || typeof schema.const === 'number'))) { + const properties = key.anyOf.reduce((acc, literal) => ({ ...acc, [literal.const]: TypeClone.Clone(schema, {}) }), {}); + return this.Object(properties, { ...options, [exports.Hint]: 'Record' }); + } + else + throw Error('TypeBuilder: Record key can only be derived from union literal of number or string'); + } + else if (TypeGuard.TLiteral(key)) { + if (typeof key.const === 'string' || typeof key.const === 'number') { + return this.Object({ [key.const]: TypeClone.Clone(schema, {}) }, options); + } + else + throw Error('TypeBuilder: Record key can only be derived from literals of number or string'); + } + else if (TypeGuard.TInteger(key) || TypeGuard.TNumber(key)) { + const pattern = exports.PatternNumberExact; + return this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [pattern]: TypeClone.Clone(schema, {}) }, additionalProperties: false }); + } + else if (TypeGuard.TString(key)) { + const pattern = key.pattern === undefined ? exports.PatternStringExact : key.pattern; + return this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [pattern]: TypeClone.Clone(schema, {}) }, additionalProperties: false }); + } + else { + throw Error(`StandardTypeBuilder: Invalid Record Key`); + } + } + /** `[Standard]` Creates a Recursive type */ + Recursive(callback, options = {}) { + if (options.$id === undefined) + options.$id = `T${TypeOrdinal++}`; + const thisType = callback({ [exports.Kind]: 'This', $ref: `${options.$id}` }); + thisType.$id = options.$id; + return this.Create({ ...options, [exports.Hint]: 'Recursive', ...thisType }); + } + /** `[Standard]` Creates a Ref type. The referenced type must contain a $id */ + Ref(schema, options = {}) { + if (schema.$id === undefined) + throw Error('StandardTypeBuilder.Ref: Target type must specify an $id'); + return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: schema.$id }); + } + /** `[Standard]` Creates a mapped type where all properties are Required */ + Required(schema, options = {}) { + function Apply(schema) { + // prettier-ignore + switch (schema[exports.Modifier]) { + case 'ReadonlyOptional': + schema[exports.Modifier] = 'Readonly'; + break; + case 'Readonly': + schema[exports.Modifier] = 'Readonly'; + break; + case 'Optional': + delete schema[exports.Modifier]; + break; + default: + delete schema[exports.Modifier]; + break; + } + } + // prettier-ignore + return ObjectMap.Map(TypeClone.Clone(schema, {}), (schema) => { + schema.required = globalThis.Object.keys(schema.properties); + globalThis.Object.keys(schema.properties).forEach(key => Apply(schema.properties[key])); + return schema; + }, options); + } + /** `[Standard]` Creates a String type */ + String(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'String', type: 'string' }); + } + /** `[Standard]` Creates a template literal type */ + TemplateLiteral(kinds, options = {}) { + const pattern = TemplateLiteralPattern.Create(kinds); + return this.Create({ ...options, [exports.Kind]: 'TemplateLiteral', type: 'string', pattern }); + } + /** `[Standard]` Creates a Tuple type */ + Tuple(items, options = {}) { + const [additionalItems, minItems, maxItems] = [false, items.length, items.length]; + const clonedItems = items.map((item) => TypeClone.Clone(item, {})); + // prettier-ignore + const schema = (items.length > 0 ? + { ...options, [exports.Kind]: 'Tuple', type: 'array', items: clonedItems, additionalItems, minItems, maxItems } : + { ...options, [exports.Kind]: 'Tuple', type: 'array', minItems, maxItems }); + return this.Create(schema); + } + Union(union, options = {}) { + if (TypeGuard.TTemplateLiteral(union)) { + return TemplateLiteralResolver.Resolve(union); + } + else { + const anyOf = union; + if (anyOf.length === 0) + return this.Never(options); + if (anyOf.length === 1) + return this.Create(TypeClone.Clone(anyOf[0], options)); + const clonedAnyOf = anyOf.map((schema) => TypeClone.Clone(schema, {})); + return this.Create({ ...options, [exports.Kind]: 'Union', anyOf: clonedAnyOf }); + } + } + /** `[Standard]` Creates an Unknown type */ + Unknown(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Unknown' }); + } + /** `[Standard]` Creates a Unsafe type that infers for the generic argument */ + Unsafe(options = {}) { + return this.Create({ ...options, [exports.Kind]: options[exports.Kind] || 'Unsafe' }); + } +} +exports.StandardTypeBuilder = StandardTypeBuilder; +// -------------------------------------------------------------------------- +// ExtendedTypeBuilder +// -------------------------------------------------------------------------- +class ExtendedTypeBuilder extends StandardTypeBuilder { + /** `[Extended]` Creates a BigInt type */ + BigInt(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'BigInt', type: 'null', typeOf: 'BigInt' }); + } + /** `[Extended]` Extracts the ConstructorParameters from the given Constructor type */ + ConstructorParameters(schema, options = {}) { + return this.Tuple([...schema.parameters], { ...options }); + } + Constructor(parameters, returns, options = {}) { + const clonedReturns = TypeClone.Clone(returns, {}); + if (TypeGuard.TTuple(parameters)) { + const clonedParameters = parameters.items === undefined ? [] : parameters.items.map((parameter) => TypeClone.Clone(parameter, {})); + return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters: clonedParameters, returns: clonedReturns }); + } + else if (globalThis.Array.isArray(parameters)) { + const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter, {})); + return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters: clonedParameters, returns: clonedReturns }); + } + else { + throw new Error('ExtendedTypeBuilder.Constructor: Invalid parameters'); + } + } + /** `[Extended]` Creates a Date type */ + Date(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Date', type: 'object', instanceOf: 'Date' }); + } + Function(parameters, returns, options = {}) { + const clonedReturns = TypeClone.Clone(returns, {}); + if (TypeGuard.TTuple(parameters)) { + const clonedParameters = parameters.items === undefined ? [] : parameters.items.map((parameter) => TypeClone.Clone(parameter, {})); + return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters: clonedParameters, returns: clonedReturns }); + } + else if (globalThis.Array.isArray(parameters)) { + const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter, {})); + return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters: clonedParameters, returns: clonedReturns }); + } + else { + throw new Error('ExtendedTypeBuilder.Function: Invalid parameters'); + } + } + /** `[Extended]` Extracts the InstanceType from the given Constructor */ + InstanceType(schema, options = {}) { + return TypeClone.Clone(schema.returns, options); + } + /** `[Extended]` Extracts the Parameters from the given Function type */ + Parameters(schema, options = {}) { + return this.Tuple(schema.parameters, { ...options }); + } + /** `[Extended]` Creates a Promise type */ + Promise(item, options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Promise', type: 'object', instanceOf: 'Promise', item: TypeClone.Clone(item, {}) }); + } + /** `[Extended]` Creates a regular expression type */ + RegEx(regex, options = {}) { + return this.Create({ ...options, [exports.Kind]: 'String', type: 'string', pattern: regex.source }); + } + /** `[Extended]` Extracts the ReturnType from the given Function */ + ReturnType(schema, options = {}) { + return TypeClone.Clone(schema.returns, options); + } + /** `[Extended]` Creates a Symbol type */ + Symbol(options) { + return this.Create({ ...options, [exports.Kind]: 'Symbol', type: 'null', typeOf: 'Symbol' }); + } + /** `[Extended]` Creates a Undefined type */ + Undefined(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Undefined', type: 'null', typeOf: 'Undefined' }); + } + /** `[Extended]` Creates a Uint8Array type */ + Uint8Array(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Uint8Array', type: 'object', instanceOf: 'Uint8Array' }); + } + /** `[Extended]` Creates a Void type */ + Void(options = {}) { + return this.Create({ ...options, [exports.Kind]: 'Void', type: 'null', typeOf: 'Void' }); + } +} +exports.ExtendedTypeBuilder = ExtendedTypeBuilder; +/** JSON Schema TypeBuilder with Static Resolution for TypeScript */ +exports.StandardType = new StandardTypeBuilder(); +/** JSON Schema TypeBuilder with Static Resolution for TypeScript */ +exports.Type = new ExtendedTypeBuilder(); diff --git a/node_modules/@sinclair/typebox/value/cast.d.ts b/node_modules/@sinclair/typebox/value/cast.d.ts new file mode 100644 index 0000000..992d9e3 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/cast.d.ts @@ -0,0 +1,30 @@ +import * as Types from '../typebox'; +export declare class ValueCastReferenceTypeError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +export declare class ValueCastArrayUniqueItemsTypeError extends Error { + readonly schema: Types.TSchema; + readonly value: unknown; + constructor(schema: Types.TSchema, value: unknown); +} +export declare class ValueCastNeverTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCastRecursiveTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCastUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCastDereferenceError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +export declare namespace ValueCast { + function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): any; + function Cast(schema: T, references: Types.TSchema[], value: any): Types.Static; +} diff --git a/node_modules/@sinclair/typebox/value/cast.js b/node_modules/@sinclair/typebox/value/cast.js new file mode 100644 index 0000000..42fe2e1 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/cast.js @@ -0,0 +1,372 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueCast = exports.ValueCastDereferenceError = exports.ValueCastUnknownTypeError = exports.ValueCastRecursiveTypeError = exports.ValueCastNeverTypeError = exports.ValueCastArrayUniqueItemsTypeError = exports.ValueCastReferenceTypeError = void 0; +const Types = require("../typebox"); +const create_1 = require("./create"); +const check_1 = require("./check"); +const clone_1 = require("./clone"); +// ---------------------------------------------------------------------------------------------- +// Errors +// ---------------------------------------------------------------------------------------------- +class ValueCastReferenceTypeError extends Error { + constructor(schema) { + super(`ValueCast: Cannot locate referenced schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueCastReferenceTypeError = ValueCastReferenceTypeError; +class ValueCastArrayUniqueItemsTypeError extends Error { + constructor(schema, value) { + super('ValueCast: Array cast produced invalid data due to uniqueItems constraint'); + this.schema = schema; + this.value = value; + } +} +exports.ValueCastArrayUniqueItemsTypeError = ValueCastArrayUniqueItemsTypeError; +class ValueCastNeverTypeError extends Error { + constructor(schema) { + super('ValueCast: Never types cannot be cast'); + this.schema = schema; + } +} +exports.ValueCastNeverTypeError = ValueCastNeverTypeError; +class ValueCastRecursiveTypeError extends Error { + constructor(schema) { + super('ValueCast.Recursive: Cannot cast recursive schemas'); + this.schema = schema; + } +} +exports.ValueCastRecursiveTypeError = ValueCastRecursiveTypeError; +class ValueCastUnknownTypeError extends Error { + constructor(schema) { + super('ValueCast: Unknown type'); + this.schema = schema; + } +} +exports.ValueCastUnknownTypeError = ValueCastUnknownTypeError; +class ValueCastDereferenceError extends Error { + constructor(schema) { + super(`ValueCast: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueCastDereferenceError = ValueCastDereferenceError; +// ---------------------------------------------------------------------------------------------- +// The following will score a schema against a value. For objects, the score is the tally of +// points awarded for each property of the value. Property points are (1.0 / propertyCount) +// to prevent large property counts biasing results. Properties that match literal values are +// maximally awarded as literals are typically used as union discriminator fields. +// ---------------------------------------------------------------------------------------------- +var UnionCastCreate; +(function (UnionCastCreate) { + function Score(schema, references, value) { + if (schema[Types.Kind] === 'Object' && typeof value === 'object' && value !== null) { + const object = schema; + const keys = Object.keys(value); + const entries = globalThis.Object.entries(object.properties); + const [point, max] = [1 / entries.length, entries.length]; + return entries.reduce((acc, [key, schema]) => { + const literal = schema[Types.Kind] === 'Literal' && schema.const === value[key] ? max : 0; + const checks = check_1.ValueCheck.Check(schema, references, value[key]) ? point : 0; + const exists = keys.includes(key) ? point : 0; + return acc + (literal + checks + exists); + }, 0); + } + else { + return check_1.ValueCheck.Check(schema, references, value) ? 1 : 0; + } + } + function Select(union, references, value) { + let [select, best] = [union.anyOf[0], 0]; + for (const schema of union.anyOf) { + const score = Score(schema, references, value); + if (score > best) { + select = schema; + best = score; + } + } + return select; + } + function Create(union, references, value) { + if (union.default !== undefined) { + return union.default; + } + else { + const schema = Select(union, references, value); + return ValueCast.Cast(schema, references, value); + } + } + UnionCastCreate.Create = Create; +})(UnionCastCreate || (UnionCastCreate = {})); +var ValueCast; +(function (ValueCast) { + // ---------------------------------------------------------------------------------------------- + // Guards + // ---------------------------------------------------------------------------------------------- + function IsObject(value) { + return typeof value === 'object' && value !== null && !globalThis.Array.isArray(value); + } + function IsArray(value) { + return typeof value === 'object' && globalThis.Array.isArray(value); + } + function IsNumber(value) { + return typeof value === 'number' && !isNaN(value); + } + function IsString(value) { + return typeof value === 'string'; + } + // ---------------------------------------------------------------------------------------------- + // Cast + // ---------------------------------------------------------------------------------------------- + function Any(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Array(schema, references, value) { + if (check_1.ValueCheck.Check(schema, references, value)) + return clone_1.ValueClone.Clone(value); + const created = IsArray(value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + const minimum = IsNumber(schema.minItems) && created.length < schema.minItems ? [...created, ...globalThis.Array.from({ length: schema.minItems - created.length }, () => null)] : created; + const maximum = IsNumber(schema.maxItems) && minimum.length > schema.maxItems ? minimum.slice(0, schema.maxItems) : minimum; + const casted = maximum.map((value) => Visit(schema.items, references, value)); + if (schema.uniqueItems !== true) + return casted; + const unique = [...new Set(casted)]; + if (!check_1.ValueCheck.Check(schema, references, unique)) + throw new ValueCastArrayUniqueItemsTypeError(schema, unique); + return unique; + } + function BigInt(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Boolean(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Constructor(schema, references, value) { + if (check_1.ValueCheck.Check(schema, references, value)) + return create_1.ValueCreate.Create(schema, references); + const required = new Set(schema.returns.required || []); + const result = function () { }; + for (const [key, property] of globalThis.Object.entries(schema.returns.properties)) { + if (!required.has(key) && value.prototype[key] === undefined) + continue; + result.prototype[key] = Visit(property, references, value.prototype[key]); + } + return result; + } + function Date(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Function(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Integer(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Intersect(schema, references, value) { + const created = create_1.ValueCreate.Create(schema, references); + const mapped = IsObject(created) && IsObject(value) ? { ...created, ...value } : value; + return check_1.ValueCheck.Check(schema, references, mapped) ? mapped : create_1.ValueCreate.Create(schema, references); + } + function Literal(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Never(schema, references, value) { + throw new ValueCastNeverTypeError(schema); + } + function Not(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema.allOf[1], references); + } + function Null(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Number(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Object(schema, references, value) { + if (check_1.ValueCheck.Check(schema, references, value)) + return value; + if (value === null || typeof value !== 'object') + return create_1.ValueCreate.Create(schema, references); + const required = new Set(schema.required || []); + const result = {}; + for (const [key, property] of globalThis.Object.entries(schema.properties)) { + if (!required.has(key) && value[key] === undefined) + continue; + result[key] = Visit(property, references, value[key]); + } + // additional schema properties + if (typeof schema.additionalProperties === 'object') { + const propertyNames = globalThis.Object.getOwnPropertyNames(schema.properties); + for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) { + if (propertyNames.includes(propertyName)) + continue; + result[propertyName] = Visit(schema.additionalProperties, references, value[propertyName]); + } + } + return result; + } + function Promise(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Record(schema, references, value) { + if (check_1.ValueCheck.Check(schema, references, value)) + return clone_1.ValueClone.Clone(value); + if (value === null || typeof value !== 'object' || globalThis.Array.isArray(value) || value instanceof globalThis.Date) + return create_1.ValueCreate.Create(schema, references); + const subschemaPropertyName = globalThis.Object.getOwnPropertyNames(schema.patternProperties)[0]; + const subschema = schema.patternProperties[subschemaPropertyName]; + const result = {}; + for (const [propKey, propValue] of globalThis.Object.entries(value)) { + result[propKey] = Visit(subschema, references, propValue); + } + return result; + } + function Ref(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueCastDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function String(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references); + } + function Symbol(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function TemplateLiteral(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function This(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueCastDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function Tuple(schema, references, value) { + if (check_1.ValueCheck.Check(schema, references, value)) + return clone_1.ValueClone.Clone(value); + if (!globalThis.Array.isArray(value)) + return create_1.ValueCreate.Create(schema, references); + if (schema.items === undefined) + return []; + return schema.items.map((schema, index) => Visit(schema, references, value[index])); + } + function Undefined(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Union(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : UnionCastCreate.Create(schema, references, value); + } + function Uint8Array(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Unknown(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Void(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function UserDefined(schema, references, value) { + return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references); + } + function Visit(schema, references, value) { + const references_ = IsString(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + switch (schema[Types.Kind]) { + case 'Any': + return Any(schema_, references_, value); + case 'Array': + return Array(schema_, references_, value); + case 'BigInt': + return BigInt(schema_, references_, value); + case 'Boolean': + return Boolean(schema_, references_, value); + case 'Constructor': + return Constructor(schema_, references_, value); + case 'Date': + return Date(schema_, references_, value); + case 'Function': + return Function(schema_, references_, value); + case 'Integer': + return Integer(schema_, references_, value); + case 'Intersect': + return Intersect(schema_, references_, value); + case 'Literal': + return Literal(schema_, references_, value); + case 'Never': + return Never(schema_, references_, value); + case 'Not': + return Not(schema_, references_, value); + case 'Null': + return Null(schema_, references_, value); + case 'Number': + return Number(schema_, references_, value); + case 'Object': + return Object(schema_, references_, value); + case 'Promise': + return Promise(schema_, references_, value); + case 'Record': + return Record(schema_, references_, value); + case 'Ref': + return Ref(schema_, references_, value); + case 'String': + return String(schema_, references_, value); + case 'Symbol': + return Symbol(schema_, references_, value); + case 'TemplateLiteral': + return TemplateLiteral(schema_, references_, value); + case 'This': + return This(schema_, references_, value); + case 'Tuple': + return Tuple(schema_, references_, value); + case 'Undefined': + return Undefined(schema_, references_, value); + case 'Union': + return Union(schema_, references_, value); + case 'Uint8Array': + return Uint8Array(schema_, references_, value); + case 'Unknown': + return Unknown(schema_, references_, value); + case 'Void': + return Void(schema_, references_, value); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new ValueCastUnknownTypeError(schema_); + return UserDefined(schema_, references_, value); + } + } + ValueCast.Visit = Visit; + function Cast(schema, references, value) { + return Visit(schema, references, clone_1.ValueClone.Clone(value)); + } + ValueCast.Cast = Cast; +})(ValueCast = exports.ValueCast || (exports.ValueCast = {})); diff --git a/node_modules/@sinclair/typebox/value/check.d.ts b/node_modules/@sinclair/typebox/value/check.d.ts new file mode 100644 index 0000000..ee18d9b --- /dev/null +++ b/node_modules/@sinclair/typebox/value/check.d.ts @@ -0,0 +1,12 @@ +import * as Types from '../typebox'; +export declare class ValueCheckUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCheckDereferenceError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +export declare namespace ValueCheck { + function Check(schema: T, references: Types.TSchema[], value: any): boolean; +} diff --git a/node_modules/@sinclair/typebox/value/check.js b/node_modules/@sinclair/typebox/value/check.js new file mode 100644 index 0000000..833aa64 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/check.js @@ -0,0 +1,484 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueCheck = exports.ValueCheckDereferenceError = exports.ValueCheckUnknownTypeError = void 0; +const Types = require("../typebox"); +const index_1 = require("../system/index"); +const hash_1 = require("./hash"); +// ------------------------------------------------------------------------- +// Errors +// ------------------------------------------------------------------------- +class ValueCheckUnknownTypeError extends Error { + constructor(schema) { + super(`ValueCheck: ${schema[Types.Kind] ? `Unknown type '${schema[Types.Kind]}'` : 'Unknown type'}`); + this.schema = schema; + } +} +exports.ValueCheckUnknownTypeError = ValueCheckUnknownTypeError; +class ValueCheckDereferenceError extends Error { + constructor(schema) { + super(`ValueCheck: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueCheckDereferenceError = ValueCheckDereferenceError; +var ValueCheck; +(function (ValueCheck) { + // ---------------------------------------------------------------------- + // Guards + // ---------------------------------------------------------------------- + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsInteger(value) { + return globalThis.Number.isInteger(value); + } + function IsString(value) { + return typeof value === 'string'; + } + function IsDefined(value) { + return value !== undefined; + } + // ---------------------------------------------------------------------- + // Policies + // ---------------------------------------------------------------------- + function IsExactOptionalProperty(value, key) { + return index_1.TypeSystem.ExactOptionalPropertyTypes ? key in value : value[key] !== undefined; + } + function IsObject(value) { + const result = typeof value === 'object' && value !== null; + return index_1.TypeSystem.AllowArrayObjects ? result : result && !globalThis.Array.isArray(value); + } + function IsRecordObject(value) { + return IsObject(value) && !(value instanceof globalThis.Date) && !(value instanceof globalThis.Uint8Array); + } + function IsNumber(value) { + const result = typeof value === 'number'; + return index_1.TypeSystem.AllowNaN ? result : result && globalThis.Number.isFinite(value); + } + function IsVoid(value) { + const result = value === undefined; + return index_1.TypeSystem.AllowVoidNull ? result || value === null : result; + } + // ---------------------------------------------------------------------- + // Types + // ---------------------------------------------------------------------- + function Any(schema, references, value) { + return true; + } + function Array(schema, references, value) { + if (!globalThis.Array.isArray(value)) { + return false; + } + if (IsDefined(schema.minItems) && !(value.length >= schema.minItems)) { + return false; + } + if (IsDefined(schema.maxItems) && !(value.length <= schema.maxItems)) { + return false; + } + // prettier-ignore + if (schema.uniqueItems === true && !((function () { const set = new Set(); for (const element of value) { + const hashed = hash_1.ValueHash.Create(element); + if (set.has(hashed)) { + return false; + } + else { + set.add(hashed); + } + } return true; })())) { + return false; + } + return value.every((value) => Visit(schema.items, references, value)); + } + function BigInt(schema, references, value) { + if (!IsBigInt(value)) { + return false; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === globalThis.BigInt(0))) { + return false; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + return false; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + return false; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + return false; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + return false; + } + return true; + } + function Boolean(schema, references, value) { + return typeof value === 'boolean'; + } + function Constructor(schema, references, value) { + return Visit(schema.returns, references, value.prototype); + } + function Date(schema, references, value) { + if (!(value instanceof globalThis.Date)) { + return false; + } + if (!IsNumber(value.getTime())) { + return false; + } + if (IsDefined(schema.exclusiveMinimumTimestamp) && !(value.getTime() > schema.exclusiveMinimumTimestamp)) { + return false; + } + if (IsDefined(schema.exclusiveMaximumTimestamp) && !(value.getTime() < schema.exclusiveMaximumTimestamp)) { + return false; + } + if (IsDefined(schema.minimumTimestamp) && !(value.getTime() >= schema.minimumTimestamp)) { + return false; + } + if (IsDefined(schema.maximumTimestamp) && !(value.getTime() <= schema.maximumTimestamp)) { + return false; + } + return true; + } + function Function(schema, references, value) { + return typeof value === 'function'; + } + function Integer(schema, references, value) { + if (!IsInteger(value)) { + return false; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { + return false; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + return false; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + return false; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + return false; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + return false; + } + return true; + } + function Intersect(schema, references, value) { + if (!schema.allOf.every((schema) => Visit(schema, references, value))) { + return false; + } + else if (schema.unevaluatedProperties === false) { + const schemaKeys = Types.KeyResolver.Resolve(schema); + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + return valueKeys.every((key) => schemaKeys.includes(key)); + } + else if (Types.TypeGuard.TSchema(schema.unevaluatedProperties)) { + const schemaKeys = Types.KeyResolver.Resolve(schema); + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + return valueKeys.every((key) => schemaKeys.includes(key) || Visit(schema.unevaluatedProperties, references, value[key])); + } + else { + return true; + } + } + function Literal(schema, references, value) { + return value === schema.const; + } + function Never(schema, references, value) { + return false; + } + function Not(schema, references, value) { + return !Visit(schema.allOf[0].not, references, value) && Visit(schema.allOf[1], references, value); + } + function Null(schema, references, value) { + return value === null; + } + function Number(schema, references, value) { + if (!IsNumber(value)) { + return false; + } + if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { + return false; + } + if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { + return false; + } + if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { + return false; + } + if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { + return false; + } + if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { + return false; + } + return true; + } + function Object(schema, references, value) { + if (!IsObject(value)) { + return false; + } + if (IsDefined(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) { + return false; + } + if (IsDefined(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { + return false; + } + const knownKeys = globalThis.Object.getOwnPropertyNames(schema.properties); + for (const knownKey of knownKeys) { + const property = schema.properties[knownKey]; + if (schema.required && schema.required.includes(knownKey)) { + if (!Visit(property, references, value[knownKey])) { + return false; + } + if (Types.ExtendsUndefined.Check(property)) { + return knownKey in value; + } + } + else { + if (IsExactOptionalProperty(value, knownKey) && !Visit(property, references, value[knownKey])) { + return false; + } + } + } + if (schema.additionalProperties === false) { + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + // optimization: value is valid if schemaKey length matches the valueKey length + if (schema.required && schema.required.length === knownKeys.length && valueKeys.length === knownKeys.length) { + return true; + } + else { + return valueKeys.every((valueKey) => knownKeys.includes(valueKey)); + } + } + else if (typeof schema.additionalProperties === 'object') { + const valueKeys = globalThis.Object.getOwnPropertyNames(value); + return valueKeys.every((key) => knownKeys.includes(key) || Visit(schema.additionalProperties, references, value[key])); + } + else { + return true; + } + } + function Promise(schema, references, value) { + return typeof value === 'object' && typeof value.then === 'function'; + } + function Record(schema, references, value) { + if (!IsRecordObject(value)) { + return false; + } + if (IsDefined(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) { + return false; + } + if (IsDefined(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { + return false; + } + const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0]; + const regex = new RegExp(keyPattern); + if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) { + return false; + } + for (const propValue of globalThis.Object.values(value)) { + if (!Visit(valueSchema, references, propValue)) + return false; + } + return true; + } + function Ref(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueCheckDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function String(schema, references, value) { + if (!IsString(value)) { + return false; + } + if (IsDefined(schema.minLength)) { + if (!(value.length >= schema.minLength)) + return false; + } + if (IsDefined(schema.maxLength)) { + if (!(value.length <= schema.maxLength)) + return false; + } + if (IsDefined(schema.pattern)) { + const regex = new RegExp(schema.pattern); + if (!regex.test(value)) + return false; + } + if (IsDefined(schema.format)) { + if (!Types.FormatRegistry.Has(schema.format)) + return false; + const func = Types.FormatRegistry.Get(schema.format); + return func(value); + } + return true; + } + function Symbol(schema, references, value) { + if (!(typeof value === 'symbol')) { + return false; + } + return true; + } + function TemplateLiteral(schema, references, value) { + if (!IsString(value)) { + return false; + } + return new RegExp(schema.pattern).test(value); + } + function This(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueCheckDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function Tuple(schema, references, value) { + if (!globalThis.Array.isArray(value)) { + return false; + } + if (schema.items === undefined && !(value.length === 0)) { + return false; + } + if (!(value.length === schema.maxItems)) { + return false; + } + if (!schema.items) { + return true; + } + for (let i = 0; i < schema.items.length; i++) { + if (!Visit(schema.items[i], references, value[i])) + return false; + } + return true; + } + function Undefined(schema, references, value) { + return value === undefined; + } + function Union(schema, references, value) { + return schema.anyOf.some((inner) => Visit(inner, references, value)); + } + function Uint8Array(schema, references, value) { + if (!(value instanceof globalThis.Uint8Array)) { + return false; + } + if (IsDefined(schema.maxByteLength) && !(value.length <= schema.maxByteLength)) { + return false; + } + if (IsDefined(schema.minByteLength) && !(value.length >= schema.minByteLength)) { + return false; + } + return true; + } + function Unknown(schema, references, value) { + return true; + } + function Void(schema, references, value) { + return IsVoid(value); + } + function UserDefined(schema, references, value) { + if (!Types.TypeRegistry.Has(schema[Types.Kind])) + return false; + const func = Types.TypeRegistry.Get(schema[Types.Kind]); + return func(schema, value); + } + function Visit(schema, references, value) { + const references_ = IsDefined(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + switch (schema_[Types.Kind]) { + case 'Any': + return Any(schema_, references_, value); + case 'Array': + return Array(schema_, references_, value); + case 'BigInt': + return BigInt(schema_, references_, value); + case 'Boolean': + return Boolean(schema_, references_, value); + case 'Constructor': + return Constructor(schema_, references_, value); + case 'Date': + return Date(schema_, references_, value); + case 'Function': + return Function(schema_, references_, value); + case 'Integer': + return Integer(schema_, references_, value); + case 'Intersect': + return Intersect(schema_, references_, value); + case 'Literal': + return Literal(schema_, references_, value); + case 'Never': + return Never(schema_, references_, value); + case 'Not': + return Not(schema_, references_, value); + case 'Null': + return Null(schema_, references_, value); + case 'Number': + return Number(schema_, references_, value); + case 'Object': + return Object(schema_, references_, value); + case 'Promise': + return Promise(schema_, references_, value); + case 'Record': + return Record(schema_, references_, value); + case 'Ref': + return Ref(schema_, references_, value); + case 'String': + return String(schema_, references_, value); + case 'Symbol': + return Symbol(schema_, references_, value); + case 'TemplateLiteral': + return TemplateLiteral(schema_, references_, value); + case 'This': + return This(schema_, references_, value); + case 'Tuple': + return Tuple(schema_, references_, value); + case 'Undefined': + return Undefined(schema_, references_, value); + case 'Union': + return Union(schema_, references_, value); + case 'Uint8Array': + return Uint8Array(schema_, references_, value); + case 'Unknown': + return Unknown(schema_, references_, value); + case 'Void': + return Void(schema_, references_, value); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new ValueCheckUnknownTypeError(schema_); + return UserDefined(schema_, references_, value); + } + } + // ------------------------------------------------------------------------- + // Check + // ------------------------------------------------------------------------- + function Check(schema, references, value) { + return Visit(schema, references, value); + } + ValueCheck.Check = Check; +})(ValueCheck = exports.ValueCheck || (exports.ValueCheck = {})); diff --git a/node_modules/@sinclair/typebox/value/clone.d.ts b/node_modules/@sinclair/typebox/value/clone.d.ts new file mode 100644 index 0000000..5ca0adf --- /dev/null +++ b/node_modules/@sinclair/typebox/value/clone.d.ts @@ -0,0 +1,3 @@ +export declare namespace ValueClone { + function Clone(value: T): T; +} diff --git a/node_modules/@sinclair/typebox/value/clone.js b/node_modules/@sinclair/typebox/value/clone.js new file mode 100644 index 0000000..75e2685 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/clone.js @@ -0,0 +1,71 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueClone = void 0; +const is_1 = require("./is"); +var ValueClone; +(function (ValueClone) { + function Array(value) { + return value.map((element) => Clone(element)); + } + function Date(value) { + return new globalThis.Date(value.toISOString()); + } + function Object(value) { + const keys = [...globalThis.Object.keys(value), ...globalThis.Object.getOwnPropertySymbols(value)]; + return keys.reduce((acc, key) => ({ ...acc, [key]: Clone(value[key]) }), {}); + } + function TypedArray(value) { + return value.slice(); + } + function Value(value) { + return value; + } + function Clone(value) { + if (is_1.Is.Date(value)) { + return Date(value); + } + else if (is_1.Is.Object(value)) { + return Object(value); + } + else if (is_1.Is.Array(value)) { + return Array(value); + } + else if (is_1.Is.TypedArray(value)) { + return TypedArray(value); + } + else if (is_1.Is.Value(value)) { + return Value(value); + } + else { + throw new Error('ValueClone: Unable to clone value'); + } + } + ValueClone.Clone = Clone; +})(ValueClone = exports.ValueClone || (exports.ValueClone = {})); diff --git a/node_modules/@sinclair/typebox/value/convert.d.ts b/node_modules/@sinclair/typebox/value/convert.d.ts new file mode 100644 index 0000000..99c5d5d --- /dev/null +++ b/node_modules/@sinclair/typebox/value/convert.d.ts @@ -0,0 +1,13 @@ +import * as Types from '../typebox'; +export declare class ValueConvertUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueConvertDereferenceError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +export declare namespace ValueConvert { + function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): unknown; + function Convert(schema: T, references: Types.TSchema[], value: any): unknown; +} diff --git a/node_modules/@sinclair/typebox/value/convert.js b/node_modules/@sinclair/typebox/value/convert.js new file mode 100644 index 0000000..c6a608d --- /dev/null +++ b/node_modules/@sinclair/typebox/value/convert.js @@ -0,0 +1,372 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueConvert = exports.ValueConvertDereferenceError = exports.ValueConvertUnknownTypeError = void 0; +const Types = require("../typebox"); +const clone_1 = require("./clone"); +const check_1 = require("./check"); +// ---------------------------------------------------------------------------------------------- +// Errors +// ---------------------------------------------------------------------------------------------- +class ValueConvertUnknownTypeError extends Error { + constructor(schema) { + super('ValueConvert: Unknown type'); + this.schema = schema; + } +} +exports.ValueConvertUnknownTypeError = ValueConvertUnknownTypeError; +class ValueConvertDereferenceError extends Error { + constructor(schema) { + super(`ValueConvert: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueConvertDereferenceError = ValueConvertDereferenceError; +var ValueConvert; +(function (ValueConvert) { + // ---------------------------------------------------------------------------------------------- + // Guards + // ---------------------------------------------------------------------------------------------- + function IsObject(value) { + return typeof value === 'object' && value !== null && !globalThis.Array.isArray(value); + } + function IsArray(value) { + return typeof value === 'object' && globalThis.Array.isArray(value); + } + function IsDate(value) { + return typeof value === 'object' && value instanceof globalThis.Date; + } + function IsSymbol(value) { + return typeof value === 'symbol'; + } + function IsString(value) { + return typeof value === 'string'; + } + function IsBoolean(value) { + return typeof value === 'boolean'; + } + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsNumber(value) { + return typeof value === 'number' && !isNaN(value); + } + function IsStringNumeric(value) { + return IsString(value) && !isNaN(value) && !isNaN(parseFloat(value)); + } + function IsValueToString(value) { + return IsBigInt(value) || IsBoolean(value) || IsNumber(value); + } + function IsValueTrue(value) { + return value === true || (IsNumber(value) && value === 1) || (IsBigInt(value) && value === globalThis.BigInt('1')) || (IsString(value) && (value.toLowerCase() === 'true' || value === '1')); + } + function IsValueFalse(value) { + return value === false || (IsNumber(value) && value === 0) || (IsBigInt(value) && value === globalThis.BigInt('0')) || (IsString(value) && (value.toLowerCase() === 'false' || value === '0')); + } + function IsTimeStringWithTimeZone(value) { + return IsString(value) && /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i.test(value); + } + function IsTimeStringWithoutTimeZone(value) { + return IsString(value) && /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)?$/i.test(value); + } + function IsDateTimeStringWithTimeZone(value) { + return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i.test(value); + } + function IsDateTimeStringWithoutTimeZone(value) { + return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)?$/i.test(value); + } + function IsDateString(value) { + return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\d$/i.test(value); + } + // ---------------------------------------------------------------------------------------------- + // Convert + // ---------------------------------------------------------------------------------------------- + function TryConvertLiteralString(value, target) { + const conversion = TryConvertString(value); + return conversion === target ? conversion : value; + } + function TryConvertLiteralNumber(value, target) { + const conversion = TryConvertNumber(value); + return conversion === target ? conversion : value; + } + function TryConvertLiteralBoolean(value, target) { + const conversion = TryConvertBoolean(value); + return conversion === target ? conversion : value; + } + function TryConvertLiteral(schema, value) { + if (typeof schema.const === 'string') { + return TryConvertLiteralString(value, schema.const); + } + else if (typeof schema.const === 'number') { + return TryConvertLiteralNumber(value, schema.const); + } + else if (typeof schema.const === 'boolean') { + return TryConvertLiteralBoolean(value, schema.const); + } + else { + return clone_1.ValueClone.Clone(value); + } + } + function TryConvertBoolean(value) { + return IsValueTrue(value) ? true : IsValueFalse(value) ? false : value; + } + function TryConvertBigInt(value) { + return IsStringNumeric(value) ? globalThis.BigInt(parseInt(value)) : IsNumber(value) ? globalThis.BigInt(value | 0) : IsValueFalse(value) ? 0 : IsValueTrue(value) ? 1 : value; + } + function TryConvertString(value) { + return IsValueToString(value) ? value.toString() : value; + } + function TryConvertNumber(value) { + return IsStringNumeric(value) ? parseFloat(value) : IsValueTrue(value) ? 1 : IsValueFalse(value) ? 0 : value; + } + function TryConvertInteger(value) { + return IsStringNumeric(value) ? parseInt(value) : IsNumber(value) ? value | 0 : IsValueTrue(value) ? 1 : IsValueFalse(value) ? 0 : value; + } + function TryConvertNull(value) { + return IsString(value) && value.toLowerCase() === 'null' ? null : value; + } + function TryConvertUndefined(value) { + return IsString(value) && value === 'undefined' ? undefined : value; + } + function TryConvertDate(value) { + // note: this function may return an invalid dates for the regex tests + // above. Invalid dates will however be checked during the casting + // function and will return a epoch date if invalid. Consider better + // string parsing for the iso dates in future revisions. + return IsDate(value) + ? value + : IsNumber(value) + ? new globalThis.Date(value) + : IsValueTrue(value) + ? new globalThis.Date(1) + : IsValueFalse(value) + ? new globalThis.Date(0) + : IsStringNumeric(value) + ? new globalThis.Date(parseInt(value)) + : IsTimeStringWithoutTimeZone(value) + ? new globalThis.Date(`1970-01-01T${value}.000Z`) + : IsTimeStringWithTimeZone(value) + ? new globalThis.Date(`1970-01-01T${value}`) + : IsDateTimeStringWithoutTimeZone(value) + ? new globalThis.Date(`${value}.000Z`) + : IsDateTimeStringWithTimeZone(value) + ? new globalThis.Date(value) + : IsDateString(value) + ? new globalThis.Date(`${value}T00:00:00.000Z`) + : value; + } + // ---------------------------------------------------------------------------------------------- + // Cast + // ---------------------------------------------------------------------------------------------- + function Any(schema, references, value) { + return value; + } + function Array(schema, references, value) { + if (IsArray(value)) { + return value.map((value) => Visit(schema.items, references, value)); + } + return value; + } + function BigInt(schema, references, value) { + return TryConvertBigInt(value); + } + function Boolean(schema, references, value) { + return TryConvertBoolean(value); + } + function Constructor(schema, references, value) { + return clone_1.ValueClone.Clone(value); + } + function Date(schema, references, value) { + return TryConvertDate(value); + } + function Function(schema, references, value) { + return value; + } + function Integer(schema, references, value) { + return TryConvertInteger(value); + } + function Intersect(schema, references, value) { + return value; + } + function Literal(schema, references, value) { + return TryConvertLiteral(schema, value); + } + function Never(schema, references, value) { + return value; + } + function Null(schema, references, value) { + return TryConvertNull(value); + } + function Number(schema, references, value) { + return TryConvertNumber(value); + } + function Object(schema, references, value) { + if (IsObject(value)) + return globalThis.Object.keys(schema.properties).reduce((acc, key) => { + return value[key] !== undefined ? { ...acc, [key]: Visit(schema.properties[key], references, value[key]) } : { ...acc }; + }, value); + return value; + } + function Promise(schema, references, value) { + return value; + } + function Record(schema, references, value) { + const propertyKey = globalThis.Object.getOwnPropertyNames(schema.patternProperties)[0]; + const property = schema.patternProperties[propertyKey]; + const result = {}; + for (const [propKey, propValue] of globalThis.Object.entries(value)) { + result[propKey] = Visit(property, references, propValue); + } + return result; + } + function Ref(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueConvertDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function String(schema, references, value) { + return TryConvertString(value); + } + function Symbol(schema, references, value) { + return value; + } + function TemplateLiteral(schema, references, value) { + return value; + } + function This(schema, references, value) { + const index = references.findIndex((foreign) => foreign.$id === schema.$ref); + if (index === -1) + throw new ValueConvertDereferenceError(schema); + const target = references[index]; + return Visit(target, references, value); + } + function Tuple(schema, references, value) { + if (IsArray(value) && schema.items !== undefined) { + return value.map((value, index) => { + return index < schema.items.length ? Visit(schema.items[index], references, value) : value; + }); + } + return value; + } + function Undefined(schema, references, value) { + return TryConvertUndefined(value); + } + function Union(schema, references, value) { + for (const subschema of schema.anyOf) { + const converted = Visit(subschema, references, value); + if (check_1.ValueCheck.Check(subschema, references, converted)) { + return converted; + } + } + return value; + } + function Uint8Array(schema, references, value) { + return value; + } + function Unknown(schema, references, value) { + return value; + } + function Void(schema, references, value) { + return value; + } + function UserDefined(schema, references, value) { + return value; + } + function Visit(schema, references, value) { + const references_ = IsString(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + switch (schema[Types.Kind]) { + case 'Any': + return Any(schema_, references_, value); + case 'Array': + return Array(schema_, references_, value); + case 'BigInt': + return BigInt(schema_, references_, value); + case 'Boolean': + return Boolean(schema_, references_, value); + case 'Constructor': + return Constructor(schema_, references_, value); + case 'Date': + return Date(schema_, references_, value); + case 'Function': + return Function(schema_, references_, value); + case 'Integer': + return Integer(schema_, references_, value); + case 'Intersect': + return Intersect(schema_, references_, value); + case 'Literal': + return Literal(schema_, references_, value); + case 'Never': + return Never(schema_, references_, value); + case 'Null': + return Null(schema_, references_, value); + case 'Number': + return Number(schema_, references_, value); + case 'Object': + return Object(schema_, references_, value); + case 'Promise': + return Promise(schema_, references_, value); + case 'Record': + return Record(schema_, references_, value); + case 'Ref': + return Ref(schema_, references_, value); + case 'String': + return String(schema_, references_, value); + case 'Symbol': + return Symbol(schema_, references_, value); + case 'TemplateLiteral': + return TemplateLiteral(schema_, references_, value); + case 'This': + return This(schema_, references_, value); + case 'Tuple': + return Tuple(schema_, references_, value); + case 'Undefined': + return Undefined(schema_, references_, value); + case 'Union': + return Union(schema_, references_, value); + case 'Uint8Array': + return Uint8Array(schema_, references_, value); + case 'Unknown': + return Unknown(schema_, references_, value); + case 'Void': + return Void(schema_, references_, value); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new ValueConvertUnknownTypeError(schema_); + return UserDefined(schema_, references_, value); + } + } + ValueConvert.Visit = Visit; + function Convert(schema, references, value) { + return Visit(schema, references, clone_1.ValueClone.Clone(value)); + } + ValueConvert.Convert = Convert; +})(ValueConvert = exports.ValueConvert || (exports.ValueConvert = {})); diff --git a/node_modules/@sinclair/typebox/value/create.d.ts b/node_modules/@sinclair/typebox/value/create.d.ts new file mode 100644 index 0000000..86e1e5e --- /dev/null +++ b/node_modules/@sinclair/typebox/value/create.d.ts @@ -0,0 +1,26 @@ +import * as Types from '../typebox'; +export declare class ValueCreateUnknownTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCreateNeverTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCreateIntersectTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCreateTempateLiteralTypeError extends Error { + readonly schema: Types.TSchema; + constructor(schema: Types.TSchema); +} +export declare class ValueCreateDereferenceError extends Error { + readonly schema: Types.TRef | Types.TThis; + constructor(schema: Types.TRef | Types.TThis); +} +export declare namespace ValueCreate { + /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */ + function Visit(schema: Types.TSchema, references: Types.TSchema[]): unknown; + function Create(schema: T, references: Types.TSchema[]): Types.Static; +} diff --git a/node_modules/@sinclair/typebox/value/create.js b/node_modules/@sinclair/typebox/value/create.js new file mode 100644 index 0000000..42374a8 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/create.js @@ -0,0 +1,480 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueCreate = exports.ValueCreateDereferenceError = exports.ValueCreateTempateLiteralTypeError = exports.ValueCreateIntersectTypeError = exports.ValueCreateNeverTypeError = exports.ValueCreateUnknownTypeError = void 0; +const Types = require("../typebox"); +const check_1 = require("./check"); +// -------------------------------------------------------------------------- +// Errors +// -------------------------------------------------------------------------- +class ValueCreateUnknownTypeError extends Error { + constructor(schema) { + super('ValueCreate: Unknown type'); + this.schema = schema; + } +} +exports.ValueCreateUnknownTypeError = ValueCreateUnknownTypeError; +class ValueCreateNeverTypeError extends Error { + constructor(schema) { + super('ValueCreate: Never types cannot be created'); + this.schema = schema; + } +} +exports.ValueCreateNeverTypeError = ValueCreateNeverTypeError; +class ValueCreateIntersectTypeError extends Error { + constructor(schema) { + super('ValueCreate: Intersect produced invalid value. Consider using a default value.'); + this.schema = schema; + } +} +exports.ValueCreateIntersectTypeError = ValueCreateIntersectTypeError; +class ValueCreateTempateLiteralTypeError extends Error { + constructor(schema) { + super('ValueCreate: Can only create template literal values from patterns that produce finite sequences. Consider using a default value.'); + this.schema = schema; + } +} +exports.ValueCreateTempateLiteralTypeError = ValueCreateTempateLiteralTypeError; +class ValueCreateDereferenceError extends Error { + constructor(schema) { + super(`ValueCreate: Unable to dereference schema with $id '${schema.$ref}'`); + this.schema = schema; + } +} +exports.ValueCreateDereferenceError = ValueCreateDereferenceError; +// -------------------------------------------------------------------------- +// ValueCreate +// -------------------------------------------------------------------------- +var ValueCreate; +(function (ValueCreate) { + // -------------------------------------------------------- + // Guards + // -------------------------------------------------------- + function IsString(value) { + return typeof value === 'string'; + } + // -------------------------------------------------------- + // Types + // -------------------------------------------------------- + function Any(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return {}; + } + } + function Array(schema, references) { + if (schema.uniqueItems === true && schema.default === undefined) { + throw new Error('ValueCreate.Array: Arrays with uniqueItems require a default value'); + } + else if ('default' in schema) { + return schema.default; + } + else if (schema.minItems !== undefined) { + return globalThis.Array.from({ length: schema.minItems }).map((item) => { + return ValueCreate.Create(schema.items, references); + }); + } + else { + return []; + } + } + function BigInt(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return globalThis.BigInt(0); + } + } + function Boolean(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return false; + } + } + function Constructor(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + const value = ValueCreate.Create(schema.returns, references); + if (typeof value === 'object' && !globalThis.Array.isArray(value)) { + return class { + constructor() { + for (const [key, val] of globalThis.Object.entries(value)) { + const self = this; + self[key] = val; + } + } + }; + } + else { + return class { + }; + } + } + } + function Date(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if (schema.minimumTimestamp !== undefined) { + return new globalThis.Date(schema.minimumTimestamp); + } + else { + return new globalThis.Date(0); + } + } + function Function(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return () => ValueCreate.Create(schema.returns, references); + } + } + function Integer(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if (schema.minimum !== undefined) { + return schema.minimum; + } + else { + return 0; + } + } + function Intersect(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + // Note: The best we can do here is attempt to instance each sub type and apply through object assign. For non-object + // sub types, we just escape the assignment and just return the value. In the latter case, this is typically going to + // be a consequence of an illogical intersection. + const value = schema.allOf.reduce((acc, schema) => { + const next = Visit(schema, references); + return typeof next === 'object' ? { ...acc, ...next } : next; + }, {}); + if (!check_1.ValueCheck.Check(schema, references, value)) + throw new ValueCreateIntersectTypeError(schema); + return value; + } + } + function Literal(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return schema.const; + } + } + function Never(schema, references) { + throw new ValueCreateNeverTypeError(schema); + } + function Not(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return Visit(schema.allOf[1], references); + } + } + function Null(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return null; + } + } + function Number(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if (schema.minimum !== undefined) { + return schema.minimum; + } + else { + return 0; + } + } + function Object(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + const required = new Set(schema.required); + return (schema.default || + globalThis.Object.entries(schema.properties).reduce((acc, [key, schema]) => { + return required.has(key) ? { ...acc, [key]: ValueCreate.Create(schema, references) } : { ...acc }; + }, {})); + } + } + function Promise(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return globalThis.Promise.resolve(ValueCreate.Create(schema.item, references)); + } + } + function Record(schema, references) { + const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0]; + if ('default' in schema) { + return schema.default; + } + else if (!(keyPattern === Types.PatternStringExact || keyPattern === Types.PatternNumberExact)) { + const propertyKeys = keyPattern.slice(1, keyPattern.length - 1).split('|'); + return propertyKeys.reduce((acc, key) => { + return { ...acc, [key]: Create(valueSchema, references) }; + }, {}); + } + else { + return {}; + } + } + function Ref(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + const index = references.findIndex((foreign) => foreign.$id === schema.$id); + if (index === -1) + throw new ValueCreateDereferenceError(schema); + const target = references[index]; + return Visit(target, references); + } + } + function String(schema, references) { + if (schema.pattern !== undefined) { + if (!('default' in schema)) { + throw new Error('ValueCreate.String: String types with patterns must specify a default value'); + } + else { + return schema.default; + } + } + else if (schema.format !== undefined) { + if (!('default' in schema)) { + throw new Error('ValueCreate.String: String types with formats must specify a default value'); + } + else { + return schema.default; + } + } + else { + if ('default' in schema) { + return schema.default; + } + else if (schema.minLength !== undefined) { + return globalThis.Array.from({ length: schema.minLength }) + .map(() => '.') + .join(''); + } + else { + return ''; + } + } + } + function Symbol(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if ('value' in schema) { + return globalThis.Symbol.for(schema.value); + } + else { + return globalThis.Symbol(); + } + } + function TemplateLiteral(schema, references) { + if ('default' in schema) { + return schema.default; + } + const expression = Types.TemplateLiteralParser.ParseExact(schema.pattern); + if (!Types.TemplateLiteralFinite.Check(expression)) + throw new ValueCreateTempateLiteralTypeError(schema); + const sequence = Types.TemplateLiteralGenerator.Generate(expression); + return sequence.next().value; + } + function This(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + const index = references.findIndex((foreign) => foreign.$id === schema.$id); + if (index === -1) + throw new ValueCreateDereferenceError(schema); + const target = references[index]; + return Visit(target, references); + } + } + function Tuple(schema, references) { + if ('default' in schema) { + return schema.default; + } + if (schema.items === undefined) { + return []; + } + else { + return globalThis.Array.from({ length: schema.minItems }).map((_, index) => ValueCreate.Create(schema.items[index], references)); + } + } + function Undefined(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return undefined; + } + } + function Union(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if (schema.anyOf.length === 0) { + throw new Error('ValueCreate.Union: Cannot create Union with zero variants'); + } + else { + return ValueCreate.Create(schema.anyOf[0], references); + } + } + function Uint8Array(schema, references) { + if ('default' in schema) { + return schema.default; + } + else if (schema.minByteLength !== undefined) { + return new globalThis.Uint8Array(schema.minByteLength); + } + else { + return new globalThis.Uint8Array(0); + } + } + function Unknown(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return {}; + } + } + function Void(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + return void 0; + } + } + function UserDefined(schema, references) { + if ('default' in schema) { + return schema.default; + } + else { + throw new Error('ValueCreate.UserDefined: User defined types must specify a default value'); + } + } + /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */ + function Visit(schema, references) { + const references_ = IsString(schema.$id) ? [...references, schema] : references; + const schema_ = schema; + switch (schema_[Types.Kind]) { + case 'Any': + return Any(schema_, references_); + case 'Array': + return Array(schema_, references_); + case 'BigInt': + return BigInt(schema_, references_); + case 'Boolean': + return Boolean(schema_, references_); + case 'Constructor': + return Constructor(schema_, references_); + case 'Date': + return Date(schema_, references_); + case 'Function': + return Function(schema_, references_); + case 'Integer': + return Integer(schema_, references_); + case 'Intersect': + return Intersect(schema_, references_); + case 'Literal': + return Literal(schema_, references_); + case 'Never': + return Never(schema_, references_); + case 'Not': + return Not(schema_, references_); + case 'Null': + return Null(schema_, references_); + case 'Number': + return Number(schema_, references_); + case 'Object': + return Object(schema_, references_); + case 'Promise': + return Promise(schema_, references_); + case 'Record': + return Record(schema_, references_); + case 'Ref': + return Ref(schema_, references_); + case 'String': + return String(schema_, references_); + case 'Symbol': + return Symbol(schema_, references_); + case 'TemplateLiteral': + return TemplateLiteral(schema_, references_); + case 'This': + return This(schema_, references_); + case 'Tuple': + return Tuple(schema_, references_); + case 'Undefined': + return Undefined(schema_, references_); + case 'Union': + return Union(schema_, references_); + case 'Uint8Array': + return Uint8Array(schema_, references_); + case 'Unknown': + return Unknown(schema_, references_); + case 'Void': + return Void(schema_, references_); + default: + if (!Types.TypeRegistry.Has(schema_[Types.Kind])) + throw new ValueCreateUnknownTypeError(schema_); + return UserDefined(schema_, references_); + } + } + ValueCreate.Visit = Visit; + function Create(schema, references) { + return Visit(schema, references); + } + ValueCreate.Create = Create; +})(ValueCreate = exports.ValueCreate || (exports.ValueCreate = {})); diff --git a/node_modules/@sinclair/typebox/value/delta.d.ts b/node_modules/@sinclair/typebox/value/delta.d.ts new file mode 100644 index 0000000..3320fac --- /dev/null +++ b/node_modules/@sinclair/typebox/value/delta.d.ts @@ -0,0 +1,43 @@ +import { Static } from '../typebox'; +export type Insert = Static; +export declare const Insert: import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"insert">; + path: import("../typebox").TString; + value: import("../typebox").TUnknown; +}>; +export type Update = Static; +export declare const Update: import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"update">; + path: import("../typebox").TString; + value: import("../typebox").TUnknown; +}>; +export type Delete = Static; +export declare const Delete: import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"delete">; + path: import("../typebox").TString; +}>; +export type Edit = Static; +export declare const Edit: import("../typebox").TUnion<[import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"insert">; + path: import("../typebox").TString; + value: import("../typebox").TUnknown; +}>, import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"update">; + path: import("../typebox").TString; + value: import("../typebox").TUnknown; +}>, import("../typebox").TObject<{ + type: import("../typebox").TLiteral<"delete">; + path: import("../typebox").TString; +}>]>; +export declare class ValueDeltaObjectWithSymbolKeyError extends Error { + readonly key: unknown; + constructor(key: unknown); +} +export declare class ValueDeltaUnableToDiffUnknownValue extends Error { + readonly value: unknown; + constructor(value: unknown); +} +export declare namespace ValueDelta { + function Diff(current: unknown, next: unknown): Edit[]; + function Patch(current: unknown, edits: Edit[]): T; +} diff --git a/node_modules/@sinclair/typebox/value/delta.js b/node_modules/@sinclair/typebox/value/delta.js new file mode 100644 index 0000000..89c06a0 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/delta.js @@ -0,0 +1,204 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueDelta = exports.ValueDeltaUnableToDiffUnknownValue = exports.ValueDeltaObjectWithSymbolKeyError = exports.Edit = exports.Delete = exports.Update = exports.Insert = void 0; +const typebox_1 = require("../typebox"); +const is_1 = require("./is"); +const clone_1 = require("./clone"); +const pointer_1 = require("./pointer"); +exports.Insert = typebox_1.Type.Object({ + type: typebox_1.Type.Literal('insert'), + path: typebox_1.Type.String(), + value: typebox_1.Type.Unknown(), +}); +exports.Update = typebox_1.Type.Object({ + type: typebox_1.Type.Literal('update'), + path: typebox_1.Type.String(), + value: typebox_1.Type.Unknown(), +}); +exports.Delete = typebox_1.Type.Object({ + type: typebox_1.Type.Literal('delete'), + path: typebox_1.Type.String(), +}); +exports.Edit = typebox_1.Type.Union([exports.Insert, exports.Update, exports.Delete]); +// --------------------------------------------------------------------- +// Errors +// --------------------------------------------------------------------- +class ValueDeltaObjectWithSymbolKeyError extends Error { + constructor(key) { + super('ValueDelta: Cannot diff objects with symbol keys'); + this.key = key; + } +} +exports.ValueDeltaObjectWithSymbolKeyError = ValueDeltaObjectWithSymbolKeyError; +class ValueDeltaUnableToDiffUnknownValue extends Error { + constructor(value) { + super('ValueDelta: Unable to create diff edits for unknown value'); + this.value = value; + } +} +exports.ValueDeltaUnableToDiffUnknownValue = ValueDeltaUnableToDiffUnknownValue; +// --------------------------------------------------------------------- +// ValueDelta +// --------------------------------------------------------------------- +var ValueDelta; +(function (ValueDelta) { + // --------------------------------------------------------------------- + // Edits + // --------------------------------------------------------------------- + function Update(path, value) { + return { type: 'update', path, value }; + } + function Insert(path, value) { + return { type: 'insert', path, value }; + } + function Delete(path) { + return { type: 'delete', path }; + } + // --------------------------------------------------------------------- + // Diff + // --------------------------------------------------------------------- + function* Object(path, current, next) { + if (!is_1.Is.Object(next)) + return yield Update(path, next); + const currentKeys = [...globalThis.Object.keys(current), ...globalThis.Object.getOwnPropertySymbols(current)]; + const nextKeys = [...globalThis.Object.keys(next), ...globalThis.Object.getOwnPropertySymbols(next)]; + for (const key of currentKeys) { + if (typeof key === 'symbol') + throw new ValueDeltaObjectWithSymbolKeyError(key); + if (next[key] === undefined && nextKeys.includes(key)) + yield Update(`${path}/${String(key)}`, undefined); + } + for (const key of nextKeys) { + if (current[key] === undefined || next[key] === undefined) + continue; + if (typeof key === 'symbol') + throw new ValueDeltaObjectWithSymbolKeyError(key); + yield* Visit(`${path}/${String(key)}`, current[key], next[key]); + } + for (const key of nextKeys) { + if (typeof key === 'symbol') + throw new ValueDeltaObjectWithSymbolKeyError(key); + if (current[key] === undefined) + yield Insert(`${path}/${String(key)}`, next[key]); + } + for (const key of currentKeys.reverse()) { + if (typeof key === 'symbol') + throw new ValueDeltaObjectWithSymbolKeyError(key); + if (next[key] === undefined && !nextKeys.includes(key)) + yield Delete(`${path}/${String(key)}`); + } + } + function* Array(path, current, next) { + if (!is_1.Is.Array(next)) + return yield Update(path, next); + for (let i = 0; i < Math.min(current.length, next.length); i++) { + yield* Visit(`${path}/${i}`, current[i], next[i]); + } + for (let i = 0; i < next.length; i++) { + if (i < current.length) + continue; + yield Insert(`${path}/${i}`, next[i]); + } + for (let i = current.length - 1; i >= 0; i--) { + if (i < next.length) + continue; + yield Delete(`${path}/${i}`); + } + } + function* TypedArray(path, current, next) { + if (!is_1.Is.TypedArray(next) || current.length !== next.length || globalThis.Object.getPrototypeOf(current).constructor.name !== globalThis.Object.getPrototypeOf(next).constructor.name) + return yield Update(path, next); + for (let i = 0; i < Math.min(current.length, next.length); i++) { + yield* Visit(`${path}/${i}`, current[i], next[i]); + } + } + function* Value(path, current, next) { + if (current === next) + return; + yield Update(path, next); + } + function* Visit(path, current, next) { + if (is_1.Is.Object(current)) { + return yield* Object(path, current, next); + } + else if (is_1.Is.Array(current)) { + return yield* Array(path, current, next); + } + else if (is_1.Is.TypedArray(current)) { + return yield* TypedArray(path, current, next); + } + else if (is_1.Is.Value(current)) { + return yield* Value(path, current, next); + } + else { + throw new ValueDeltaUnableToDiffUnknownValue(current); + } + } + function Diff(current, next) { + return [...Visit('', current, next)]; + } + ValueDelta.Diff = Diff; + // --------------------------------------------------------------------- + // Patch + // --------------------------------------------------------------------- + function IsRootUpdate(edits) { + return edits.length > 0 && edits[0].path === '' && edits[0].type === 'update'; + } + function IsIdentity(edits) { + return edits.length === 0; + } + function Patch(current, edits) { + if (IsRootUpdate(edits)) { + return clone_1.ValueClone.Clone(edits[0].value); + } + if (IsIdentity(edits)) { + return clone_1.ValueClone.Clone(current); + } + const clone = clone_1.ValueClone.Clone(current); + for (const edit of edits) { + switch (edit.type) { + case 'insert': { + pointer_1.ValuePointer.Set(clone, edit.path, edit.value); + break; + } + case 'update': { + pointer_1.ValuePointer.Set(clone, edit.path, edit.value); + break; + } + case 'delete': { + pointer_1.ValuePointer.Delete(clone, edit.path); + break; + } + } + } + return clone; + } + ValueDelta.Patch = Patch; +})(ValueDelta = exports.ValueDelta || (exports.ValueDelta = {})); diff --git a/node_modules/@sinclair/typebox/value/equal.d.ts b/node_modules/@sinclair/typebox/value/equal.d.ts new file mode 100644 index 0000000..785c2b8 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/equal.d.ts @@ -0,0 +1,3 @@ +export declare namespace ValueEqual { + function Equal(left: T, right: unknown): right is T; +} diff --git a/node_modules/@sinclair/typebox/value/equal.js b/node_modules/@sinclair/typebox/value/equal.js new file mode 100644 index 0000000..ed9773b --- /dev/null +++ b/node_modules/@sinclair/typebox/value/equal.js @@ -0,0 +1,80 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueEqual = void 0; +const is_1 = require("./is"); +var ValueEqual; +(function (ValueEqual) { + function Object(left, right) { + if (!is_1.Is.Object(right)) + return false; + const leftKeys = [...globalThis.Object.keys(left), ...globalThis.Object.getOwnPropertySymbols(left)]; + const rightKeys = [...globalThis.Object.keys(right), ...globalThis.Object.getOwnPropertySymbols(right)]; + if (leftKeys.length !== rightKeys.length) + return false; + return leftKeys.every((key) => Equal(left[key], right[key])); + } + function Date(left, right) { + return is_1.Is.Date(right) && left.getTime() === right.getTime(); + } + function Array(left, right) { + if (!is_1.Is.Array(right) || left.length !== right.length) + return false; + return left.every((value, index) => Equal(value, right[index])); + } + function TypedArray(left, right) { + if (!is_1.Is.TypedArray(right) || left.length !== right.length || globalThis.Object.getPrototypeOf(left).constructor.name !== globalThis.Object.getPrototypeOf(right).constructor.name) + return false; + return left.every((value, index) => Equal(value, right[index])); + } + function Value(left, right) { + return left === right; + } + function Equal(left, right) { + if (is_1.Is.Object(left)) { + return Object(left, right); + } + else if (is_1.Is.Date(left)) { + return Date(left, right); + } + else if (is_1.Is.TypedArray(left)) { + return TypedArray(left, right); + } + else if (is_1.Is.Array(left)) { + return Array(left, right); + } + else if (is_1.Is.Value(left)) { + return Value(left, right); + } + else { + throw new Error('ValueEquals: Unable to compare value'); + } + } + ValueEqual.Equal = Equal; +})(ValueEqual = exports.ValueEqual || (exports.ValueEqual = {})); diff --git a/node_modules/@sinclair/typebox/value/hash.d.ts b/node_modules/@sinclair/typebox/value/hash.d.ts new file mode 100644 index 0000000..4c9116b --- /dev/null +++ b/node_modules/@sinclair/typebox/value/hash.d.ts @@ -0,0 +1,8 @@ +export declare class ValueHashError extends Error { + readonly value: unknown; + constructor(value: unknown); +} +export declare namespace ValueHash { + /** Creates a FNV1A-64 non cryptographic hash of the given value */ + function Create(value: unknown): bigint; +} diff --git a/node_modules/@sinclair/typebox/value/hash.js b/node_modules/@sinclair/typebox/value/hash.js new file mode 100644 index 0000000..9594420 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/hash.js @@ -0,0 +1,208 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/hash + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueHash = exports.ValueHashError = void 0; +class ValueHashError extends Error { + constructor(value) { + super(`Hash: Unable to hash value`); + this.value = value; + } +} +exports.ValueHashError = ValueHashError; +var ValueHash; +(function (ValueHash) { + let ByteMarker; + (function (ByteMarker) { + ByteMarker[ByteMarker["Undefined"] = 0] = "Undefined"; + ByteMarker[ByteMarker["Null"] = 1] = "Null"; + ByteMarker[ByteMarker["Boolean"] = 2] = "Boolean"; + ByteMarker[ByteMarker["Number"] = 3] = "Number"; + ByteMarker[ByteMarker["String"] = 4] = "String"; + ByteMarker[ByteMarker["Object"] = 5] = "Object"; + ByteMarker[ByteMarker["Array"] = 6] = "Array"; + ByteMarker[ByteMarker["Date"] = 7] = "Date"; + ByteMarker[ByteMarker["Uint8Array"] = 8] = "Uint8Array"; + ByteMarker[ByteMarker["Symbol"] = 9] = "Symbol"; + ByteMarker[ByteMarker["BigInt"] = 10] = "BigInt"; + })(ByteMarker || (ByteMarker = {})); + // ---------------------------------------------------- + // State + // ---------------------------------------------------- + let Hash = globalThis.BigInt('14695981039346656037'); + const [Prime, Size] = [globalThis.BigInt('1099511628211'), globalThis.BigInt('2') ** globalThis.BigInt('64')]; + const Bytes = globalThis.Array.from({ length: 256 }).map((_, i) => globalThis.BigInt(i)); + const F64 = new globalThis.Float64Array(1); + const F64In = new globalThis.DataView(F64.buffer); + const F64Out = new globalThis.Uint8Array(F64.buffer); + // ---------------------------------------------------- + // Guards + // ---------------------------------------------------- + function IsDate(value) { + return value instanceof globalThis.Date; + } + function IsUint8Array(value) { + return value instanceof globalThis.Uint8Array; + } + function IsArray(value) { + return globalThis.Array.isArray(value); + } + function IsBoolean(value) { + return typeof value === 'boolean'; + } + function IsNull(value) { + return value === null; + } + function IsNumber(value) { + return typeof value === 'number'; + } + function IsSymbol(value) { + return typeof value === 'symbol'; + } + function IsBigInt(value) { + return typeof value === 'bigint'; + } + function IsObject(value) { + return typeof value === 'object' && value !== null && !IsArray(value) && !IsDate(value) && !IsUint8Array(value); + } + function IsString(value) { + return typeof value === 'string'; + } + function IsUndefined(value) { + return value === undefined; + } + // ---------------------------------------------------- + // Encoding + // ---------------------------------------------------- + function Array(value) { + FNV1A64(ByteMarker.Array); + for (const item of value) { + Visit(item); + } + } + function Boolean(value) { + FNV1A64(ByteMarker.Boolean); + FNV1A64(value ? 1 : 0); + } + function BigInt(value) { + FNV1A64(ByteMarker.BigInt); + F64In.setBigInt64(0, value); + for (const byte of F64Out) { + FNV1A64(byte); + } + } + function Date(value) { + FNV1A64(ByteMarker.Date); + Visit(value.getTime()); + } + function Null(value) { + FNV1A64(ByteMarker.Null); + } + function Number(value) { + FNV1A64(ByteMarker.Number); + F64In.setFloat64(0, value); + for (const byte of F64Out) { + FNV1A64(byte); + } + } + function Object(value) { + FNV1A64(ByteMarker.Object); + for (const key of globalThis.Object.keys(value).sort()) { + Visit(key); + Visit(value[key]); + } + } + function String(value) { + FNV1A64(ByteMarker.String); + for (let i = 0; i < value.length; i++) { + FNV1A64(value.charCodeAt(i)); + } + } + function Symbol(value) { + FNV1A64(ByteMarker.Symbol); + Visit(value.description); + } + function Uint8Array(value) { + FNV1A64(ByteMarker.Uint8Array); + for (let i = 0; i < value.length; i++) { + FNV1A64(value[i]); + } + } + function Undefined(value) { + return FNV1A64(ByteMarker.Undefined); + } + function Visit(value) { + if (IsArray(value)) { + Array(value); + } + else if (IsBoolean(value)) { + Boolean(value); + } + else if (IsBigInt(value)) { + BigInt(value); + } + else if (IsDate(value)) { + Date(value); + } + else if (IsNull(value)) { + Null(value); + } + else if (IsNumber(value)) { + Number(value); + } + else if (IsObject(value)) { + Object(value); + } + else if (IsString(value)) { + String(value); + } + else if (IsSymbol(value)) { + Symbol(value); + } + else if (IsUint8Array(value)) { + Uint8Array(value); + } + else if (IsUndefined(value)) { + Undefined(value); + } + else { + throw new ValueHashError(value); + } + } + function FNV1A64(byte) { + Hash = Hash ^ Bytes[byte]; + Hash = (Hash * Prime) % Size; + } + /** Creates a FNV1A-64 non cryptographic hash of the given value */ + function Create(value) { + Hash = globalThis.BigInt('14695981039346656037'); + Visit(value); + return Hash; + } + ValueHash.Create = Create; +})(ValueHash = exports.ValueHash || (exports.ValueHash = {})); diff --git a/node_modules/@sinclair/typebox/value/index.d.ts b/node_modules/@sinclair/typebox/value/index.d.ts new file mode 100644 index 0000000..4ad0b77 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/index.d.ts @@ -0,0 +1,6 @@ +export { ValueError, ValueErrorIterator, ValueErrorType } from '../errors/index'; +export { ValueHash } from './hash'; +export { Edit, Insert, Update, Delete } from './delta'; +export { Mutable } from './mutate'; +export * from './pointer'; +export * from './value'; diff --git a/node_modules/@sinclair/typebox/value/index.js b/node_modules/@sinclair/typebox/value/index.js new file mode 100644 index 0000000..1f21de4 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/index.js @@ -0,0 +1,56 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Delete = exports.Update = exports.Insert = exports.Edit = exports.ValueHash = exports.ValueErrorType = exports.ValueErrorIterator = void 0; +var index_1 = require("../errors/index"); +Object.defineProperty(exports, "ValueErrorIterator", { enumerable: true, get: function () { return index_1.ValueErrorIterator; } }); +Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } }); +var hash_1 = require("./hash"); +Object.defineProperty(exports, "ValueHash", { enumerable: true, get: function () { return hash_1.ValueHash; } }); +var delta_1 = require("./delta"); +Object.defineProperty(exports, "Edit", { enumerable: true, get: function () { return delta_1.Edit; } }); +Object.defineProperty(exports, "Insert", { enumerable: true, get: function () { return delta_1.Insert; } }); +Object.defineProperty(exports, "Update", { enumerable: true, get: function () { return delta_1.Update; } }); +Object.defineProperty(exports, "Delete", { enumerable: true, get: function () { return delta_1.Delete; } }); +__exportStar(require("./pointer"), exports); +__exportStar(require("./value"), exports); diff --git a/node_modules/@sinclair/typebox/value/is.d.ts b/node_modules/@sinclair/typebox/value/is.d.ts new file mode 100644 index 0000000..b78ba9c --- /dev/null +++ b/node_modules/@sinclair/typebox/value/is.d.ts @@ -0,0 +1,11 @@ +export type ValueType = null | undefined | Function | symbol | bigint | number | boolean | string; +export type ObjectType = Record; +export type TypedArrayType = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array; +export type ArrayType = unknown[]; +export declare namespace Is { + function Object(value: unknown): value is ObjectType; + function Date(value: unknown): value is Date; + function Array(value: unknown): value is ArrayType; + function Value(value: unknown): value is ValueType; + function TypedArray(value: unknown): value is TypedArrayType; +} diff --git a/node_modules/@sinclair/typebox/value/is.js b/node_modules/@sinclair/typebox/value/is.js new file mode 100644 index 0000000..fbe1ed4 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/is.js @@ -0,0 +1,53 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Is = void 0; +var Is; +(function (Is) { + function Object(value) { + return value !== null && typeof value === 'object' && !globalThis.Array.isArray(value) && !ArrayBuffer.isView(value) && !(value instanceof globalThis.Date); + } + Is.Object = Object; + function Date(value) { + return value instanceof globalThis.Date; + } + Is.Date = Date; + function Array(value) { + return globalThis.Array.isArray(value) && !ArrayBuffer.isView(value); + } + Is.Array = Array; + function Value(value) { + return value === null || value === undefined || typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string'; + } + Is.Value = Value; + function TypedArray(value) { + return ArrayBuffer.isView(value); + } + Is.TypedArray = TypedArray; +})(Is = exports.Is || (exports.Is = {})); diff --git a/node_modules/@sinclair/typebox/value/mutate.d.ts b/node_modules/@sinclair/typebox/value/mutate.d.ts new file mode 100644 index 0000000..e45c07e --- /dev/null +++ b/node_modules/@sinclair/typebox/value/mutate.d.ts @@ -0,0 +1,13 @@ +export declare class ValueMutateTypeMismatchError extends Error { + constructor(); +} +export declare class ValueMutateInvalidRootMutationError extends Error { + constructor(); +} +export type Mutable = { + [key: string]: unknown; +} | unknown[]; +export declare namespace ValueMutate { + /** Performs a deep mutable value assignment while retaining internal references. */ + function Mutate(current: Mutable, next: Mutable): void; +} diff --git a/node_modules/@sinclair/typebox/value/mutate.js b/node_modules/@sinclair/typebox/value/mutate.js new file mode 100644 index 0000000..4151596 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/mutate.js @@ -0,0 +1,121 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValueMutate = exports.ValueMutateInvalidRootMutationError = exports.ValueMutateTypeMismatchError = void 0; +const is_1 = require("./is"); +const pointer_1 = require("./pointer"); +const clone_1 = require("./clone"); +class ValueMutateTypeMismatchError extends Error { + constructor() { + super('ValueMutate: Cannot assign due type mismatch of assignable values'); + } +} +exports.ValueMutateTypeMismatchError = ValueMutateTypeMismatchError; +class ValueMutateInvalidRootMutationError extends Error { + constructor() { + super('ValueMutate: Only object and array types can be mutated at the root level'); + } +} +exports.ValueMutateInvalidRootMutationError = ValueMutateInvalidRootMutationError; +var ValueMutate; +(function (ValueMutate) { + function Object(root, path, current, next) { + if (!is_1.Is.Object(current)) { + pointer_1.ValuePointer.Set(root, path, clone_1.ValueClone.Clone(next)); + } + else { + const currentKeys = globalThis.Object.keys(current); + const nextKeys = globalThis.Object.keys(next); + for (const currentKey of currentKeys) { + if (!nextKeys.includes(currentKey)) { + delete current[currentKey]; + } + } + for (const nextKey of nextKeys) { + if (!currentKeys.includes(nextKey)) { + current[nextKey] = null; + } + } + for (const nextKey of nextKeys) { + Visit(root, `${path}/${nextKey}`, current[nextKey], next[nextKey]); + } + } + } + function Array(root, path, current, next) { + if (!is_1.Is.Array(current)) { + pointer_1.ValuePointer.Set(root, path, clone_1.ValueClone.Clone(next)); + } + else { + for (let index = 0; index < next.length; index++) { + Visit(root, `${path}/${index}`, current[index], next[index]); + } + current.splice(next.length); + } + } + function TypedArray(root, path, current, next) { + if (is_1.Is.TypedArray(current) && current.length === next.length) { + for (let i = 0; i < current.length; i++) { + current[i] = next[i]; + } + } + else { + pointer_1.ValuePointer.Set(root, path, clone_1.ValueClone.Clone(next)); + } + } + function Value(root, path, current, next) { + if (current === next) + return; + pointer_1.ValuePointer.Set(root, path, next); + } + function Visit(root, path, current, next) { + if (is_1.Is.Array(next)) { + return Array(root, path, current, next); + } + else if (is_1.Is.TypedArray(next)) { + return TypedArray(root, path, current, next); + } + else if (is_1.Is.Object(next)) { + return Object(root, path, current, next); + } + else if (is_1.Is.Value(next)) { + return Value(root, path, current, next); + } + } + /** Performs a deep mutable value assignment while retaining internal references. */ + function Mutate(current, next) { + if (is_1.Is.TypedArray(current) || is_1.Is.Value(current) || is_1.Is.TypedArray(next) || is_1.Is.Value(next)) { + throw new ValueMutateInvalidRootMutationError(); + } + if ((is_1.Is.Object(current) && is_1.Is.Array(next)) || (is_1.Is.Array(current) && is_1.Is.Object(next))) { + throw new ValueMutateTypeMismatchError(); + } + Visit(current, '', current, next); + } + ValueMutate.Mutate = Mutate; +})(ValueMutate = exports.ValueMutate || (exports.ValueMutate = {})); diff --git a/node_modules/@sinclair/typebox/value/pointer.d.ts b/node_modules/@sinclair/typebox/value/pointer.d.ts new file mode 100644 index 0000000..abae1e1 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/pointer.d.ts @@ -0,0 +1,24 @@ +export declare class ValuePointerRootSetError extends Error { + readonly value: unknown; + readonly path: string; + readonly update: unknown; + constructor(value: unknown, path: string, update: unknown); +} +export declare class ValuePointerRootDeleteError extends Error { + readonly value: unknown; + readonly path: string; + constructor(value: unknown, path: string); +} +/** Provides functionality to update values through RFC6901 string pointers */ +export declare namespace ValuePointer { + /** Formats the given pointer into navigable key components */ + function Format(pointer: string): IterableIterator; + /** Sets the value at the given pointer. If the value at the pointer does not exist it is created */ + function Set(value: any, pointer: string, update: unknown): void; + /** Deletes a value at the given pointer */ + function Delete(value: any, pointer: string): void; + /** Returns true if a value exists at the given pointer */ + function Has(value: any, pointer: string): boolean; + /** Gets the value at the given pointer */ + function Get(value: any, pointer: string): any; +} diff --git a/node_modules/@sinclair/typebox/value/pointer.js b/node_modules/@sinclair/typebox/value/pointer.js new file mode 100644 index 0000000..981be63 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/pointer.js @@ -0,0 +1,142 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValuePointer = exports.ValuePointerRootDeleteError = exports.ValuePointerRootSetError = void 0; +class ValuePointerRootSetError extends Error { + constructor(value, path, update) { + super('ValuePointer: Cannot set root value'); + this.value = value; + this.path = path; + this.update = update; + } +} +exports.ValuePointerRootSetError = ValuePointerRootSetError; +class ValuePointerRootDeleteError extends Error { + constructor(value, path) { + super('ValuePointer: Cannot delete root value'); + this.value = value; + this.path = path; + } +} +exports.ValuePointerRootDeleteError = ValuePointerRootDeleteError; +/** Provides functionality to update values through RFC6901 string pointers */ +var ValuePointer; +(function (ValuePointer) { + function Escape(component) { + return component.indexOf('~') === -1 ? component : component.replace(/~1/g, '/').replace(/~0/g, '~'); + } + /** Formats the given pointer into navigable key components */ + function* Format(pointer) { + if (pointer === '') + return; + let [start, end] = [0, 0]; + for (let i = 0; i < pointer.length; i++) { + const char = pointer.charAt(i); + if (char === '/') { + if (i === 0) { + start = i + 1; + } + else { + end = i; + yield Escape(pointer.slice(start, end)); + start = i + 1; + } + } + else { + end = i; + } + } + yield Escape(pointer.slice(start)); + } + ValuePointer.Format = Format; + /** Sets the value at the given pointer. If the value at the pointer does not exist it is created */ + function Set(value, pointer, update) { + if (pointer === '') + throw new ValuePointerRootSetError(value, pointer, update); + let [owner, next, key] = [null, value, '']; + for (const component of Format(pointer)) { + if (next[component] === undefined) + next[component] = {}; + owner = next; + next = next[component]; + key = component; + } + owner[key] = update; + } + ValuePointer.Set = Set; + /** Deletes a value at the given pointer */ + function Delete(value, pointer) { + if (pointer === '') + throw new ValuePointerRootDeleteError(value, pointer); + let [owner, next, key] = [null, value, '']; + for (const component of Format(pointer)) { + if (next[component] === undefined || next[component] === null) + return; + owner = next; + next = next[component]; + key = component; + } + if (globalThis.Array.isArray(owner)) { + const index = parseInt(key); + owner.splice(index, 1); + } + else { + delete owner[key]; + } + } + ValuePointer.Delete = Delete; + /** Returns true if a value exists at the given pointer */ + function Has(value, pointer) { + if (pointer === '') + return true; + let [owner, next, key] = [null, value, '']; + for (const component of Format(pointer)) { + if (next[component] === undefined) + return false; + owner = next; + next = next[component]; + key = component; + } + return globalThis.Object.getOwnPropertyNames(owner).includes(key); + } + ValuePointer.Has = Has; + /** Gets the value at the given pointer */ + function Get(value, pointer) { + if (pointer === '') + return value; + let current = value; + for (const component of Format(pointer)) { + if (current[component] === undefined) + return undefined; + current = current[component]; + } + return current; + } + ValuePointer.Get = Get; +})(ValuePointer = exports.ValuePointer || (exports.ValuePointer = {})); diff --git a/node_modules/@sinclair/typebox/value/value.d.ts b/node_modules/@sinclair/typebox/value/value.d.ts new file mode 100644 index 0000000..bf8d32f --- /dev/null +++ b/node_modules/@sinclair/typebox/value/value.d.ts @@ -0,0 +1,39 @@ +import * as Types from '../typebox'; +import { ValueErrorIterator } from '../errors/index'; +import { Mutable } from './mutate'; +import { Edit } from './delta'; +/** Provides functions to perform structural updates to JavaScript values */ +export declare namespace Value { + /** Casts a value into a given type. The return value will retain as much information of the original value as possible. Cast will convert string, number, boolean and date values if a reasonable conversion is possible. */ + function Cast(schema: T, references: [...R], value: unknown): Types.Static; + /** Casts a value into a given type. The return value will retain as much information of the original value as possible. Cast will convert string, number, boolean and date values if a reasonable conversion is possible. */ + function Cast(schema: T, value: unknown): Types.Static; + /** Creates a value from the given type */ + function Create(schema: T, references: [...R]): Types.Static; + /** Creates a value from the given type */ + function Create(schema: T): Types.Static; + /** Returns true if the value matches the given type. */ + function Check(schema: T, references: [...R], value: unknown): value is Types.Static; + /** Returns true if the value matches the given type. */ + function Check(schema: T, value: unknown): value is Types.Static; + /** Converts any type mismatched values to their target type if a conversion is possible. */ + function Convert(schema: T, references: [...R], value: unknown): unknown; + /** Converts any type mismatched values to their target type if a conversion is possible. */ + function Convert(schema: T, value: unknown): unknown; + /** Returns a structural clone of the given value */ + function Clone(value: T): T; + /** Returns an iterator for each error in this value. */ + function Errors(schema: T, references: [...R], value: unknown): ValueErrorIterator; + /** Returns an iterator for each error in this value. */ + function Errors(schema: T, value: unknown): ValueErrorIterator; + /** Returns true if left and right values are structurally equal */ + function Equal(left: T, right: unknown): right is T; + /** Returns edits to transform the current value into the next value */ + function Diff(current: unknown, next: unknown): Edit[]; + /** Returns a FNV1A-64 non cryptographic hash of the given value */ + function Hash(value: unknown): bigint; + /** Returns a new value with edits applied to the given value */ + function Patch(current: unknown, edits: Edit[]): T; + /** Performs a deep mutable value assignment while retaining internal references. */ + function Mutate(current: Mutable, next: Mutable): void; +} diff --git a/node_modules/@sinclair/typebox/value/value.js b/node_modules/@sinclair/typebox/value/value.js new file mode 100644 index 0000000..e1ab919 --- /dev/null +++ b/node_modules/@sinclair/typebox/value/value.js @@ -0,0 +1,99 @@ +"use strict"; +/*-------------------------------------------------------------------------- + +@sinclair/typebox/value + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Value = void 0; +const index_1 = require("../errors/index"); +const mutate_1 = require("./mutate"); +const hash_1 = require("./hash"); +const equal_1 = require("./equal"); +const cast_1 = require("./cast"); +const clone_1 = require("./clone"); +const convert_1 = require("./convert"); +const create_1 = require("./create"); +const check_1 = require("./check"); +const delta_1 = require("./delta"); +/** Provides functions to perform structural updates to JavaScript values */ +var Value; +(function (Value) { + function Cast(...args) { + const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]]; + return cast_1.ValueCast.Cast(schema, references, value); + } + Value.Cast = Cast; + function Create(...args) { + const [schema, references] = args.length === 2 ? [args[0], args[1]] : [args[0], []]; + return create_1.ValueCreate.Create(schema, references); + } + Value.Create = Create; + function Check(...args) { + const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]]; + return check_1.ValueCheck.Check(schema, references, value); + } + Value.Check = Check; + function Convert(...args) { + const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]]; + return convert_1.ValueConvert.Convert(schema, references, value); + } + Value.Convert = Convert; + /** Returns a structural clone of the given value */ + function Clone(value) { + return clone_1.ValueClone.Clone(value); + } + Value.Clone = Clone; + function Errors(...args) { + const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]]; + return index_1.ValueErrors.Errors(schema, references, value); + } + Value.Errors = Errors; + /** Returns true if left and right values are structurally equal */ + function Equal(left, right) { + return equal_1.ValueEqual.Equal(left, right); + } + Value.Equal = Equal; + /** Returns edits to transform the current value into the next value */ + function Diff(current, next) { + return delta_1.ValueDelta.Diff(current, next); + } + Value.Diff = Diff; + /** Returns a FNV1A-64 non cryptographic hash of the given value */ + function Hash(value) { + return hash_1.ValueHash.Create(value); + } + Value.Hash = Hash; + /** Returns a new value with edits applied to the given value */ + function Patch(current, edits) { + return delta_1.ValueDelta.Patch(current, edits); + } + Value.Patch = Patch; + /** Performs a deep mutable value assignment while retaining internal references. */ + function Mutate(current, next) { + mutate_1.ValueMutate.Mutate(current, next); + } + Value.Mutate = Mutate; +})(Value = exports.Value || (exports.Value = {})); diff --git a/node_modules/@types/estree/LICENSE b/node_modules/@types/estree/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/node_modules/@types/estree/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/estree/README.md b/node_modules/@types/estree/README.md new file mode 100644 index 0000000..3e3e70f --- /dev/null +++ b/node_modules/@types/estree/README.md @@ -0,0 +1,15 @@ +# Installation +> `npm install --save @types/estree` + +# Summary +This package contains type definitions for estree (https://github.com/estree/estree). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/estree. + +### Additional Details + * Last updated: Wed, 06 May 2026 21:01:00 GMT + * Dependencies: none + +# Credits +These definitions were written by [RReverser](https://github.com/RReverser). diff --git a/node_modules/@types/estree/flow.d.ts b/node_modules/@types/estree/flow.d.ts new file mode 100644 index 0000000..9d001a9 --- /dev/null +++ b/node_modules/@types/estree/flow.d.ts @@ -0,0 +1,167 @@ +declare namespace ESTree { + interface FlowTypeAnnotation extends Node {} + + interface FlowBaseTypeAnnotation extends FlowTypeAnnotation {} + + interface FlowLiteralTypeAnnotation extends FlowTypeAnnotation, Literal {} + + interface FlowDeclaration extends Declaration {} + + interface AnyTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface ArrayTypeAnnotation extends FlowTypeAnnotation { + elementType: FlowTypeAnnotation; + } + + interface BooleanLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface BooleanTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface ClassImplements extends Node { + id: Identifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface ClassProperty { + key: Expression; + value?: Expression | null; + typeAnnotation?: TypeAnnotation | null; + computed: boolean; + static: boolean; + } + + interface DeclareClass extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + body: ObjectTypeAnnotation; + extends: InterfaceExtends[]; + } + + interface DeclareFunction extends FlowDeclaration { + id: Identifier; + } + + interface DeclareModule extends FlowDeclaration { + id: Literal | Identifier; + body: BlockStatement; + } + + interface DeclareVariable extends FlowDeclaration { + id: Identifier; + } + + interface FunctionTypeAnnotation extends FlowTypeAnnotation { + params: FunctionTypeParam[]; + returnType: FlowTypeAnnotation; + rest?: FunctionTypeParam | null; + typeParameters?: TypeParameterDeclaration | null; + } + + interface FunctionTypeParam { + name: Identifier; + typeAnnotation: FlowTypeAnnotation; + optional: boolean; + } + + interface GenericTypeAnnotation extends FlowTypeAnnotation { + id: Identifier | QualifiedTypeIdentifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface InterfaceExtends extends Node { + id: Identifier | QualifiedTypeIdentifier; + typeParameters?: TypeParameterInstantiation | null; + } + + interface InterfaceDeclaration extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + extends: InterfaceExtends[]; + body: ObjectTypeAnnotation; + } + + interface IntersectionTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface MixedTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface NullableTypeAnnotation extends FlowTypeAnnotation { + typeAnnotation: TypeAnnotation; + } + + interface NumberLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface NumberTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface StringLiteralTypeAnnotation extends FlowLiteralTypeAnnotation {} + + interface StringTypeAnnotation extends FlowBaseTypeAnnotation {} + + interface TupleTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface TypeofTypeAnnotation extends FlowTypeAnnotation { + argument: FlowTypeAnnotation; + } + + interface TypeAlias extends FlowDeclaration { + id: Identifier; + typeParameters?: TypeParameterDeclaration | null; + right: FlowTypeAnnotation; + } + + interface TypeAnnotation extends Node { + typeAnnotation: FlowTypeAnnotation; + } + + interface TypeCastExpression extends Expression { + expression: Expression; + typeAnnotation: TypeAnnotation; + } + + interface TypeParameterDeclaration extends Node { + params: Identifier[]; + } + + interface TypeParameterInstantiation extends Node { + params: FlowTypeAnnotation[]; + } + + interface ObjectTypeAnnotation extends FlowTypeAnnotation { + properties: ObjectTypeProperty[]; + indexers: ObjectTypeIndexer[]; + callProperties: ObjectTypeCallProperty[]; + } + + interface ObjectTypeCallProperty extends Node { + value: FunctionTypeAnnotation; + static: boolean; + } + + interface ObjectTypeIndexer extends Node { + id: Identifier; + key: FlowTypeAnnotation; + value: FlowTypeAnnotation; + static: boolean; + } + + interface ObjectTypeProperty extends Node { + key: Expression; + value: FlowTypeAnnotation; + optional: boolean; + static: boolean; + } + + interface QualifiedTypeIdentifier extends Node { + qualification: Identifier | QualifiedTypeIdentifier; + id: Identifier; + } + + interface UnionTypeAnnotation extends FlowTypeAnnotation { + types: FlowTypeAnnotation[]; + } + + interface VoidTypeAnnotation extends FlowBaseTypeAnnotation {} +} diff --git a/node_modules/@types/estree/index.d.ts b/node_modules/@types/estree/index.d.ts new file mode 100644 index 0000000..7d4ab36 --- /dev/null +++ b/node_modules/@types/estree/index.d.ts @@ -0,0 +1,694 @@ +// This definition file follows a somewhat unusual format. ESTree allows +// runtime type checks based on the `type` parameter. In order to explain this +// to typescript we want to use discriminated union types: +// https://github.com/Microsoft/TypeScript/pull/9163 +// +// For ESTree this is a bit tricky because the high level interfaces like +// Node or Function are pulling double duty. We want to pass common fields down +// to the interfaces that extend them (like Identifier or +// ArrowFunctionExpression), but you can't extend a type union or enforce +// common fields on them. So we've split the high level interfaces into two +// types, a base type which passes down inherited fields, and a type union of +// all types which extend the base type. Only the type union is exported, and +// the union is how other types refer to the collection of inheriting types. +// +// This makes the definitions file here somewhat more difficult to maintain, +// but it has the notable advantage of making ESTree much easier to use as +// an end user. + +export interface BaseNodeWithoutComments { + // Every leaf interface that extends BaseNode must specify a type property. + // The type property should be a string literal. For example, Identifier + // has: `type: "Identifier"` + type: string; + loc?: SourceLocation | null | undefined; + range?: [number, number] | undefined; +} + +export interface BaseNode extends BaseNodeWithoutComments { + leadingComments?: Comment[] | undefined; + trailingComments?: Comment[] | undefined; +} + +export interface NodeMap { + AssignmentProperty: AssignmentProperty; + CatchClause: CatchClause; + Class: Class; + ClassBody: ClassBody; + Expression: Expression; + Function: Function; + Identifier: Identifier; + Literal: Literal; + MethodDefinition: MethodDefinition; + ModuleDeclaration: ModuleDeclaration; + ModuleSpecifier: ModuleSpecifier; + Pattern: Pattern; + PrivateIdentifier: PrivateIdentifier; + Program: Program; + Property: Property; + PropertyDefinition: PropertyDefinition; + SpreadElement: SpreadElement; + Statement: Statement; + Super: Super; + SwitchCase: SwitchCase; + TemplateElement: TemplateElement; + VariableDeclarator: VariableDeclarator; +} + +export type Node = NodeMap[keyof NodeMap]; + +export interface Comment extends BaseNodeWithoutComments { + type: "Line" | "Block"; + value: string; +} + +export interface SourceLocation { + source?: string | null | undefined; + start: Position; + end: Position; +} + +export interface Position { + /** >= 1 */ + line: number; + /** >= 0 */ + column: number; +} + +export interface Program extends BaseNode { + type: "Program"; + sourceType: "script" | "module"; + body: Array; + comments?: Comment[] | undefined; +} + +export interface Directive extends BaseNode { + type: "ExpressionStatement"; + expression: Literal; + directive: string; +} + +export interface BaseFunction extends BaseNode { + params: Pattern[]; + generator?: boolean | undefined; + async?: boolean | undefined; + // The body is either BlockStatement or Expression because arrow functions + // can have a body that's either. FunctionDeclarations and + // FunctionExpressions have only BlockStatement bodies. + body: BlockStatement | Expression; +} + +export type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; + +export type Statement = + | ExpressionStatement + | BlockStatement + | StaticBlock + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement + | Declaration; + +export interface BaseStatement extends BaseNode {} + +export interface EmptyStatement extends BaseStatement { + type: "EmptyStatement"; +} + +export interface BlockStatement extends BaseStatement { + type: "BlockStatement"; + body: Statement[]; + innerComments?: Comment[] | undefined; +} + +export interface StaticBlock extends Omit { + type: "StaticBlock"; +} + +export interface ExpressionStatement extends BaseStatement { + type: "ExpressionStatement"; + expression: Expression; +} + +export interface IfStatement extends BaseStatement { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate?: Statement | null | undefined; +} + +export interface LabeledStatement extends BaseStatement { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +} + +export interface BreakStatement extends BaseStatement { + type: "BreakStatement"; + label?: Identifier | null | undefined; +} + +export interface ContinueStatement extends BaseStatement { + type: "ContinueStatement"; + label?: Identifier | null | undefined; +} + +export interface WithStatement extends BaseStatement { + type: "WithStatement"; + object: Expression; + body: Statement; +} + +export interface SwitchStatement extends BaseStatement { + type: "SwitchStatement"; + discriminant: Expression; + cases: SwitchCase[]; +} + +export interface ReturnStatement extends BaseStatement { + type: "ReturnStatement"; + argument?: Expression | null | undefined; +} + +export interface ThrowStatement extends BaseStatement { + type: "ThrowStatement"; + argument: Expression; +} + +export interface TryStatement extends BaseStatement { + type: "TryStatement"; + block: BlockStatement; + handler?: CatchClause | null | undefined; + finalizer?: BlockStatement | null | undefined; +} + +export interface WhileStatement extends BaseStatement { + type: "WhileStatement"; + test: Expression; + body: Statement; +} + +export interface DoWhileStatement extends BaseStatement { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +} + +export interface ForStatement extends BaseStatement { + type: "ForStatement"; + init?: VariableDeclaration | Expression | null | undefined; + test?: Expression | null | undefined; + update?: Expression | null | undefined; + body: Statement; +} + +export interface BaseForXStatement extends BaseStatement { + left: VariableDeclaration | Pattern; + right: Expression; + body: Statement; +} + +export interface ForInStatement extends BaseForXStatement { + type: "ForInStatement"; +} + +export interface DebuggerStatement extends BaseStatement { + type: "DebuggerStatement"; +} + +export type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration; + +export interface BaseDeclaration extends BaseStatement {} + +export interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration { + type: "FunctionDeclaration"; + /** It is null when a function declaration is a part of the `export default function` statement */ + id: Identifier | null; + body: BlockStatement; +} + +export interface FunctionDeclaration extends MaybeNamedFunctionDeclaration { + id: Identifier; +} + +export interface VariableDeclaration extends BaseDeclaration { + type: "VariableDeclaration"; + declarations: VariableDeclarator[]; + kind: "var" | "let" | "const" | "using" | "await using"; +} + +export interface VariableDeclarator extends BaseNode { + type: "VariableDeclarator"; + id: Pattern; + init?: Expression | null | undefined; +} + +export interface ExpressionMap { + ArrayExpression: ArrayExpression; + ArrowFunctionExpression: ArrowFunctionExpression; + AssignmentExpression: AssignmentExpression; + AwaitExpression: AwaitExpression; + BinaryExpression: BinaryExpression; + CallExpression: CallExpression; + ChainExpression: ChainExpression; + ClassExpression: ClassExpression; + ConditionalExpression: ConditionalExpression; + FunctionExpression: FunctionExpression; + Identifier: Identifier; + ImportExpression: ImportExpression; + Literal: Literal; + LogicalExpression: LogicalExpression; + MemberExpression: MemberExpression; + MetaProperty: MetaProperty; + NewExpression: NewExpression; + ObjectExpression: ObjectExpression; + SequenceExpression: SequenceExpression; + TaggedTemplateExpression: TaggedTemplateExpression; + TemplateLiteral: TemplateLiteral; + ThisExpression: ThisExpression; + UnaryExpression: UnaryExpression; + UpdateExpression: UpdateExpression; + YieldExpression: YieldExpression; +} + +export type Expression = ExpressionMap[keyof ExpressionMap]; + +export interface BaseExpression extends BaseNode {} + +export type ChainElement = SimpleCallExpression | MemberExpression; + +export interface ChainExpression extends BaseExpression { + type: "ChainExpression"; + expression: ChainElement; +} + +export interface ThisExpression extends BaseExpression { + type: "ThisExpression"; +} + +export interface ArrayExpression extends BaseExpression { + type: "ArrayExpression"; + elements: Array; +} + +export interface ObjectExpression extends BaseExpression { + type: "ObjectExpression"; + properties: Array; +} + +export interface PrivateIdentifier extends BaseNode { + type: "PrivateIdentifier"; + name: string; +} + +export interface Property extends BaseNode { + type: "Property"; + key: Expression; + value: Expression | Pattern; // Could be an AssignmentProperty + kind: "init" | "get" | "set"; + method: boolean; + shorthand: boolean; + computed: boolean; +} + +export interface PropertyDefinition extends BaseNode { + type: "PropertyDefinition"; + key: Expression | PrivateIdentifier; + value?: Expression | null | undefined; + computed: boolean; + static: boolean; +} + +export interface FunctionExpression extends BaseFunction, BaseExpression { + id?: Identifier | null | undefined; + type: "FunctionExpression"; + body: BlockStatement; +} + +export interface SequenceExpression extends BaseExpression { + type: "SequenceExpression"; + expressions: Expression[]; +} + +export interface UnaryExpression extends BaseExpression { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: true; + argument: Expression; +} + +export interface BinaryExpression extends BaseExpression { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression | PrivateIdentifier; + right: Expression; +} + +export interface AssignmentExpression extends BaseExpression { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | MemberExpression; + right: Expression; +} + +export interface UpdateExpression extends BaseExpression { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +} + +export interface LogicalExpression extends BaseExpression { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +} + +export interface ConditionalExpression extends BaseExpression { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +} + +export interface BaseCallExpression extends BaseExpression { + callee: Expression | Super; + arguments: Array; +} +export type CallExpression = SimpleCallExpression | NewExpression; + +export interface SimpleCallExpression extends BaseCallExpression { + type: "CallExpression"; + optional: boolean; +} + +export interface NewExpression extends BaseCallExpression { + type: "NewExpression"; +} + +export interface MemberExpression extends BaseExpression, BasePattern { + type: "MemberExpression"; + object: Expression | Super; + property: Expression | PrivateIdentifier; + computed: boolean; + optional: boolean; +} + +export type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression; + +export interface BasePattern extends BaseNode {} + +export interface SwitchCase extends BaseNode { + type: "SwitchCase"; + test?: Expression | null | undefined; + consequent: Statement[]; +} + +export interface CatchClause extends BaseNode { + type: "CatchClause"; + param: Pattern | null; + body: BlockStatement; +} + +export interface Identifier extends BaseNode, BaseExpression, BasePattern { + type: "Identifier"; + name: string; +} + +export type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral; + +export interface SimpleLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value: string | boolean | number | null; + raw?: string | undefined; +} + +export interface RegExpLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: RegExp | null | undefined; + regex: { + pattern: string; + flags: string; + }; + raw?: string | undefined; +} + +export interface BigIntLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: bigint | null | undefined; + bigint: string; + raw?: string | undefined; +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +export type BinaryOperator = + | "==" + | "!=" + | "===" + | "!==" + | "<" + | "<=" + | ">" + | ">=" + | "<<" + | ">>" + | ">>>" + | "+" + | "-" + | "*" + | "/" + | "%" + | "**" + | "|" + | "^" + | "&" + | "in" + | "instanceof"; + +export type LogicalOperator = "||" | "&&" | "??"; + +export type AssignmentOperator = + | "=" + | "+=" + | "-=" + | "*=" + | "/=" + | "%=" + | "**=" + | "<<=" + | ">>=" + | ">>>=" + | "|=" + | "^=" + | "&=" + | "||=" + | "&&=" + | "??="; + +export type UpdateOperator = "++" | "--"; + +export interface ForOfStatement extends BaseForXStatement { + type: "ForOfStatement"; + await: boolean; +} + +export interface Super extends BaseNode { + type: "Super"; +} + +export interface SpreadElement extends BaseNode { + type: "SpreadElement"; + argument: Expression; +} + +export interface ArrowFunctionExpression extends BaseExpression, BaseFunction { + type: "ArrowFunctionExpression"; + expression: boolean; + body: BlockStatement | Expression; +} + +export interface YieldExpression extends BaseExpression { + type: "YieldExpression"; + argument?: Expression | null | undefined; + delegate: boolean; +} + +export interface TemplateLiteral extends BaseExpression { + type: "TemplateLiteral"; + quasis: TemplateElement[]; + expressions: Expression[]; +} + +export interface TaggedTemplateExpression extends BaseExpression { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends BaseNode { + type: "TemplateElement"; + tail: boolean; + value: { + /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */ + cooked?: string | null | undefined; + raw: string; + }; +} + +export interface AssignmentProperty extends Property { + value: Pattern; + kind: "init"; + method: boolean; // false +} + +export interface ObjectPattern extends BasePattern { + type: "ObjectPattern"; + properties: Array; +} + +export interface ArrayPattern extends BasePattern { + type: "ArrayPattern"; + elements: Array; +} + +export interface RestElement extends BasePattern { + type: "RestElement"; + argument: Pattern; +} + +export interface AssignmentPattern extends BasePattern { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +} + +export type Class = ClassDeclaration | ClassExpression; +export interface BaseClass extends BaseNode { + superClass?: Expression | null | undefined; + body: ClassBody; +} + +export interface ClassBody extends BaseNode { + type: "ClassBody"; + body: Array; +} + +export interface MethodDefinition extends BaseNode { + type: "MethodDefinition"; + key: Expression | PrivateIdentifier; + value: FunctionExpression; + kind: "constructor" | "method" | "get" | "set"; + computed: boolean; + static: boolean; +} + +export interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration { + type: "ClassDeclaration"; + /** It is null when a class declaration is a part of the `export default class` statement */ + id: Identifier | null; +} + +export interface ClassDeclaration extends MaybeNamedClassDeclaration { + id: Identifier; +} + +export interface ClassExpression extends BaseClass, BaseExpression { + type: "ClassExpression"; + id?: Identifier | null | undefined; +} + +export interface MetaProperty extends BaseExpression { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +} + +export type ModuleDeclaration = + | ImportDeclaration + | ExportNamedDeclaration + | ExportDefaultDeclaration + | ExportAllDeclaration; +export interface BaseModuleDeclaration extends BaseNode {} + +export type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier; +export interface BaseModuleSpecifier extends BaseNode { + local: Identifier; +} + +export interface ImportDeclaration extends BaseModuleDeclaration { + type: "ImportDeclaration"; + specifiers: Array; + attributes: ImportAttribute[]; + source: Literal; +} + +export interface ImportSpecifier extends BaseModuleSpecifier { + type: "ImportSpecifier"; + imported: Identifier | Literal; +} + +export interface ImportAttribute extends BaseNode { + type: "ImportAttribute"; + key: Identifier | Literal; + value: Literal; +} + +export interface ImportExpression extends BaseExpression { + type: "ImportExpression"; + source: Expression; + options?: Expression | null | undefined; +} + +export interface ImportDefaultSpecifier extends BaseModuleSpecifier { + type: "ImportDefaultSpecifier"; +} + +export interface ImportNamespaceSpecifier extends BaseModuleSpecifier { + type: "ImportNamespaceSpecifier"; +} + +export interface ExportNamedDeclaration extends BaseModuleDeclaration { + type: "ExportNamedDeclaration"; + declaration?: Declaration | null | undefined; + specifiers: ExportSpecifier[]; + attributes: ImportAttribute[]; + source?: Literal | null | undefined; +} + +export interface ExportSpecifier extends Omit { + type: "ExportSpecifier"; + local: Identifier | Literal; + exported: Identifier | Literal; +} + +export interface ExportDefaultDeclaration extends BaseModuleDeclaration { + type: "ExportDefaultDeclaration"; + declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression; +} + +export interface ExportAllDeclaration extends BaseModuleDeclaration { + type: "ExportAllDeclaration"; + exported: Identifier | Literal | null; + attributes: ImportAttribute[]; + source: Literal; +} + +export interface AwaitExpression extends BaseExpression { + type: "AwaitExpression"; + argument: Expression; +} diff --git a/node_modules/@types/estree/package.json b/node_modules/@types/estree/package.json new file mode 100644 index 0000000..367a5d9 --- /dev/null +++ b/node_modules/@types/estree/package.json @@ -0,0 +1,27 @@ +{ + "name": "@types/estree", + "version": "1.0.9", + "description": "TypeScript definitions for estree", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/estree", + "license": "MIT", + "contributors": [ + { + "name": "RReverser", + "githubUsername": "RReverser", + "url": "https://github.com/RReverser" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/estree" + }, + "scripts": {}, + "dependencies": {}, + "peerDependencies": {}, + "typesPublisherContentHash": "db16da859cb0bee641414117047a4becba2e9f39d3e14a6745f887c47ef68482", + "typeScriptVersion": "5.3", + "nonNpm": true +} \ No newline at end of file diff --git a/node_modules/@vitest/expect/LICENSE b/node_modules/@vitest/expect/LICENSE new file mode 100644 index 0000000..5ae481f --- /dev/null +++ b/node_modules/@vitest/expect/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/expect/README.md b/node_modules/@vitest/expect/README.md new file mode 100644 index 0000000..da5d16d --- /dev/null +++ b/node_modules/@vitest/expect/README.md @@ -0,0 +1,17 @@ +# @vitest/expect + +Jest's expect matchers as a Chai plugin. + +## Usage + +```js +import * as chai from 'chai' +import { JestAsymmetricMatchers, JestChaiExpect, JestExtend } from '@vitest/expect' + +// allows using expect.extend instead of chai.use to extend plugins +chai.use(JestExtend) +// adds all jest matchers to expect +chai.use(JestChaiExpect) +// adds asymmetric matchers like stringContaining, objectContaining +chai.use(JestAsymmetricMatchers) +``` diff --git a/node_modules/@vitest/expect/dist/chai.d.cts b/node_modules/@vitest/expect/dist/chai.d.cts new file mode 100644 index 0000000..7e23131 --- /dev/null +++ b/node_modules/@vitest/expect/dist/chai.d.cts @@ -0,0 +1,1968 @@ +// Type definitions for chai 4.3 +// Project: http://chaijs.com/ +// Definitions by: Bart van der Schoor +// Andrew Brown +// Olivier Chevet +// Matt Wistrand +// Shaun Luttin +// Satana Charuwichitratana +// Erik Schierboom +// Bogdan Paranytsia +// CXuesong +// Joey Kilpatrick +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +declare namespace Chai { + type Message = string | (() => string); + type ObjectProperty = string | symbol | number; + + interface PathInfo { + parent: object; + name: string; + value?: any; + exists: boolean; + } + + interface ErrorConstructor { + new(...args: any[]): Error; + } + + interface ChaiUtils { + addChainableMethod( + // object to define the method on, e.g. chai.Assertion.prototype + ctx: object, + // method name + name: string, + // method itself; any arguments + method: (...args: any[]) => void, + // called when property is accessed + chainingBehavior?: () => void, + ): void; + overwriteChainableMethod( + ctx: object, + name: string, + method: (...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + addLengthGuard( + fn: Function, + assertionName: string, + isChainable: boolean, + ): void; + addMethod(ctx: object, name: string, method: Function): void; + addProperty(ctx: object, name: string, getter: () => any): void; + overwriteMethod(ctx: object, name: string, method: Function): void; + overwriteProperty(ctx: object, name: string, getter: () => any): void; + compareByInspect(a: object, b: object): -1 | 1; + expectTypes(obj: object, types: string[]): void; + flag(obj: object, key: string, value?: any): any; + getActual(obj: object, args: AssertionArgs): any; + getProperties(obj: object): string[]; + getEnumerableProperties(obj: object): string[]; + getOwnEnumerablePropertySymbols(obj: object): symbol[]; + getOwnEnumerableProperties(obj: object): Array; + getMessage(errorLike: Error | string): string; + getMessage(obj: any, args: AssertionArgs): string; + inspect(obj: any, showHidden?: boolean, depth?: number, colors?: boolean): string; + isProxyEnabled(): boolean; + objDisplay(obj: object): void; + proxify(obj: object, nonChainableMethodName: string): object; + test(obj: object, args: AssertionArgs): boolean; + transferFlags(assertion: Assertion, obj: object, includeAll?: boolean): void; + compatibleInstance(thrown: Error, errorLike: Error | ErrorConstructor): boolean; + compatibleConstructor(thrown: Error, errorLike: Error | ErrorConstructor): boolean; + compatibleMessage(thrown: Error, errMatcher: string | RegExp): boolean; + getConstructorName(constructorFn: Function): string; + getFuncName(constructorFn: Function): string | null; + + // Reexports from pathval: + hasProperty(obj: object | undefined | null, name: ObjectProperty): boolean; + getPathInfo(obj: object, path: string): PathInfo; + getPathValue(obj: object, path: string): object | undefined; + } + + type ChaiPlugin = (chai: ChaiStatic, utils: ChaiUtils) => void; + + interface ChaiStatic { + expect: ExpectStatic; + should(): Should; + /** + * Provides a way to extend the internals of Chai + */ + use(fn: ChaiPlugin): ChaiStatic; + util: ChaiUtils; + assert: AssertStatic; + config: Config; + Assertion: AssertionStatic; + AssertionError: typeof AssertionError; + version: string; + } + + export interface ExpectStatic { + (val: any, message?: string): Assertion; + fail(message?: string): never; + fail(actual: any, expected: any, message?: string, operator?: Operator): never; + } + + export interface AssertStatic extends Assert { + } + + // chai.Assertion.prototype.assert arguments + type AssertionArgs = [ + // 'expression to be tested' + // This parameter is unused and the docs list its type as + // 'Philosophical', which is mentioned nowhere else in the source. Do + // with that what you will! + any, + Message, // message if value fails + Message, // message if negated value fails + any, // expected value + any?, // actual value + boolean?, // showDiff + ]; + + export interface AssertionPrototype { + assert(...args: AssertionArgs): void; + _obj: any; + } + + export interface AssertionStatic extends AssertionPrototype { + prototype: AssertionPrototype; + + new(target: any, message?: string, ssfi?: Function, lockSsfi?: boolean): Assertion; + + // Deprecated properties: + includeStack: boolean; + showDiff: boolean; + + // Partials of functions on ChaiUtils: + addProperty(name: string, getter: (this: AssertionStatic) => any): void; + addMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void; + addChainableMethod( + name: string, + method: (this: AssertionStatic, ...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + overwriteProperty(name: string, getter: (this: AssertionStatic) => any): void; + overwriteMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void; + overwriteChainableMethod( + name: string, + method: (this: AssertionStatic, ...args: any[]) => void, + chainingBehavior?: () => void, + ): void; + } + + export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!=="; + + export type OperatorComparable = boolean | null | number | string | undefined | Date; + + interface ShouldAssertion { + equal(value1: any, value2: any, message?: string): void; + Throw: ShouldThrow; + throw: ShouldThrow; + exist(value: any, message?: string): void; + } + + interface Should extends ShouldAssertion { + not: ShouldAssertion; + fail(message?: string): never; + fail(actual: any, expected: any, message?: string, operator?: Operator): never; + } + + interface ShouldThrow { + (actual: Function, expected?: string | RegExp, message?: string): void; + (actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void; + } + + interface Assertion extends LanguageChains, NumericComparison, TypeComparison { + not: Assertion; + deep: Deep; + ordered: Ordered; + nested: Nested; + own: Own; + any: KeyFilter; + all: KeyFilter; + a: Assertion; + an: Assertion; + include: Include; + includes: Include; + contain: Include; + contains: Include; + ok: Assertion; + true: Assertion; + false: Assertion; + null: Assertion; + undefined: Assertion; + NaN: Assertion; + exist: Assertion; + empty: Assertion; + arguments: Assertion; + Arguments: Assertion; + finite: Assertion; + equal: Equal; + equals: Equal; + eq: Equal; + eql: Equal; + eqls: Equal; + property: Property; + ownProperty: Property; + haveOwnProperty: Property; + ownPropertyDescriptor: OwnPropertyDescriptor; + haveOwnPropertyDescriptor: OwnPropertyDescriptor; + length: Length; + lengthOf: Length; + match: Match; + matches: Match; + string(string: string, message?: string): Assertion; + keys: Keys; + key(string: string): Assertion; + throw: Throw; + throws: Throw; + Throw: Throw; + respondTo: RespondTo; + respondsTo: RespondTo; + itself: Assertion; + satisfy: Satisfy; + satisfies: Satisfy; + closeTo: CloseTo; + approximately: CloseTo; + members: Members; + increase: PropertyChange; + increases: PropertyChange; + decrease: PropertyChange; + decreases: PropertyChange; + change: PropertyChange; + changes: PropertyChange; + extensible: Assertion; + sealed: Assertion; + frozen: Assertion; + oneOf: OneOf; + } + + interface LanguageChains { + to: Assertion; + be: Assertion; + been: Assertion; + is: Assertion; + that: Assertion; + which: Assertion; + and: Assertion; + has: Assertion; + have: Assertion; + with: Assertion; + at: Assertion; + of: Assertion; + same: Assertion; + but: Assertion; + does: Assertion; + } + + interface NumericComparison { + above: NumberComparer; + gt: NumberComparer; + greaterThan: NumberComparer; + least: NumberComparer; + gte: NumberComparer; + greaterThanOrEqual: NumberComparer; + below: NumberComparer; + lt: NumberComparer; + lessThan: NumberComparer; + most: NumberComparer; + lte: NumberComparer; + lessThanOrEqual: NumberComparer; + within(start: number, finish: number, message?: string): Assertion; + within(start: Date, finish: Date, message?: string): Assertion; + } + + interface NumberComparer { + (value: number | Date, message?: string): Assertion; + } + + interface TypeComparison { + (type: string, message?: string): Assertion; + instanceof: InstanceOf; + instanceOf: InstanceOf; + } + + interface InstanceOf { + (constructor: any, message?: string): Assertion; + } + + interface CloseTo { + (expected: number, delta: number, message?: string): Assertion; + } + + interface Nested { + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + members: Members; + } + + interface Own { + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + } + + interface Deep extends KeyFilter { + be: Assertion; + equal: Equal; + equals: Equal; + eq: Equal; + include: Include; + includes: Include; + contain: Include; + contains: Include; + property: Property; + ordered: Ordered; + nested: Nested; + oneOf: OneOf; + own: Own; + } + + interface Ordered { + members: Members; + } + + interface KeyFilter { + keys: Keys; + members: Members; + } + + interface Equal { + (value: any, message?: string): Assertion; + } + + interface Property { + (name: string | symbol, value: any, message?: string): Assertion; + (name: string | symbol, message?: string): Assertion; + } + + interface OwnPropertyDescriptor { + (name: string | symbol, descriptor: PropertyDescriptor, message?: string): Assertion; + (name: string | symbol, message?: string): Assertion; + } + + interface Length extends LanguageChains, NumericComparison { + (length: number, message?: string): Assertion; + } + + interface Include { + (value: any, message?: string): Assertion; + keys: Keys; + deep: Deep; + ordered: Ordered; + members: Members; + any: KeyFilter; + all: KeyFilter; + oneOf: OneOf; + } + + interface OneOf { + (list: ReadonlyArray, message?: string): Assertion; + } + + interface Match { + (regexp: RegExp, message?: string): Assertion; + } + + interface Keys { + (...keys: string[]): Assertion; + (keys: ReadonlyArray | Object): Assertion; + } + + interface Throw { + (expected?: string | RegExp, message?: string): Assertion; + (constructor: Error | Function, expected?: string | RegExp, message?: string): Assertion; + } + + interface RespondTo { + (method: string, message?: string): Assertion; + } + + interface Satisfy { + (matcher: Function, message?: string): Assertion; + } + + interface Members { + (set: ReadonlyArray, message?: string): Assertion; + } + + interface PropertyChange { + (object: Object, property?: string, message?: string): DeltaAssertion; + } + + interface DeltaAssertion extends Assertion { + by(delta: number, msg?: string): Assertion; + } + + export interface Assert { + /** + * @param expression Expression to test for truthiness. + * @param message Message to display on error. + */ + (expression: any, message?: string): asserts expression; + + /** + * Throws a failure. + * + * @param message Message to display on error. + * @remarks Node.js assert module-compatible. + */ + fail(message?: string): never; + + /** + * Throws a failure. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + * @param operator Comparison operator, if not strict equality. + * @remarks Node.js assert module-compatible. + */ + fail(actual: T, expected: T, message?: string, operator?: Operator): never; + + /** + * Asserts that object is truthy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + isOk(value: T, message?: string): void; + + /** + * Asserts that object is truthy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + ok(value: T, message?: string): void; + + /** + * Asserts that object is falsy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + isNotOk(value: T, message?: string): void; + + /** + * Asserts that object is falsy. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + notOk(value: T, message?: string): void; + + /** + * Asserts non-strict equality (==) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + equal(actual: T, expected: T, message?: string): void; + + /** + * Asserts non-strict inequality (!=) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts strict equality (===) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + strictEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts strict inequality (!==) of actual and expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notStrictEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts that actual is deeply equal to expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + deepEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts that actual is not deeply equal to expected. + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + notDeepEqual(actual: T, expected: T, message?: string): void; + + /** + * Alias to deepEqual + * + * T Type of the objects. + * @param actual Actual value. + * @param expected Potential expected value. + * @param message Message to display on error. + */ + deepStrictEqual(actual: T, expected: T, message?: string): void; + + /** + * Asserts valueToCheck is strictly greater than (>) valueToBeAbove. + * + * @param valueToCheck Actual value. + * @param valueToBeAbove Minimum Potential expected value. + * @param message Message to display on error. + */ + isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void; + + /** + * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast. + * + * @param valueToCheck Actual value. + * @param valueToBeAtLeast Minimum Potential expected value. + * @param message Message to display on error. + */ + isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void; + + /** + * Asserts valueToCheck is strictly less than (<) valueToBeBelow. + * + * @param valueToCheck Actual value. + * @param valueToBeBelow Minimum Potential expected value. + * @param message Message to display on error. + */ + isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void; + + /** + * Asserts valueToCheck is less than or equal to (<=) valueToBeAtMost. + * + * @param valueToCheck Actual value. + * @param valueToBeAtMost Minimum Potential expected value. + * @param message Message to display on error. + */ + isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void; + + /** + * Asserts that value is true. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isTrue(value: T, message?: string): void; + + /** + * Asserts that value is false. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isFalse(value: T, message?: string): void; + + /** + * Asserts that value is not true. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotTrue(value: T, message?: string): void; + + /** + * Asserts that value is not false. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotFalse(value: T, message?: string): void; + + /** + * Asserts that value is null. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNull(value: T, message?: string): void; + + /** + * Asserts that value is not null. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNull(value: T, message?: string): void; + + /** + * Asserts that value is NaN. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNaN(value: T, message?: string): void; + + /** + * Asserts that value is not NaN. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNaN(value: T, message?: string): void; + + /** + * Asserts that the target is neither null nor undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + exists(value: T, message?: string): void; + + /** + * Asserts that the target is either null or undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + notExists(value: T, message?: string): void; + + /** + * Asserts that value is undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isUndefined(value: T, message?: string): void; + + /** + * Asserts that value is not undefined. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isDefined(value: T, message?: string): void; + + /** + * Asserts that value is a function. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isFunction(value: T, message?: string): void; + + /** + * Asserts that value is not a function. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotFunction(value: T, message?: string): void; + + /** + * Asserts that value is an object of type 'Object' + * (as revealed by Object.prototype.toString). + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + * @remarks The assertion does not match subclassed objects. + */ + isObject(value: T, message?: string): void; + + /** + * Asserts that value is not an object of type 'Object' + * (as revealed by Object.prototype.toString). + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotObject(value: T, message?: string): void; + + /** + * Asserts that value is an array. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isArray(value: T, message?: string): void; + + /** + * Asserts that value is not an array. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotArray(value: T, message?: string): void; + + /** + * Asserts that value is a string. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isString(value: T, message?: string): void; + + /** + * Asserts that value is not a string. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotString(value: T, message?: string): void; + + /** + * Asserts that value is a number. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNumber(value: T, message?: string): void; + + /** + * Asserts that value is not a number. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotNumber(value: T, message?: string): void; + + /** + * Asserts that value is a finite number. + * Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * T Type of value + * @param value Actual value + * @param message Message to display on error. + */ + isFinite(value: T, message?: string): void; + + /** + * Asserts that value is a boolean. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isBoolean(value: T, message?: string): void; + + /** + * Asserts that value is not a boolean. + * + * T Type of value. + * @param value Actual value. + * @param message Message to display on error. + */ + isNotBoolean(value: T, message?: string): void; + + /** + * Asserts that value's type is name, as determined by Object.prototype.toString. + * + * T Type of value. + * @param value Actual value. + * @param name Potential expected type name of value. + * @param message Message to display on error. + */ + typeOf(value: T, name: string, message?: string): void; + + /** + * Asserts that value's type is not name, as determined by Object.prototype.toString. + * + * T Type of value. + * @param value Actual value. + * @param name Potential expected type name of value. + * @param message Message to display on error. + */ + notTypeOf(value: T, name: string, message?: string): void; + + /** + * Asserts that value is an instance of constructor. + * + * T Type of value. + * @param value Actual value. + * @param constructor Potential expected contructor of value. + * @param message Message to display on error. + */ + instanceOf(value: T, constructor: Function, message?: string): void; + + /** + * Asserts that value is not an instance of constructor. + * + * T Type of value. + * @param value Actual value. + * @param constructor Potential expected contructor of value. + * @param message Message to display on error. + */ + notInstanceOf(value: T, type: Function, message?: string): void; + + /** + * Asserts that haystack includes needle. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + */ + include(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + include( + haystack: ReadonlyArray | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of values in haystack. + * @param haystack WeakSet container. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + include(haystack: WeakSet, needle: T, message?: string): void; + + /** + * Asserts that haystack includes needle. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + include(haystack: T, needle: Partial, message?: string): void; + + /** + * Asserts that haystack does not includes needle. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + */ + notInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack does not includes needle. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notInclude( + haystack: ReadonlyArray | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack does not includes needle. + * + * T Type of values in haystack. + * @param haystack WeakSet container. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notInclude(haystack: WeakSet, needle: T, message?: string): void; + + /** + * Asserts that haystack does not includes needle. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + notInclude(haystack: T, needle: Partial, message?: string): void; + + /** + * Asserts that haystack includes needle. Deep equality is used. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + * + * @deprecated Does not have any effect on string. Use {@link Assert#include} instead. + */ + deepInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack includes needle. Deep equality is used. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + deepInclude( + haystack: ReadonlyArray | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack does not includes needle. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + deepInclude(haystack: T, needle: T extends WeakSet ? never : Partial, message?: string): void; + + /** + * Asserts that haystack does not includes needle. Deep equality is used. + * + * @param haystack Container string. + * @param needle Potential substring of haystack. + * @param message Message to display on error. + * + * @deprecated Does not have any effect on string. Use {@link Assert#notInclude} instead. + */ + notDeepInclude(haystack: string, needle: string, message?: string): void; + + /** + * Asserts that haystack does not includes needle. Deep equality is used. + * + * T Type of values in haystack. + * @param haystack Container array, set or map. + * @param needle Potential value contained in haystack. + * @param message Message to display on error. + */ + notDeepInclude( + haystack: ReadonlyArray | ReadonlySet | ReadonlyMap, + needle: T, + message?: string, + ): void; + + /** + * Asserts that haystack does not includes needle. Deep equality is used. + * + * T Type of haystack. + * @param haystack Object. + * @param needle Potential subset of the haystack's properties. + * @param message Message to display on error. + */ + notDeepInclude(haystack: T, needle: T extends WeakSet ? never : Partial, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + nestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ does not include ‘needle’. Can be used to assert the absence of a subset of properties in an object. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while checking for deep equality + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + deepNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ does not include ‘needle’. Can be used to assert the absence of a subset of properties in an object while checking for deep equality. + * + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes.Asserts that ‘haystack’ includes ‘needle’. + * Can be used to assert the inclusion of a subset of properties in an object. + * Enables the use of dot- and bracket-notation for referencing nested properties. + * ‘[]’ and ‘.’ in property names can be escaped using double backslashes. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notDeepNestedInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + ownInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties and checking for deep + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + deepOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that ‘haystack’ includes ‘needle’. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties and checking for deep equality. + * + * @param haystack + * @param needle + * @param message Message to display on error. + */ + notDeepOwnInclude(haystack: any, needle: any, message?: string): void; + + /** + * Asserts that value matches the regular expression regexp. + * + * @param value Actual value. + * @param regexp Potential match of value. + * @param message Message to display on error. + */ + match(value: string, regexp: RegExp, message?: string): void; + + /** + * Asserts that value does not match the regular expression regexp. + * + * @param value Actual value. + * @param regexp Potential match of value. + * @param message Message to display on error. + */ + notMatch(expected: any, regexp: RegExp, message?: string): void; + + /** + * Asserts that object has a property named by property. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + property(object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that object has a property named by property. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + notProperty(object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that object has a property named by property, which can be a string + * using dot- and bracket-notation for deep reference. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + deepProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object does not have a property named by property, which can be a + * string using dot- and bracket-notation for deep reference. + * + * T Type of object. + * @param object Container object. + * @param property Potential contained property of object. + * @param message Message to display on error. + */ + notDeepProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + propertyVal(object: T, property: string, /* keyof T */ value: V, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + notPropertyVal(object: T, property: string, /* keyof T */ value: V, message?: string): void; + + /** + * Asserts that object has a property named by property, which can be a string + * using dot- and bracket-notation for deep reference. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + deepPropertyVal(object: T, property: string, value: V, message?: string): void; + + /** + * Asserts that object does not have a property named by property, which can be a + * string using dot- and bracket-notation for deep reference. + * + * T Type of object. + * V Type of value. + * @param object Container object. + * @param property Potential contained property of object. + * @param value Potential expected property value. + * @param message Message to display on error. + */ + notDeepPropertyVal(object: T, property: string, value: V, message?: string): void; + + /** + * Asserts that object has a length property with the expected value. + * + * T Type of object. + * @param object Container object. + * @param length Potential expected length of object. + * @param message Message to display on error. + */ + lengthOf(object: T, length: number, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + throw( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + throws(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + throws( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + Throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + Throw( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Asserts that fn will not throw an error. + * + * @param fn Function that may throw. + * @param errMsgMatcher Expected error message matcher. + * @param ignored Ignored parameter. + * @param message Message to display on error. + */ + doesNotThrow(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void; + + /** + * Asserts that fn will not throw an error. + * + * @param fn Function that may throw. + * @param errorLike Expected error constructor or error instance. + * @param errMsgMatcher Expected error message matcher. + * @param message Message to display on error. + */ + doesNotThrow( + fn: () => void, + errorLike?: ErrorConstructor | Error | null, + errMsgMatcher?: RegExp | string | null, + message?: string, + ): void; + + /** + * Compares two values using operator. + * + * @param val1 Left value during comparison. + * @param operator Comparison operator. + * @param val2 Right value during comparison. + * @param message Message to display on error. + */ + operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void; + + /** + * Asserts that the target is equal to expected, to within a +/- delta range. + * + * @param actual Actual value + * @param expected Potential expected value. + * @param delta Maximum differenced between values. + * @param message Message to display on error. + */ + closeTo(actual: number, expected: number, delta: number, message?: string): void; + + /** + * Asserts that the target is equal to expected, to within a +/- delta range. + * + * @param actual Actual value + * @param expected Potential expected value. + * @param delta Maximum differenced between values. + * @param message Message to display on error. + */ + approximately(act: number, exp: number, delta: number, message?: string): void; + + /** + * Asserts that set1 and set2 have the same members. Order is not take into account. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members using deep equality checking. + * Order is not take into account. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameDeepMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members in the same order. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 don’t have the same members in the same order. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + notSameOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 have the same members in the same order. + * Uses a deep equality check. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + sameDeepOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that set1 and set2 don’t have the same members in the same order. + * Uses a deep equality check. + * + * T Type of set values. + * @param set1 Actual set of values. + * @param set2 Potential expected set of values. + * @param message Message to display on error. + */ + notSameDeepOrderedMembers(set1: T[], set2: T[], message?: string): void; + + /** + * Asserts that subset is included in superset in the same order beginning with the first element in superset. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in the same order beginning with the first element in superset. + * Uses a strict equality check (===). + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + notIncludeOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset in the same order beginning with the first element in superset. + * Uses a deep equality check. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeDeepOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in the same order beginning with the first element in superset. + * Uses a deep equality check. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + notIncludeDeepOrderedMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset. Order is not take into account. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset isn’t included in superset in any order. + * Uses a strict equality check (===). Duplicates are ignored. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential not contained set of values. + * @param message Message to display on error. + */ + notIncludeMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that subset is included in superset using deep equality checking. + * Order is not take into account. + * + * T Type of set values. + * @param superset Actual set of values. + * @param subset Potential contained set of values. + * @param message Message to display on error. + */ + includeDeepMembers(superset: T[], subset: T[], message?: string): void; + + /** + * Asserts that non-object, non-array value inList appears in the flat array list. + * + * T Type of list values. + * @param inList Value expected to be in the list. + * @param list List of values. + * @param message Message to display on error. + */ + oneOf(inList: T, list: T[], message?: string): void; + + /** + * Asserts that a function changes the value of a property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be modified. + * @param message Message to display on error. + */ + changes(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function does not change the value of a property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be modified. + * @param message Message to display on error. + */ + doesNotChange(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function increases an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be increased. + * @param message Message to display on error. + */ + increases(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function does not increase an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be increased. + * @param message Message to display on error. + */ + doesNotIncrease(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function decreases an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected to be decreased. + * @param message Message to display on error. + */ + decreases(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts that a function does not decrease an object property. + * + * T Type of object. + * @param modifier Function to run. + * @param object Container object. + * @param property Property of object expected not to be decreased. + * @param message Message to display on error. + */ + doesNotDecrease(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void; + + /** + * Asserts if value is not a false value, and throws if it is a true value. + * + * T Type of object. + * @param object Actual value. + * @param message Message to display on error. + * @remarks This is added to allow for chai to be a drop-in replacement for + * Node’s assert class. + */ + ifError(object: T, message?: string): void; + + /** + * Asserts that object is extensible (can have new properties added to it). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isExtensible(object: T, message?: string): void; + + /** + * Asserts that object is extensible (can have new properties added to it). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + extensible(object: T, message?: string): void; + + /** + * Asserts that object is not extensible. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotExtensible(object: T, message?: string): void; + + /** + * Asserts that object is not extensible. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notExtensible(object: T, message?: string): void; + + /** + * Asserts that object is sealed (can have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isSealed(object: T, message?: string): void; + + /** + * Asserts that object is sealed (can have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + sealed(object: T, message?: string): void; + + /** + * Asserts that object is not sealed. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotSealed(object: T, message?: string): void; + + /** + * Asserts that object is not sealed. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notSealed(object: T, message?: string): void; + + /** + * Asserts that object is frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isFrozen(object: T, message?: string): void; + + /** + * Asserts that object is frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + frozen(object: T, message?: string): void; + + /** + * Asserts that object is not frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isNotFrozen(object: T, message?: string): void; + + /** + * Asserts that object is not frozen (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + notFrozen(object: T, message?: string): void; + + /** + * Asserts that the target does not contain any values. For arrays and + * strings, it checks the length property. For Map and Set instances, it + * checks the size property. For non-function objects, it gets the count + * of own enumerable string keys. + * + * T Type of object + * @param object Actual value. + * @param message Message to display on error. + */ + isEmpty(object: T, message?: string): void; + + /** + * Asserts that the target contains values. For arrays and strings, it checks + * the length property. For Map and Set instances, it checks the size property. + * For non-function objects, it gets the count of own enumerable string keys. + * + * T Type of object. + * @param object Object to test. + * @param message Message to display on error. + */ + isNotEmpty(object: T, message?: string): void; + + /** + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAnyKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAllKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + containsAllKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAnyKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAllKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAnyDeepKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + hasAllDeepKeys(object: T, keys: Array | { [key: string]: any }, message?: string): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + containsAllDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAnyDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * T Type of object. + * @param object Object to test. + * @param keys Keys to check + * @param message Message to display on error. + */ + doesNotHaveAllDeepKeys( + object: T, + keys: Array | { [key: string]: any }, + message?: string, + ): void; + + /** + * Asserts that object has a direct or inherited property named by property, + * which can be a string using dot- and bracket-notation for nested reference. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param message Message to display on error. + */ + nestedProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object does not have a property named by property, + * which can be a string using dot- and bracket-notation for nested reference. + * The property cannot exist on the object nor anywhere in its prototype chain. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param message Message to display on error. + */ + notNestedProperty(object: T, property: string, message?: string): void; + + /** + * Asserts that object has a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===). + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + nestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object does not have a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===). + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + notNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object has a property named by property with a value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a deep equality check. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + deepNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + + /** + * Asserts that object does not have a property named by property with value given by value. + * property can use dot- and bracket-notation for nested reference. Uses a deep equality check. + * + * T Type of object. + * @param object Object to test. + * @param property Property to test. + * @param value Value to test. + * @param message Message to display on error. + */ + notDeepNestedPropertyVal(object: T, property: string, value: any, message?: string): void; + } + + export interface Config { + /** + * Default: false + */ + includeStack: boolean; + + /** + * Default: true + */ + showDiff: boolean; + + /** + * Default: 40 + */ + truncateThreshold: number; + + /** + * Default: true + */ + useProxy: boolean; + + /** + * Default: ['then', 'catch', 'inspect', 'toJSON'] + */ + proxyExcludedKeys: string[]; + } + + export class AssertionError { + constructor(message: string, _props?: any, ssf?: Function); + name: string; + message: string; + showDiff: boolean; + stack: string; + } +} + +declare const chai: Chai.ChaiStatic; + +declare module "chai" { + export = chai; +} + +// interface Object { +// should: Chai.Assertion; +// } diff --git a/node_modules/@vitest/expect/dist/index.d.ts b/node_modules/@vitest/expect/dist/index.d.ts new file mode 100644 index 0000000..b58db33 --- /dev/null +++ b/node_modules/@vitest/expect/dist/index.d.ts @@ -0,0 +1,258 @@ +import * as _vitest_utils from '@vitest/utils'; +import { stringify, Constructable } from '@vitest/utils'; +export { setupColors } from '@vitest/utils'; +import { diff } from '@vitest/utils/diff'; +export { DiffOptions } from '@vitest/utils/diff'; + +type Formatter = (input: string | number | null | undefined) => string; + +declare function getMatcherUtils(): { + EXPECTED_COLOR: _vitest_utils.ColorMethod; + RECEIVED_COLOR: _vitest_utils.ColorMethod; + INVERTED_COLOR: _vitest_utils.ColorMethod; + BOLD_WEIGHT: _vitest_utils.ColorMethod; + DIM_COLOR: _vitest_utils.ColorMethod; + matcherHint: (matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions) => string; + printReceived: (object: unknown) => string; + printExpected: (value: unknown) => string; +}; +declare function addCustomEqualityTesters(newTesters: Array): void; + +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +type ChaiPlugin = Chai.ChaiPlugin; +type Tester = (this: TesterContext, a: any, b: any, customTesters: Array) => boolean | undefined; +interface TesterContext { + equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean; +} + +interface MatcherHintOptions { + comment?: string; + expectedColor?: Formatter; + isDirectExpectCall?: boolean; + isNot?: boolean; + promise?: string; + receivedColor?: Formatter; + secondArgument?: string; + secondArgumentColor?: Formatter; +} +interface MatcherState { + customTesters: Array; + assertionCalls: number; + currentTestName?: string; + dontThrow?: () => void; + error?: Error; + equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean; + expand?: boolean; + expectedAssertionsNumber?: number | null; + expectedAssertionsNumberErrorGen?: (() => Error) | null; + isExpectingAssertions?: boolean; + isExpectingAssertionsError?: Error | null; + isNot: boolean; + promise: string; + suppressedErrors: Array; + testPath?: string; + utils: ReturnType & { + diff: typeof diff; + stringify: typeof stringify; + iterableEquality: Tester; + subsetEquality: Tester; + }; + soft?: boolean; +} +interface SyncExpectationResult { + pass: boolean; + message: () => string; + actual?: any; + expected?: any; +} +type AsyncExpectationResult = Promise; +type ExpectationResult = SyncExpectationResult | AsyncExpectationResult; +interface RawMatcherFn { + (this: T, received: any, expected: any, options?: any): ExpectationResult; +} +type MatchersObject = Record>; +interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining { + (actual: T, message?: string): Assertion; + unreachable: (message?: string) => never; + soft: (actual: T, message?: string) => Assertion; + extend: (expects: MatchersObject) => void; + addEqualityTesters: (testers: Array) => void; + assertions: (expected: number) => void; + hasAssertions: () => void; + anything: () => any; + any: (constructor: unknown) => any; + getState: () => MatcherState; + setState: (state: Partial) => void; + not: AsymmetricMatchersContaining; +} +interface AsymmetricMatchersContaining { + stringContaining: (expected: string) => any; + objectContaining: (expected: T) => any; + arrayContaining: (expected: Array) => any; + stringMatching: (expected: string | RegExp) => any; + closeTo: (expected: number, precision?: number) => any; +} +interface JestAssertion extends jest.Matchers { + toEqual: (expected: E) => void; + toStrictEqual: (expected: E) => void; + toBe: (expected: E) => void; + toMatch: (expected: string | RegExp) => void; + toMatchObject: (expected: E) => void; + toContain: (item: E) => void; + toContainEqual: (item: E) => void; + toBeTruthy: () => void; + toBeFalsy: () => void; + toBeGreaterThan: (num: number | bigint) => void; + toBeGreaterThanOrEqual: (num: number | bigint) => void; + toBeLessThan: (num: number | bigint) => void; + toBeLessThanOrEqual: (num: number | bigint) => void; + toBeNaN: () => void; + toBeUndefined: () => void; + toBeNull: () => void; + toBeDefined: () => void; + toBeInstanceOf: (expected: E) => void; + toBeCalledTimes: (times: number) => void; + toHaveLength: (length: number) => void; + toHaveProperty: (property: string | (string | number)[], value?: E) => void; + toBeCloseTo: (number: number, numDigits?: number) => void; + toHaveBeenCalledTimes: (times: number) => void; + toHaveBeenCalled: () => void; + toBeCalled: () => void; + toHaveBeenCalledWith: (...args: E) => void; + toBeCalledWith: (...args: E) => void; + toHaveBeenNthCalledWith: (n: number, ...args: E) => void; + nthCalledWith: (nthCall: number, ...args: E) => void; + toHaveBeenLastCalledWith: (...args: E) => void; + lastCalledWith: (...args: E) => void; + toThrow: (expected?: string | Constructable | RegExp | Error) => void; + toThrowError: (expected?: string | Constructable | RegExp | Error) => void; + toReturn: () => void; + toHaveReturned: () => void; + toReturnTimes: (times: number) => void; + toHaveReturnedTimes: (times: number) => void; + toReturnWith: (value: E) => void; + toHaveReturnedWith: (value: E) => void; + toHaveLastReturnedWith: (value: E) => void; + lastReturnedWith: (value: E) => void; + toHaveNthReturnedWith: (nthCall: number, value: E) => void; + nthReturnedWith: (nthCall: number, value: E) => void; +} +type VitestAssertion = { + [K in keyof A]: A[K] extends Chai.Assertion ? Assertion : A[K] extends (...args: any[]) => any ? A[K] : VitestAssertion; +} & ((type: string, message?: string) => Assertion); +type Promisify = { + [K in keyof O]: O[K] extends (...args: infer A) => infer R ? O extends R ? Promisify : (...args: A) => Promise : O[K]; +}; +interface Assertion extends VitestAssertion, JestAssertion { + toBeTypeOf: (expected: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => void; + toHaveBeenCalledOnce: () => void; + toSatisfy: (matcher: (value: E) => boolean, message?: string) => void; + resolves: Promisify>; + rejects: Promisify>; +} +declare global { + namespace jest { + interface Matchers { + } + } +} + +interface AsymmetricMatcherInterface { + asymmetricMatch: (other: unknown) => boolean; + toString: () => string; + getExpectedType?: () => string; + toAsymmetricMatcher?: () => string; +} +declare abstract class AsymmetricMatcher implements AsymmetricMatcherInterface { + protected sample: T; + protected inverse: boolean; + $$typeof: symbol; + constructor(sample: T, inverse?: boolean); + protected getMatcherContext(expect?: Chai.ExpectStatic): State; + abstract asymmetricMatch(other: unknown): boolean; + abstract toString(): string; + getExpectedType?(): string; + toAsymmetricMatcher?(): string; +} +declare class StringContaining extends AsymmetricMatcher { + constructor(sample: string, inverse?: boolean); + asymmetricMatch(other: string): boolean; + toString(): string; + getExpectedType(): string; +} +declare class Anything extends AsymmetricMatcher { + asymmetricMatch(other: unknown): boolean; + toString(): string; + toAsymmetricMatcher(): string; +} +declare class ObjectContaining extends AsymmetricMatcher> { + constructor(sample: Record, inverse?: boolean); + getPrototype(obj: object): any; + hasProperty(obj: object | null, property: string): boolean; + asymmetricMatch(other: any): boolean; + toString(): string; + getExpectedType(): string; +} +declare class ArrayContaining extends AsymmetricMatcher> { + constructor(sample: Array, inverse?: boolean); + asymmetricMatch(other: Array): boolean; + toString(): string; + getExpectedType(): string; +} +declare class Any extends AsymmetricMatcher { + constructor(sample: unknown); + fnNameFor(func: Function): string; + asymmetricMatch(other: unknown): boolean; + toString(): string; + getExpectedType(): string; + toAsymmetricMatcher(): string; +} +declare class StringMatching extends AsymmetricMatcher { + constructor(sample: string | RegExp, inverse?: boolean); + asymmetricMatch(other: string): boolean; + toString(): string; + getExpectedType(): string; +} +declare const JestAsymmetricMatchers: ChaiPlugin; + +declare function equals(a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean): boolean; +declare function isAsymmetric(obj: any): boolean; +declare function hasAsymmetric(obj: any, seen?: Set): boolean; +declare function isA(typeName: string, value: unknown): boolean; +declare function fnNameFor(func: Function): string; +declare function hasProperty(obj: object | null, property: string): boolean; +declare function isImmutableUnorderedKeyed(maybeKeyed: any): boolean; +declare function isImmutableUnorderedSet(maybeSet: any): boolean; +declare function iterableEquality(a: any, b: any, customTesters?: Array, aStack?: Array, bStack?: Array): boolean | undefined; +declare function subsetEquality(object: unknown, subset: unknown, customTesters?: Array): boolean | undefined; +declare function typeEquality(a: any, b: any): boolean | undefined; +declare function arrayBufferEquality(a: unknown, b: unknown): boolean | undefined; +declare function sparseArrayEquality(a: unknown, b: unknown, customTesters?: Array): boolean | undefined; +declare function generateToBeMessage(deepEqualityName: string, expected?: string, actual?: string): string; +declare function pluralize(word: string, count: number): string; +declare function getObjectKeys(object: object): Array; +declare function getObjectSubset(object: any, subset: any, customTesters?: Array): { + subset: any; + stripped: number; +}; + +declare const MATCHERS_OBJECT: unique symbol; +declare const JEST_MATCHERS_OBJECT: unique symbol; +declare const GLOBAL_EXPECT: unique symbol; +declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol; + +declare function getState(expect: ExpectStatic): State; +declare function setState(state: Partial, expect: ExpectStatic): void; + +declare const JestChaiExpect: ChaiPlugin; + +declare const JestExtend: ChaiPlugin; + +export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, type Assertion, AsymmetricMatcher, type AsymmetricMatcherInterface, type AsymmetricMatchersContaining, type AsyncExpectationResult, type ChaiPlugin, type ExpectStatic, type ExpectationResult, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, type JestAssertion, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, type MatcherHintOptions, type MatcherState, type MatchersObject, ObjectContaining, type RawMatcherFn, StringContaining, StringMatching, type SyncExpectationResult, type Tester, type TesterContext, addCustomEqualityTesters, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality }; diff --git a/node_modules/@vitest/expect/dist/index.js b/node_modules/@vitest/expect/dist/index.js new file mode 100644 index 0000000..13af149 --- /dev/null +++ b/node_modules/@vitest/expect/dist/index.js @@ -0,0 +1,1639 @@ +import { getType, getColors, stringify, isObject, assertTypes } from '@vitest/utils'; +export { setupColors } from '@vitest/utils'; +import { diff } from '@vitest/utils/diff'; +import { isMockFunction } from '@vitest/spy'; +import { processError } from '@vitest/utils/error'; +import { util } from 'chai'; + +const MATCHERS_OBJECT = Symbol.for("matchers-object"); +const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object"); +const GLOBAL_EXPECT = Symbol.for("expect-global"); +const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object"); + +if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) { + const globalState = /* @__PURE__ */ new WeakMap(); + const matchers = /* @__PURE__ */ Object.create(null); + const customEqualityTesters = []; + const assymetricMatchers = /* @__PURE__ */ Object.create(null); + Object.defineProperty(globalThis, MATCHERS_OBJECT, { + get: () => globalState + }); + Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, { + configurable: true, + get: () => ({ + state: globalState.get(globalThis[GLOBAL_EXPECT]), + matchers, + customEqualityTesters + }) + }); + Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { + get: () => assymetricMatchers + }); +} +function getState(expect) { + return globalThis[MATCHERS_OBJECT].get(expect); +} +function setState(state, expect) { + const map = globalThis[MATCHERS_OBJECT]; + const current = map.get(expect) || {}; + Object.assign(current, state); + map.set(expect, current); +} + +function getMatcherUtils() { + const c = () => getColors(); + const EXPECTED_COLOR = c().green; + const RECEIVED_COLOR = c().red; + const INVERTED_COLOR = c().inverse; + const BOLD_WEIGHT = c().bold; + const DIM_COLOR = c().dim; + function matcherHint(matcherName, received = "received", expected = "expected", options = {}) { + const { + comment = "", + isDirectExpectCall = false, + // seems redundant with received === '' + isNot = false, + promise = "", + secondArgument = "", + expectedColor = EXPECTED_COLOR, + receivedColor = RECEIVED_COLOR, + secondArgumentColor = EXPECTED_COLOR + } = options; + let hint = ""; + let dimString = "expect"; + if (!isDirectExpectCall && received !== "") { + hint += DIM_COLOR(`${dimString}(`) + receivedColor(received); + dimString = ")"; + } + if (promise !== "") { + hint += DIM_COLOR(`${dimString}.`) + promise; + dimString = ""; + } + if (isNot) { + hint += `${DIM_COLOR(`${dimString}.`)}not`; + dimString = ""; + } + if (matcherName.includes(".")) { + dimString += matcherName; + } else { + hint += DIM_COLOR(`${dimString}.`) + matcherName; + dimString = ""; + } + if (expected === "") { + dimString += "()"; + } else { + hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected); + if (secondArgument) + hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument); + dimString = ")"; + } + if (comment !== "") + dimString += ` // ${comment}`; + if (dimString !== "") + hint += DIM_COLOR(dimString); + return hint; + } + const SPACE_SYMBOL = "\xB7"; + const replaceTrailingSpaces = (text) => text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length)); + const printReceived = (object) => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object))); + const printExpected = (value) => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value))); + return { + EXPECTED_COLOR, + RECEIVED_COLOR, + INVERTED_COLOR, + BOLD_WEIGHT, + DIM_COLOR, + matcherHint, + printReceived, + printExpected + }; +} +function addCustomEqualityTesters(newTesters) { + if (!Array.isArray(newTesters)) { + throw new TypeError( + `expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType( + newTesters + )}"` + ); + } + globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push( + ...newTesters + ); +} +function getCustomEqualityTesters() { + return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters; +} + +function equals(a, b, customTesters, strictCheck) { + customTesters = customTesters || []; + return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey); +} +const functionToString = Function.prototype.toString; +function isAsymmetric(obj) { + return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch); +} +function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) { + if (seen.has(obj)) + return false; + seen.add(obj); + if (isAsymmetric(obj)) + return true; + if (Array.isArray(obj)) + return obj.some((i) => hasAsymmetric(i, seen)); + if (obj instanceof Set) + return Array.from(obj).some((i) => hasAsymmetric(i, seen)); + if (isObject(obj)) + return Object.values(obj).some((v) => hasAsymmetric(v, seen)); + return false; +} +function asymmetricMatch(a, b) { + const asymmetricA = isAsymmetric(a); + const asymmetricB = isAsymmetric(b); + if (asymmetricA && asymmetricB) + return void 0; + if (asymmetricA) + return a.asymmetricMatch(b); + if (asymmetricB) + return b.asymmetricMatch(a); +} +function eq(a, b, aStack, bStack, customTesters, hasKey2) { + let result = true; + const asymmetricResult = asymmetricMatch(a, b); + if (asymmetricResult !== void 0) + return asymmetricResult; + const testerContext = { equals }; + for (let i = 0; i < customTesters.length; i++) { + const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters); + if (customTesterResult !== void 0) + return customTesterResult; + } + if (a instanceof Error && b instanceof Error) + return a.message === b.message; + if (typeof URL === "function" && a instanceof URL && b instanceof URL) + return a.href === b.href; + if (Object.is(a, b)) + return true; + if (a === null || b === null) + return a === b; + const className = Object.prototype.toString.call(a); + if (className !== Object.prototype.toString.call(b)) + return false; + switch (className) { + case "[object Boolean]": + case "[object String]": + case "[object Number]": + if (typeof a !== typeof b) { + return false; + } else if (typeof a !== "object" && typeof b !== "object") { + return Object.is(a, b); + } else { + return Object.is(a.valueOf(), b.valueOf()); + } + case "[object Date]": { + const numA = +a; + const numB = +b; + return numA === numB || Number.isNaN(numA) && Number.isNaN(numB); + } + case "[object RegExp]": + return a.source === b.source && a.flags === b.flags; + } + if (typeof a !== "object" || typeof b !== "object") + return false; + if (isDomNode(a) && isDomNode(b)) + return a.isEqualNode(b); + let length = aStack.length; + while (length--) { + if (aStack[length] === a) + return bStack[length] === b; + else if (bStack[length] === b) + return false; + } + aStack.push(a); + bStack.push(b); + if (className === "[object Array]" && a.length !== b.length) + return false; + const aKeys = keys(a, hasKey2); + let key; + let size = aKeys.length; + if (keys(b, hasKey2).length !== size) + return false; + while (size--) { + key = aKeys[size]; + result = hasKey2(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey2); + if (!result) + return false; + } + aStack.pop(); + bStack.pop(); + return result; +} +function keys(obj, hasKey2) { + const keys2 = []; + for (const key in obj) { + if (hasKey2(obj, key)) + keys2.push(key); + } + return keys2.concat( + Object.getOwnPropertySymbols(obj).filter( + (symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable + ) + ); +} +function hasDefinedKey(obj, key) { + return hasKey(obj, key) && obj[key] !== void 0; +} +function hasKey(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} +function isA(typeName, value) { + return Object.prototype.toString.apply(value) === `[object ${typeName}]`; +} +function isDomNode(obj) { + return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function"; +} +function fnNameFor(func) { + if (func.name) + return func.name; + const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/); + return matches ? matches[1] : ""; +} +function getPrototype(obj) { + if (Object.getPrototypeOf) + return Object.getPrototypeOf(obj); + if (obj.constructor.prototype === obj) + return null; + return obj.constructor.prototype; +} +function hasProperty(obj, property) { + if (!obj) + return false; + if (Object.prototype.hasOwnProperty.call(obj, property)) + return true; + return hasProperty(getPrototype(obj), property); +} +const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@"; +const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@"; +const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@"; +function isImmutableUnorderedKeyed(maybeKeyed) { + return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]); +} +function isImmutableUnorderedSet(maybeSet) { + return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]); +} +const IteratorSymbol = Symbol.iterator; +function hasIterator(object) { + return !!(object != null && object[IteratorSymbol]); +} +function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) { + if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) + return void 0; + if (a.constructor !== b.constructor) + return false; + let length = aStack.length; + while (length--) { + if (aStack[length] === a) + return bStack[length] === b; + } + aStack.push(a); + bStack.push(b); + const filteredCustomTesters = [ + ...customTesters.filter((t) => t !== iterableEquality), + iterableEqualityWithStack + ]; + function iterableEqualityWithStack(a2, b2) { + return iterableEquality( + a2, + b2, + [...customTesters], + [...aStack], + [...bStack] + ); + } + if (a.size !== void 0) { + if (a.size !== b.size) { + return false; + } else if (isA("Set", a) || isImmutableUnorderedSet(a)) { + let allFound = true; + for (const aValue of a) { + if (!b.has(aValue)) { + let has = false; + for (const bValue of b) { + const isEqual = equals(aValue, bValue, filteredCustomTesters); + if (isEqual === true) + has = true; + } + if (has === false) { + allFound = false; + break; + } + } + } + aStack.pop(); + bStack.pop(); + return allFound; + } else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) { + let allFound = true; + for (const aEntry of a) { + if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) { + let has = false; + for (const bEntry of b) { + const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters); + let matchedValue = false; + if (matchedKey === true) + matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters); + if (matchedValue === true) + has = true; + } + if (has === false) { + allFound = false; + break; + } + } + } + aStack.pop(); + bStack.pop(); + return allFound; + } + } + const bIterator = b[IteratorSymbol](); + for (const aValue of a) { + const nextB = bIterator.next(); + if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters)) + return false; + } + if (!bIterator.next().done) + return false; + const aEntries = Object.entries(a); + const bEntries = Object.entries(b); + if (!equals(aEntries, bEntries)) + return false; + aStack.pop(); + bStack.pop(); + return true; +} +function hasPropertyInObject(object, key) { + const shouldTerminate = !object || typeof object !== "object" || object === Object.prototype; + if (shouldTerminate) + return false; + return Object.prototype.hasOwnProperty.call(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key); +} +function isObjectWithKeys(a) { + return isObject(a) && !(a instanceof Error) && !Array.isArray(a) && !(a instanceof Date); +} +function subsetEquality(object, subset, customTesters = []) { + const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality); + const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object2, subset2) => { + if (!isObjectWithKeys(subset2)) + return void 0; + return Object.keys(subset2).every((key) => { + if (subset2[key] != null && typeof subset2[key] === "object") { + if (seenReferences.has(subset2[key])) + return equals(object2[key], subset2[key], filteredCustomTesters); + seenReferences.set(subset2[key], true); + } + const result = object2 != null && hasPropertyInObject(object2, key) && equals(object2[key], subset2[key], [ + ...filteredCustomTesters, + subsetEqualityWithContext(seenReferences) + ]); + seenReferences.delete(subset2[key]); + return result; + }); + }; + return subsetEqualityWithContext()(object, subset); +} +function typeEquality(a, b) { + if (a == null || b == null || a.constructor === b.constructor) + return void 0; + return false; +} +function arrayBufferEquality(a, b) { + let dataViewA = a; + let dataViewB = b; + if (!(a instanceof DataView && b instanceof DataView)) { + if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) + return void 0; + try { + dataViewA = new DataView(a); + dataViewB = new DataView(b); + } catch { + return void 0; + } + } + if (dataViewA.byteLength !== dataViewB.byteLength) + return false; + for (let i = 0; i < dataViewA.byteLength; i++) { + if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) + return false; + } + return true; +} +function sparseArrayEquality(a, b, customTesters = []) { + if (!Array.isArray(a) || !Array.isArray(b)) + return void 0; + const aKeys = Object.keys(a); + const bKeys = Object.keys(b); + const filteredCustomTesters = customTesters.filter((t) => t !== sparseArrayEquality); + return equals(a, b, filteredCustomTesters, true) && equals(aKeys, bKeys); +} +function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") { + const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`; + if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) + return `${toBeMessage} + +If it should pass with deep equality, replace "toBe" with "${deepEqualityName}" + +Expected: ${expected} +Received: serializes to the same string +`; + return toBeMessage; +} +function pluralize(word, count) { + return `${count} ${word}${count === 1 ? "" : "s"}`; +} +function getObjectKeys(object) { + return [ + ...Object.keys(object), + ...Object.getOwnPropertySymbols(object).filter( + (s) => { + var _a; + return (_a = Object.getOwnPropertyDescriptor(object, s)) == null ? void 0 : _a.enumerable; + } + ) + ]; +} +function getObjectSubset(object, subset, customTesters = []) { + let stripped = 0; + const getObjectSubsetWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object2, subset2) => { + if (Array.isArray(object2)) { + if (Array.isArray(subset2) && subset2.length === object2.length) { + return subset2.map( + (sub, i) => getObjectSubsetWithContext(seenReferences)(object2[i], sub) + ); + } + } else if (object2 instanceof Date) { + return object2; + } else if (isObject(object2) && isObject(subset2)) { + if (equals(object2, subset2, [ + ...customTesters, + iterableEquality, + subsetEquality + ])) { + return subset2; + } + const trimmed = {}; + seenReferences.set(object2, trimmed); + for (const key of getObjectKeys(object2)) { + if (hasPropertyInObject(subset2, key)) { + trimmed[key] = seenReferences.has(object2[key]) ? seenReferences.get(object2[key]) : getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]); + } else { + if (!seenReferences.has(object2[key])) { + stripped += 1; + if (isObject(object2[key])) + stripped += getObjectKeys(object2[key]).length; + getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]); + } + } + } + if (getObjectKeys(trimmed).length > 0) + return trimmed; + } + return object2; + }; + return { subset: getObjectSubsetWithContext()(object, subset), stripped }; +} + +class AsymmetricMatcher { + constructor(sample, inverse = false) { + this.sample = sample; + this.inverse = inverse; + } + // should have "jest" to be compatible with its ecosystem + $$typeof = Symbol.for("jest.asymmetricMatcher"); + getMatcherContext(expect) { + return { + ...getState(expect || globalThis[GLOBAL_EXPECT]), + equals, + isNot: this.inverse, + customTesters: getCustomEqualityTesters(), + utils: { + ...getMatcherUtils(), + diff, + stringify, + iterableEquality, + subsetEquality + } + }; + } + // implement custom chai/loupe inspect for better AssertionError.message formatting + // https://github.com/chaijs/loupe/blob/9b8a6deabcd50adc056a64fb705896194710c5c6/src/index.ts#L29 + [Symbol.for("chai/inspect")](options) { + const result = stringify(this, options.depth, { min: true }); + if (result.length <= options.truncate) + return result; + return `${this.toString()}{\u2026}`; + } +} +class StringContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + if (!isA("String", sample)) + throw new Error("Expected is not a string"); + super(sample, inverse); + } + asymmetricMatch(other) { + const result = isA("String", other) && other.includes(this.sample); + return this.inverse ? !result : result; + } + toString() { + return `String${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "string"; + } +} +class Anything extends AsymmetricMatcher { + asymmetricMatch(other) { + return other != null; + } + toString() { + return "Anything"; + } + toAsymmetricMatcher() { + return "Anything"; + } +} +class ObjectContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + super(sample, inverse); + } + getPrototype(obj) { + if (Object.getPrototypeOf) + return Object.getPrototypeOf(obj); + if (obj.constructor.prototype === obj) + return null; + return obj.constructor.prototype; + } + hasProperty(obj, property) { + if (!obj) + return false; + if (Object.prototype.hasOwnProperty.call(obj, property)) + return true; + return this.hasProperty(this.getPrototype(obj), property); + } + asymmetricMatch(other) { + if (typeof this.sample !== "object") { + throw new TypeError( + `You must provide an object to ${this.toString()}, not '${typeof this.sample}'.` + ); + } + let result = true; + const matcherContext = this.getMatcherContext(); + for (const property in this.sample) { + if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property], matcherContext.customTesters)) { + result = false; + break; + } + } + return this.inverse ? !result : result; + } + toString() { + return `Object${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "object"; + } +} +class ArrayContaining extends AsymmetricMatcher { + constructor(sample, inverse = false) { + super(sample, inverse); + } + asymmetricMatch(other) { + if (!Array.isArray(this.sample)) { + throw new TypeError( + `You must provide an array to ${this.toString()}, not '${typeof this.sample}'.` + ); + } + const matcherContext = this.getMatcherContext(); + const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every( + (item) => other.some((another) => equals(item, another, matcherContext.customTesters)) + ); + return this.inverse ? !result : result; + } + toString() { + return `Array${this.inverse ? "Not" : ""}Containing`; + } + getExpectedType() { + return "array"; + } +} +class Any extends AsymmetricMatcher { + constructor(sample) { + if (typeof sample === "undefined") { + throw new TypeError( + "any() expects to be passed a constructor function. Please pass one or use anything() to match any object." + ); + } + super(sample); + } + fnNameFor(func) { + if (func.name) + return func.name; + const functionToString = Function.prototype.toString; + const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/); + return matches ? matches[1] : ""; + } + asymmetricMatch(other) { + if (this.sample === String) + return typeof other == "string" || other instanceof String; + if (this.sample === Number) + return typeof other == "number" || other instanceof Number; + if (this.sample === Function) + return typeof other == "function" || other instanceof Function; + if (this.sample === Boolean) + return typeof other == "boolean" || other instanceof Boolean; + if (this.sample === BigInt) + return typeof other == "bigint" || other instanceof BigInt; + if (this.sample === Symbol) + return typeof other == "symbol" || other instanceof Symbol; + if (this.sample === Object) + return typeof other == "object"; + return other instanceof this.sample; + } + toString() { + return "Any"; + } + getExpectedType() { + if (this.sample === String) + return "string"; + if (this.sample === Number) + return "number"; + if (this.sample === Function) + return "function"; + if (this.sample === Object) + return "object"; + if (this.sample === Boolean) + return "boolean"; + return this.fnNameFor(this.sample); + } + toAsymmetricMatcher() { + return `Any<${this.fnNameFor(this.sample)}>`; + } +} +class StringMatching extends AsymmetricMatcher { + constructor(sample, inverse = false) { + if (!isA("String", sample) && !isA("RegExp", sample)) + throw new Error("Expected is not a String or a RegExp"); + super(new RegExp(sample), inverse); + } + asymmetricMatch(other) { + const result = isA("String", other) && this.sample.test(other); + return this.inverse ? !result : result; + } + toString() { + return `String${this.inverse ? "Not" : ""}Matching`; + } + getExpectedType() { + return "string"; + } +} +class CloseTo extends AsymmetricMatcher { + precision; + constructor(sample, precision = 2, inverse = false) { + if (!isA("Number", sample)) + throw new Error("Expected is not a Number"); + if (!isA("Number", precision)) + throw new Error("Precision is not a Number"); + super(sample); + this.inverse = inverse; + this.precision = precision; + } + asymmetricMatch(other) { + if (!isA("Number", other)) + return false; + let result = false; + if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) { + result = true; + } else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) { + result = true; + } else { + result = Math.abs(this.sample - other) < 10 ** -this.precision / 2; + } + return this.inverse ? !result : result; + } + toString() { + return `Number${this.inverse ? "Not" : ""}CloseTo`; + } + getExpectedType() { + return "number"; + } + toAsymmetricMatcher() { + return [ + this.toString(), + this.sample, + `(${pluralize("digit", this.precision)})` + ].join(" "); + } +} +const JestAsymmetricMatchers = (chai, utils) => { + utils.addMethod( + chai.expect, + "anything", + () => new Anything() + ); + utils.addMethod( + chai.expect, + "any", + (expected) => new Any(expected) + ); + utils.addMethod( + chai.expect, + "stringContaining", + (expected) => new StringContaining(expected) + ); + utils.addMethod( + chai.expect, + "objectContaining", + (expected) => new ObjectContaining(expected) + ); + utils.addMethod( + chai.expect, + "arrayContaining", + (expected) => new ArrayContaining(expected) + ); + utils.addMethod( + chai.expect, + "stringMatching", + (expected) => new StringMatching(expected) + ); + utils.addMethod( + chai.expect, + "closeTo", + (expected, precision) => new CloseTo(expected, precision) + ); + chai.expect.not = { + stringContaining: (expected) => new StringContaining(expected, true), + objectContaining: (expected) => new ObjectContaining(expected, true), + arrayContaining: (expected) => new ArrayContaining(expected, true), + stringMatching: (expected) => new StringMatching(expected, true), + closeTo: (expected, precision) => new CloseTo(expected, precision, true) + }; +}; + +function recordAsyncExpect(test, promise) { + if (test && promise instanceof Promise) { + promise = promise.finally(() => { + const index = test.promises.indexOf(promise); + if (index !== -1) + test.promises.splice(index, 1); + }); + if (!test.promises) + test.promises = []; + test.promises.push(promise); + } + return promise; +} +function wrapSoft(utils, fn) { + return function(...args) { + var _a; + const test = utils.flag(this, "vitest-test"); + const state = (test == null ? void 0 : test.context._local) ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]); + if (!state.soft) + return fn.apply(this, args); + if (!test) + throw new Error("expect.soft() can only be used inside a test"); + try { + return fn.apply(this, args); + } catch (err) { + test.result || (test.result = { state: "fail" }); + test.result.state = "fail"; + (_a = test.result).errors || (_a.errors = []); + test.result.errors.push(processError(err)); + } + }; +} + +const JestChaiExpect = (chai, utils) => { + const { AssertionError } = chai; + const c = () => getColors(); + const customTesters = getCustomEqualityTesters(); + function def(name, fn) { + const addMethod = (n) => { + const softWrapper = wrapSoft(utils, fn); + utils.addMethod(chai.Assertion.prototype, n, softWrapper); + utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper); + }; + if (Array.isArray(name)) + name.forEach((n) => addMethod(n)); + else + addMethod(name); + } + ["throw", "throws", "Throw"].forEach((m) => { + utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => { + return function(...args) { + const promise = utils.flag(this, "promise"); + const object = utils.flag(this, "object"); + const isNot = utils.flag(this, "negate"); + if (promise === "rejects") { + utils.flag(this, "object", () => { + throw object; + }); + } else if (promise === "resolves" && typeof object !== "function") { + if (!isNot) { + const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't"; + const error = { + showDiff: false + }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } else { + return; + } + } + _super.apply(this, args); + }; + }); + }); + def("withTest", function(test) { + utils.flag(this, "vitest-test", test); + return this; + }); + def("toEqual", function(expected) { + const actual = utils.flag(this, "object"); + const equal = equals( + actual, + expected, + [...customTesters, iterableEquality] + ); + return this.assert( + equal, + "expected #{this} to deeply equal #{exp}", + "expected #{this} to not deeply equal #{exp}", + expected, + actual + ); + }); + def("toStrictEqual", function(expected) { + const obj = utils.flag(this, "object"); + const equal = equals( + obj, + expected, + [ + ...customTesters, + iterableEquality, + typeEquality, + sparseArrayEquality, + arrayBufferEquality + ], + true + ); + return this.assert( + equal, + "expected #{this} to strictly equal #{exp}", + "expected #{this} to not strictly equal #{exp}", + expected, + obj + ); + }); + def("toBe", function(expected) { + const actual = this._obj; + const pass = Object.is(actual, expected); + let deepEqualityName = ""; + if (!pass) { + const toStrictEqualPass = equals( + actual, + expected, + [ + ...customTesters, + iterableEquality, + typeEquality, + sparseArrayEquality, + arrayBufferEquality + ], + true + ); + if (toStrictEqualPass) { + deepEqualityName = "toStrictEqual"; + } else { + const toEqualPass = equals( + actual, + expected, + [...customTesters, iterableEquality] + ); + if (toEqualPass) + deepEqualityName = "toEqual"; + } + } + return this.assert( + pass, + generateToBeMessage(deepEqualityName), + "expected #{this} not to be #{exp} // Object.is equality", + expected, + actual + ); + }); + def("toMatchObject", function(expected) { + const actual = this._obj; + const pass = equals(actual, expected, [...customTesters, iterableEquality, subsetEquality]); + const isNot = utils.flag(this, "negate"); + const { subset: actualSubset, stripped } = getObjectSubset(actual, expected); + if (pass && isNot || !pass && !isNot) { + const msg = utils.getMessage( + this, + [ + pass, + "expected #{this} to match object #{exp}", + "expected #{this} to not match object #{exp}", + expected, + actualSubset, + false + ] + ); + const message = stripped === 0 ? msg : `${msg} +(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`; + throw new AssertionError(message, { showDiff: true, expected, actual: actualSubset }); + } + }); + def("toMatch", function(expected) { + const actual = this._obj; + if (typeof actual !== "string") + throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`); + return this.assert( + typeof expected === "string" ? actual.includes(expected) : actual.match(expected), + `expected #{this} to match #{exp}`, + `expected #{this} not to match #{exp}`, + expected, + actual + ); + }); + def("toContain", function(item) { + const actual = this._obj; + if (typeof Node !== "undefined" && actual instanceof Node) { + if (!(item instanceof Node)) + throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`); + return this.assert( + actual.contains(item), + "expected #{this} to contain element #{exp}", + "expected #{this} not to contain element #{exp}", + item, + actual + ); + } + if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) { + assertTypes(item, "class name", ["string"]); + const isNot = utils.flag(this, "negate"); + const expectedClassList = isNot ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`; + return this.assert( + actual.contains(item), + `expected "${actual.value}" to contain "${item}"`, + `expected "${actual.value}" not to contain "${item}"`, + expectedClassList, + actual.value + ); + } + if (typeof actual === "string" && typeof item === "string") { + return this.assert( + actual.includes(item), + `expected #{this} to contain #{exp}`, + `expected #{this} not to contain #{exp}`, + item, + actual + ); + } + if (actual != null && typeof actual !== "string") + utils.flag(this, "object", Array.from(actual)); + return this.contain(item); + }); + def("toContainEqual", function(expected) { + const obj = utils.flag(this, "object"); + const index = Array.from(obj).findIndex((item) => { + return equals(item, expected, customTesters); + }); + this.assert( + index !== -1, + "expected #{this} to deep equally contain #{exp}", + "expected #{this} to not deep equally contain #{exp}", + expected + ); + }); + def("toBeTruthy", function() { + const obj = utils.flag(this, "object"); + this.assert( + Boolean(obj), + "expected #{this} to be truthy", + "expected #{this} to not be truthy", + obj, + false + ); + }); + def("toBeFalsy", function() { + const obj = utils.flag(this, "object"); + this.assert( + !obj, + "expected #{this} to be falsy", + "expected #{this} to not be falsy", + obj, + false + ); + }); + def("toBeGreaterThan", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert( + actual > expected, + `expected ${actual} to be greater than ${expected}`, + `expected ${actual} to be not greater than ${expected}`, + actual, + expected, + false + ); + }); + def("toBeGreaterThanOrEqual", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert( + actual >= expected, + `expected ${actual} to be greater than or equal to ${expected}`, + `expected ${actual} to be not greater than or equal to ${expected}`, + actual, + expected, + false + ); + }); + def("toBeLessThan", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert( + actual < expected, + `expected ${actual} to be less than ${expected}`, + `expected ${actual} to be not less than ${expected}`, + actual, + expected, + false + ); + }); + def("toBeLessThanOrEqual", function(expected) { + const actual = this._obj; + assertTypes(actual, "actual", ["number", "bigint"]); + assertTypes(expected, "expected", ["number", "bigint"]); + return this.assert( + actual <= expected, + `expected ${actual} to be less than or equal to ${expected}`, + `expected ${actual} to be not less than or equal to ${expected}`, + actual, + expected, + false + ); + }); + def("toBeNaN", function() { + return this.be.NaN; + }); + def("toBeUndefined", function() { + return this.be.undefined; + }); + def("toBeNull", function() { + return this.be.null; + }); + def("toBeDefined", function() { + const negate = utils.flag(this, "negate"); + utils.flag(this, "negate", false); + if (negate) + return this.be.undefined; + return this.not.be.undefined; + }); + def("toBeTypeOf", function(expected) { + const actual = typeof this._obj; + const equal = expected === actual; + return this.assert( + equal, + "expected #{this} to be type of #{exp}", + "expected #{this} not to be type of #{exp}", + expected, + actual + ); + }); + def("toBeInstanceOf", function(obj) { + return this.instanceOf(obj); + }); + def("toHaveLength", function(length) { + return this.have.length(length); + }); + def("toHaveProperty", function(...args) { + if (Array.isArray(args[0])) + args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join("."); + const actual = this._obj; + const [propertyName, expected] = args; + const getValue = () => { + const hasOwn = Object.prototype.hasOwnProperty.call(actual, propertyName); + if (hasOwn) + return { value: actual[propertyName], exists: true }; + return utils.getPathInfo(actual, propertyName); + }; + const { value, exists } = getValue(); + const pass = exists && (args.length === 1 || equals(expected, value, customTesters)); + const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`; + return this.assert( + pass, + `expected #{this} to have property "${propertyName}"${valueString}`, + `expected #{this} to not have property "${propertyName}"${valueString}`, + expected, + exists ? value : void 0 + ); + }); + def("toBeCloseTo", function(received, precision = 2) { + const expected = this._obj; + let pass = false; + let expectedDiff = 0; + let receivedDiff = 0; + if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) { + pass = true; + } else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) { + pass = true; + } else { + expectedDiff = 10 ** -precision / 2; + receivedDiff = Math.abs(expected - received); + pass = receivedDiff < expectedDiff; + } + return this.assert( + pass, + `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, + `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, + received, + expected, + false + ); + }); + const assertIsMock = (assertion) => { + if (!isMockFunction(assertion._obj)) + throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`); + }; + const getSpy = (assertion) => { + assertIsMock(assertion); + return assertion._obj; + }; + const ordinalOf = (i) => { + const j = i % 10; + const k = i % 100; + if (j === 1 && k !== 11) + return `${i}st`; + if (j === 2 && k !== 12) + return `${i}nd`; + if (j === 3 && k !== 13) + return `${i}rd`; + return `${i}th`; + }; + const formatCalls = (spy, msg, actualCall) => { + if (spy.mock.calls) { + msg += c().gray(` + +Received: + +${spy.mock.calls.map((callArg, i) => { + let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call: + +`); + if (actualCall) + methodCall += diff(actualCall, callArg, { omitAnnotationLines: true }); + else + methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n"); + methodCall += "\n"; + return methodCall; + }).join("\n")}`); + } + msg += c().gray(` + +Number of calls: ${c().bold(spy.mock.calls.length)} +`); + return msg; + }; + const formatReturns = (spy, msg, actualReturn) => { + msg += c().gray(` + +Received: + +${spy.mock.results.map((callReturn, i) => { + let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return: + +`); + if (actualReturn) + methodCall += diff(actualReturn, callReturn.value, { omitAnnotationLines: true }); + else + methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n"); + methodCall += "\n"; + return methodCall; + }).join("\n")}`); + msg += c().gray(` + +Number of calls: ${c().bold(spy.mock.calls.length)} +`); + return msg; + }; + def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + return this.assert( + callCount === number, + `expected "${spyName}" to be called #{exp} times, but got ${callCount} times`, + `expected "${spyName}" to not be called #{exp} times`, + number, + callCount, + false + ); + }); + def("toHaveBeenCalledOnce", function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + return this.assert( + callCount === 1, + `expected "${spyName}" to be called once, but got ${callCount} times`, + `expected "${spyName}" to not be called once`, + 1, + callCount, + false + ); + }); + def(["toHaveBeenCalled", "toBeCalled"], function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const callCount = spy.mock.calls.length; + const called = callCount > 0; + const isNot = utils.flag(this, "negate"); + let msg = utils.getMessage( + this, + [ + called, + `expected "${spyName}" to be called at least once`, + `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`, + true, + called + ] + ); + if (called && isNot) + msg = formatCalls(spy, msg); + if (called && isNot || !called && !isNot) + throw new AssertionError(msg); + }); + def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const pass = spy.mock.calls.some((callArg) => equals(callArg, args, [...customTesters, iterableEquality])); + const isNot = utils.flag(this, "negate"); + const msg = utils.getMessage( + this, + [ + pass, + `expected "${spyName}" to be called with arguments: #{exp}`, + `expected "${spyName}" to not be called with arguments: #{exp}`, + args + ] + ); + if (pass && isNot || !pass && !isNot) + throw new AssertionError(formatCalls(spy, msg, args)); + }); + def(["toHaveBeenNthCalledWith", "nthCalledWith"], function(times, ...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const nthCall = spy.mock.calls[times - 1]; + const callCount = spy.mock.calls.length; + const isCalled = times <= callCount; + this.assert( + equals(nthCall, args, [...customTesters, iterableEquality]), + `expected ${ordinalOf(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`, + `expected ${ordinalOf(times)} "${spyName}" call to not have been called with #{exp}`, + args, + nthCall, + isCalled + ); + }); + def(["toHaveBeenLastCalledWith", "lastCalledWith"], function(...args) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const lastCall = spy.mock.calls[spy.mock.calls.length - 1]; + this.assert( + equals(lastCall, args, [...customTesters, iterableEquality]), + `expected last "${spyName}" call to have been called with #{exp}`, + `expected last "${spyName}" call to not have been called with #{exp}`, + args, + lastCall + ); + }); + def(["toThrow", "toThrowError"], function(expected) { + if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) + return this.throws(expected); + const obj = this._obj; + const promise = utils.flag(this, "promise"); + const isNot = utils.flag(this, "negate"); + let thrown = null; + if (promise === "rejects") { + thrown = obj; + } else if (promise === "resolves" && typeof obj !== "function") { + if (!isNot) { + const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't"; + const error = { + showDiff: false + }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } else { + return; + } + } else { + let isThrow = false; + try { + obj(); + } catch (err) { + isThrow = true; + thrown = err; + } + if (!isThrow && !isNot) { + const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't"; + const error = { + showDiff: false + }; + throw new AssertionError(message, error, utils.flag(this, "ssfi")); + } + } + if (typeof expected === "function") { + const name = expected.name || expected.prototype.constructor.name; + return this.assert( + thrown && thrown instanceof expected, + `expected error to be instance of ${name}`, + `expected error not to be instance of ${name}`, + expected, + thrown + ); + } + if (expected instanceof Error) { + return this.assert( + thrown && expected.message === thrown.message, + `expected error to have message: ${expected.message}`, + `expected error not to have message: ${expected.message}`, + expected.message, + thrown && thrown.message + ); + } + if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") { + const matcher = expected; + return this.assert( + thrown && matcher.asymmetricMatch(thrown), + "expected error to match asymmetric matcher", + "expected error not to match asymmetric matcher", + matcher, + thrown + ); + } + throw new Error(`"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`); + }); + def(["toHaveReturned", "toReturn"], function() { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const calledAndNotThrew = spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw"); + this.assert( + calledAndNotThrew, + `expected "${spyName}" to be successfully called at least once`, + `expected "${spyName}" to not be successfully called`, + calledAndNotThrew, + !calledAndNotThrew, + false + ); + }); + def(["toHaveReturnedTimes", "toReturnTimes"], function(times) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const successfulReturns = spy.mock.results.reduce((success, { type }) => type === "throw" ? success : ++success, 0); + this.assert( + successfulReturns === times, + `expected "${spyName}" to be successfully called ${times} times`, + `expected "${spyName}" to not be successfully called ${times} times`, + `expected number of returns: ${times}`, + `received number of returns: ${successfulReturns}`, + false + ); + }); + def(["toHaveReturnedWith", "toReturnWith"], function(value) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const pass = spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)); + const isNot = utils.flag(this, "negate"); + const msg = utils.getMessage( + this, + [ + pass, + `expected "${spyName}" to return with: #{exp} at least once`, + `expected "${spyName}" to not return with: #{exp}`, + value + ] + ); + if (pass && isNot || !pass && !isNot) + throw new AssertionError(formatReturns(spy, msg, value)); + }); + def(["toHaveLastReturnedWith", "lastReturnedWith"], function(value) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const { value: lastResult } = spy.mock.results[spy.mock.results.length - 1]; + const pass = equals(lastResult, value); + this.assert( + pass, + `expected last "${spyName}" call to return #{exp}`, + `expected last "${spyName}" call to not return #{exp}`, + value, + lastResult + ); + }); + def(["toHaveNthReturnedWith", "nthReturnedWith"], function(nthCall, value) { + const spy = getSpy(this); + const spyName = spy.getMockName(); + const isNot = utils.flag(this, "negate"); + const { type: callType, value: callResult } = spy.mock.results[nthCall - 1]; + const ordinalCall = `${ordinalOf(nthCall)} call`; + if (!isNot && callType === "throw") + chai.assert.fail(`expected ${ordinalCall} to return #{exp}, but instead it threw an error`); + const nthCallReturn = equals(callResult, value); + this.assert( + nthCallReturn, + `expected ${ordinalCall} "${spyName}" call to return #{exp}`, + `expected ${ordinalCall} "${spyName}" call to not return #{exp}`, + value, + callResult + ); + }); + def("toSatisfy", function(matcher, message) { + return this.be.satisfy(matcher, message); + }); + utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() { + const error = new Error("resolves"); + utils.flag(this, "promise", "resolves"); + utils.flag(this, "error", error); + const test = utils.flag(this, "vitest-test"); + const obj = utils.flag(this, "object"); + if (typeof (obj == null ? void 0 : obj.then) !== "function") + throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`); + const proxy = new Proxy(this, { + get: (target, key, receiver) => { + const result = Reflect.get(target, key, receiver); + if (typeof result !== "function") + return result instanceof chai.Assertion ? proxy : result; + return async (...args) => { + const promise = obj.then( + (value) => { + utils.flag(this, "object", value); + return result.call(this, ...args); + }, + (err) => { + const _error = new AssertionError( + `promise rejected "${utils.inspect(err)}" instead of resolving`, + { showDiff: false } + ); + _error.cause = err; + _error.stack = error.stack.replace(error.message, _error.message); + throw _error; + } + ); + return recordAsyncExpect(test, promise); + }; + } + }); + return proxy; + }); + utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() { + const error = new Error("rejects"); + utils.flag(this, "promise", "rejects"); + utils.flag(this, "error", error); + const test = utils.flag(this, "vitest-test"); + const obj = utils.flag(this, "object"); + const wrapper = typeof obj === "function" ? obj() : obj; + if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function") + throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`); + const proxy = new Proxy(this, { + get: (target, key, receiver) => { + const result = Reflect.get(target, key, receiver); + if (typeof result !== "function") + return result instanceof chai.Assertion ? proxy : result; + return async (...args) => { + const promise = wrapper.then( + (value) => { + const _error = new AssertionError( + `promise resolved "${utils.inspect(value)}" instead of rejecting`, + { showDiff: true, expected: new Error("rejected promise"), actual: value } + ); + _error.stack = error.stack.replace(error.message, _error.message); + throw _error; + }, + (err) => { + utils.flag(this, "object", err); + return result.call(this, ...args); + } + ); + return recordAsyncExpect(test, promise); + }; + } + }); + return proxy; + }); +}; + +function getMatcherState(assertion, expect) { + const obj = assertion._obj; + const isNot = util.flag(assertion, "negate"); + const promise = util.flag(assertion, "promise") || ""; + const jestUtils = { + ...getMatcherUtils(), + diff, + stringify, + iterableEquality, + subsetEquality + }; + const matcherState = { + ...getState(expect), + customTesters: getCustomEqualityTesters(), + isNot, + utils: jestUtils, + promise, + equals, + // needed for built-in jest-snapshots, but we don't use it + suppressedErrors: [] + }; + return { + state: matcherState, + isNot, + obj + }; +} +class JestExtendError extends Error { + constructor(message, actual, expected) { + super(message); + this.actual = actual; + this.expected = expected; + } +} +function JestExtendPlugin(expect, matchers) { + return (c, utils) => { + Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => { + function expectWrapper(...args) { + const { state, isNot, obj } = getMatcherState(this, expect); + const result = expectAssertion.call(state, obj, ...args); + if (result && typeof result === "object" && result instanceof Promise) { + return result.then(({ pass: pass2, message: message2, actual: actual2, expected: expected2 }) => { + if (pass2 && isNot || !pass2 && !isNot) + throw new JestExtendError(message2(), actual2, expected2); + }); + } + const { pass, message, actual, expected } = result; + if (pass && isNot || !pass && !isNot) + throw new JestExtendError(message(), actual, expected); + } + const softWrapper = wrapSoft(utils, expectWrapper); + utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper); + utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper); + class CustomMatcher extends AsymmetricMatcher { + constructor(inverse = false, ...sample) { + super(sample, inverse); + } + asymmetricMatch(other) { + const { pass } = expectAssertion.call( + this.getMatcherContext(expect), + other, + ...this.sample + ); + return this.inverse ? !pass : pass; + } + toString() { + return `${this.inverse ? "not." : ""}${expectAssertionName}`; + } + getExpectedType() { + return "any"; + } + toAsymmetricMatcher() { + return `${this.toString()}<${this.sample.map(String).join(", ")}>`; + } + } + const customMatcher = (...sample) => new CustomMatcher(false, ...sample); + Object.defineProperty(expect, expectAssertionName, { + configurable: true, + enumerable: true, + value: customMatcher, + writable: true + }); + Object.defineProperty(expect.not, expectAssertionName, { + configurable: true, + enumerable: true, + value: (...sample) => new CustomMatcher(true, ...sample), + writable: true + }); + Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, { + configurable: true, + enumerable: true, + value: customMatcher, + writable: true + }); + }); + }; +} +const JestExtend = (chai, utils) => { + utils.addMethod(chai.expect, "extend", (expect, expects) => { + chai.use(JestExtendPlugin(expect, expects)); + }); +}; + +export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality }; diff --git a/node_modules/@vitest/expect/index.d.ts b/node_modules/@vitest/expect/index.d.ts new file mode 100644 index 0000000..3b82ac4 --- /dev/null +++ b/node_modules/@vitest/expect/index.d.ts @@ -0,0 +1,3 @@ +import './dist/chai.cjs' + +export * from './dist/index.js' diff --git a/node_modules/@vitest/expect/package.json b/node_modules/@vitest/expect/package.json new file mode 100644 index 0000000..41ffce0 --- /dev/null +++ b/node_modules/@vitest/expect/package.json @@ -0,0 +1,47 @@ +{ + "name": "@vitest/expect", + "type": "module", + "version": "1.6.1", + "description": "Jest's expect matchers as a Chai plugin", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/expect#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/expect" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./index.d.ts", + "default": "./dist/index.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "chai": "^4.3.10", + "@vitest/utils": "1.6.1", + "@vitest/spy": "1.6.1" + }, + "devDependencies": { + "@types/chai": "4.3.6", + "picocolors": "^1.0.0", + "rollup-plugin-copy": "^3.5.0", + "@vitest/runner": "1.6.1" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/runner/LICENSE b/node_modules/@vitest/runner/LICENSE new file mode 100644 index 0000000..5ae481f --- /dev/null +++ b/node_modules/@vitest/runner/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/runner/README.md b/node_modules/@vitest/runner/README.md new file mode 100644 index 0000000..2796b6a --- /dev/null +++ b/node_modules/@vitest/runner/README.md @@ -0,0 +1,5 @@ +# @vitest/runner + +Vitest mechanism to collect and run tasks. + +[GitHub](https://github.com/vitest-dev/vitest) | [Documentation](https://vitest.dev/advanced/runner) diff --git a/node_modules/@vitest/runner/dist/chunk-tasks.js b/node_modules/@vitest/runner/dist/chunk-tasks.js new file mode 100644 index 0000000..6628bc5 --- /dev/null +++ b/node_modules/@vitest/runner/dist/chunk-tasks.js @@ -0,0 +1,171 @@ +import { processError } from '@vitest/utils/error'; +import { toArray } from '@vitest/utils'; + +function partitionSuiteChildren(suite) { + let tasksGroup = []; + const tasksGroups = []; + for (const c of suite.tasks) { + if (tasksGroup.length === 0 || c.concurrent === tasksGroup[0].concurrent) { + tasksGroup.push(c); + } else { + tasksGroups.push(tasksGroup); + tasksGroup = [c]; + } + } + if (tasksGroup.length > 0) + tasksGroups.push(tasksGroup); + return tasksGroups; +} + +function interpretTaskModes(suite, namePattern, onlyMode, parentIsOnly, allowOnly) { + const suiteIsOnly = parentIsOnly || suite.mode === "only"; + suite.tasks.forEach((t) => { + const includeTask = suiteIsOnly || t.mode === "only"; + if (onlyMode) { + if (t.type === "suite" && (includeTask || someTasksAreOnly(t))) { + if (t.mode === "only") { + checkAllowOnly(t, allowOnly); + t.mode = "run"; + } + } else if (t.mode === "run" && !includeTask) { + t.mode = "skip"; + } else if (t.mode === "only") { + checkAllowOnly(t, allowOnly); + t.mode = "run"; + } + } + if (t.type === "test") { + if (namePattern && !getTaskFullName(t).match(namePattern)) + t.mode = "skip"; + } else if (t.type === "suite") { + if (t.mode === "skip") + skipAllTasks(t); + else + interpretTaskModes(t, namePattern, onlyMode, includeTask, allowOnly); + } + }); + if (suite.mode === "run") { + if (suite.tasks.length && suite.tasks.every((i) => i.mode !== "run")) + suite.mode = "skip"; + } +} +function getTaskFullName(task) { + return `${task.suite ? `${getTaskFullName(task.suite)} ` : ""}${task.name}`; +} +function someTasksAreOnly(suite) { + return suite.tasks.some((t) => t.mode === "only" || t.type === "suite" && someTasksAreOnly(t)); +} +function skipAllTasks(suite) { + suite.tasks.forEach((t) => { + if (t.mode === "run") { + t.mode = "skip"; + if (t.type === "suite") + skipAllTasks(t); + } + }); +} +function checkAllowOnly(task, allowOnly) { + if (allowOnly) + return; + const error = processError(new Error("[Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error")); + task.result = { + state: "fail", + errors: [error] + }; +} +function generateHash(str) { + let hash = 0; + if (str.length === 0) + return `${hash}`; + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; + } + return `${hash}`; +} +function calculateSuiteHash(parent) { + parent.tasks.forEach((t, idx) => { + t.id = `${parent.id}_${idx}`; + if (t.type === "suite") + calculateSuiteHash(t); + }); +} + +function createChainable(keys, fn) { + function create(context) { + const chain2 = function(...args) { + return fn.apply(context, args); + }; + Object.assign(chain2, fn); + chain2.withContext = () => chain2.bind(context); + chain2.setContext = (key, value) => { + context[key] = value; + }; + chain2.mergeContext = (ctx) => { + Object.assign(context, ctx); + }; + for (const key of keys) { + Object.defineProperty(chain2, key, { + get() { + return create({ ...context, [key]: true }); + } + }); + } + return chain2; + } + const chain = create({}); + chain.fn = fn; + return chain; +} + +function isAtomTest(s) { + return s.type === "test" || s.type === "custom"; +} +function getTests(suite) { + const tests = []; + const arraySuites = toArray(suite); + for (const s of arraySuites) { + if (isAtomTest(s)) { + tests.push(s); + } else { + for (const task of s.tasks) { + if (isAtomTest(task)) { + tests.push(task); + } else { + const taskTests = getTests(task); + for (const test of taskTests) + tests.push(test); + } + } + } + } + return tests; +} +function getTasks(tasks = []) { + return toArray(tasks).flatMap((s) => isAtomTest(s) ? [s] : [s, ...getTasks(s.tasks)]); +} +function getSuites(suite) { + return toArray(suite).flatMap((s) => s.type === "suite" ? [s, ...getSuites(s.tasks)] : []); +} +function hasTests(suite) { + return toArray(suite).some((s) => s.tasks.some((c) => isAtomTest(c) || hasTests(c))); +} +function hasFailed(suite) { + return toArray(suite).some((s) => { + var _a; + return ((_a = s.result) == null ? void 0 : _a.state) === "fail" || s.type === "suite" && hasFailed(s.tasks); + }); +} +function getNames(task) { + const names = [task.name]; + let current = task; + while ((current == null ? void 0 : current.suite) || (current == null ? void 0 : current.file)) { + current = current.suite || current.file; + if (current == null ? void 0 : current.name) + names.unshift(current.name); + } + return names; +} + +export { getTests as a, getTasks as b, calculateSuiteHash as c, getSuites as d, hasFailed as e, getNames as f, generateHash as g, hasTests as h, interpretTaskModes as i, createChainable as j, partitionSuiteChildren as p, someTasksAreOnly as s }; diff --git a/node_modules/@vitest/runner/dist/index.d.ts b/node_modules/@vitest/runner/dist/index.d.ts new file mode 100644 index 0000000..4301766 --- /dev/null +++ b/node_modules/@vitest/runner/dist/index.d.ts @@ -0,0 +1,33 @@ +import { VitestRunner } from './types.js'; +export { CancelReason, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource } from './types.js'; +import { T as Task, F as File, d as SuiteAPI, e as TestAPI, f as SuiteCollector, g as CustomAPI, h as SuiteHooks, O as OnTestFailedHandler, i as OnTestFinishedHandler, a as Test, C as Custom, S as Suite } from './tasks-K5XERDtv.js'; +export { D as DoneCallback, E as ExtendedContext, t as Fixture, s as FixtureFn, r as FixtureOptions, u as Fixtures, v as HookCleanupCallback, H as HookListener, I as InferFixturesTypes, R as RunMode, y as RuntimeContext, B as SequenceHooks, G as SequenceSetupFiles, x as SuiteFactory, k as TaskBase, A as TaskContext, w as TaskCustomOptions, m as TaskMeta, l as TaskPopulated, n as TaskResult, o as TaskResultPack, j as TaskState, z as TestContext, p as TestFunction, q as TestOptions, U as Use } from './tasks-K5XERDtv.js'; +import { Awaitable } from '@vitest/utils'; +export { processError } from '@vitest/utils/error'; +import '@vitest/utils/diff'; + +declare function updateTask(task: Task, runner: VitestRunner): void; +declare function startTests(paths: string[], runner: VitestRunner): Promise; + +declare const suite: SuiteAPI; +declare const test: TestAPI; +declare const describe: SuiteAPI; +declare const it: TestAPI; +declare function getCurrentSuite(): SuiteCollector; +declare function createTaskCollector(fn: (...args: any[]) => any, context?: Record): CustomAPI; + +declare function beforeAll(fn: SuiteHooks['beforeAll'][0], timeout?: number): void; +declare function afterAll(fn: SuiteHooks['afterAll'][0], timeout?: number): void; +declare function beforeEach(fn: SuiteHooks['beforeEach'][0], timeout?: number): void; +declare function afterEach(fn: SuiteHooks['afterEach'][0], timeout?: number): void; +declare const onTestFailed: (fn: OnTestFailedHandler) => void; +declare const onTestFinished: (fn: OnTestFinishedHandler) => void; + +declare function setFn(key: Test | Custom, fn: (() => Awaitable)): void; +declare function getFn(key: Task): (() => Awaitable); +declare function setHooks(key: Suite, hooks: SuiteHooks): void; +declare function getHooks(key: Suite): SuiteHooks; + +declare function getCurrentTest(): T; + +export { Custom, CustomAPI, File, OnTestFailedHandler, OnTestFinishedHandler, Suite, SuiteAPI, SuiteCollector, SuiteHooks, Task, Test, TestAPI, VitestRunner, afterAll, afterEach, beforeAll, beforeEach, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, setFn, setHooks, startTests, suite, test, updateTask }; diff --git a/node_modules/@vitest/runner/dist/index.js b/node_modules/@vitest/runner/dist/index.js new file mode 100644 index 0000000..e59d533 --- /dev/null +++ b/node_modules/@vitest/runner/dist/index.js @@ -0,0 +1,1005 @@ +import limit from 'p-limit'; +import { getSafeTimers, isObject, createDefer, format, objDisplay, objectAttr, toArray, shuffle } from '@vitest/utils'; +import { processError } from '@vitest/utils/error'; +export { processError } from '@vitest/utils/error'; +import { j as createChainable, g as generateHash, c as calculateSuiteHash, s as someTasksAreOnly, i as interpretTaskModes, p as partitionSuiteChildren, h as hasTests, e as hasFailed } from './chunk-tasks.js'; +import { relative } from 'pathe'; +import { parseSingleStack } from '@vitest/utils/source-map'; + +const fnMap = /* @__PURE__ */ new WeakMap(); +const fixtureMap = /* @__PURE__ */ new WeakMap(); +const hooksMap = /* @__PURE__ */ new WeakMap(); +function setFn(key, fn) { + fnMap.set(key, fn); +} +function getFn(key) { + return fnMap.get(key); +} +function setFixture(key, fixture) { + fixtureMap.set(key, fixture); +} +function getFixture(key) { + return fixtureMap.get(key); +} +function setHooks(key, hooks) { + hooksMap.set(key, hooks); +} +function getHooks(key) { + return hooksMap.get(key); +} + +class PendingError extends Error { + constructor(message, task) { + super(message); + this.message = message; + this.taskId = task.id; + } + code = "VITEST_PENDING"; + taskId; +} + +const collectorContext = { + tasks: [], + currentSuite: null +}; +function collectTask(task) { + var _a; + (_a = collectorContext.currentSuite) == null ? void 0 : _a.tasks.push(task); +} +async function runWithSuite(suite, fn) { + const prev = collectorContext.currentSuite; + collectorContext.currentSuite = suite; + await fn(); + collectorContext.currentSuite = prev; +} +function withTimeout(fn, timeout, isHook = false) { + if (timeout <= 0 || timeout === Number.POSITIVE_INFINITY) + return fn; + const { setTimeout, clearTimeout } = getSafeTimers(); + return (...args) => { + return Promise.race([fn(...args), new Promise((resolve, reject) => { + var _a; + const timer = setTimeout(() => { + clearTimeout(timer); + reject(new Error(makeTimeoutMsg(isHook, timeout))); + }, timeout); + (_a = timer.unref) == null ? void 0 : _a.call(timer); + })]); + }; +} +function createTestContext(test, runner) { + var _a; + const context = function() { + throw new Error("done() callback is deprecated, use promise instead"); + }; + context.task = test; + context.skip = () => { + test.pending = true; + throw new PendingError("test is skipped; abort execution", test); + }; + context.onTestFailed = (fn) => { + test.onFailed || (test.onFailed = []); + test.onFailed.push(fn); + }; + context.onTestFinished = (fn) => { + test.onFinished || (test.onFinished = []); + test.onFinished.push(fn); + }; + return ((_a = runner.extendTaskContext) == null ? void 0 : _a.call(runner, context)) || context; +} +function makeTimeoutMsg(isHook, timeout) { + return `${isHook ? "Hook" : "Test"} timed out in ${timeout}ms. +If this is a long-running ${isHook ? "hook" : "test"}, pass a timeout value as the last argument or configure it globally with "${isHook ? "hookTimeout" : "testTimeout"}".`; +} + +function mergeContextFixtures(fixtures, context = {}) { + const fixtureOptionKeys = ["auto"]; + const fixtureArray = Object.entries(fixtures).map(([prop, value]) => { + const fixtureItem = { value }; + if (Array.isArray(value) && value.length >= 2 && isObject(value[1]) && Object.keys(value[1]).some((key) => fixtureOptionKeys.includes(key))) { + Object.assign(fixtureItem, value[1]); + fixtureItem.value = value[0]; + } + fixtureItem.prop = prop; + fixtureItem.isFn = typeof fixtureItem.value === "function"; + return fixtureItem; + }); + if (Array.isArray(context.fixtures)) + context.fixtures = context.fixtures.concat(fixtureArray); + else + context.fixtures = fixtureArray; + fixtureArray.forEach((fixture) => { + if (fixture.isFn) { + const usedProps = getUsedProps(fixture.value); + if (usedProps.length) + fixture.deps = context.fixtures.filter(({ prop }) => prop !== fixture.prop && usedProps.includes(prop)); + } + }); + return context; +} +const fixtureValueMaps = /* @__PURE__ */ new Map(); +const cleanupFnArrayMap = /* @__PURE__ */ new Map(); +async function callFixtureCleanup(context) { + const cleanupFnArray = cleanupFnArrayMap.get(context) ?? []; + for (const cleanup of cleanupFnArray.reverse()) + await cleanup(); + cleanupFnArrayMap.delete(context); +} +function withFixtures(fn, testContext) { + return (hookContext) => { + const context = hookContext || testContext; + if (!context) + return fn({}); + const fixtures = getFixture(context); + if (!(fixtures == null ? void 0 : fixtures.length)) + return fn(context); + const usedProps = getUsedProps(fn); + const hasAutoFixture = fixtures.some(({ auto }) => auto); + if (!usedProps.length && !hasAutoFixture) + return fn(context); + if (!fixtureValueMaps.get(context)) + fixtureValueMaps.set(context, /* @__PURE__ */ new Map()); + const fixtureValueMap = fixtureValueMaps.get(context); + if (!cleanupFnArrayMap.has(context)) + cleanupFnArrayMap.set(context, []); + const cleanupFnArray = cleanupFnArrayMap.get(context); + const usedFixtures = fixtures.filter(({ prop, auto }) => auto || usedProps.includes(prop)); + const pendingFixtures = resolveDeps(usedFixtures); + if (!pendingFixtures.length) + return fn(context); + async function resolveFixtures() { + for (const fixture of pendingFixtures) { + if (fixtureValueMap.has(fixture)) + continue; + const resolvedValue = fixture.isFn ? await resolveFixtureFunction(fixture.value, context, cleanupFnArray) : fixture.value; + context[fixture.prop] = resolvedValue; + fixtureValueMap.set(fixture, resolvedValue); + cleanupFnArray.unshift(() => { + fixtureValueMap.delete(fixture); + }); + } + } + return resolveFixtures().then(() => fn(context)); + }; +} +async function resolveFixtureFunction(fixtureFn, context, cleanupFnArray) { + const useFnArgPromise = createDefer(); + let isUseFnArgResolved = false; + const fixtureReturn = fixtureFn(context, async (useFnArg) => { + isUseFnArgResolved = true; + useFnArgPromise.resolve(useFnArg); + const useReturnPromise = createDefer(); + cleanupFnArray.push(async () => { + useReturnPromise.resolve(); + await fixtureReturn; + }); + await useReturnPromise; + }).catch((e) => { + if (!isUseFnArgResolved) { + useFnArgPromise.reject(e); + return; + } + throw e; + }); + return useFnArgPromise; +} +function resolveDeps(fixtures, depSet = /* @__PURE__ */ new Set(), pendingFixtures = []) { + fixtures.forEach((fixture) => { + if (pendingFixtures.includes(fixture)) + return; + if (!fixture.isFn || !fixture.deps) { + pendingFixtures.push(fixture); + return; + } + if (depSet.has(fixture)) + throw new Error(`Circular fixture dependency detected: ${fixture.prop} <- ${[...depSet].reverse().map((d) => d.prop).join(" <- ")}`); + depSet.add(fixture); + resolveDeps(fixture.deps, depSet, pendingFixtures); + pendingFixtures.push(fixture); + depSet.clear(); + }); + return pendingFixtures; +} +function getUsedProps(fn) { + const match = fn.toString().match(/[^(]*\(([^)]*)/); + if (!match) + return []; + const args = splitByComma(match[1]); + if (!args.length) + return []; + const first = args[0]; + if (!(first.startsWith("{") && first.endsWith("}"))) + throw new Error(`The first argument inside a fixture must use object destructuring pattern, e.g. ({ test } => {}). Instead, received "${first}".`); + const _first = first.slice(1, -1).replace(/\s/g, ""); + const props = splitByComma(_first).map((prop) => { + return prop.replace(/\:.*|\=.*/g, ""); + }); + const last = props.at(-1); + if (last && last.startsWith("...")) + throw new Error(`Rest parameters are not supported in fixtures, received "${last}".`); + return props; +} +function splitByComma(s) { + const result = []; + const stack = []; + let start = 0; + for (let i = 0; i < s.length; i++) { + if (s[i] === "{" || s[i] === "[") { + stack.push(s[i] === "{" ? "}" : "]"); + } else if (s[i] === stack[stack.length - 1]) { + stack.pop(); + } else if (!stack.length && s[i] === ",") { + const token = s.substring(start, i).trim(); + if (token) + result.push(token); + start = i + 1; + } + } + const lastToken = s.substring(start).trim(); + if (lastToken) + result.push(lastToken); + return result; +} + +let _test; +function setCurrentTest(test) { + _test = test; +} +function getCurrentTest() { + return _test; +} + +const suite = createSuite(); +const test = createTest( + function(name, optionsOrFn, optionsOrTest) { + if (getCurrentTest()) + throw new Error('Calling the test function inside another test function is not allowed. Please put it inside "describe" or "suite" so it can be properly collected.'); + getCurrentSuite().test.fn.call(this, formatName(name), optionsOrFn, optionsOrTest); + } +); +const describe = suite; +const it = test; +let runner; +let defaultSuite; +let currentTestFilepath; +function getDefaultSuite() { + return defaultSuite; +} +function getTestFilepath() { + return currentTestFilepath; +} +function getRunner() { + return runner; +} +function clearCollectorContext(filepath, currentRunner) { + if (!defaultSuite) + defaultSuite = currentRunner.config.sequence.shuffle ? suite.shuffle("") : currentRunner.config.sequence.concurrent ? suite.concurrent("") : suite(""); + runner = currentRunner; + currentTestFilepath = filepath; + collectorContext.tasks.length = 0; + defaultSuite.clear(); + collectorContext.currentSuite = defaultSuite; +} +function getCurrentSuite() { + return collectorContext.currentSuite || defaultSuite; +} +function createSuiteHooks() { + return { + beforeAll: [], + afterAll: [], + beforeEach: [], + afterEach: [] + }; +} +function parseArguments(optionsOrFn, optionsOrTest) { + let options = {}; + let fn = () => { + }; + if (typeof optionsOrTest === "object") { + if (typeof optionsOrFn === "object") + throw new TypeError("Cannot use two objects as arguments. Please provide options and a function callback in that order."); + options = optionsOrTest; + } else if (typeof optionsOrTest === "number") { + options = { timeout: optionsOrTest }; + } else if (typeof optionsOrFn === "object") { + options = optionsOrFn; + } + if (typeof optionsOrFn === "function") { + if (typeof optionsOrTest === "function") + throw new TypeError("Cannot use two functions as arguments. Please use the second argument for options."); + fn = optionsOrFn; + } else if (typeof optionsOrTest === "function") { + fn = optionsOrTest; + } + return { + options, + handler: fn + }; +} +function createSuiteCollector(name, factory = () => { +}, mode, shuffle, each, suiteOptions) { + const tasks = []; + const factoryQueue = []; + let suite2; + initSuite(true); + const task = function(name2 = "", options = {}) { + const task2 = { + id: "", + name: name2, + suite: void 0, + each: options.each, + fails: options.fails, + context: void 0, + type: "custom", + retry: options.retry ?? runner.config.retry, + repeats: options.repeats, + mode: options.only ? "only" : options.skip ? "skip" : options.todo ? "todo" : "run", + meta: options.meta ?? /* @__PURE__ */ Object.create(null) + }; + const handler = options.handler; + if (options.concurrent || !options.sequential && runner.config.sequence.concurrent) + task2.concurrent = true; + if (shuffle) + task2.shuffle = true; + const context = createTestContext(task2, runner); + Object.defineProperty(task2, "context", { + value: context, + enumerable: false + }); + setFixture(context, options.fixtures); + if (handler) { + setFn(task2, withTimeout( + withFixtures(handler, context), + (options == null ? void 0 : options.timeout) ?? runner.config.testTimeout + )); + } + if (runner.config.includeTaskLocation) { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 15; + const error = new Error("stacktrace").stack; + Error.stackTraceLimit = limit; + const stack = findTestFileStackTrace(error, task2.each ?? false); + if (stack) + task2.location = stack; + } + tasks.push(task2); + return task2; + }; + const test2 = createTest(function(name2, optionsOrFn, optionsOrTest) { + let { options, handler } = parseArguments( + optionsOrFn, + optionsOrTest + ); + if (typeof suiteOptions === "object") + options = Object.assign({}, suiteOptions, options); + options.concurrent = this.concurrent || !this.sequential && (options == null ? void 0 : options.concurrent); + options.sequential = this.sequential || !this.concurrent && (options == null ? void 0 : options.sequential); + const test3 = task( + formatName(name2), + { ...this, ...options, handler } + ); + test3.type = "test"; + }); + const collector = { + type: "collector", + name, + mode, + options: suiteOptions, + test: test2, + tasks, + collect, + task, + clear, + on: addHook + }; + function addHook(name2, ...fn) { + getHooks(suite2)[name2].push(...fn); + } + function initSuite(includeLocation) { + if (typeof suiteOptions === "number") + suiteOptions = { timeout: suiteOptions }; + suite2 = { + id: "", + type: "suite", + name, + mode, + each, + shuffle, + tasks: [], + meta: /* @__PURE__ */ Object.create(null), + projectName: "" + }; + if (runner && includeLocation && runner.config.includeTaskLocation) { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 15; + const error = new Error("stacktrace").stack; + Error.stackTraceLimit = limit; + const stack = findTestFileStackTrace(error, suite2.each ?? false); + if (stack) + suite2.location = stack; + } + setHooks(suite2, createSuiteHooks()); + } + function clear() { + tasks.length = 0; + factoryQueue.length = 0; + initSuite(false); + } + async function collect(file) { + factoryQueue.length = 0; + if (factory) + await runWithSuite(collector, () => factory(test2)); + const allChildren = []; + for (const i of [...factoryQueue, ...tasks]) + allChildren.push(i.type === "collector" ? await i.collect(file) : i); + suite2.file = file; + suite2.tasks = allChildren; + allChildren.forEach((task2) => { + task2.suite = suite2; + if (file) + task2.file = file; + }); + return suite2; + } + collectTask(collector); + return collector; +} +function createSuite() { + function suiteFn(name, factoryOrOptions, optionsOrFactory = {}) { + const mode = this.only ? "only" : this.skip ? "skip" : this.todo ? "todo" : "run"; + const currentSuite = getCurrentSuite(); + let { options, handler: factory } = parseArguments( + factoryOrOptions, + optionsOrFactory + ); + if (currentSuite == null ? void 0 : currentSuite.options) + options = { ...currentSuite.options, ...options }; + options.concurrent = this.concurrent || !this.sequential && (options == null ? void 0 : options.concurrent); + options.sequential = this.sequential || !this.concurrent && (options == null ? void 0 : options.sequential); + return createSuiteCollector(formatName(name), factory, mode, this.shuffle, this.each, options); + } + suiteFn.each = function(cases, ...args) { + const suite2 = this.withContext(); + this.setContext("each", true); + if (Array.isArray(cases) && args.length) + cases = formatTemplateString(cases, args); + return (name, optionsOrFn, fnOrOptions) => { + const _name = formatName(name); + const arrayOnlyCases = cases.every(Array.isArray); + const { options, handler } = parseArguments( + optionsOrFn, + fnOrOptions + ); + const fnFirst = typeof optionsOrFn === "function"; + cases.forEach((i, idx) => { + const items = Array.isArray(i) ? i : [i]; + if (fnFirst) { + arrayOnlyCases ? suite2(formatTitle(_name, items, idx), () => handler(...items), options) : suite2(formatTitle(_name, items, idx), () => handler(i), options); + } else { + arrayOnlyCases ? suite2(formatTitle(_name, items, idx), options, () => handler(...items)) : suite2(formatTitle(_name, items, idx), options, () => handler(i)); + } + }); + this.setContext("each", void 0); + }; + }; + suiteFn.skipIf = (condition) => condition ? suite.skip : suite; + suiteFn.runIf = (condition) => condition ? suite : suite.skip; + return createChainable( + ["concurrent", "sequential", "shuffle", "skip", "only", "todo"], + suiteFn + ); +} +function createTaskCollector(fn, context) { + const taskFn = fn; + taskFn.each = function(cases, ...args) { + const test2 = this.withContext(); + this.setContext("each", true); + if (Array.isArray(cases) && args.length) + cases = formatTemplateString(cases, args); + return (name, optionsOrFn, fnOrOptions) => { + const _name = formatName(name); + const arrayOnlyCases = cases.every(Array.isArray); + const { options, handler } = parseArguments( + optionsOrFn, + fnOrOptions + ); + const fnFirst = typeof optionsOrFn === "function"; + cases.forEach((i, idx) => { + const items = Array.isArray(i) ? i : [i]; + if (fnFirst) { + arrayOnlyCases ? test2(formatTitle(_name, items, idx), () => handler(...items), options) : test2(formatTitle(_name, items, idx), () => handler(i), options); + } else { + arrayOnlyCases ? test2(formatTitle(_name, items, idx), options, () => handler(...items)) : test2(formatTitle(_name, items, idx), options, () => handler(i)); + } + }); + this.setContext("each", void 0); + }; + }; + taskFn.skipIf = function(condition) { + return condition ? this.skip : this; + }; + taskFn.runIf = function(condition) { + return condition ? this : this.skip; + }; + taskFn.extend = function(fixtures) { + const _context = mergeContextFixtures(fixtures, context); + return createTest(function fn2(name, optionsOrFn, optionsOrTest) { + getCurrentSuite().test.fn.call(this, formatName(name), optionsOrFn, optionsOrTest); + }, _context); + }; + const _test = createChainable( + ["concurrent", "sequential", "skip", "only", "todo", "fails"], + taskFn + ); + if (context) + _test.mergeContext(context); + return _test; +} +function createTest(fn, context) { + return createTaskCollector(fn, context); +} +function formatName(name) { + return typeof name === "string" ? name : name instanceof Function ? name.name || "" : String(name); +} +function formatTitle(template, items, idx) { + if (template.includes("%#")) { + template = template.replace(/%%/g, "__vitest_escaped_%__").replace(/%#/g, `${idx}`).replace(/__vitest_escaped_%__/g, "%%"); + } + const count = template.split("%").length - 1; + let formatted = format(template, ...items.slice(0, count)); + if (isObject(items[0])) { + formatted = formatted.replace( + /\$([$\w_.]+)/g, + // https://github.com/chaijs/chai/pull/1490 + (_, key) => { + var _a, _b; + return objDisplay(objectAttr(items[0], key), { truncate: (_b = (_a = runner == null ? void 0 : runner.config) == null ? void 0 : _a.chaiConfig) == null ? void 0 : _b.truncateThreshold }); + } + ); + } + return formatted; +} +function formatTemplateString(cases, args) { + const header = cases.join("").trim().replace(/ /g, "").split("\n").map((i) => i.split("|"))[0]; + const res = []; + for (let i = 0; i < Math.floor(args.length / header.length); i++) { + const oneCase = {}; + for (let j = 0; j < header.length; j++) + oneCase[header[j]] = args[i * header.length + j]; + res.push(oneCase); + } + return res; +} +function findTestFileStackTrace(error, each) { + const lines = error.split("\n").slice(1); + for (const line of lines) { + const stack = parseSingleStack(line); + if (stack && stack.file === getTestFilepath()) { + return { + line: stack.line, + /** + * test.each([1, 2])('name') + * ^ leads here, but should + * ^ lead here + * in source maps it's the same boundary, so it just points to the start of it + */ + column: each ? stack.column + 1 : stack.column + }; + } + } +} + +async function runSetupFiles(config, runner) { + const files = toArray(config.setupFiles); + if (config.sequence.setupFiles === "parallel") { + await Promise.all( + files.map(async (fsPath) => { + await runner.importFile(fsPath, "setup"); + }) + ); + } else { + for (const fsPath of files) + await runner.importFile(fsPath, "setup"); + } +} + +const now$1 = Date.now; +async function collectTests(paths, runner) { + const files = []; + const config = runner.config; + for (const filepath of paths) { + const path = relative(config.root, filepath); + const file = { + id: generateHash(`${path}${config.name || ""}`), + name: path, + type: "suite", + mode: "run", + filepath, + tasks: [], + meta: /* @__PURE__ */ Object.create(null), + projectName: config.name + }; + clearCollectorContext(filepath, runner); + try { + const setupStart = now$1(); + await runSetupFiles(config, runner); + const collectStart = now$1(); + file.setupDuration = collectStart - setupStart; + await runner.importFile(filepath, "collect"); + const defaultTasks = await getDefaultSuite().collect(file); + setHooks(file, getHooks(defaultTasks)); + for (const c of [...defaultTasks.tasks, ...collectorContext.tasks]) { + if (c.type === "test") { + file.tasks.push(c); + } else if (c.type === "custom") { + file.tasks.push(c); + } else if (c.type === "suite") { + file.tasks.push(c); + } else if (c.type === "collector") { + const suite = await c.collect(file); + if (suite.name || suite.tasks.length) + file.tasks.push(suite); + } + } + file.collectDuration = now$1() - collectStart; + } catch (e) { + const error = processError(e); + file.result = { + state: "fail", + errors: [error] + }; + } + calculateSuiteHash(file); + const hasOnlyTasks = someTasksAreOnly(file); + interpretTaskModes(file, config.testNamePattern, hasOnlyTasks, false, config.allowOnly); + files.push(file); + } + return files; +} + +const now = Date.now; +function updateSuiteHookState(suite, name, state, runner) { + var _a; + if (!suite.result) + suite.result = { state: "run" }; + if (!((_a = suite.result) == null ? void 0 : _a.hooks)) + suite.result.hooks = {}; + const suiteHooks = suite.result.hooks; + if (suiteHooks) { + suiteHooks[name] = state; + updateTask(suite, runner); + } +} +function getSuiteHooks(suite, name, sequence) { + const hooks = getHooks(suite)[name]; + if (sequence === "stack" && (name === "afterAll" || name === "afterEach")) + return hooks.slice().reverse(); + return hooks; +} +async function callTaskHooks(task, hooks, sequence) { + if (sequence === "stack") + hooks = hooks.slice().reverse(); + if (sequence === "parallel") { + await Promise.all(hooks.map((fn) => fn(task.result))); + } else { + for (const fn of hooks) + await fn(task.result); + } +} +async function callSuiteHook(suite, currentTask, name, runner, args) { + const sequence = runner.config.sequence.hooks; + const callbacks = []; + if (name === "beforeEach" && suite.suite) { + callbacks.push( + ...await callSuiteHook(suite.suite, currentTask, name, runner, args) + ); + } + updateSuiteHookState(currentTask, name, "run", runner); + const hooks = getSuiteHooks(suite, name, sequence); + if (sequence === "parallel") { + callbacks.push(...await Promise.all(hooks.map((fn) => fn(...args)))); + } else { + for (const hook of hooks) + callbacks.push(await hook(...args)); + } + updateSuiteHookState(currentTask, name, "pass", runner); + if (name === "afterEach" && suite.suite) { + callbacks.push( + ...await callSuiteHook(suite.suite, currentTask, name, runner, args) + ); + } + return callbacks; +} +const packs = /* @__PURE__ */ new Map(); +let updateTimer; +let previousUpdate; +function updateTask(task, runner) { + packs.set(task.id, [task.result, task.meta]); + const { clearTimeout, setTimeout } = getSafeTimers(); + clearTimeout(updateTimer); + updateTimer = setTimeout(() => { + previousUpdate = sendTasksUpdate(runner); + }, 10); +} +async function sendTasksUpdate(runner) { + var _a; + const { clearTimeout } = getSafeTimers(); + clearTimeout(updateTimer); + await previousUpdate; + if (packs.size) { + const taskPacks = Array.from(packs).map(([id, task]) => { + return [ + id, + task[0], + task[1] + ]; + }); + const p = (_a = runner.onTaskUpdate) == null ? void 0 : _a.call(runner, taskPacks); + packs.clear(); + return p; + } +} +async function callCleanupHooks(cleanups) { + await Promise.all(cleanups.map(async (fn) => { + if (typeof fn !== "function") + return; + await fn(); + })); +} +async function runTest(test, runner) { + var _a, _b, _c, _d, _e, _f; + await ((_a = runner.onBeforeRunTask) == null ? void 0 : _a.call(runner, test)); + if (test.mode !== "run") + return; + if (((_b = test.result) == null ? void 0 : _b.state) === "fail") { + updateTask(test, runner); + return; + } + const start = now(); + test.result = { + state: "run", + startTime: start, + retryCount: 0 + }; + updateTask(test, runner); + setCurrentTest(test); + const repeats = test.repeats ?? 0; + for (let repeatCount = 0; repeatCount <= repeats; repeatCount++) { + const retry = test.retry ?? 0; + for (let retryCount = 0; retryCount <= retry; retryCount++) { + let beforeEachCleanups = []; + try { + await ((_c = runner.onBeforeTryTask) == null ? void 0 : _c.call(runner, test, { retry: retryCount, repeats: repeatCount })); + test.result.repeatCount = repeatCount; + beforeEachCleanups = await callSuiteHook(test.suite, test, "beforeEach", runner, [test.context, test.suite]); + if (runner.runTask) { + await runner.runTask(test); + } else { + const fn = getFn(test); + if (!fn) + throw new Error("Test function is not found. Did you add it using `setFn`?"); + await fn(); + } + if (test.promises) { + const result = await Promise.allSettled(test.promises); + const errors = result.map((r) => r.status === "rejected" ? r.reason : void 0).filter(Boolean); + if (errors.length) + throw errors; + } + await ((_d = runner.onAfterTryTask) == null ? void 0 : _d.call(runner, test, { retry: retryCount, repeats: repeatCount })); + if (test.result.state !== "fail") { + if (!test.repeats) + test.result.state = "pass"; + else if (test.repeats && retry === retryCount) + test.result.state = "pass"; + } + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + if (test.pending || ((_e = test.result) == null ? void 0 : _e.state) === "skip") { + test.mode = "skip"; + test.result = { state: "skip" }; + updateTask(test, runner); + setCurrentTest(void 0); + return; + } + try { + await callSuiteHook(test.suite, test, "afterEach", runner, [test.context, test.suite]); + await callCleanupHooks(beforeEachCleanups); + await callFixtureCleanup(test.context); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + if (test.result.state === "pass") + break; + if (retryCount < retry) { + test.result.state = "run"; + test.result.retryCount = (test.result.retryCount ?? 0) + 1; + } + updateTask(test, runner); + } + } + try { + await callTaskHooks(test, test.onFinished || [], "stack"); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + if (test.result.state === "fail") { + try { + await callTaskHooks(test, test.onFailed || [], runner.config.sequence.hooks); + } catch (e) { + failTask(test.result, e, runner.config.diffOptions); + } + } + if (test.fails) { + if (test.result.state === "pass") { + const error = processError(new Error("Expect test to fail")); + test.result.state = "fail"; + test.result.errors = [error]; + } else { + test.result.state = "pass"; + test.result.errors = void 0; + } + } + setCurrentTest(void 0); + test.result.duration = now() - start; + await ((_f = runner.onAfterRunTask) == null ? void 0 : _f.call(runner, test)); + updateTask(test, runner); +} +function failTask(result, err, diffOptions) { + if (err instanceof PendingError) { + result.state = "skip"; + return; + } + result.state = "fail"; + const errors = Array.isArray(err) ? err : [err]; + for (const e of errors) { + const error = processError(e, diffOptions); + result.errors ?? (result.errors = []); + result.errors.push(error); + } +} +function markTasksAsSkipped(suite, runner) { + suite.tasks.forEach((t) => { + t.mode = "skip"; + t.result = { ...t.result, state: "skip" }; + updateTask(t, runner); + if (t.type === "suite") + markTasksAsSkipped(t, runner); + }); +} +async function runSuite(suite, runner) { + var _a, _b, _c, _d; + await ((_a = runner.onBeforeRunSuite) == null ? void 0 : _a.call(runner, suite)); + if (((_b = suite.result) == null ? void 0 : _b.state) === "fail") { + markTasksAsSkipped(suite, runner); + updateTask(suite, runner); + return; + } + const start = now(); + suite.result = { + state: "run", + startTime: start + }; + updateTask(suite, runner); + let beforeAllCleanups = []; + if (suite.mode === "skip") { + suite.result.state = "skip"; + } else if (suite.mode === "todo") { + suite.result.state = "todo"; + } else { + try { + beforeAllCleanups = await callSuiteHook(suite, suite, "beforeAll", runner, [suite]); + if (runner.runSuite) { + await runner.runSuite(suite); + } else { + for (let tasksGroup of partitionSuiteChildren(suite)) { + if (tasksGroup[0].concurrent === true) { + const mutex = limit(runner.config.maxConcurrency); + await Promise.all(tasksGroup.map((c) => mutex(() => runSuiteChild(c, runner)))); + } else { + const { sequence } = runner.config; + if (sequence.shuffle || suite.shuffle) { + const suites = tasksGroup.filter((group) => group.type === "suite"); + const tests = tasksGroup.filter((group) => group.type === "test"); + const groups = shuffle([suites, tests], sequence.seed); + tasksGroup = groups.flatMap((group) => shuffle(group, sequence.seed)); + } + for (const c of tasksGroup) + await runSuiteChild(c, runner); + } + } + } + } catch (e) { + failTask(suite.result, e, runner.config.diffOptions); + } + try { + await callSuiteHook(suite, suite, "afterAll", runner, [suite]); + await callCleanupHooks(beforeAllCleanups); + } catch (e) { + failTask(suite.result, e, runner.config.diffOptions); + } + if (suite.mode === "run") { + if (!runner.config.passWithNoTests && !hasTests(suite)) { + suite.result.state = "fail"; + if (!((_c = suite.result.errors) == null ? void 0 : _c.length)) { + const error = processError(new Error(`No test found in suite ${suite.name}`)); + suite.result.errors = [error]; + } + } else if (hasFailed(suite)) { + suite.result.state = "fail"; + } else { + suite.result.state = "pass"; + } + } + updateTask(suite, runner); + suite.result.duration = now() - start; + await ((_d = runner.onAfterRunSuite) == null ? void 0 : _d.call(runner, suite)); + } +} +async function runSuiteChild(c, runner) { + if (c.type === "test" || c.type === "custom") + return runTest(c, runner); + else if (c.type === "suite") + return runSuite(c, runner); +} +async function runFiles(files, runner) { + var _a, _b; + for (const file of files) { + if (!file.tasks.length && !runner.config.passWithNoTests) { + if (!((_b = (_a = file.result) == null ? void 0 : _a.errors) == null ? void 0 : _b.length)) { + const error = processError(new Error(`No test suite found in file ${file.filepath}`)); + file.result = { + state: "fail", + errors: [error] + }; + } + } + await runSuite(file, runner); + } +} +async function startTests(paths, runner) { + var _a, _b, _c, _d; + await ((_a = runner.onBeforeCollect) == null ? void 0 : _a.call(runner, paths)); + const files = await collectTests(paths, runner); + await ((_b = runner.onCollected) == null ? void 0 : _b.call(runner, files)); + await ((_c = runner.onBeforeRunFiles) == null ? void 0 : _c.call(runner, files)); + await runFiles(files, runner); + await ((_d = runner.onAfterRunFiles) == null ? void 0 : _d.call(runner, files)); + await sendTasksUpdate(runner); + return files; +} + +function getDefaultHookTimeout() { + return getRunner().config.hookTimeout; +} +function beforeAll(fn, timeout) { + return getCurrentSuite().on("beforeAll", withTimeout(fn, timeout ?? getDefaultHookTimeout(), true)); +} +function afterAll(fn, timeout) { + return getCurrentSuite().on("afterAll", withTimeout(fn, timeout ?? getDefaultHookTimeout(), true)); +} +function beforeEach(fn, timeout) { + return getCurrentSuite().on("beforeEach", withTimeout(withFixtures(fn), timeout ?? getDefaultHookTimeout(), true)); +} +function afterEach(fn, timeout) { + return getCurrentSuite().on("afterEach", withTimeout(withFixtures(fn), timeout ?? getDefaultHookTimeout(), true)); +} +const onTestFailed = createTestHook("onTestFailed", (test, handler) => { + test.onFailed || (test.onFailed = []); + test.onFailed.push(handler); +}); +const onTestFinished = createTestHook("onTestFinished", (test, handler) => { + test.onFinished || (test.onFinished = []); + test.onFinished.push(handler); +}); +function createTestHook(name, handler) { + return (fn) => { + const current = getCurrentTest(); + if (!current) + throw new Error(`Hook ${name}() can only be called inside a test`); + return handler(current, fn); + }; +} + +export { afterAll, afterEach, beforeAll, beforeEach, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, setFn, setHooks, startTests, suite, test, updateTask }; diff --git a/node_modules/@vitest/runner/dist/tasks-K5XERDtv.d.ts b/node_modules/@vitest/runner/dist/tasks-K5XERDtv.d.ts new file mode 100644 index 0000000..43689ec --- /dev/null +++ b/node_modules/@vitest/runner/dist/tasks-K5XERDtv.d.ts @@ -0,0 +1,280 @@ +import { ErrorWithDiff, Awaitable } from '@vitest/utils'; + +type ChainableFunction any, C = {}> = F & { + [x in T]: ChainableFunction; +} & { + fn: (this: Record, ...args: Parameters) => ReturnType; +} & C; +declare function createChainable(keys: T[], fn: (this: Record, ...args: Args) => R): ChainableFunction R>; + +interface FixtureItem extends FixtureOptions { + prop: string; + value: any; + /** + * Indicates whether the fixture is a function + */ + isFn: boolean; + /** + * The dependencies(fixtures) of current fixture function. + */ + deps?: FixtureItem[]; +} + +type RunMode = 'run' | 'skip' | 'only' | 'todo'; +type TaskState = RunMode | 'pass' | 'fail'; +interface TaskBase { + id: string; + name: string; + mode: RunMode; + meta: TaskMeta; + each?: boolean; + concurrent?: boolean; + shuffle?: boolean; + suite?: Suite; + file?: File; + result?: TaskResult; + retry?: number; + repeats?: number; + location?: { + line: number; + column: number; + }; +} +interface TaskPopulated extends TaskBase { + suite: Suite; + pending?: boolean; + result?: TaskResult; + fails?: boolean; + onFailed?: OnTestFailedHandler[]; + onFinished?: OnTestFinishedHandler[]; + /** + * Store promises (from async expects) to wait for them before finishing the test + */ + promises?: Promise[]; +} +interface TaskMeta { +} +interface TaskResult { + state: TaskState; + duration?: number; + startTime?: number; + heap?: number; + errors?: ErrorWithDiff[]; + htmlError?: string; + hooks?: Partial>; + retryCount?: number; + repeatCount?: number; +} +type TaskResultPack = [id: string, result: TaskResult | undefined, meta: TaskMeta]; +interface Suite extends TaskBase { + type: 'suite'; + tasks: Task[]; + filepath?: string; + projectName: string; +} +interface File extends Suite { + filepath: string; + collectDuration?: number; + setupDuration?: number; +} +interface Test extends TaskPopulated { + type: 'test'; + context: TaskContext & ExtraContext & TestContext; +} +interface Custom extends TaskPopulated { + type: 'custom'; + context: TaskContext & ExtraContext & TestContext; +} +type Task = Test | Suite | Custom | File; +type DoneCallback = (error?: any) => void; +type TestFunction = (context: ExtendedContext & ExtraContext) => Awaitable | void; +type ExtractEachCallbackArgs> = { + 1: [T[0]]; + 2: [T[0], T[1]]; + 3: [T[0], T[1], T[2]]; + 4: [T[0], T[1], T[2], T[3]]; + 5: [T[0], T[1], T[2], T[3], T[4]]; + 6: [T[0], T[1], T[2], T[3], T[4], T[5]]; + 7: [T[0], T[1], T[2], T[3], T[4], T[5], T[6]]; + 8: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7]]; + 9: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]]; + 10: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]]; + fallback: Array ? U : any>; +}[T extends Readonly<[any]> ? 1 : T extends Readonly<[any, any]> ? 2 : T extends Readonly<[any, any, any]> ? 3 : T extends Readonly<[any, any, any, any]> ? 4 : T extends Readonly<[any, any, any, any, any]> ? 5 : T extends Readonly<[any, any, any, any, any, any]> ? 6 : T extends Readonly<[any, any, any, any, any, any, any]> ? 7 : T extends Readonly<[any, any, any, any, any, any, any, any]> ? 8 : T extends Readonly<[any, any, any, any, any, any, any, any, any]> ? 9 : T extends Readonly<[any, any, any, any, any, any, any, any, any, any]> ? 10 : 'fallback']; +interface EachFunctionReturn { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: (...args: T) => Awaitable, options: TestOptions): void; + (name: string | Function, fn: (...args: T) => Awaitable, options?: number | TestOptions): void; + (name: string | Function, options: TestOptions, fn: (...args: T) => Awaitable): void; +} +interface TestEachFunction { + (cases: ReadonlyArray): EachFunctionReturn; + >(cases: ReadonlyArray): EachFunctionReturn>; + (cases: ReadonlyArray): EachFunctionReturn; + (...args: [TemplateStringsArray, ...any]): EachFunctionReturn; +} +interface TestCollectorCallable { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: TestFunction, options: TestOptions): void; + (name: string | Function, fn?: TestFunction, options?: number | TestOptions): void; + (name: string | Function, options?: TestOptions, fn?: TestFunction): void; +} +type ChainableTestAPI = ChainableFunction<'concurrent' | 'sequential' | 'only' | 'skip' | 'todo' | 'fails', TestCollectorCallable, { + each: TestEachFunction; +}>; +interface TestOptions { + /** + * Test timeout. + */ + timeout?: number; + /** + * Times to retry the test if fails. Useful for making flaky tests more stable. + * When retries is up, the last test error will be thrown. + * + * @default 0 + */ + retry?: number; + /** + * How many times the test will run. + * Only inner tests will repeat if set on `describe()`, nested `describe()` will inherit parent's repeat by default. + * + * @default 0 + */ + repeats?: number; + /** + * Whether tests run concurrently. + * Tests inherit `concurrent` from `describe()` and nested `describe()` will inherit from parent's `concurrent`. + */ + concurrent?: boolean; + /** + * Whether tests run sequentially. + * Tests inherit `sequential` from `describe()` and nested `describe()` will inherit from parent's `sequential`. + */ + sequential?: boolean; + /** + * Whether the test should be skipped. + */ + skip?: boolean; + /** + * Should this test be the only one running in a suite. + */ + only?: boolean; + /** + * Whether the test should be skipped and marked as a todo. + */ + todo?: boolean; + /** + * Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail. + */ + fails?: boolean; +} +interface ExtendedAPI { + skipIf: (condition: any) => ChainableTestAPI; + runIf: (condition: any) => ChainableTestAPI; +} +type CustomAPI = ChainableTestAPI & ExtendedAPI & { + extend: = {}>(fixtures: Fixtures) => CustomAPI<{ + [K in keyof T | keyof ExtraContext]: K extends keyof T ? T[K] : K extends keyof ExtraContext ? ExtraContext[K] : never; + }>; +}; +type TestAPI = ChainableTestAPI & ExtendedAPI & { + extend: = {}>(fixtures: Fixtures) => TestAPI<{ + [K in keyof T | keyof ExtraContext]: K extends keyof T ? T[K] : K extends keyof ExtraContext ? ExtraContext[K] : never; + }>; +}; +interface FixtureOptions { + /** + * Whether to automatically set up current fixture, even though it's not being used in tests. + */ + auto?: boolean; +} +type Use = (value: T) => Promise; +type FixtureFn = (context: Omit & ExtraContext, use: Use) => Promise; +type Fixture = ((...args: any) => any) extends T[K] ? (T[K] extends any ? FixtureFn>> : never) : T[K] | (T[K] extends any ? FixtureFn>> : never); +type Fixtures, ExtraContext = {}> = { + [K in keyof T]: Fixture> | [Fixture>, FixtureOptions?]; +}; +type InferFixturesTypes = T extends TestAPI ? C : T; +interface SuiteCollectorCallable { + /** + * @deprecated Use options as the second argument instead + */ + (name: string | Function, fn: SuiteFactory, options: TestOptions): SuiteCollector; + (name: string | Function, fn?: SuiteFactory, options?: number | TestOptions): SuiteCollector; + (name: string | Function, options: TestOptions, fn?: SuiteFactory): SuiteCollector; +} +type ChainableSuiteAPI = ChainableFunction<'concurrent' | 'sequential' | 'only' | 'skip' | 'todo' | 'shuffle', SuiteCollectorCallable, { + each: TestEachFunction; +}>; +type SuiteAPI = ChainableSuiteAPI & { + skipIf: (condition: any) => ChainableSuiteAPI; + runIf: (condition: any) => ChainableSuiteAPI; +}; +type HookListener = (...args: T) => Awaitable; +type HookCleanupCallback = (() => Awaitable) | void; +interface SuiteHooks { + beforeAll: HookListener<[Readonly], HookCleanupCallback>[]; + afterAll: HookListener<[Readonly]>[]; + beforeEach: HookListener<[ExtendedContext & ExtraContext, Readonly], HookCleanupCallback>[]; + afterEach: HookListener<[ExtendedContext & ExtraContext, Readonly]>[]; +} +interface TaskCustomOptions extends TestOptions { + concurrent?: boolean; + sequential?: boolean; + skip?: boolean; + only?: boolean; + todo?: boolean; + fails?: boolean; + each?: boolean; + meta?: Record; + fixtures?: FixtureItem[]; + handler?: (context: TaskContext) => Awaitable; +} +interface SuiteCollector { + readonly name: string; + readonly mode: RunMode; + options?: TestOptions; + type: 'collector'; + test: TestAPI; + tasks: (Suite | Custom | Test | SuiteCollector)[]; + task: (name: string, options?: TaskCustomOptions) => Custom; + collect: (file?: File) => Promise; + clear: () => void; + on: >(name: T, ...fn: SuiteHooks[T]) => void; +} +type SuiteFactory = (test: TestAPI) => Awaitable; +interface RuntimeContext { + tasks: (SuiteCollector | Test)[]; + currentSuite: SuiteCollector | null; +} +interface TestContext { +} +interface TaskContext { + /** + * Metadata of the current test + */ + task: Readonly; + /** + * Extract hooks on test failed + */ + onTestFailed: (fn: OnTestFailedHandler) => void; + /** + * Extract hooks on test failed + */ + onTestFinished: (fn: OnTestFinishedHandler) => void; + /** + * Mark tests as skipped. All execution after this call will be skipped. + */ + skip: () => void; +} +type ExtendedContext = TaskContext & TestContext; +type OnTestFailedHandler = (result: TaskResult) => Awaitable; +type OnTestFinishedHandler = (result: TaskResult) => Awaitable; +type SequenceHooks = 'stack' | 'list' | 'parallel'; +type SequenceSetupFiles = 'list' | 'parallel'; + +export { type TaskContext as A, type SequenceHooks as B, type Custom as C, type DoneCallback as D, type ExtendedContext as E, type File as F, type SequenceSetupFiles as G, type HookListener as H, type InferFixturesTypes as I, type OnTestFailedHandler as O, type RunMode as R, type Suite as S, type Task as T, type Use as U, type Test as a, type ChainableFunction as b, createChainable as c, type SuiteAPI as d, type TestAPI as e, type SuiteCollector as f, type CustomAPI as g, type SuiteHooks as h, type OnTestFinishedHandler as i, type TaskState as j, type TaskBase as k, type TaskPopulated as l, type TaskMeta as m, type TaskResult as n, type TaskResultPack as o, type TestFunction as p, type TestOptions as q, type FixtureOptions as r, type FixtureFn as s, type Fixture as t, type Fixtures as u, type HookCleanupCallback as v, type TaskCustomOptions as w, type SuiteFactory as x, type RuntimeContext as y, type TestContext as z }; diff --git a/node_modules/@vitest/runner/dist/types.d.ts b/node_modules/@vitest/runner/dist/types.d.ts new file mode 100644 index 0000000..e6acd88 --- /dev/null +++ b/node_modules/@vitest/runner/dist/types.d.ts @@ -0,0 +1,121 @@ +import { B as SequenceHooks, G as SequenceSetupFiles, F as File, T as Task, S as Suite, o as TaskResultPack, a as Test, C as Custom, A as TaskContext, E as ExtendedContext } from './tasks-K5XERDtv.js'; +export { g as CustomAPI, D as DoneCallback, t as Fixture, s as FixtureFn, r as FixtureOptions, u as Fixtures, v as HookCleanupCallback, H as HookListener, I as InferFixturesTypes, O as OnTestFailedHandler, i as OnTestFinishedHandler, R as RunMode, y as RuntimeContext, d as SuiteAPI, f as SuiteCollector, x as SuiteFactory, h as SuiteHooks, k as TaskBase, w as TaskCustomOptions, m as TaskMeta, l as TaskPopulated, n as TaskResult, j as TaskState, e as TestAPI, z as TestContext, p as TestFunction, q as TestOptions, U as Use } from './tasks-K5XERDtv.js'; +import { DiffOptions } from '@vitest/utils/diff'; +import '@vitest/utils'; + +interface VitestRunnerConfig { + root: string; + setupFiles: string[] | string; + name: string; + passWithNoTests: boolean; + testNamePattern?: RegExp; + allowOnly?: boolean; + sequence: { + shuffle?: boolean; + concurrent?: boolean; + seed: number; + hooks: SequenceHooks; + setupFiles: SequenceSetupFiles; + }; + chaiConfig?: { + truncateThreshold?: number; + }; + maxConcurrency: number; + testTimeout: number; + hookTimeout: number; + retry: number; + includeTaskLocation?: boolean; + diffOptions?: DiffOptions; +} +type VitestRunnerImportSource = 'collect' | 'setup'; +interface VitestRunnerConstructor { + new (config: VitestRunnerConfig): VitestRunner; +} +type CancelReason = 'keyboard-input' | 'test-failure' | string & Record; +interface VitestRunner { + /** + * First thing that's getting called before actually collecting and running tests. + */ + onBeforeCollect?: (paths: string[]) => unknown; + /** + * Called after collecting tests and before "onBeforeRun". + */ + onCollected?: (files: File[]) => unknown; + /** + * Called when test runner should cancel next test runs. + * Runner should listen for this method and mark tests and suites as skipped in + * "onBeforeRunSuite" and "onBeforeRunTask" when called. + */ + onCancel?: (reason: CancelReason) => unknown; + /** + * Called before running a single test. Doesn't have "result" yet. + */ + onBeforeRunTask?: (test: Task) => unknown; + /** + * Called before actually running the test function. Already has "result" with "state" and "startTime". + */ + onBeforeTryTask?: (test: Task, options: { + retry: number; + repeats: number; + }) => unknown; + /** + * Called after result and state are set. + */ + onAfterRunTask?: (test: Task) => unknown; + /** + * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws. + */ + onAfterTryTask?: (test: Task, options: { + retry: number; + repeats: number; + }) => unknown; + /** + * Called before running a single suite. Doesn't have "result" yet. + */ + onBeforeRunSuite?: (suite: Suite) => unknown; + /** + * Called after running a single suite. Has state and result. + */ + onAfterRunSuite?: (suite: Suite) => unknown; + /** + * If defined, will be called instead of usual Vitest suite partition and handling. + * "before" and "after" hooks will not be ignored. + */ + runSuite?: (suite: Suite) => Promise; + /** + * If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function. + * "before" and "after" hooks will not be ignored. + */ + runTask?: (test: Task) => Promise; + /** + * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests. + */ + onTaskUpdate?: (task: TaskResultPack[]) => Promise; + /** + * Called before running all tests in collected paths. + */ + onBeforeRunFiles?: (files: File[]) => unknown; + /** + * Called right after running all tests in collected paths. + */ + onAfterRunFiles?: (files: File[]) => unknown; + /** + * Called when new context for a test is defined. Useful, if you want to add custom properties to the context. + * If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead. + * + * This method is called for both "test" and "custom" handlers. + * + * @see https://vitest.dev/advanced/runner.html#your-task-function + */ + extendTaskContext?: (context: TaskContext) => ExtendedContext; + /** + * Called, when files are imported. Can be called in two situations: when collecting tests and when importing setup files. + */ + importFile: (filepath: string, source: VitestRunnerImportSource) => unknown; + /** + * Publicly available configuration. + */ + config: VitestRunnerConfig; +} + +export { type CancelReason, Custom, ExtendedContext, File, SequenceHooks, SequenceSetupFiles, Suite, Task, TaskContext, TaskResultPack, Test, type VitestRunner, type VitestRunnerConfig, type VitestRunnerConstructor, type VitestRunnerImportSource }; diff --git a/node_modules/@vitest/runner/dist/types.js b/node_modules/@vitest/runner/dist/types.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/node_modules/@vitest/runner/dist/types.js @@ -0,0 +1 @@ + diff --git a/node_modules/@vitest/runner/dist/utils.d.ts b/node_modules/@vitest/runner/dist/utils.d.ts new file mode 100644 index 0000000..ff4999c --- /dev/null +++ b/node_modules/@vitest/runner/dist/utils.d.ts @@ -0,0 +1,25 @@ +import { S as Suite, T as Task, a as Test, C as Custom } from './tasks-K5XERDtv.js'; +export { b as ChainableFunction, c as createChainable } from './tasks-K5XERDtv.js'; +import { Arrayable } from '@vitest/utils'; + +/** + * If any tasks been marked as `only`, mark all other tasks as `skip`. + */ +declare function interpretTaskModes(suite: Suite, namePattern?: string | RegExp, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean): void; +declare function someTasksAreOnly(suite: Suite): boolean; +declare function generateHash(str: string): string; +declare function calculateSuiteHash(parent: Suite): void; + +/** + * Partition in tasks groups by consecutive concurrent + */ +declare function partitionSuiteChildren(suite: Suite): Task[][]; + +declare function getTests(suite: Arrayable): (Test | Custom)[]; +declare function getTasks(tasks?: Arrayable): Task[]; +declare function getSuites(suite: Arrayable): Suite[]; +declare function hasTests(suite: Arrayable): boolean; +declare function hasFailed(suite: Arrayable): boolean; +declare function getNames(task: Task): string[]; + +export { calculateSuiteHash, generateHash, getNames, getSuites, getTasks, getTests, hasFailed, hasTests, interpretTaskModes, partitionSuiteChildren, someTasksAreOnly }; diff --git a/node_modules/@vitest/runner/dist/utils.js b/node_modules/@vitest/runner/dist/utils.js new file mode 100644 index 0000000..c326e81 --- /dev/null +++ b/node_modules/@vitest/runner/dist/utils.js @@ -0,0 +1,3 @@ +export { c as calculateSuiteHash, j as createChainable, g as generateHash, f as getNames, d as getSuites, b as getTasks, a as getTests, e as hasFailed, h as hasTests, i as interpretTaskModes, p as partitionSuiteChildren, s as someTasksAreOnly } from './chunk-tasks.js'; +import '@vitest/utils/error'; +import '@vitest/utils'; diff --git a/node_modules/@vitest/runner/package.json b/node_modules/@vitest/runner/package.json new file mode 100644 index 0000000..82b7481 --- /dev/null +++ b/node_modules/@vitest/runner/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vitest/runner", + "type": "module", + "version": "1.6.1", + "description": "Vitest test runner", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/runner#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/runner" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": true, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./utils": { + "types": "./dist/utils.d.ts", + "default": "./dist/utils.js" + }, + "./types": { + "types": "./dist/types.d.ts", + "default": "./dist/types.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "p-limit": "^5.0.0", + "pathe": "^1.1.1", + "@vitest/utils": "1.6.1" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/runner/types.d.ts b/node_modules/@vitest/runner/types.d.ts new file mode 100644 index 0000000..26a1254 --- /dev/null +++ b/node_modules/@vitest/runner/types.d.ts @@ -0,0 +1 @@ +export * from './dist/types.js' diff --git a/node_modules/@vitest/runner/utils.d.ts b/node_modules/@vitest/runner/utils.d.ts new file mode 100644 index 0000000..e3f344e --- /dev/null +++ b/node_modules/@vitest/runner/utils.d.ts @@ -0,0 +1 @@ +export * from './dist/utils.js' diff --git a/node_modules/@vitest/snapshot/LICENSE b/node_modules/@vitest/snapshot/LICENSE new file mode 100644 index 0000000..5ae481f --- /dev/null +++ b/node_modules/@vitest/snapshot/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/snapshot/README.md b/node_modules/@vitest/snapshot/README.md new file mode 100644 index 0000000..4c4ecda --- /dev/null +++ b/node_modules/@vitest/snapshot/README.md @@ -0,0 +1,79 @@ +# @vitest/snapshot + +Lightweight implementation of Jest's snapshots. + +## Usage + +```js +import { SnapshotClient } from '@vitest/snapshot' +import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment' +import { SnapshotManager } from '@vitest/snapshot/manager' + +const client = new SnapshotClient({ + // you need to provide your own equality check implementation if you use it + // this function is called when `.toMatchSnapshot({ property: 1 })` is called + isEqual: (received, expected) => equals(received, expected, [iterableEquality, subsetEquality]), +}) + +// class that implements snapshot saving and reading +// by default uses fs module, but you can provide your own implementation depending on the environment +const environment = new NodeSnapshotEnvironment() + +// you need to implement this yourselves, +// this depends on your runner +function getCurrentFilepath() { + return '/file.spec.js' +} +function getCurrentTestName() { + return 'test1' +} + +// example for inline snapshots, nothing is required to support regular snapshots, +// just call `assert` with `isInline: false` +function wrapper(received) { + function __INLINE_SNAPSHOT__(inlineSnapshot, message) { + client.assert({ + received, + message, + isInline: true, + inlineSnapshot, + filepath: getCurrentFilepath(), + name: getCurrentTestName(), + }) + } + return { + // the name is hard-coded, it should be inside another function, so Vitest can find the actual test file where it was called (parses call stack trace + 2) + // you can override this behaviour in SnapshotState's `_inferInlineSnapshotStack` method by providing your own SnapshotState to SnapshotClient constructor + toMatchInlineSnapshot: (...args) => __INLINE_SNAPSHOT__(...args), + } +} + +const options = { + updateSnapshot: 'new', + snapshotEnvironment: environment, +} + +await client.startCurrentRun(getCurrentFilepath(), getCurrentTestName(), options) + +// this will save snapshot to a file which is returned by "snapshotEnvironment.resolvePath" +client.assert({ + received: 'some text', + isInline: false, +}) + +// uses "pretty-format", so it requires quotes +// also naming is hard-coded when parsing test files +wrapper('text 1').toMatchInlineSnapshot() +wrapper('text 2').toMatchInlineSnapshot('"text 2"') + +const result = await client.finishCurrentRun() // this saves files and returns SnapshotResult + +// you can use manager to manage several clients +const manager = new SnapshotManager(options) +manager.add(result) + +// do something +// and then read the summary + +console.log(manager.summary) +``` diff --git a/node_modules/@vitest/snapshot/dist/environment-cMiGIVXz.d.ts b/node_modules/@vitest/snapshot/dist/environment-cMiGIVXz.d.ts new file mode 100644 index 0000000..1b2d012 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment-cMiGIVXz.d.ts @@ -0,0 +1,14 @@ +interface SnapshotEnvironment { + getVersion: () => string; + getHeader: () => string; + resolvePath: (filepath: string) => Promise; + resolveRawPath: (testPath: string, rawPath: string) => Promise; + saveSnapshotFile: (filepath: string, snapshot: string) => Promise; + readSnapshotFile: (filepath: string) => Promise; + removeSnapshotFile: (filepath: string) => Promise; +} +interface SnapshotEnvironmentOptions { + snapshotsDirName?: string; +} + +export type { SnapshotEnvironment as S, SnapshotEnvironmentOptions as a }; diff --git a/node_modules/@vitest/snapshot/dist/environment.d.ts b/node_modules/@vitest/snapshot/dist/environment.d.ts new file mode 100644 index 0000000..27cc6b5 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment.d.ts @@ -0,0 +1,16 @@ +import { S as SnapshotEnvironment, a as SnapshotEnvironmentOptions } from './environment-cMiGIVXz.js'; + +declare class NodeSnapshotEnvironment implements SnapshotEnvironment { + private options; + constructor(options?: SnapshotEnvironmentOptions); + getVersion(): string; + getHeader(): string; + resolveRawPath(testPath: string, rawPath: string): Promise; + resolvePath(filepath: string): Promise; + prepareDirectory(dirPath: string): Promise; + saveSnapshotFile(filepath: string, snapshot: string): Promise; + readSnapshotFile(filepath: string): Promise; + removeSnapshotFile(filepath: string): Promise; +} + +export { NodeSnapshotEnvironment, SnapshotEnvironment }; diff --git a/node_modules/@vitest/snapshot/dist/environment.js b/node_modules/@vitest/snapshot/dist/environment.js new file mode 100644 index 0000000..f6a95f4 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/environment.js @@ -0,0 +1,44 @@ +import { promises, existsSync } from 'node:fs'; +import { isAbsolute, resolve, dirname, join, basename } from 'pathe'; + +class NodeSnapshotEnvironment { + constructor(options = {}) { + this.options = options; + } + getVersion() { + return "1"; + } + getHeader() { + return `// Snapshot v${this.getVersion()}`; + } + async resolveRawPath(testPath, rawPath) { + return isAbsolute(rawPath) ? rawPath : resolve(dirname(testPath), rawPath); + } + async resolvePath(filepath) { + return join( + join( + dirname(filepath), + this.options.snapshotsDirName ?? "__snapshots__" + ), + `${basename(filepath)}.snap` + ); + } + async prepareDirectory(dirPath) { + await promises.mkdir(dirPath, { recursive: true }); + } + async saveSnapshotFile(filepath, snapshot) { + await promises.mkdir(dirname(filepath), { recursive: true }); + await promises.writeFile(filepath, snapshot, "utf-8"); + } + async readSnapshotFile(filepath) { + if (!existsSync(filepath)) + return null; + return promises.readFile(filepath, "utf-8"); + } + async removeSnapshotFile(filepath) { + if (existsSync(filepath)) + await promises.unlink(filepath); + } +} + +export { NodeSnapshotEnvironment }; diff --git a/node_modules/@vitest/snapshot/dist/index-S94ASl6q.d.ts b/node_modules/@vitest/snapshot/dist/index-S94ASl6q.d.ts new file mode 100644 index 0000000..7db0681 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/index-S94ASl6q.d.ts @@ -0,0 +1,60 @@ +import { Plugin, OptionsReceived } from 'pretty-format'; +import { S as SnapshotEnvironment } from './environment-cMiGIVXz.js'; + +interface RawSnapshotInfo { + file: string; + readonly?: boolean; + content?: string; +} + +type SnapshotData = Record; +type SnapshotUpdateState = 'all' | 'new' | 'none'; +type SnapshotSerializer = Plugin; +interface SnapshotStateOptions { + updateSnapshot: SnapshotUpdateState; + snapshotEnvironment: SnapshotEnvironment; + expand?: boolean; + snapshotFormat?: OptionsReceived; + resolveSnapshotPath?: (path: string, extension: string) => string; +} +interface SnapshotMatchOptions { + testName: string; + received: unknown; + key?: string; + inlineSnapshot?: string; + isInline: boolean; + error?: Error; + rawSnapshot?: RawSnapshotInfo; +} +interface SnapshotResult { + filepath: string; + added: number; + fileDeleted: boolean; + matched: number; + unchecked: number; + uncheckedKeys: Array; + unmatched: number; + updated: number; +} +interface UncheckedSnapshot { + filePath: string; + keys: Array; +} +interface SnapshotSummary { + added: number; + didUpdate: boolean; + failure: boolean; + filesAdded: number; + filesRemoved: number; + filesRemovedList: Array; + filesUnmatched: number; + filesUpdated: number; + matched: number; + total: number; + unchecked: number; + uncheckedKeysByFile: Array; + unmatched: number; + updated: number; +} + +export type { RawSnapshotInfo as R, SnapshotStateOptions as S, UncheckedSnapshot as U, SnapshotMatchOptions as a, SnapshotResult as b, SnapshotData as c, SnapshotUpdateState as d, SnapshotSerializer as e, SnapshotSummary as f }; diff --git a/node_modules/@vitest/snapshot/dist/index.d.ts b/node_modules/@vitest/snapshot/dist/index.d.ts new file mode 100644 index 0000000..ba78fd8 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/index.d.ts @@ -0,0 +1,109 @@ +import { S as SnapshotStateOptions, a as SnapshotMatchOptions, b as SnapshotResult, R as RawSnapshotInfo } from './index-S94ASl6q.js'; +export { c as SnapshotData, e as SnapshotSerializer, f as SnapshotSummary, d as SnapshotUpdateState, U as UncheckedSnapshot } from './index-S94ASl6q.js'; +import { S as SnapshotEnvironment } from './environment-cMiGIVXz.js'; +import { Plugin, Plugins } from 'pretty-format'; + +interface ParsedStack { + method: string; + file: string; + line: number; + column: number; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +interface SnapshotReturnOptions { + actual: string; + count: number; + expected?: string; + key: string; + pass: boolean; +} +interface SaveStatus { + deleted: boolean; + saved: boolean; +} +declare class SnapshotState { + testFilePath: string; + snapshotPath: string; + private _counters; + private _dirty; + private _updateSnapshot; + private _snapshotData; + private _initialData; + private _inlineSnapshots; + private _rawSnapshots; + private _uncheckedKeys; + private _snapshotFormat; + private _environment; + private _fileExists; + added: number; + expand: boolean; + matched: number; + unmatched: number; + updated: number; + private constructor(); + static create(testFilePath: string, options: SnapshotStateOptions): Promise; + get environment(): SnapshotEnvironment; + markSnapshotsAsCheckedForTest(testName: string): void; + protected _inferInlineSnapshotStack(stacks: ParsedStack[]): ParsedStack | null; + private _addSnapshot; + clear(): void; + save(): Promise; + getUncheckedCount(): number; + getUncheckedKeys(): Array; + removeUncheckedKeys(): void; + match({ testName, received, key, inlineSnapshot, isInline, error, rawSnapshot, }: SnapshotMatchOptions): SnapshotReturnOptions; + pack(): Promise; +} + +interface AssertOptions { + received: unknown; + filepath?: string; + name?: string; + message?: string; + isInline?: boolean; + properties?: object; + inlineSnapshot?: string; + error?: Error; + errorMessage?: string; + rawSnapshot?: RawSnapshotInfo; +} +interface SnapshotClientOptions { + isEqual?: (received: unknown, expected: unknown) => boolean; +} +declare class SnapshotClient { + private options; + filepath?: string; + name?: string; + snapshotState: SnapshotState | undefined; + snapshotStateMap: Map; + constructor(options?: SnapshotClientOptions); + startCurrentRun(filepath: string, name: string, options: SnapshotStateOptions): Promise; + getSnapshotState(filepath: string): SnapshotState; + clearTest(): void; + skipTestSnapshots(name: string): void; + assert(options: AssertOptions): void; + assertRaw(options: AssertOptions): Promise; + finishCurrentRun(): Promise; + clear(): void; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +declare function addSerializer(plugin: Plugin): void; +declare function getSerializers(): Plugins; + +declare function stripSnapshotIndentation(inlineSnapshot: string): string; + +export { SnapshotClient, SnapshotMatchOptions, SnapshotResult, SnapshotState, SnapshotStateOptions, addSerializer, getSerializers, stripSnapshotIndentation }; diff --git a/node_modules/@vitest/snapshot/dist/index.js b/node_modules/@vitest/snapshot/dist/index.js new file mode 100644 index 0000000..4b1e617 --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/index.js @@ -0,0 +1,1548 @@ +import { plugins, format } from 'pretty-format'; +import { resolve as resolve$2 } from 'pathe'; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var naturalCompare$2 = {exports: {}}; + +/* + * @version 1.4.0 + * @date 2015-10-26 + * @stability 3 - Stable + * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) + * @license MIT License + */ + + +var naturalCompare = function(a, b) { + var i, codeA + , codeB = 1 + , posA = 0 + , posB = 0 + , alphabet = String.alphabet; + + function getCode(str, pos, code) { + if (code) { + for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i; + return +str.slice(pos - 1, i) + } + code = alphabet && alphabet.indexOf(str.charAt(pos)); + return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code + : code < 46 ? 65 // - + : code < 48 ? code - 1 + : code < 58 ? code + 18 // 0-9 + : code < 65 ? code - 11 + : code < 91 ? code + 11 // A-Z + : code < 97 ? code - 37 + : code < 123 ? code + 5 // a-z + : code - 63 + } + + + if ((a+="") != (b+="")) for (;codeB;) { + codeA = getCode(a, posA++); + codeB = getCode(b, posB++); + + if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { + codeA = getCode(a, posA, posA); + codeB = getCode(b, posB, posA = i); + posB = i; + } + + if (codeA != codeB) return (codeA < codeB) ? -1 : 1 + } + return 0 +}; + +try { + naturalCompare$2.exports = naturalCompare; +} catch (e) { + String.naturalCompare = naturalCompare; +} + +var naturalCompareExports = naturalCompare$2.exports; +var naturalCompare$1 = /*@__PURE__*/getDefaultExportFromCjs(naturalCompareExports); + +function notNullish(v) { + return v != null; +} +function isPrimitive(value) { + return value === null || typeof value !== "function" && typeof value !== "object"; +} +function isObject(item) { + return item != null && typeof item === "object" && !Array.isArray(item); +} +function getCallLastIndex(code) { + let charIndex = -1; + let inString = null; + let startedBracers = 0; + let endedBracers = 0; + let beforeChar = null; + while (charIndex <= code.length) { + beforeChar = code[charIndex]; + charIndex++; + const char = code[charIndex]; + const isCharString = char === '"' || char === "'" || char === "`"; + if (isCharString && beforeChar !== "\\") { + if (inString === char) + inString = null; + else if (!inString) + inString = char; + } + if (!inString) { + if (char === "(") + startedBracers++; + if (char === ")") + endedBracers++; + } + if (startedBracers && endedBracers && startedBracers === endedBracers) + return charIndex; + } + return null; +} + +let getPromiseValue = () => 'Promise{…}'; +try { + const { getPromiseDetails, kPending, kRejected } = process.binding('util'); + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = (value, options) => { + const [state, innerValue] = getPromiseDetails(value); + if (state === kPending) { + return 'Promise{}' + } + return `Promise${state === kRejected ? '!' : ''}{${options.inspect(innerValue, options)}}` + }; + } +} catch (notNode) { + /* ignore */ +} + +/* ! + * loupe + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +let nodeInspect = false; +try { + // eslint-disable-next-line global-require + const nodeUtil = require('util'); + nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; +} catch (noNodeInspect) { + nodeInspect = false; +} + +const lineSplitRE = /\r?\n/; +function positionToOffset(source, lineNumber, columnNumber) { + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let start = 0; + if (lineNumber > lines.length) + return source.length; + for (let i = 0; i < lineNumber - 1; i++) + start += lines[i].length + nl; + return start + columnNumber; +} +function offsetToLineNumber(source, offset) { + if (offset > source.length) { + throw new Error( + `offset is longer than source length! offset ${offset} > length ${source.length}` + ); + } + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let counted = 0; + let line = 0; + for (; line < lines.length; line++) { + const lineLength = lines[line].length + nl; + if (counted + lineLength >= offset) + break; + counted += lineLength; + } + return line + 1; +} + +// Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell +// License: MIT. +var LineTerminatorSequence; +LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; +RegExp(LineTerminatorSequence.source); + +// src/index.ts +var reservedWords = { + keyword: [ + "break", + "case", + "catch", + "continue", + "debugger", + "default", + "do", + "else", + "finally", + "for", + "function", + "if", + "return", + "switch", + "throw", + "try", + "var", + "const", + "while", + "with", + "new", + "this", + "super", + "class", + "extends", + "export", + "import", + "null", + "true", + "false", + "in", + "instanceof", + "typeof", + "void", + "delete" + ], + strict: [ + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield" + ] +}; new Set(reservedWords.keyword); new Set(reservedWords.strict); + +const serialize$1 = (val, config, indentation, depth, refs, printer) => { + const name = val.getMockName(); + const nameString = name === "vi.fn()" ? "" : ` ${name}`; + let callsString = ""; + if (val.mock.calls.length !== 0) { + const indentationNext = indentation + config.indent; + callsString = ` {${config.spacingOuter}${indentationNext}"calls": ${printer(val.mock.calls, config, indentationNext, depth, refs)}${config.min ? ", " : ","}${config.spacingOuter}${indentationNext}"results": ${printer(val.mock.results, config, indentationNext, depth, refs)}${config.min ? "" : ","}${config.spacingOuter}${indentation}}`; + } + return `[MockFunction${nameString}]${callsString}`; +}; +const test = (val) => val && !!val._isMockFunction; +const plugin = { serialize: serialize$1, test }; + +const { + DOMCollection, + DOMElement, + Immutable, + ReactElement, + ReactTestComponent, + AsymmetricMatcher +} = plugins; +let PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher, + plugin +]; +function addSerializer(plugin) { + PLUGINS = [plugin].concat(PLUGINS); +} +function getSerializers() { + return PLUGINS; +} + +function testNameToKey(testName, count) { + return `${testName} ${count}`; +} +function keyToTestName(key) { + if (!/ \d+$/.test(key)) + throw new Error("Snapshot keys must end with a number."); + return key.replace(/ \d+$/, ""); +} +function getSnapshotData(content, options) { + const update = options.updateSnapshot; + const data = /* @__PURE__ */ Object.create(null); + let snapshotContents = ""; + let dirty = false; + if (content != null) { + try { + snapshotContents = content; + const populate = new Function("exports", snapshotContents); + populate(data); + } catch { + } + } + const isInvalid = snapshotContents; + if ((update === "all" || update === "new") && isInvalid) + dirty = true; + return { data, dirty }; +} +function addExtraLineBreaks(string) { + return string.includes("\n") ? ` +${string} +` : string; +} +function removeExtraLineBreaks(string) { + return string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string; +} +const escapeRegex = true; +const printFunctionName = false; +function serialize(val, indent = 2, formatOverrides = {}) { + return normalizeNewlines( + format(val, { + escapeRegex, + indent, + plugins: getSerializers(), + printFunctionName, + ...formatOverrides + }) + ); +} +function escapeBacktickString(str) { + return str.replace(/`|\\|\${/g, "\\$&"); +} +function printBacktickString(str) { + return `\`${escapeBacktickString(str)}\``; +} +function normalizeNewlines(string) { + return string.replace(/\r\n|\r/g, "\n"); +} +async function saveSnapshotFile(environment, snapshotData, snapshotPath) { + const snapshots = Object.keys(snapshotData).sort(naturalCompare$1).map( + (key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};` + ); + const content = `${environment.getHeader()} + +${snapshots.join("\n\n")} +`; + const oldContent = await environment.readSnapshotFile(snapshotPath); + const skipWriting = oldContent != null && oldContent === content; + if (skipWriting) + return; + await environment.saveSnapshotFile( + snapshotPath, + content + ); +} +function prepareExpected(expected) { + function findStartIndent() { + var _a, _b; + const matchObject = /^( +)}\s+$/m.exec(expected || ""); + const objectIndent = (_a = matchObject == null ? void 0 : matchObject[1]) == null ? void 0 : _a.length; + if (objectIndent) + return objectIndent; + const matchText = /^\n( +)"/.exec(expected || ""); + return ((_b = matchText == null ? void 0 : matchText[1]) == null ? void 0 : _b.length) || 0; + } + const startIndent = findStartIndent(); + let expectedTrimmed = expected == null ? void 0 : expected.trim(); + if (startIndent) { + expectedTrimmed = expectedTrimmed == null ? void 0 : expectedTrimmed.replace(new RegExp(`^${" ".repeat(startIndent)}`, "gm"), "").replace(/ +}$/, "}"); + } + return expectedTrimmed; +} +function deepMergeArray(target = [], source = []) { + const mergedOutput = Array.from(target); + source.forEach((sourceElement, index) => { + const targetElement = mergedOutput[index]; + if (Array.isArray(target[index])) { + mergedOutput[index] = deepMergeArray(target[index], sourceElement); + } else if (isObject(targetElement)) { + mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement); + } else { + mergedOutput[index] = sourceElement; + } + }); + return mergedOutput; +} +function deepMergeSnapshot(target, source) { + if (isObject(target) && isObject(source)) { + const mergedOutput = { ...target }; + Object.keys(source).forEach((key) => { + if (isObject(source[key]) && !source[key].$$typeof) { + if (!(key in target)) + Object.assign(mergedOutput, { [key]: source[key] }); + else + mergedOutput[key] = deepMergeSnapshot(target[key], source[key]); + } else if (Array.isArray(source[key])) { + mergedOutput[key] = deepMergeArray(target[key], source[key]); + } else { + Object.assign(mergedOutput, { [key]: source[key] }); + } + }); + return mergedOutput; + } else if (Array.isArray(target) && Array.isArray(source)) { + return deepMergeArray(target, source); + } + return target; +} + +const comma = ','.charCodeAt(0); +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decode(mappings) { + const state = new Int32Array(5); + const decoded = []; + let index = 0; + do { + const semi = indexOf(mappings, index); + const line = []; + let sorted = true; + let lastCol = 0; + state[0] = 0; + for (let i = index; i < semi; i++) { + let seg; + i = decodeInteger(mappings, i, state, 0); // genColumn + const col = state[0]; + if (col < lastCol) + sorted = false; + lastCol = col; + if (hasMoreVlq(mappings, i, semi)) { + i = decodeInteger(mappings, i, state, 1); // sourcesIndex + i = decodeInteger(mappings, i, state, 2); // sourceLine + i = decodeInteger(mappings, i, state, 3); // sourceColumn + if (hasMoreVlq(mappings, i, semi)) { + i = decodeInteger(mappings, i, state, 4); // namesIndex + seg = [col, state[1], state[2], state[3], state[4]]; + } + else { + seg = [col, state[1], state[2], state[3]]; + } + } + else { + seg = [col]; + } + line.push(seg); + } + if (!sorted) + sort(line); + decoded.push(line); + index = semi + 1; + } while (index <= mappings.length); + return decoded; +} +function indexOf(mappings, index) { + const idx = mappings.indexOf(';', index); + return idx === -1 ? mappings.length : idx; +} +function decodeInteger(mappings, pos, state, j) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = mappings.charCodeAt(pos++); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -0x80000000 | -value; + } + state[j] += value; + return pos; +} +function hasMoreVlq(mappings, i, length) { + if (i >= length) + return false; + return mappings.charCodeAt(i) !== comma; +} +function sort(line) { + line.sort(sortComparator$1); +} +function sortComparator$1(a, b) { + return a[0] - b[0]; +} + +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +var UrlType; +(function (UrlType) { + UrlType[UrlType["Empty"] = 1] = "Empty"; + UrlType[UrlType["Hash"] = 2] = "Hash"; + UrlType[UrlType["Query"] = 3] = "Query"; + UrlType[UrlType["RelativePath"] = 4] = "RelativePath"; + UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath"; + UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative"; + UrlType[UrlType["Absolute"] = 7] = "Absolute"; +})(UrlType || (UrlType = {})); +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: UrlType.Absolute, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = UrlType.SchemeRelative; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = UrlType.AbsolutePath; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? UrlType.Query + : input.startsWith('#') + ? UrlType.Hash + : UrlType.RelativePath + : UrlType.Empty; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= UrlType.RelativePath; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve$1(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== UrlType.Absolute) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case UrlType.Empty: + url.hash = baseUrl.hash; + // fall through + case UrlType.Hash: + url.query = baseUrl.query; + // fall through + case UrlType.Query: + case UrlType.RelativePath: + mergePaths(url, baseUrl); + // fall through + case UrlType.AbsolutePath: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case UrlType.SchemeRelative: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case UrlType.Hash: + case UrlType.Query: + return queryHash; + case UrlType.RelativePath: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case UrlType.AbsolutePath: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +function resolve(input, base) { + // The base is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + if (base && !base.endsWith('/')) + base += '/'; + return resolve$1(input, base); +} + +/** + * Removes everything after the last "/", but leaves the slash. + */ +function stripFilename(path) { + if (!path) + return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} + +const COLUMN = 0; +const SOURCES_INDEX = 1; +const SOURCE_LINE = 2; +const SOURCE_COLUMN = 3; +const NAMES_INDEX = 4; + +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) + return mappings; + // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If + // not, we do not want to modify the consumer's input array. + if (!owned) + mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) + return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) + line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +let found = false; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } + else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1, + }; +} +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + // lastIndex may be -1 if the previous needle was not found. + low = lastIndex === -1 ? 0 : lastIndex; + } + else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return (state.lastIndex = binarySearch(haystack, needle, low, high)); +} + +const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)'; +const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)'; +const LEAST_UPPER_BOUND = -1; +const GREATEST_LOWER_BOUND = 1; +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +let decodedMappings; +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +let originalPositionFor; +class TraceMap { + constructor(map, mapUrl) { + const isString = typeof map === 'string'; + if (!isString && map._decodedMemo) + return map; + const parsed = (isString ? JSON.parse(map) : map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + const from = resolve(sourceRoot || '', stripFilename(mapUrl)); + this.resolvedSources = sources.map((s) => resolve(s || '', from)); + const { mappings } = parsed; + if (typeof mappings === 'string') { + this._encoded = mappings; + this._decoded = undefined; + } + else { + this._encoded = undefined; + this._decoded = maybeSort(mappings, isString); + } + this._decodedMemo = memoizedState(); + this._bySources = undefined; + this._bySourceMemos = undefined; + } +} +(() => { + decodedMappings = (map) => { + return (map._decoded || (map._decoded = decode(map._encoded))); + }; + originalPositionFor = (map, { line, column, bias }) => { + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) + return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal(segments, map._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND); + if (index === -1) + return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) + return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null); + }; +})(); +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } + else if (bias === LEAST_UPPER_BOUND) + index++; + if (index === -1 || index === segments.length) + return -1; + return index; +} + +const CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/; +const stackIgnorePatterns = [ + "node:internal", + /\/packages\/\w+\/dist\//, + /\/@vitest\/\w+\/dist\//, + "/vitest/dist/", + "/vitest/src/", + "/vite-node/dist/", + "/vite-node/src/", + "/node_modules/chai/", + "/node_modules/tinypool/", + "/node_modules/tinyspy/", + "/deps/chai.js", + /__vitest_browser__/ +]; +function extractLocation(urlLike) { + if (!urlLike.includes(":")) + return [urlLike]; + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, "")); + if (!parts) + return [urlLike]; + let url = parts[1]; + if (url.startsWith("http:") || url.startsWith("https:")) { + const urlObj = new URL(url); + url = urlObj.pathname; + } + if (url.startsWith("/@fs/")) { + url = url.slice(typeof process !== "undefined" && process.platform === "win32" ? 5 : 4); + } + return [url, parts[2] || void 0, parts[3] || void 0]; +} +function parseSingleFFOrSafariStack(raw) { + let line = raw.trim(); + if (SAFARI_NATIVE_CODE_REGEXP.test(line)) + return null; + if (line.includes(" > eval")) + line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1"); + if (!line.includes("@") && !line.includes(":")) + return null; + const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/; + const matches = line.match(functionNameRegex); + const functionName = matches && matches[1] ? matches[1] : void 0; + const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, "")); + if (!url || !lineNumber || !columnNumber) + return null; + return { + file: url, + method: functionName || "", + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseSingleV8Stack(raw) { + let line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) + return null; + if (line.includes("(eval ")) + line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, ""); + let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""); + const location = sanitizedLine.match(/ (\(.+\)$)/); + sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine; + const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine); + let method = location && sanitizedLine || ""; + let file = url && ["eval", ""].includes(url) ? void 0 : url; + if (!file || !lineNumber || !columnNumber) + return null; + if (method.startsWith("async ")) + method = method.slice(6); + if (file.startsWith("file://")) + file = file.slice(7); + file = resolve$2(file); + if (method) + method = method.replace(/__vite_ssr_import_\d+__\./g, ""); + return { + method, + file, + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseStacktrace(stack, options = {}) { + const { ignoreStackEntries = stackIgnorePatterns } = options; + let stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack); + if (ignoreStackEntries.length) + stacks = stacks.filter((stack2) => !ignoreStackEntries.some((p) => stack2.file.match(p))); + return stacks.map((stack2) => { + var _a; + const map = (_a = options.getSourceMap) == null ? void 0 : _a.call(options, stack2.file); + if (!map || typeof map !== "object" || !map.version) + return stack2; + const traceMap = new TraceMap(map); + const { line, column } = originalPositionFor(traceMap, stack2); + if (line != null && column != null) + return { ...stack2, line, column }; + return stack2; + }); +} +function parseFFOrSafariStackTrace(stack) { + return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish); +} +function parseV8Stacktrace(stack) { + return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish); +} +function parseErrorStacktrace(e, options = {}) { + if (!e || isPrimitive(e)) + return []; + if (e.stacks) + return e.stacks; + const stackStr = e.stack || e.stackStr || ""; + let stackFrames = parseStacktrace(stackStr, options); + if (options.frameFilter) + stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false); + e.stacks = stackFrames; + return stackFrames; +} + +async function saveInlineSnapshots(environment, snapshots) { + const MagicString = (await import('magic-string')).default; + const files = new Set(snapshots.map((i) => i.file)); + await Promise.all(Array.from(files).map(async (file) => { + const snaps = snapshots.filter((i) => i.file === file); + const code = await environment.readSnapshotFile(file); + const s = new MagicString(code); + for (const snap of snaps) { + const index = positionToOffset(code, snap.line, snap.column); + replaceInlineSnap(code, s, index, snap.snapshot); + } + const transformed = s.toString(); + if (transformed !== code) + await environment.saveSnapshotFile(file, transformed); + })); +} +const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*({)/m; +function replaceObjectSnap(code, s, index, newSnap) { + let _code = code.slice(index); + const startMatch = startObjectRegex.exec(_code); + if (!startMatch) + return false; + _code = _code.slice(startMatch.index); + let callEnd = getCallLastIndex(_code); + if (callEnd === null) + return false; + callEnd += index + startMatch.index; + const shapeStart = index + startMatch.index + startMatch[0].length; + const shapeEnd = getObjectShapeEndIndex(code, shapeStart); + const snap = `, ${prepareSnapString(newSnap, code, index)}`; + if (shapeEnd === callEnd) { + s.appendLeft(callEnd, snap); + } else { + s.overwrite(shapeEnd, callEnd, snap); + } + return true; +} +function getObjectShapeEndIndex(code, index) { + let startBraces = 1; + let endBraces = 0; + while (startBraces !== endBraces && index < code.length) { + const s = code[index++]; + if (s === "{") + startBraces++; + else if (s === "}") + endBraces++; + } + return index; +} +function prepareSnapString(snap, source, index) { + const lineNumber = offsetToLineNumber(source, index); + const line = source.split(lineSplitRE)[lineNumber - 1]; + const indent = line.match(/^\s*/)[0] || ""; + const indentNext = indent.includes(" ") ? `${indent} ` : `${indent} `; + const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g); + const isOneline = lines.length <= 1; + const quote = "`"; + if (isOneline) + return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\${/g, "\\${")}${quote}`; + return `${quote} +${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\${/g, "\\${")} +${indent}${quote}`; +} +const startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*[\w_$]*(['"`\)])/m; +function replaceInlineSnap(code, s, index, newSnap) { + const codeStartingAtIndex = code.slice(index); + const startMatch = startRegex.exec(codeStartingAtIndex); + const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex); + if (!startMatch || startMatch.index !== (firstKeywordMatch == null ? void 0 : firstKeywordMatch.index)) + return replaceObjectSnap(code, s, index, newSnap); + const quote = startMatch[1]; + const startIndex = index + startMatch.index + startMatch[0].length; + const snapString = prepareSnapString(newSnap, code, index); + if (quote === ")") { + s.appendRight(startIndex - 1, snapString); + return true; + } + const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`); + const endMatch = quoteEndRE.exec(code.slice(startIndex)); + if (!endMatch) + return false; + const endIndex = startIndex + endMatch.index + endMatch[0].length; + s.overwrite(startIndex - 1, endIndex, snapString); + return true; +} +const INDENTATION_REGEX = /^([^\S\n]*)\S/m; +function stripSnapshotIndentation(inlineSnapshot) { + const match = inlineSnapshot.match(INDENTATION_REGEX); + if (!match || !match[1]) { + return inlineSnapshot; + } + const indentation = match[1]; + const lines = inlineSnapshot.split(/\n/g); + if (lines.length <= 2) { + return inlineSnapshot; + } + if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") { + return inlineSnapshot; + } + for (let i = 1; i < lines.length - 1; i++) { + if (lines[i] !== "") { + if (lines[i].indexOf(indentation) !== 0) { + return inlineSnapshot; + } + lines[i] = lines[i].substring(indentation.length); + } + } + lines[lines.length - 1] = ""; + inlineSnapshot = lines.join("\n"); + return inlineSnapshot; +} + +async function saveRawSnapshots(environment, snapshots) { + await Promise.all(snapshots.map(async (snap) => { + if (!snap.readonly) + await environment.saveSnapshotFile(snap.file, snap.snapshot); + })); +} + +class SnapshotState { + constructor(testFilePath, snapshotPath, snapshotContent, options) { + this.testFilePath = testFilePath; + this.snapshotPath = snapshotPath; + const { data, dirty } = getSnapshotData( + snapshotContent, + options + ); + this._fileExists = snapshotContent != null; + this._initialData = data; + this._snapshotData = data; + this._dirty = dirty; + this._inlineSnapshots = []; + this._rawSnapshots = []; + this._uncheckedKeys = new Set(Object.keys(this._snapshotData)); + this._counters = /* @__PURE__ */ new Map(); + this.expand = options.expand || false; + this.added = 0; + this.matched = 0; + this.unmatched = 0; + this._updateSnapshot = options.updateSnapshot; + this.updated = 0; + this._snapshotFormat = { + printBasicPrototype: false, + escapeString: false, + ...options.snapshotFormat + }; + this._environment = options.snapshotEnvironment; + } + _counters; + _dirty; + _updateSnapshot; + _snapshotData; + _initialData; + _inlineSnapshots; + _rawSnapshots; + _uncheckedKeys; + _snapshotFormat; + _environment; + _fileExists; + added; + expand; + matched; + unmatched; + updated; + static async create(testFilePath, options) { + const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath); + const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath); + return new SnapshotState(testFilePath, snapshotPath, content, options); + } + get environment() { + return this._environment; + } + markSnapshotsAsCheckedForTest(testName) { + this._uncheckedKeys.forEach((uncheckedKey) => { + if (keyToTestName(uncheckedKey) === testName) + this._uncheckedKeys.delete(uncheckedKey); + }); + } + _inferInlineSnapshotStack(stacks) { + const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/)); + if (promiseIndex !== -1) + return stacks[promiseIndex + 3]; + const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__")); + return stackIndex !== -1 ? stacks[stackIndex + 2] : null; + } + _addSnapshot(key, receivedSerialized, options) { + this._dirty = true; + if (options.isInline) { + const stacks = parseErrorStacktrace(options.error || new Error("snapshot"), { ignoreStackEntries: [] }); + const stack = this._inferInlineSnapshotStack(stacks); + if (!stack) { + throw new Error( + `@vitest/snapshot: Couldn't infer stack frame for inline snapshot. +${JSON.stringify(stacks)}` + ); + } + stack.column--; + this._inlineSnapshots.push({ + snapshot: receivedSerialized, + ...stack + }); + } else if (options.rawSnapshot) { + this._rawSnapshots.push({ + ...options.rawSnapshot, + snapshot: receivedSerialized + }); + } else { + this._snapshotData[key] = receivedSerialized; + } + } + clear() { + this._snapshotData = this._initialData; + this._counters = /* @__PURE__ */ new Map(); + this.added = 0; + this.matched = 0; + this.unmatched = 0; + this.updated = 0; + this._dirty = false; + } + async save() { + const hasExternalSnapshots = Object.keys(this._snapshotData).length; + const hasInlineSnapshots = this._inlineSnapshots.length; + const hasRawSnapshots = this._rawSnapshots.length; + const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots && !hasRawSnapshots; + const status = { + deleted: false, + saved: false + }; + if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) { + if (hasExternalSnapshots) { + await saveSnapshotFile(this._environment, this._snapshotData, this.snapshotPath); + this._fileExists = true; + } + if (hasInlineSnapshots) + await saveInlineSnapshots(this._environment, this._inlineSnapshots); + if (hasRawSnapshots) + await saveRawSnapshots(this._environment, this._rawSnapshots); + status.saved = true; + } else if (!hasExternalSnapshots && this._fileExists) { + if (this._updateSnapshot === "all") { + await this._environment.removeSnapshotFile(this.snapshotPath); + this._fileExists = false; + } + status.deleted = true; + } + return status; + } + getUncheckedCount() { + return this._uncheckedKeys.size || 0; + } + getUncheckedKeys() { + return Array.from(this._uncheckedKeys); + } + removeUncheckedKeys() { + if (this._updateSnapshot === "all" && this._uncheckedKeys.size) { + this._dirty = true; + this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]); + this._uncheckedKeys.clear(); + } + } + match({ + testName, + received, + key, + inlineSnapshot, + isInline, + error, + rawSnapshot + }) { + this._counters.set(testName, (this._counters.get(testName) || 0) + 1); + const count = Number(this._counters.get(testName)); + if (!key) + key = testNameToKey(testName, count); + if (!(isInline && this._snapshotData[key] !== void 0)) + this._uncheckedKeys.delete(key); + let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, void 0, this._snapshotFormat); + if (!rawSnapshot) + receivedSerialized = addExtraLineBreaks(receivedSerialized); + if (rawSnapshot) { + if (rawSnapshot.content && rawSnapshot.content.match(/\r\n/) && !receivedSerialized.match(/\r\n/)) + rawSnapshot.content = normalizeNewlines(rawSnapshot.content); + } + const expected = isInline ? inlineSnapshot : rawSnapshot ? rawSnapshot.content : this._snapshotData[key]; + const expectedTrimmed = prepareExpected(expected); + const pass = expectedTrimmed === prepareExpected(receivedSerialized); + const hasSnapshot = expected !== void 0; + const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null; + if (pass && !isInline && !rawSnapshot) { + this._snapshotData[key] = receivedSerialized; + } + if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) { + if (this._updateSnapshot === "all") { + if (!pass) { + if (hasSnapshot) + this.updated++; + else + this.added++; + this._addSnapshot(key, receivedSerialized, { error, isInline, rawSnapshot }); + } else { + this.matched++; + } + } else { + this._addSnapshot(key, receivedSerialized, { error, isInline, rawSnapshot }); + this.added++; + } + return { + actual: "", + count, + expected: "", + key, + pass: true + }; + } else { + if (!pass) { + this.unmatched++; + return { + actual: removeExtraLineBreaks(receivedSerialized), + count, + expected: expectedTrimmed !== void 0 ? removeExtraLineBreaks(expectedTrimmed) : void 0, + key, + pass: false + }; + } else { + this.matched++; + return { + actual: "", + count, + expected: "", + key, + pass: true + }; + } + } + } + async pack() { + const snapshot = { + filepath: this.testFilePath, + added: 0, + fileDeleted: false, + matched: 0, + unchecked: 0, + uncheckedKeys: [], + unmatched: 0, + updated: 0 + }; + const uncheckedCount = this.getUncheckedCount(); + const uncheckedKeys = this.getUncheckedKeys(); + if (uncheckedCount) + this.removeUncheckedKeys(); + const status = await this.save(); + snapshot.fileDeleted = status.deleted; + snapshot.added = this.added; + snapshot.matched = this.matched; + snapshot.unmatched = this.unmatched; + snapshot.updated = this.updated; + snapshot.unchecked = !status.deleted ? uncheckedCount : 0; + snapshot.uncheckedKeys = Array.from(uncheckedKeys); + return snapshot; + } +} + +function createMismatchError(message, expand, actual, expected) { + const error = new Error(message); + Object.defineProperty(error, "actual", { + value: actual, + enumerable: true, + configurable: true, + writable: true + }); + Object.defineProperty(error, "expected", { + value: expected, + enumerable: true, + configurable: true, + writable: true + }); + Object.defineProperty(error, "diffOptions", { value: { expand } }); + return error; +} +class SnapshotClient { + constructor(options = {}) { + this.options = options; + } + filepath; + name; + snapshotState; + snapshotStateMap = /* @__PURE__ */ new Map(); + async startCurrentRun(filepath, name, options) { + var _a; + this.filepath = filepath; + this.name = name; + if (((_a = this.snapshotState) == null ? void 0 : _a.testFilePath) !== filepath) { + await this.finishCurrentRun(); + if (!this.getSnapshotState(filepath)) { + this.snapshotStateMap.set( + filepath, + await SnapshotState.create( + filepath, + options + ) + ); + } + this.snapshotState = this.getSnapshotState(filepath); + } + } + getSnapshotState(filepath) { + return this.snapshotStateMap.get(filepath); + } + clearTest() { + this.filepath = void 0; + this.name = void 0; + } + skipTestSnapshots(name) { + var _a; + (_a = this.snapshotState) == null ? void 0 : _a.markSnapshotsAsCheckedForTest(name); + } + assert(options) { + var _a, _b, _c, _d; + const { + filepath = this.filepath, + name = this.name, + message, + isInline = false, + properties, + inlineSnapshot, + error, + errorMessage, + rawSnapshot + } = options; + let { received } = options; + if (!filepath) + throw new Error("Snapshot cannot be used outside of test"); + if (typeof properties === "object") { + if (typeof received !== "object" || !received) + throw new Error("Received value must be an object when the matcher has properties"); + try { + const pass2 = ((_b = (_a = this.options).isEqual) == null ? void 0 : _b.call(_a, received, properties)) ?? false; + if (!pass2) + throw createMismatchError("Snapshot properties mismatched", (_c = this.snapshotState) == null ? void 0 : _c.expand, received, properties); + else + received = deepMergeSnapshot(received, properties); + } catch (err) { + err.message = errorMessage || "Snapshot mismatched"; + throw err; + } + } + const testName = [ + name, + ...message ? [message] : [] + ].join(" > "); + const snapshotState = this.getSnapshotState(filepath); + const { actual, expected, key, pass } = snapshotState.match({ + testName, + received, + isInline, + error, + inlineSnapshot, + rawSnapshot + }); + if (!pass) + throw createMismatchError(`Snapshot \`${key || "unknown"}\` mismatched`, (_d = this.snapshotState) == null ? void 0 : _d.expand, actual == null ? void 0 : actual.trim(), expected == null ? void 0 : expected.trim()); + } + async assertRaw(options) { + if (!options.rawSnapshot) + throw new Error("Raw snapshot is required"); + const { + filepath = this.filepath, + rawSnapshot + } = options; + if (rawSnapshot.content == null) { + if (!filepath) + throw new Error("Snapshot cannot be used outside of test"); + const snapshotState = this.getSnapshotState(filepath); + options.filepath || (options.filepath = filepath); + rawSnapshot.file = await snapshotState.environment.resolveRawPath(filepath, rawSnapshot.file); + rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) || void 0; + } + return this.assert(options); + } + async finishCurrentRun() { + if (!this.snapshotState) + return null; + const result = await this.snapshotState.pack(); + this.snapshotState = void 0; + return result; + } + clear() { + this.snapshotStateMap.clear(); + } +} + +export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation }; diff --git a/node_modules/@vitest/snapshot/dist/manager.d.ts b/node_modules/@vitest/snapshot/dist/manager.d.ts new file mode 100644 index 0000000..8695e5d --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/manager.d.ts @@ -0,0 +1,18 @@ +import { S as SnapshotStateOptions, f as SnapshotSummary, b as SnapshotResult } from './index-S94ASl6q.js'; +import 'pretty-format'; +import './environment-cMiGIVXz.js'; + +declare class SnapshotManager { + options: Omit; + summary: SnapshotSummary; + extension: string; + constructor(options: Omit); + clear(): void; + add(result: SnapshotResult): void; + resolvePath(testPath: string): string; + resolveRawPath(testPath: string, rawPath: string): string; +} +declare function emptySummary(options: Omit): SnapshotSummary; +declare function addSnapshotResult(summary: SnapshotSummary, result: SnapshotResult): void; + +export { SnapshotManager, addSnapshotResult, emptySummary }; diff --git a/node_modules/@vitest/snapshot/dist/manager.js b/node_modules/@vitest/snapshot/dist/manager.js new file mode 100644 index 0000000..21cc7ef --- /dev/null +++ b/node_modules/@vitest/snapshot/dist/manager.js @@ -0,0 +1,75 @@ +import { join, dirname, basename, isAbsolute, resolve } from 'pathe'; + +class SnapshotManager { + constructor(options) { + this.options = options; + this.clear(); + } + summary = void 0; + extension = ".snap"; + clear() { + this.summary = emptySummary(this.options); + } + add(result) { + addSnapshotResult(this.summary, result); + } + resolvePath(testPath) { + const resolver = this.options.resolveSnapshotPath || (() => { + return join( + join( + dirname(testPath), + "__snapshots__" + ), + `${basename(testPath)}${this.extension}` + ); + }); + const path = resolver(testPath, this.extension); + return path; + } + resolveRawPath(testPath, rawPath) { + return isAbsolute(rawPath) ? rawPath : resolve(dirname(testPath), rawPath); + } +} +function emptySummary(options) { + const summary = { + added: 0, + failure: false, + filesAdded: 0, + filesRemoved: 0, + filesRemovedList: [], + filesUnmatched: 0, + filesUpdated: 0, + matched: 0, + total: 0, + unchecked: 0, + uncheckedKeysByFile: [], + unmatched: 0, + updated: 0, + didUpdate: options.updateSnapshot === "all" + }; + return summary; +} +function addSnapshotResult(summary, result) { + if (result.added) + summary.filesAdded++; + if (result.fileDeleted) + summary.filesRemoved++; + if (result.unmatched) + summary.filesUnmatched++; + if (result.updated) + summary.filesUpdated++; + summary.added += result.added; + summary.matched += result.matched; + summary.unchecked += result.unchecked; + if (result.uncheckedKeys && result.uncheckedKeys.length > 0) { + summary.uncheckedKeysByFile.push({ + filePath: result.filepath, + keys: result.uncheckedKeys + }); + } + summary.unmatched += result.unmatched; + summary.updated += result.updated; + summary.total += result.added + result.matched + result.unmatched + result.updated; +} + +export { SnapshotManager, addSnapshotResult, emptySummary }; diff --git a/node_modules/@vitest/snapshot/environment.d.ts b/node_modules/@vitest/snapshot/environment.d.ts new file mode 100644 index 0000000..855f0d1 --- /dev/null +++ b/node_modules/@vitest/snapshot/environment.d.ts @@ -0,0 +1 @@ +export * from './dist/environment.js' diff --git a/node_modules/@vitest/snapshot/manager.d.ts b/node_modules/@vitest/snapshot/manager.d.ts new file mode 100644 index 0000000..f3e8077 --- /dev/null +++ b/node_modules/@vitest/snapshot/manager.d.ts @@ -0,0 +1 @@ +export * from './dist/manager.js' diff --git a/node_modules/@vitest/snapshot/package.json b/node_modules/@vitest/snapshot/package.json new file mode 100644 index 0000000..6c58b56 --- /dev/null +++ b/node_modules/@vitest/snapshot/package.json @@ -0,0 +1,54 @@ +{ + "name": "@vitest/snapshot", + "type": "module", + "version": "1.6.1", + "description": "Vitest snapshot manager", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/snapshot#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/snapshot" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./environment": { + "types": "./dist/environment.d.ts", + "default": "./dist/environment.js" + }, + "./manager": { + "types": "./dist/manager.d.ts", + "default": "./dist/manager.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "devDependencies": { + "@types/natural-compare": "^1.4.3", + "natural-compare": "^1.4.0", + "@vitest/utils": "1.6.1" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/spy/LICENSE b/node_modules/@vitest/spy/LICENSE new file mode 100644 index 0000000..5ae481f --- /dev/null +++ b/node_modules/@vitest/spy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/spy/README.md b/node_modules/@vitest/spy/README.md new file mode 100644 index 0000000..5d23c87 --- /dev/null +++ b/node_modules/@vitest/spy/README.md @@ -0,0 +1,3 @@ +# @vitest/spy + +Lightweight Jest compatible spy implementation. diff --git a/node_modules/@vitest/spy/dist/index.d.ts b/node_modules/@vitest/spy/dist/index.d.ts new file mode 100644 index 0000000..3e93f8f --- /dev/null +++ b/node_modules/@vitest/spy/dist/index.d.ts @@ -0,0 +1,285 @@ +interface MockResultReturn { + type: 'return'; + /** + * The value that was returned from the function. If function returned a Promise, then this will be a resolved value. + */ + value: T; +} +interface MockResultIncomplete { + type: 'incomplete'; + value: undefined; +} +interface MockResultThrow { + type: 'throw'; + /** + * An error that was thrown during function execution. + */ + value: any; +} +type MockResult = MockResultReturn | MockResultThrow | MockResultIncomplete; +interface MockContext { + /** + * This is an array containing all arguments for each call. One item of the array is the arguments of that call. + * + * @example + * const fn = vi.fn() + * + * fn('arg1', 'arg2') + * fn('arg3') + * + * fn.mock.calls === [ + * ['arg1', 'arg2'], // first call + * ['arg3'], // second call + * ] + */ + calls: TArgs[]; + /** + * This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note that this is an actual context (`this`) of the function, not a return value. + */ + instances: TReturns[]; + /** + * The order of mock's execution. This returns an array of numbers which are shared between all defined mocks. + * + * @example + * const fn1 = vi.fn() + * const fn2 = vi.fn() + * + * fn1() + * fn2() + * fn1() + * + * fn1.mock.invocationCallOrder === [1, 3] + * fn2.mock.invocationCallOrder === [2] + */ + invocationCallOrder: number[]; + /** + * This is an array containing all values that were `returned` from the function. + * + * The `value` property contains the returned value or thrown error. If the function returned a promise, the `value` will be the _resolved_ value, not the actual `Promise`, unless it was never resolved. + * + * @example + * const fn = vi.fn() + * .mockReturnValueOnce('result') + * .mockImplementationOnce(() => { throw new Error('thrown error') }) + * + * const result = fn() + * + * try { + * fn() + * } + * catch {} + * + * fn.mock.results === [ + * { + * type: 'return', + * value: 'result', + * }, + * { + * type: 'throw', + * value: Error, + * }, + * ] + */ + results: MockResult[]; + /** + * This contains the arguments of the last call. If spy wasn't called, will return `undefined`. + */ + lastCall: TArgs | undefined; +} +type Procedure = (...args: any[]) => any; +type Methods = keyof { + [K in keyof T as T[K] extends Procedure ? K : never]: T[K]; +}; +type Properties = { + [K in keyof T]: T[K] extends Procedure ? never : K; +}[keyof T] & (string | symbol); +type Classes = { + [K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never; +}[keyof T] & (string | symbol); +/** + * @deprecated Use MockInstance instead + */ +interface SpyInstance extends MockInstance { +} +interface MockInstance { + /** + * Use it to return the name given to mock with method `.mockName(name)`. + */ + getMockName: () => string; + /** + * Sets internal mock name. Useful to see the name of the mock if an assertion fails. + */ + mockName: (n: string) => this; + /** + * Current context of the mock. It stores information about all invocation calls, instances, and results. + */ + mock: MockContext; + /** + * Clears all information about every call. After calling it, all properties on `.mock` will return an empty state. This method does not reset implementations. + * + * It is useful if you need to clean up mock between different assertions. + */ + mockClear: () => this; + /** + * Does what `mockClear` does and makes inner implementation an empty function (returning `undefined` when invoked). This also resets all "once" implementations. + * + * This is useful when you want to completely reset a mock to the default state. + */ + mockReset: () => this; + /** + * Does what `mockReset` does and restores inner implementation to the original function. + * + * Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`. + */ + mockRestore: () => void; + /** + * Returns current mock implementation if there is one. + * + * If mock was created with `vi.fn`, it will consider passed down method as a mock implementation. + * + * If mock was created with `vi.spyOn`, it will return `undefined` unless a custom implementation was provided. + */ + getMockImplementation: () => ((...args: TArgs) => TReturns) | undefined; + /** + * Accepts a function that will be used as an implementation of the mock. + * @example + * const increment = vi.fn().mockImplementation(count => count + 1); + * expect(increment(3)).toBe(4); + */ + mockImplementation: (fn: ((...args: TArgs) => TReturns)) => this; + /** + * Accepts a function that will be used as a mock implementation during the next call. Can be chained so that multiple function calls produce different results. + * @example + * const fn = vi.fn(count => count).mockImplementationOnce(count => count + 1); + * expect(fn(3)).toBe(4); + * expect(fn(3)).toBe(3); + */ + mockImplementationOnce: (fn: ((...args: TArgs) => TReturns)) => this; + /** + * Overrides the original mock implementation temporarily while the callback is being executed. + * @example + * const myMockFn = vi.fn(() => 'original') + * + * myMockFn.withImplementation(() => 'temp', () => { + * myMockFn() // 'temp' + * }) + * + * myMockFn() // 'original' + */ + withImplementation: (fn: ((...args: TArgs) => TReturns), cb: () => T) => T extends Promise ? Promise : this; + /** + * Use this if you need to return `this` context from the method without invoking actual implementation. + */ + mockReturnThis: () => this; + /** + * Accepts a value that will be returned whenever the mock function is called. + */ + mockReturnValue: (obj: TReturns) => this; + /** + * Accepts a value that will be returned during the next function call. If chained, every consecutive call will return the specified value. + * + * When there are no more `mockReturnValueOnce` values to use, mock will fallback to the previously defined implementation if there is one. + * @example + * const myMockFn = vi + * .fn() + * .mockReturnValue('default') + * .mockReturnValueOnce('first call') + * .mockReturnValueOnce('second call') + * + * // 'first call', 'second call', 'default' + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ + mockReturnValueOnce: (obj: TReturns) => this; + /** + * Accepts a value that will be resolved when async function is called. + * @example + * const asyncMock = vi.fn().mockResolvedValue(42) + * asyncMock() // Promise<42> + */ + mockResolvedValue: (obj: Awaited) => this; + /** + * Accepts a value that will be resolved during the next function call. If chained, every consecutive call will resolve specified value. + * @example + * const myMockFn = vi + * .fn() + * .mockResolvedValue('default') + * .mockResolvedValueOnce('first call') + * .mockResolvedValueOnce('second call') + * + * // Promise<'first call'>, Promise<'second call'>, Promise<'default'> + * console.log(myMockFn(), myMockFn(), myMockFn()) + */ + mockResolvedValueOnce: (obj: Awaited) => this; + /** + * Accepts an error that will be rejected when async function is called. + * @example + * const asyncMock = vi.fn().mockRejectedValue(new Error('Async error')) + * await asyncMock() // throws 'Async error' + */ + mockRejectedValue: (obj: any) => this; + /** + * Accepts a value that will be rejected during the next function call. If chained, every consecutive call will reject specified value. + * @example + * const asyncMock = vi + * .fn() + * .mockResolvedValueOnce('first call') + * .mockRejectedValueOnce(new Error('Async error')) + * + * await asyncMock() // first call + * await asyncMock() // throws "Async error" + */ + mockRejectedValueOnce: (obj: any) => this; +} +interface Mock extends MockInstance { + new (...args: TArgs): TReturns; + (...args: TArgs): TReturns; +} +interface PartialMock extends MockInstance> ? Promise>> : Partial> { + new (...args: TArgs): TReturns; + (...args: TArgs): TReturns; +} +type MaybeMockedConstructor = T extends new (...args: Array) => infer R ? Mock, R> : T; +type MockedFunction = Mock, ReturnType> & { + [K in keyof T]: T[K]; +}; +type PartiallyMockedFunction = PartialMock, ReturnType> & { + [K in keyof T]: T[K]; +}; +type MockedFunctionDeep = Mock, ReturnType> & MockedObjectDeep; +type PartiallyMockedFunctionDeep = PartialMock, ReturnType> & MockedObjectDeep; +type MockedObject = MaybeMockedConstructor & { + [K in Methods]: T[K] extends Procedure ? MockedFunction : T[K]; +} & { + [K in Properties]: T[K]; +}; +type MockedObjectDeep = MaybeMockedConstructor & { + [K in Methods]: T[K] extends Procedure ? MockedFunctionDeep : T[K]; +} & { + [K in Properties]: MaybeMockedDeep; +}; +type MaybeMockedDeep = T extends Procedure ? MockedFunctionDeep : T extends object ? MockedObjectDeep : T; +type MaybePartiallyMockedDeep = T extends Procedure ? PartiallyMockedFunctionDeep : T extends object ? MockedObjectDeep : T; +type MaybeMocked = T extends Procedure ? MockedFunction : T extends object ? MockedObject : T; +type MaybePartiallyMocked = T extends Procedure ? PartiallyMockedFunction : T extends object ? MockedObject : T; +interface Constructable { + new (...args: any[]): any; +} +type MockedClass = MockInstance any ? P : never, InstanceType> & { + prototype: T extends { + prototype: any; + } ? Mocked : never; +} & T; +type Mocked = { + [P in keyof T]: T[P] extends (...args: infer Args) => infer Returns ? MockInstance : T[P] extends Constructable ? MockedClass : T[P]; +} & T; +declare const mocks: Set>; +declare function isMockFunction(fn: any): fn is MockInstance; +declare function spyOn>>(obj: T, methodName: S, accessType: 'get'): MockInstance<[], T[S]>; +declare function spyOn>>(obj: T, methodName: G, accessType: 'set'): MockInstance<[T[G]], void>; +declare function spyOn> | Methods>)>(obj: T, methodName: M): Required[M] extends ({ + new (...args: infer A): infer R; +}) | ((...args: infer A) => infer R) ? MockInstance : never; +declare function fn(): Mock; +declare function fn(implementation: (...args: TArgs) => R): Mock; + +export { type MaybeMocked, type MaybeMockedConstructor, type MaybeMockedDeep, type MaybePartiallyMocked, type MaybePartiallyMockedDeep, type Mock, type MockContext, type MockInstance, type Mocked, type MockedClass, type MockedFunction, type MockedFunctionDeep, type MockedObject, type MockedObjectDeep, type PartialMock, type PartiallyMockedFunction, type PartiallyMockedFunctionDeep, type SpyInstance, fn, isMockFunction, mocks, spyOn }; diff --git a/node_modules/@vitest/spy/dist/index.js b/node_modules/@vitest/spy/dist/index.js new file mode 100644 index 0000000..9dc6378 --- /dev/null +++ b/node_modules/@vitest/spy/dist/index.js @@ -0,0 +1,130 @@ +import * as tinyspy from 'tinyspy'; + +const mocks = /* @__PURE__ */ new Set(); +function isMockFunction(fn2) { + return typeof fn2 === "function" && "_isMockFunction" in fn2 && fn2._isMockFunction; +} +function spyOn(obj, method, accessType) { + const dictionary = { + get: "getter", + set: "setter" + }; + const objMethod = accessType ? { [dictionary[accessType]]: method } : method; + const stub = tinyspy.internalSpyOn(obj, objMethod); + return enhanceSpy(stub); +} +let callOrder = 0; +function enhanceSpy(spy) { + const stub = spy; + let implementation; + let instances = []; + let invocations = []; + const state = tinyspy.getInternalState(spy); + const mockContext = { + get calls() { + return state.calls; + }, + get instances() { + return instances; + }, + get invocationCallOrder() { + return invocations; + }, + get results() { + return state.results.map(([callType, value]) => { + const type = callType === "error" ? "throw" : "return"; + return { type, value }; + }); + }, + get lastCall() { + return state.calls[state.calls.length - 1]; + } + }; + let onceImplementations = []; + let implementationChangedTemporarily = false; + function mockCall(...args) { + instances.push(this); + invocations.push(++callOrder); + const impl = implementationChangedTemporarily ? implementation : onceImplementations.shift() || implementation || state.getOriginal() || (() => { + }); + return impl.apply(this, args); + } + let name = stub.name; + stub.getMockName = () => name || "vi.fn()"; + stub.mockName = (n) => { + name = n; + return stub; + }; + stub.mockClear = () => { + state.reset(); + instances = []; + invocations = []; + return stub; + }; + stub.mockReset = () => { + stub.mockClear(); + implementation = () => void 0; + onceImplementations = []; + return stub; + }; + stub.mockRestore = () => { + stub.mockReset(); + state.restore(); + implementation = void 0; + return stub; + }; + stub.getMockImplementation = () => implementation; + stub.mockImplementation = (fn2) => { + implementation = fn2; + state.willCall(mockCall); + return stub; + }; + stub.mockImplementationOnce = (fn2) => { + onceImplementations.push(fn2); + return stub; + }; + function withImplementation(fn2, cb) { + const originalImplementation = implementation; + implementation = fn2; + state.willCall(mockCall); + implementationChangedTemporarily = true; + const reset = () => { + implementation = originalImplementation; + implementationChangedTemporarily = false; + }; + const result = cb(); + if (result instanceof Promise) { + return result.then(() => { + reset(); + return stub; + }); + } + reset(); + return stub; + } + stub.withImplementation = withImplementation; + stub.mockReturnThis = () => stub.mockImplementation(function() { + return this; + }); + stub.mockReturnValue = (val) => stub.mockImplementation(() => val); + stub.mockReturnValueOnce = (val) => stub.mockImplementationOnce(() => val); + stub.mockResolvedValue = (val) => stub.mockImplementation(() => Promise.resolve(val)); + stub.mockResolvedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.resolve(val)); + stub.mockRejectedValue = (val) => stub.mockImplementation(() => Promise.reject(val)); + stub.mockRejectedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.reject(val)); + Object.defineProperty(stub, "mock", { + get: () => mockContext + }); + state.willCall(mockCall); + mocks.add(stub); + return stub; +} +function fn(implementation) { + const enhancedSpy = enhanceSpy(tinyspy.internalSpyOn({ spy: implementation || (() => { + }) }, "spy")); + if (implementation) + enhancedSpy.mockImplementation(implementation); + return enhancedSpy; +} + +export { fn, isMockFunction, mocks, spyOn }; diff --git a/node_modules/@vitest/spy/package.json b/node_modules/@vitest/spy/package.json new file mode 100644 index 0000000..8a2b695 --- /dev/null +++ b/node_modules/@vitest/spy/package.json @@ -0,0 +1,38 @@ +{ + "name": "@vitest/spy", + "type": "module", + "version": "1.6.1", + "description": "Lightweight Jest compatible spy implementation", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/spy#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/spy" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "dependencies": { + "tinyspy": "^2.2.0" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/@vitest/utils/LICENSE b/node_modules/@vitest/utils/LICENSE new file mode 100644 index 0000000..5ae481f --- /dev/null +++ b/node_modules/@vitest/utils/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present Vitest Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@vitest/utils/diff.d.ts b/node_modules/@vitest/utils/diff.d.ts new file mode 100644 index 0000000..0a66b86 --- /dev/null +++ b/node_modules/@vitest/utils/diff.d.ts @@ -0,0 +1 @@ +export * from './dist/diff.js' diff --git a/node_modules/@vitest/utils/dist/ast.d.ts b/node_modules/@vitest/utils/dist/ast.d.ts new file mode 100644 index 0000000..80e095a --- /dev/null +++ b/node_modules/@vitest/utils/dist/ast.d.ts @@ -0,0 +1,723 @@ +// This definition file follows a somewhat unusual format. ESTree allows +// runtime type checks based on the `type` parameter. In order to explain this +// to typescript we want to use discriminated union types: +// https://github.com/Microsoft/TypeScript/pull/9163 +// +// For ESTree this is a bit tricky because the high level interfaces like +// Node or Function are pulling double duty. We want to pass common fields down +// to the interfaces that extend them (like Identifier or +// ArrowFunctionExpression), but you can't extend a type union or enforce +// common fields on them. So we've split the high level interfaces into two +// types, a base type which passes down inherited fields, and a type union of +// all types which extend the base type. Only the type union is exported, and +// the union is how other types refer to the collection of inheriting types. +// +// This makes the definitions file here somewhat more difficult to maintain, +// but it has the notable advantage of making ESTree much easier to use as +// an end user. + +interface BaseNodeWithoutComments { + // Every leaf interface that extends BaseNode must specify a type property. + // The type property should be a string literal. For example, Identifier + // has: `type: "Identifier"` + type: string; + loc?: SourceLocation | null | undefined; + range?: [number, number] | undefined; +} + +interface BaseNode extends BaseNodeWithoutComments { + leadingComments?: Comment[] | undefined; + trailingComments?: Comment[] | undefined; +} + +interface NodeMap { + AssignmentProperty: AssignmentProperty; + CatchClause: CatchClause; + Class: Class; + ClassBody: ClassBody; + Expression: Expression; + Function: Function; + Identifier: Identifier; + Literal: Literal; + MethodDefinition: MethodDefinition; + ModuleDeclaration: ModuleDeclaration; + ModuleSpecifier: ModuleSpecifier; + Pattern: Pattern; + PrivateIdentifier: PrivateIdentifier; + Program: Program; + Property: Property; + PropertyDefinition: PropertyDefinition; + SpreadElement: SpreadElement; + Statement: Statement; + Super: Super; + SwitchCase: SwitchCase; + TemplateElement: TemplateElement; + VariableDeclarator: VariableDeclarator; +} + +type Node$1 = NodeMap[keyof NodeMap]; + +interface Comment extends BaseNodeWithoutComments { + type: "Line" | "Block"; + value: string; +} + +interface SourceLocation { + source?: string | null | undefined; + start: Position; + end: Position; +} + +interface Position { + /** >= 1 */ + line: number; + /** >= 0 */ + column: number; +} + +interface Program extends BaseNode { + type: "Program"; + sourceType: "script" | "module"; + body: Array; + comments?: Comment[] | undefined; +} + +interface Directive extends BaseNode { + type: "ExpressionStatement"; + expression: Literal; + directive: string; +} + +interface BaseFunction extends BaseNode { + params: Pattern[]; + generator?: boolean | undefined; + async?: boolean | undefined; + // The body is either BlockStatement or Expression because arrow functions + // can have a body that's either. FunctionDeclarations and + // FunctionExpressions have only BlockStatement bodies. + body: BlockStatement | Expression; +} + +type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; + +type Statement = + | ExpressionStatement + | BlockStatement + | StaticBlock + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement + | Declaration; + +interface BaseStatement extends BaseNode {} + +interface EmptyStatement extends BaseStatement { + type: "EmptyStatement"; +} + +interface BlockStatement extends BaseStatement { + type: "BlockStatement"; + body: Statement[]; + innerComments?: Comment[] | undefined; +} + +interface StaticBlock extends Omit { + type: "StaticBlock"; +} + +interface ExpressionStatement extends BaseStatement { + type: "ExpressionStatement"; + expression: Expression; +} + +interface IfStatement extends BaseStatement { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate?: Statement | null | undefined; +} + +interface LabeledStatement extends BaseStatement { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +} + +interface BreakStatement extends BaseStatement { + type: "BreakStatement"; + label?: Identifier | null | undefined; +} + +interface ContinueStatement extends BaseStatement { + type: "ContinueStatement"; + label?: Identifier | null | undefined; +} + +interface WithStatement extends BaseStatement { + type: "WithStatement"; + object: Expression; + body: Statement; +} + +interface SwitchStatement extends BaseStatement { + type: "SwitchStatement"; + discriminant: Expression; + cases: SwitchCase[]; +} + +interface ReturnStatement extends BaseStatement { + type: "ReturnStatement"; + argument?: Expression | null | undefined; +} + +interface ThrowStatement extends BaseStatement { + type: "ThrowStatement"; + argument: Expression; +} + +interface TryStatement extends BaseStatement { + type: "TryStatement"; + block: BlockStatement; + handler?: CatchClause | null | undefined; + finalizer?: BlockStatement | null | undefined; +} + +interface WhileStatement extends BaseStatement { + type: "WhileStatement"; + test: Expression; + body: Statement; +} + +interface DoWhileStatement extends BaseStatement { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +} + +interface ForStatement extends BaseStatement { + type: "ForStatement"; + init?: VariableDeclaration | Expression | null | undefined; + test?: Expression | null | undefined; + update?: Expression | null | undefined; + body: Statement; +} + +interface BaseForXStatement extends BaseStatement { + left: VariableDeclaration | Pattern; + right: Expression; + body: Statement; +} + +interface ForInStatement extends BaseForXStatement { + type: "ForInStatement"; +} + +interface DebuggerStatement extends BaseStatement { + type: "DebuggerStatement"; +} + +type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration; + +interface BaseDeclaration extends BaseStatement {} + +interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration { + type: "FunctionDeclaration"; + /** It is null when a function declaration is a part of the `export default function` statement */ + id: Identifier | null; + body: BlockStatement; +} + +interface FunctionDeclaration extends MaybeNamedFunctionDeclaration { + id: Identifier; +} + +interface VariableDeclaration extends BaseDeclaration { + type: "VariableDeclaration"; + declarations: VariableDeclarator[]; + kind: "var" | "let" | "const"; +} + +interface VariableDeclarator extends BaseNode { + type: "VariableDeclarator"; + id: Pattern; + init?: Expression | null | undefined; +} + +interface ExpressionMap { + ArrayExpression: ArrayExpression; + ArrowFunctionExpression: ArrowFunctionExpression; + AssignmentExpression: AssignmentExpression; + AwaitExpression: AwaitExpression; + BinaryExpression: BinaryExpression; + CallExpression: CallExpression; + ChainExpression: ChainExpression; + ClassExpression: ClassExpression; + ConditionalExpression: ConditionalExpression; + FunctionExpression: FunctionExpression; + Identifier: Identifier; + ImportExpression: ImportExpression; + Literal: Literal; + LogicalExpression: LogicalExpression; + MemberExpression: MemberExpression; + MetaProperty: MetaProperty; + NewExpression: NewExpression; + ObjectExpression: ObjectExpression; + SequenceExpression: SequenceExpression; + TaggedTemplateExpression: TaggedTemplateExpression; + TemplateLiteral: TemplateLiteral; + ThisExpression: ThisExpression; + UnaryExpression: UnaryExpression; + UpdateExpression: UpdateExpression; + YieldExpression: YieldExpression; +} + +type Expression = ExpressionMap[keyof ExpressionMap]; + +interface BaseExpression extends BaseNode {} + +type ChainElement = SimpleCallExpression | MemberExpression; + +interface ChainExpression extends BaseExpression { + type: "ChainExpression"; + expression: ChainElement; +} + +interface ThisExpression extends BaseExpression { + type: "ThisExpression"; +} + +interface ArrayExpression extends BaseExpression { + type: "ArrayExpression"; + elements: Array; +} + +interface ObjectExpression extends BaseExpression { + type: "ObjectExpression"; + properties: Array; +} + +interface PrivateIdentifier extends BaseNode { + type: "PrivateIdentifier"; + name: string; +} + +interface Property extends BaseNode { + type: "Property"; + key: Expression | PrivateIdentifier; + value: Expression | Pattern; // Could be an AssignmentProperty + kind: "init" | "get" | "set"; + method: boolean; + shorthand: boolean; + computed: boolean; +} + +interface PropertyDefinition extends BaseNode { + type: "PropertyDefinition"; + key: Expression | PrivateIdentifier; + value?: Expression | null | undefined; + computed: boolean; + static: boolean; +} + +interface FunctionExpression extends BaseFunction, BaseExpression { + id?: Identifier | null | undefined; + type: "FunctionExpression"; + body: BlockStatement; +} + +interface SequenceExpression extends BaseExpression { + type: "SequenceExpression"; + expressions: Expression[]; +} + +interface UnaryExpression extends BaseExpression { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: true; + argument: Expression; +} + +interface BinaryExpression extends BaseExpression { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression; + right: Expression; +} + +interface AssignmentExpression extends BaseExpression { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | MemberExpression; + right: Expression; +} + +interface UpdateExpression extends BaseExpression { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +} + +interface LogicalExpression extends BaseExpression { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +} + +interface ConditionalExpression extends BaseExpression { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +} + +interface BaseCallExpression extends BaseExpression { + callee: Expression | Super; + arguments: Array; +} +type CallExpression = SimpleCallExpression | NewExpression; + +interface SimpleCallExpression extends BaseCallExpression { + type: "CallExpression"; + optional: boolean; +} + +interface NewExpression extends BaseCallExpression { + type: "NewExpression"; +} + +interface MemberExpression extends BaseExpression, BasePattern { + type: "MemberExpression"; + object: Expression | Super; + property: Expression | PrivateIdentifier; + computed: boolean; + optional: boolean; +} + +type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression; + +interface BasePattern extends BaseNode {} + +interface SwitchCase extends BaseNode { + type: "SwitchCase"; + test?: Expression | null | undefined; + consequent: Statement[]; +} + +interface CatchClause extends BaseNode { + type: "CatchClause"; + param: Pattern | null; + body: BlockStatement; +} + +interface Identifier extends BaseNode, BaseExpression, BasePattern { + type: "Identifier"; + name: string; +} + +type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral; + +interface SimpleLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value: string | boolean | number | null; + raw?: string | undefined; +} + +interface RegExpLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: RegExp | null | undefined; + regex: { + pattern: string; + flags: string; + }; + raw?: string | undefined; +} + +interface BigIntLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: bigint | null | undefined; + bigint: string; + raw?: string | undefined; +} + +type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +type BinaryOperator = + | "==" + | "!=" + | "===" + | "!==" + | "<" + | "<=" + | ">" + | ">=" + | "<<" + | ">>" + | ">>>" + | "+" + | "-" + | "*" + | "/" + | "%" + | "**" + | "|" + | "^" + | "&" + | "in" + | "instanceof"; + +type LogicalOperator = "||" | "&&" | "??"; + +type AssignmentOperator = + | "=" + | "+=" + | "-=" + | "*=" + | "/=" + | "%=" + | "**=" + | "<<=" + | ">>=" + | ">>>=" + | "|=" + | "^=" + | "&=" + | "||=" + | "&&=" + | "??="; + +type UpdateOperator = "++" | "--"; + +interface ForOfStatement extends BaseForXStatement { + type: "ForOfStatement"; + await: boolean; +} + +interface Super extends BaseNode { + type: "Super"; +} + +interface SpreadElement extends BaseNode { + type: "SpreadElement"; + argument: Expression; +} + +interface ArrowFunctionExpression extends BaseExpression, BaseFunction { + type: "ArrowFunctionExpression"; + expression: boolean; + body: BlockStatement | Expression; +} + +interface YieldExpression extends BaseExpression { + type: "YieldExpression"; + argument?: Expression | null | undefined; + delegate: boolean; +} + +interface TemplateLiteral extends BaseExpression { + type: "TemplateLiteral"; + quasis: TemplateElement[]; + expressions: Expression[]; +} + +interface TaggedTemplateExpression extends BaseExpression { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +} + +interface TemplateElement extends BaseNode { + type: "TemplateElement"; + tail: boolean; + value: { + /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */ + cooked?: string | null | undefined; + raw: string; + }; +} + +interface AssignmentProperty extends Property { + value: Pattern; + kind: "init"; + method: boolean; // false +} + +interface ObjectPattern extends BasePattern { + type: "ObjectPattern"; + properties: Array; +} + +interface ArrayPattern extends BasePattern { + type: "ArrayPattern"; + elements: Array; +} + +interface RestElement extends BasePattern { + type: "RestElement"; + argument: Pattern; +} + +interface AssignmentPattern extends BasePattern { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +} + +type Class = ClassDeclaration | ClassExpression; +interface BaseClass extends BaseNode { + superClass?: Expression | null | undefined; + body: ClassBody; +} + +interface ClassBody extends BaseNode { + type: "ClassBody"; + body: Array; +} + +interface MethodDefinition extends BaseNode { + type: "MethodDefinition"; + key: Expression | PrivateIdentifier; + value: FunctionExpression; + kind: "constructor" | "method" | "get" | "set"; + computed: boolean; + static: boolean; +} + +interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration { + type: "ClassDeclaration"; + /** It is null when a class declaration is a part of the `export default class` statement */ + id: Identifier | null; +} + +interface ClassDeclaration extends MaybeNamedClassDeclaration { + id: Identifier; +} + +interface ClassExpression extends BaseClass, BaseExpression { + type: "ClassExpression"; + id?: Identifier | null | undefined; +} + +interface MetaProperty extends BaseExpression { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +} + +type ModuleDeclaration = + | ImportDeclaration + | ExportNamedDeclaration + | ExportDefaultDeclaration + | ExportAllDeclaration; +interface BaseModuleDeclaration extends BaseNode {} + +type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier; +interface BaseModuleSpecifier extends BaseNode { + local: Identifier; +} + +interface ImportDeclaration extends BaseModuleDeclaration { + type: "ImportDeclaration"; + specifiers: Array; + source: Literal; +} + +interface ImportSpecifier extends BaseModuleSpecifier { + type: "ImportSpecifier"; + imported: Identifier; +} + +interface ImportExpression extends BaseExpression { + type: "ImportExpression"; + source: Expression; +} + +interface ImportDefaultSpecifier extends BaseModuleSpecifier { + type: "ImportDefaultSpecifier"; +} + +interface ImportNamespaceSpecifier extends BaseModuleSpecifier { + type: "ImportNamespaceSpecifier"; +} + +interface ExportNamedDeclaration extends BaseModuleDeclaration { + type: "ExportNamedDeclaration"; + declaration?: Declaration | null | undefined; + specifiers: ExportSpecifier[]; + source?: Literal | null | undefined; +} + +interface ExportSpecifier extends BaseModuleSpecifier { + type: "ExportSpecifier"; + exported: Identifier; +} + +interface ExportDefaultDeclaration extends BaseModuleDeclaration { + type: "ExportDefaultDeclaration"; + declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression; +} + +interface ExportAllDeclaration extends BaseModuleDeclaration { + type: "ExportAllDeclaration"; + exported: Identifier | null; + source: Literal; +} + +interface AwaitExpression extends BaseExpression { + type: "AwaitExpression"; + argument: Expression; +} + +type Positioned = T & { + start: number; + end: number; +}; +type Node = Positioned; +interface IdentifierInfo { + /** + * If the identifier is used in a property shorthand + * { foo } -> { foo: __import_x__.foo } + */ + hasBindingShortcut: boolean; + /** + * The identifier is used in a class declaration + */ + classDeclaration: boolean; + /** + * The identifier is a name for a class expression + */ + classExpression: boolean; +} +interface Visitors { + onIdentifier?: (node: Positioned, info: IdentifierInfo, parentStack: Node[]) => void; + onImportMeta?: (node: Node) => void; + onDynamicImport?: (node: Positioned) => void; + onCallExpression?: (node: Positioned) => void; +} +declare function setIsNodeInPattern(node: Property): WeakSet; +declare function isNodeInPattern(node: Node$1): node is Property; +/** + * Same logic from \@vue/compiler-core & \@vue/compiler-sfc + * Except this is using acorn AST + */ +declare function esmWalker(root: Node, { onIdentifier, onImportMeta, onDynamicImport, onCallExpression }: Visitors): void; +declare function isStaticProperty(node: Node$1): node is Property; +declare function isStaticPropertyKey(node: Node$1, parent: Node$1): boolean; +declare function isFunctionNode(node: Node$1): node is Function; +declare function isInDestructuringAssignment(parent: Node$1, parentStack: Node$1[]): boolean; + +export { type ArrayExpression, type ArrayPattern, type ArrowFunctionExpression, type AssignmentExpression, type AssignmentOperator, type AssignmentPattern, type AssignmentProperty, type AwaitExpression, type BaseCallExpression, type BaseClass, type BaseDeclaration, type BaseExpression, type BaseForXStatement, type BaseFunction, type BaseModuleDeclaration, type BaseModuleSpecifier, type BaseNode, type BaseNodeWithoutComments, type BasePattern, type BaseStatement, type BigIntLiteral, type BinaryExpression, type BinaryOperator, type BlockStatement, type BreakStatement, type CallExpression, type CatchClause, type ChainElement, type ChainExpression, type Class, type ClassBody, type ClassDeclaration, type ClassExpression, type Comment, type ConditionalExpression, type ContinueStatement, type DebuggerStatement, type Declaration, type Directive, type DoWhileStatement, type EmptyStatement, type ExportAllDeclaration, type ExportDefaultDeclaration, type ExportNamedDeclaration, type ExportSpecifier, type Expression, type ExpressionMap, type ExpressionStatement, type ForInStatement, type ForOfStatement, type ForStatement, type Function, type FunctionDeclaration, type FunctionExpression, type Identifier, type IfStatement, type ImportDeclaration, type ImportDefaultSpecifier, type ImportExpression, type ImportNamespaceSpecifier, type ImportSpecifier, type LabeledStatement, type Literal, type LogicalExpression, type LogicalOperator, type MaybeNamedClassDeclaration, type MaybeNamedFunctionDeclaration, type MemberExpression, type MetaProperty, type MethodDefinition, type ModuleDeclaration, type ModuleSpecifier, type NewExpression, type Node, type NodeMap, type ObjectExpression, type ObjectPattern, type Pattern, type Position, type Positioned, type PrivateIdentifier, type Program, type Property, type PropertyDefinition, type RegExpLiteral, type RestElement, type ReturnStatement, type SequenceExpression, type SimpleCallExpression, type SimpleLiteral, type SourceLocation, type SpreadElement, type Statement, type StaticBlock, type Super, type SwitchCase, type SwitchStatement, type TaggedTemplateExpression, type TemplateElement, type TemplateLiteral, type ThisExpression, type ThrowStatement, type TryStatement, type UnaryExpression, type UnaryOperator, type UpdateExpression, type UpdateOperator, type VariableDeclaration, type VariableDeclarator, type WhileStatement, type WithStatement, type YieldExpression, esmWalker, isFunctionNode, isInDestructuringAssignment, isNodeInPattern, isStaticProperty, isStaticPropertyKey, setIsNodeInPattern }; diff --git a/node_modules/@vitest/utils/dist/ast.js b/node_modules/@vitest/utils/dist/ast.js new file mode 100644 index 0000000..ad9f32f --- /dev/null +++ b/node_modules/@vitest/utils/dist/ast.js @@ -0,0 +1,180 @@ +import { walk } from 'estree-walker'; + +const isNodeInPatternWeakSet = /* @__PURE__ */ new WeakSet(); +function setIsNodeInPattern(node) { + return isNodeInPatternWeakSet.add(node); +} +function isNodeInPattern(node) { + return isNodeInPatternWeakSet.has(node); +} +function esmWalker(root, { onIdentifier, onImportMeta, onDynamicImport, onCallExpression }) { + const parentStack = []; + const varKindStack = []; + const scopeMap = /* @__PURE__ */ new WeakMap(); + const identifiers = []; + const setScope = (node, name) => { + let scopeIds = scopeMap.get(node); + if (scopeIds && scopeIds.has(name)) + return; + if (!scopeIds) { + scopeIds = /* @__PURE__ */ new Set(); + scopeMap.set(node, scopeIds); + } + scopeIds.add(name); + }; + function isInScope(name, parents) { + return parents.some((node) => { + var _a; + return node && ((_a = scopeMap.get(node)) == null ? void 0 : _a.has(name)); + }); + } + function handlePattern(p, parentScope) { + if (p.type === "Identifier") { + setScope(parentScope, p.name); + } else if (p.type === "RestElement") { + handlePattern(p.argument, parentScope); + } else if (p.type === "ObjectPattern") { + p.properties.forEach((property) => { + if (property.type === "RestElement") + setScope(parentScope, property.argument.name); + else + handlePattern(property.value, parentScope); + }); + } else if (p.type === "ArrayPattern") { + p.elements.forEach((element) => { + if (element) + handlePattern(element, parentScope); + }); + } else if (p.type === "AssignmentPattern") { + handlePattern(p.left, parentScope); + } else { + setScope(parentScope, p.name); + } + } + walk(root, { + enter(node, parent) { + if (node.type === "ImportDeclaration") + return this.skip(); + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) + parentStack.unshift(parent); + if (node.type === "VariableDeclaration") + varKindStack.unshift(node.kind); + if (node.type === "CallExpression") + onCallExpression == null ? void 0 : onCallExpression(node); + if (node.type === "MetaProperty" && node.meta.name === "import") + onImportMeta == null ? void 0 : onImportMeta(node); + else if (node.type === "ImportExpression") + onDynamicImport == null ? void 0 : onDynamicImport(node); + if (node.type === "Identifier") { + if (!isInScope(node.name, parentStack) && isRefIdentifier(node, parent, parentStack)) { + identifiers.push([node, parentStack.slice(0)]); + } + } else if (isFunctionNode(node)) { + if (node.type === "FunctionDeclaration") { + const parentScope = findParentScope(parentStack); + if (parentScope) + setScope(parentScope, node.id.name); + } + node.params.forEach((p) => { + if (p.type === "ObjectPattern" || p.type === "ArrayPattern") { + handlePattern(p, node); + return; + } + walk(p.type === "AssignmentPattern" ? p.left : p, { + enter(child, parent2) { + if ((parent2 == null ? void 0 : parent2.type) === "AssignmentPattern" && (parent2 == null ? void 0 : parent2.right) === child) + return this.skip(); + if (child.type !== "Identifier") + return; + if (isStaticPropertyKey(child, parent2)) + return; + if ((parent2 == null ? void 0 : parent2.type) === "TemplateLiteral" && (parent2 == null ? void 0 : parent2.expressions.includes(child)) || (parent2 == null ? void 0 : parent2.type) === "CallExpression" && (parent2 == null ? void 0 : parent2.callee) === child) + return; + setScope(node, child.name); + } + }); + }); + } else if (node.type === "Property" && parent.type === "ObjectPattern") { + setIsNodeInPattern(node); + } else if (node.type === "VariableDeclarator") { + const parentFunction = findParentScope( + parentStack, + varKindStack[0] === "var" + ); + if (parentFunction) + handlePattern(node.id, parentFunction); + } else if (node.type === "CatchClause" && node.param) { + handlePattern(node.param, node); + } + }, + leave(node, parent) { + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) + parentStack.shift(); + if (node.type === "VariableDeclaration") + varKindStack.shift(); + } + }); + identifiers.forEach(([node, stack]) => { + if (!isInScope(node.name, stack)) { + const parent = stack[0]; + const grandparent = stack[1]; + const hasBindingShortcut = isStaticProperty(parent) && parent.shorthand && (!isNodeInPattern(parent) || isInDestructuringAssignment(parent, parentStack)); + const classDeclaration = parent.type === "PropertyDefinition" && (grandparent == null ? void 0 : grandparent.type) === "ClassBody" || parent.type === "ClassDeclaration" && node === parent.superClass; + const classExpression = parent.type === "ClassExpression" && node === parent.id; + onIdentifier == null ? void 0 : onIdentifier(node, { + hasBindingShortcut, + classDeclaration, + classExpression + }, stack); + } + }); +} +function isRefIdentifier(id, parent, parentStack) { + if (parent.type === "CatchClause" || (parent.type === "VariableDeclarator" || parent.type === "ClassDeclaration") && parent.id === id) + return false; + if (isFunctionNode(parent)) { + if (parent.id === id) + return false; + if (parent.params.includes(id)) + return false; + } + if (parent.type === "MethodDefinition" && !parent.computed) + return false; + if (isStaticPropertyKey(id, parent)) + return false; + if (isNodeInPattern(parent) && parent.value === id) + return false; + if (parent.type === "ArrayPattern" && !isInDestructuringAssignment(parent, parentStack)) + return false; + if (parent.type === "MemberExpression" && parent.property === id && !parent.computed) + return false; + if (parent.type === "ExportSpecifier") + return false; + if (id.name === "arguments") + return false; + return true; +} +function isStaticProperty(node) { + return node && node.type === "Property" && !node.computed; +} +function isStaticPropertyKey(node, parent) { + return isStaticProperty(parent) && parent.key === node; +} +const functionNodeTypeRE = /Function(?:Expression|Declaration)$|Method$/; +function isFunctionNode(node) { + return functionNodeTypeRE.test(node.type); +} +const blockNodeTypeRE = /^BlockStatement$|^For(?:In|Of)?Statement$/; +function isBlock(node) { + return blockNodeTypeRE.test(node.type); +} +function findParentScope(parentStack, isVar = false) { + return parentStack.find(isVar ? isFunctionNode : isBlock); +} +function isInDestructuringAssignment(parent, parentStack) { + if (parent && (parent.type === "Property" || parent.type === "ArrayPattern")) + return parentStack.some((i) => i.type === "AssignmentExpression"); + return false; +} + +export { esmWalker, isFunctionNode, isInDestructuringAssignment, isNodeInPattern, isStaticProperty, isStaticPropertyKey, setIsNodeInPattern }; diff --git a/node_modules/@vitest/utils/dist/chunk-colors.js b/node_modules/@vitest/utils/dist/chunk-colors.js new file mode 100644 index 0000000..080aa1d --- /dev/null +++ b/node_modules/@vitest/utils/dist/chunk-colors.js @@ -0,0 +1,77 @@ +const SAFE_TIMERS_SYMBOL = Symbol("vitest:SAFE_TIMERS"); +const SAFE_COLORS_SYMBOL = Symbol("vitest:SAFE_COLORS"); + +const colorsMap = { + bold: ["\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"], + dim: ["\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"], + italic: ["\x1B[3m", "\x1B[23m"], + underline: ["\x1B[4m", "\x1B[24m"], + inverse: ["\x1B[7m", "\x1B[27m"], + hidden: ["\x1B[8m", "\x1B[28m"], + strikethrough: ["\x1B[9m", "\x1B[29m"], + black: ["\x1B[30m", "\x1B[39m"], + red: ["\x1B[31m", "\x1B[39m"], + green: ["\x1B[32m", "\x1B[39m"], + yellow: ["\x1B[33m", "\x1B[39m"], + blue: ["\x1B[34m", "\x1B[39m"], + magenta: ["\x1B[35m", "\x1B[39m"], + cyan: ["\x1B[36m", "\x1B[39m"], + white: ["\x1B[37m", "\x1B[39m"], + gray: ["\x1B[90m", "\x1B[39m"], + bgBlack: ["\x1B[40m", "\x1B[49m"], + bgRed: ["\x1B[41m", "\x1B[49m"], + bgGreen: ["\x1B[42m", "\x1B[49m"], + bgYellow: ["\x1B[43m", "\x1B[49m"], + bgBlue: ["\x1B[44m", "\x1B[49m"], + bgMagenta: ["\x1B[45m", "\x1B[49m"], + bgCyan: ["\x1B[46m", "\x1B[49m"], + bgWhite: ["\x1B[47m", "\x1B[49m"] +}; +const colorsEntries = Object.entries(colorsMap); +function string(str) { + return String(str); +} +string.open = ""; +string.close = ""; +const defaultColors = /* @__PURE__ */ colorsEntries.reduce((acc, [key]) => { + acc[key] = string; + return acc; +}, { isColorSupported: false }); +function getDefaultColors() { + return { ...defaultColors }; +} +function getColors() { + return globalThis[SAFE_COLORS_SYMBOL] || defaultColors; +} +function createColors(isTTY = false) { + const enabled = typeof process !== "undefined" && !("NO_COLOR" in process.env || process.argv.includes("--no-color")) && !("GITHUB_ACTIONS" in process.env) && ("FORCE_COLOR" in process.env || process.argv.includes("--color") || process.platform === "win32" || isTTY && process.env.TERM !== "dumb" || "CI" in process.env); + const replaceClose = (string2, close, replace, index) => { + const start = string2.substring(0, index) + replace; + const end = string2.substring(index + close.length); + const nextIndex = end.indexOf(close); + return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end; + }; + const formatter = (open, close, replace = open) => { + const fn = (input) => { + const string2 = String(input); + const index = string2.indexOf(close, open.length); + return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close; + }; + fn.open = open; + fn.close = close; + return fn; + }; + const colorsObject = { + isColorSupported: enabled, + reset: enabled ? (s) => `\x1B[0m${s}\x1B[0m` : string + }; + for (const [name, formatterArgs] of colorsEntries) { + colorsObject[name] = enabled ? formatter(...formatterArgs) : string; + } + return colorsObject; +} +function setupColors(colors) { + globalThis[SAFE_COLORS_SYMBOL] = colors; +} + +export { SAFE_TIMERS_SYMBOL as S, SAFE_COLORS_SYMBOL as a, getDefaultColors as b, createColors as c, getColors as g, setupColors as s }; diff --git a/node_modules/@vitest/utils/dist/chunk-display.js b/node_modules/@vitest/utils/dist/chunk-display.js new file mode 100644 index 0000000..c3ff2eb --- /dev/null +++ b/node_modules/@vitest/utils/dist/chunk-display.js @@ -0,0 +1,144 @@ +import { format as format$1, plugins } from 'pretty-format'; +import * as loupe from 'loupe'; + +const { + AsymmetricMatcher, + DOMCollection, + DOMElement, + Immutable, + ReactElement, + ReactTestComponent +} = plugins; +const PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher +]; +function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) { + const MAX_LENGTH = maxLength ?? 1e4; + let result; + try { + result = format$1(object, { + maxDepth, + escapeString: false, + // min: true, + plugins: PLUGINS, + ...options + }); + } catch { + result = format$1(object, { + callToJSON: false, + maxDepth, + escapeString: false, + // min: true, + plugins: PLUGINS, + ...options + }); + } + return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(maxDepth / 2)) : result; +} + +const formatRegExp = /%[sdjifoOcj%]/g; +function format(...args) { + if (typeof args[0] !== "string") { + const objects = []; + for (let i2 = 0; i2 < args.length; i2++) + objects.push(inspect(args[i2], { depth: 0, colors: false, compact: 3 })); + return objects.join(" "); + } + const len = args.length; + let i = 1; + const template = args[0]; + let str = String(template).replace(formatRegExp, (x) => { + if (x === "%%") + return "%"; + if (i >= len) + return x; + switch (x) { + case "%s": { + const value = args[i++]; + if (typeof value === "bigint") + return `${value.toString()}n`; + if (typeof value === "number" && value === 0 && 1 / value < 0) + return "-0"; + if (typeof value === "object" && value !== null) + return inspect(value, { depth: 0, colors: false, compact: 3 }); + return String(value); + } + case "%d": { + const value = args[i++]; + if (typeof value === "bigint") + return `${value.toString()}n`; + return Number(value).toString(); + } + case "%i": { + const value = args[i++]; + if (typeof value === "bigint") + return `${value.toString()}n`; + return Number.parseInt(String(value)).toString(); + } + case "%f": + return Number.parseFloat(String(args[i++])).toString(); + case "%o": + return inspect(args[i++], { showHidden: true, showProxy: true }); + case "%O": + return inspect(args[i++]); + case "%c": { + i++; + return ""; + } + case "%j": + try { + return JSON.stringify(args[i++]); + } catch (err) { + const m = err.message; + if ( + // chromium + m.includes("circular structure") || m.includes("cyclic structures") || m.includes("cyclic object") + ) + return "[Circular]"; + throw err; + } + default: + return x; + } + }); + for (let x = args[i]; i < len; x = args[++i]) { + if (x === null || typeof x !== "object") + str += ` ${x}`; + else + str += ` ${inspect(x)}`; + } + return str; +} +function inspect(obj, options = {}) { + if (options.truncate === 0) + options.truncate = Number.POSITIVE_INFINITY; + return loupe.inspect(obj, options); +} +function objDisplay(obj, options = {}) { + if (typeof options.truncate === "undefined") + options.truncate = 40; + const str = inspect(obj, options); + const type = Object.prototype.toString.call(obj); + if (options.truncate && str.length >= options.truncate) { + if (type === "[object Function]") { + const fn = obj; + return !fn.name ? "[Function]" : `[Function: ${fn.name}]`; + } else if (type === "[object Array]") { + return `[ Array(${obj.length}) ]`; + } else if (type === "[object Object]") { + const keys = Object.keys(obj); + const kstr = keys.length > 2 ? `${keys.splice(0, 2).join(", ")}, ...` : keys.join(", "); + return `{ Object (${kstr}) }`; + } else { + return str; + } + } + return str; +} + +export { format as f, inspect as i, objDisplay as o, stringify as s }; diff --git a/node_modules/@vitest/utils/dist/diff.d.ts b/node_modules/@vitest/utils/dist/diff.d.ts new file mode 100644 index 0000000..ad1c0e7 --- /dev/null +++ b/node_modules/@vitest/utils/dist/diff.d.ts @@ -0,0 +1,93 @@ +import { D as DiffOptions } from './types-9l4niLY8.js'; +export { a as DiffOptionsColor } from './types-9l4niLY8.js'; +import 'pretty-format'; + +/** + * Diff Match and Patch + * Copyright 2018 The diff-match-patch Authors. + * https://github.com/google/diff-match-patch + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @fileoverview Computes the difference between two texts to create a patch. + * Applies the patch onto another text, allowing for errors. + * @author fraser@google.com (Neil Fraser) + */ +/** + * CHANGES by pedrottimark to diff_match_patch_uncompressed.ts file: + * + * 1. Delete anything not needed to use diff_cleanupSemantic method + * 2. Convert from prototype properties to var declarations + * 3. Convert Diff to class from constructor and prototype + * 4. Add type annotations for arguments and return values + * 5. Add exports + */ +/** + * The data structure representing a diff is an array of tuples: + * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] + * which means: delete 'Hello', add 'Goodbye' and keep ' world.' + */ +declare const DIFF_DELETE = -1; +declare const DIFF_INSERT = 1; +declare const DIFF_EQUAL = 0; +/** + * Class representing one diff tuple. + * Attempts to look like a two-element array (which is what this used to be). + * @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL. + * @param {string} text Text to be deleted, inserted, or retained. + * @constructor + */ +declare class Diff { + 0: number; + 1: string; + constructor(op: number, text: string); +} + +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +declare function diffLinesUnified(aLines: Array, bLines: Array, options?: DiffOptions): string; +declare function diffLinesUnified2(aLinesDisplay: Array, bLinesDisplay: Array, aLinesCompare: Array, bLinesCompare: Array, options?: DiffOptions): string; +declare function diffLinesRaw(aLines: Array, bLines: Array, options?: DiffOptions): [Array, boolean]; + +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +declare function diffStringsUnified(a: string, b: string, options?: DiffOptions): string; +declare function diffStringsRaw(a: string, b: string, cleanup: boolean, options?: DiffOptions): [Array, boolean]; + +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @param a Expected value + * @param b Received value + * @param options Diff options + * @returns {string | null} a string diff + */ +declare function diff(a: any, b: any, options?: DiffOptions): string | null; + +export { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, DiffOptions, diff, diffLinesRaw, diffLinesUnified, diffLinesUnified2, diffStringsRaw, diffStringsUnified }; diff --git a/node_modules/@vitest/utils/dist/diff.js b/node_modules/@vitest/utils/dist/diff.js new file mode 100644 index 0000000..8772c34 --- /dev/null +++ b/node_modules/@vitest/utils/dist/diff.js @@ -0,0 +1,1081 @@ +import { format, plugins } from 'pretty-format'; +import * as diff$1 from 'diff-sequences'; +import { g as getColors } from './chunk-colors.js'; + +function getType(value) { + if (value === void 0) { + return "undefined"; + } else if (value === null) { + return "null"; + } else if (Array.isArray(value)) { + return "array"; + } else if (typeof value === "boolean") { + return "boolean"; + } else if (typeof value === "function") { + return "function"; + } else if (typeof value === "number") { + return "number"; + } else if (typeof value === "string") { + return "string"; + } else if (typeof value === "bigint") { + return "bigint"; + } else if (typeof value === "object") { + if (value != null) { + if (value.constructor === RegExp) + return "regexp"; + else if (value.constructor === Map) + return "map"; + else if (value.constructor === Set) + return "set"; + else if (value.constructor === Date) + return "date"; + } + return "object"; + } else if (typeof value === "symbol") { + return "symbol"; + } + throw new Error(`value of unknown type: ${value}`); +} + +const DIFF_DELETE = -1; +const DIFF_INSERT = 1; +const DIFF_EQUAL = 0; +class Diff { + 0; + 1; + constructor(op, text) { + this[0] = op; + this[1] = text; + } +} +const diff_commonPrefix = function(text1, text2) { + if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) + return 0; + let pointermin = 0; + let pointermax = Math.min(text1.length, text2.length); + let pointermid = pointermax; + let pointerstart = 0; + while (pointermin < pointermid) { + if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) { + pointermin = pointermid; + pointerstart = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; +}; +const diff_commonSuffix = function(text1, text2) { + if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) + return 0; + let pointermin = 0; + let pointermax = Math.min(text1.length, text2.length); + let pointermid = pointermax; + let pointerend = 0; + while (pointermin < pointermid) { + if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) { + pointermin = pointermid; + pointerend = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; +}; +const diff_commonOverlap_ = function(text1, text2) { + const text1_length = text1.length; + const text2_length = text2.length; + if (text1_length === 0 || text2_length === 0) + return 0; + if (text1_length > text2_length) + text1 = text1.substring(text1_length - text2_length); + else if (text1_length < text2_length) + text2 = text2.substring(0, text1_length); + const text_length = Math.min(text1_length, text2_length); + if (text1 === text2) + return text_length; + let best = 0; + let length = 1; + while (true) { + const pattern = text1.substring(text_length - length); + const found = text2.indexOf(pattern); + if (found === -1) + return best; + length += found; + if (found === 0 || text1.substring(text_length - length) === text2.substring(0, length)) { + best = length; + length++; + } + } +}; +const diff_cleanupSemantic = function(diffs) { + let changes = false; + const equalities = []; + let equalitiesLength = 0; + let lastEquality = null; + let pointer = 0; + let length_insertions1 = 0; + let length_deletions1 = 0; + let length_insertions2 = 0; + let length_deletions2 = 0; + while (pointer < diffs.length) { + if (diffs[pointer][0] === DIFF_EQUAL) { + equalities[equalitiesLength++] = pointer; + length_insertions1 = length_insertions2; + length_deletions1 = length_deletions2; + length_insertions2 = 0; + length_deletions2 = 0; + lastEquality = diffs[pointer][1]; + } else { + if (diffs[pointer][0] === DIFF_INSERT) + length_insertions2 += diffs[pointer][1].length; + else + length_deletions2 += diffs[pointer][1].length; + if (lastEquality && lastEquality.length <= Math.max(length_insertions1, length_deletions1) && lastEquality.length <= Math.max(length_insertions2, length_deletions2)) { + diffs.splice(equalities[equalitiesLength - 1], 0, new Diff(DIFF_DELETE, lastEquality)); + diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; + equalitiesLength--; + equalitiesLength--; + pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; + length_insertions1 = 0; + length_deletions1 = 0; + length_insertions2 = 0; + length_deletions2 = 0; + lastEquality = null; + changes = true; + } + } + pointer++; + } + if (changes) + diff_cleanupMerge(diffs); + diff_cleanupSemanticLossless(diffs); + pointer = 1; + while (pointer < diffs.length) { + if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) { + const deletion = diffs[pointer - 1][1]; + const insertion = diffs[pointer][1]; + const overlap_length1 = diff_commonOverlap_(deletion, insertion); + const overlap_length2 = diff_commonOverlap_(insertion, deletion); + if (overlap_length1 >= overlap_length2) { + if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) { + diffs.splice(pointer, 0, new Diff(DIFF_EQUAL, insertion.substring(0, overlap_length1))); + diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1); + diffs[pointer + 1][1] = insertion.substring(overlap_length1); + pointer++; + } + } else { + if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) { + diffs.splice(pointer, 0, new Diff(DIFF_EQUAL, deletion.substring(0, overlap_length2))); + diffs[pointer - 1][0] = DIFF_INSERT; + diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2); + diffs[pointer + 1][0] = DIFF_DELETE; + diffs[pointer + 1][1] = deletion.substring(overlap_length2); + pointer++; + } + } + pointer++; + } + pointer++; + } +}; +const nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/; +const whitespaceRegex_ = /\s/; +const linebreakRegex_ = /[\r\n]/; +const blanklineEndRegex_ = /\n\r?\n$/; +const blanklineStartRegex_ = /^\r?\n\r?\n/; +function diff_cleanupSemanticLossless(diffs) { + function diff_cleanupSemanticScore_(one, two) { + if (!one || !two) { + return 6; + } + const char1 = one.charAt(one.length - 1); + const char2 = two.charAt(0); + const nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_); + const nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_); + const whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_); + const whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_); + const lineBreak1 = whitespace1 && char1.match(linebreakRegex_); + const lineBreak2 = whitespace2 && char2.match(linebreakRegex_); + const blankLine1 = lineBreak1 && one.match(blanklineEndRegex_); + const blankLine2 = lineBreak2 && two.match(blanklineStartRegex_); + if (blankLine1 || blankLine2) { + return 5; + } else if (lineBreak1 || lineBreak2) { + return 4; + } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { + return 3; + } else if (whitespace1 || whitespace2) { + return 2; + } else if (nonAlphaNumeric1 || nonAlphaNumeric2) { + return 1; + } + return 0; + } + let pointer = 1; + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { + let equality1 = diffs[pointer - 1][1]; + let edit = diffs[pointer][1]; + let equality2 = diffs[pointer + 1][1]; + const commonOffset = diff_commonSuffix(equality1, edit); + if (commonOffset) { + const commonString = edit.substring(edit.length - commonOffset); + equality1 = equality1.substring(0, equality1.length - commonOffset); + edit = commonString + edit.substring(0, edit.length - commonOffset); + equality2 = commonString + equality2; + } + let bestEquality1 = equality1; + let bestEdit = edit; + let bestEquality2 = equality2; + let bestScore = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2); + while (edit.charAt(0) === equality2.charAt(0)) { + equality1 += edit.charAt(0); + edit = edit.substring(1) + equality2.charAt(0); + equality2 = equality2.substring(1); + const score = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2); + if (score >= bestScore) { + bestScore = score; + bestEquality1 = equality1; + bestEdit = edit; + bestEquality2 = equality2; + } + } + if (diffs[pointer - 1][1] !== bestEquality1) { + if (bestEquality1) { + diffs[pointer - 1][1] = bestEquality1; + } else { + diffs.splice(pointer - 1, 1); + pointer--; + } + diffs[pointer][1] = bestEdit; + if (bestEquality2) { + diffs[pointer + 1][1] = bestEquality2; + } else { + diffs.splice(pointer + 1, 1); + pointer--; + } + } + } + pointer++; + } +} +function diff_cleanupMerge(diffs) { + diffs.push(new Diff(DIFF_EQUAL, "")); + let pointer = 0; + let count_delete = 0; + let count_insert = 0; + let text_delete = ""; + let text_insert = ""; + let commonlength; + while (pointer < diffs.length) { + switch (diffs[pointer][0]) { + case DIFF_INSERT: + count_insert++; + text_insert += diffs[pointer][1]; + pointer++; + break; + case DIFF_DELETE: + count_delete++; + text_delete += diffs[pointer][1]; + pointer++; + break; + case DIFF_EQUAL: + if (count_delete + count_insert > 1) { + if (count_delete !== 0 && count_insert !== 0) { + commonlength = diff_commonPrefix(text_insert, text_delete); + if (commonlength !== 0) { + if (pointer - count_delete - count_insert > 0 && diffs[pointer - count_delete - count_insert - 1][0] === DIFF_EQUAL) { + diffs[pointer - count_delete - count_insert - 1][1] += text_insert.substring(0, commonlength); + } else { + diffs.splice(0, 0, new Diff(DIFF_EQUAL, text_insert.substring(0, commonlength))); + pointer++; + } + text_insert = text_insert.substring(commonlength); + text_delete = text_delete.substring(commonlength); + } + commonlength = diff_commonSuffix(text_insert, text_delete); + if (commonlength !== 0) { + diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1]; + text_insert = text_insert.substring(0, text_insert.length - commonlength); + text_delete = text_delete.substring(0, text_delete.length - commonlength); + } + } + pointer -= count_delete + count_insert; + diffs.splice(pointer, count_delete + count_insert); + if (text_delete.length) { + diffs.splice(pointer, 0, new Diff(DIFF_DELETE, text_delete)); + pointer++; + } + if (text_insert.length) { + diffs.splice(pointer, 0, new Diff(DIFF_INSERT, text_insert)); + pointer++; + } + pointer++; + } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { + diffs[pointer - 1][1] += diffs[pointer][1]; + diffs.splice(pointer, 1); + } else { + pointer++; + } + count_insert = 0; + count_delete = 0; + text_delete = ""; + text_insert = ""; + break; + } + } + if (diffs[diffs.length - 1][1] === "") + diffs.pop(); + let changes = false; + pointer = 1; + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { + if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) { + diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length); + diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; + diffs.splice(pointer - 1, 1); + changes = true; + } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) { + diffs[pointer - 1][1] += diffs[pointer + 1][1]; + diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1]; + diffs.splice(pointer + 1, 1); + changes = true; + } + } + pointer++; + } + if (changes) + diff_cleanupMerge(diffs); +} + +const NO_DIFF_MESSAGE = "Compared values have no visual difference."; +const SIMILAR_MESSAGE = "Compared values serialize to the same structure.\nPrinting internal object structure without calling `toJSON` instead."; + +function formatTrailingSpaces(line, trailingSpaceFormatter) { + return line.replace(/\s+$/, (match) => trailingSpaceFormatter(match)); +} +function printDiffLine(line, isFirstOrLast, color, indicator, trailingSpaceFormatter, emptyFirstOrLastLinePlaceholder) { + return line.length !== 0 ? color( + `${indicator} ${formatTrailingSpaces(line, trailingSpaceFormatter)}` + ) : indicator !== " " ? color(indicator) : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 ? color(`${indicator} ${emptyFirstOrLastLinePlaceholder}`) : ""; +} +function printDeleteLine(line, isFirstOrLast, { + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder +}) { + return printDiffLine( + line, + isFirstOrLast, + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder + ); +} +function printInsertLine(line, isFirstOrLast, { + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder +}) { + return printDiffLine( + line, + isFirstOrLast, + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder + ); +} +function printCommonLine(line, isFirstOrLast, { + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder +}) { + return printDiffLine( + line, + isFirstOrLast, + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder + ); +} +function createPatchMark(aStart, aEnd, bStart, bEnd, { patchColor }) { + return patchColor( + `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@` + ); +} +function joinAlignedDiffsNoExpand(diffs, options) { + const iLength = diffs.length; + const nContextLines = options.contextLines; + const nContextLines2 = nContextLines + nContextLines; + let jLength = iLength; + let hasExcessAtStartOrEnd = false; + let nExcessesBetweenChanges = 0; + let i = 0; + while (i !== iLength) { + const iStart = i; + while (i !== iLength && diffs[i][0] === DIFF_EQUAL) + i += 1; + if (iStart !== i) { + if (iStart === 0) { + if (i > nContextLines) { + jLength -= i - nContextLines; + hasExcessAtStartOrEnd = true; + } + } else if (i === iLength) { + const n = i - iStart; + if (n > nContextLines) { + jLength -= n - nContextLines; + hasExcessAtStartOrEnd = true; + } + } else { + const n = i - iStart; + if (n > nContextLines2) { + jLength -= n - nContextLines2; + nExcessesBetweenChanges += 1; + } + } + } + while (i !== iLength && diffs[i][0] !== DIFF_EQUAL) + i += 1; + } + const hasPatch = nExcessesBetweenChanges !== 0 || hasExcessAtStartOrEnd; + if (nExcessesBetweenChanges !== 0) + jLength += nExcessesBetweenChanges + 1; + else if (hasExcessAtStartOrEnd) + jLength += 1; + const jLast = jLength - 1; + const lines = []; + let jPatchMark = 0; + if (hasPatch) + lines.push(""); + let aStart = 0; + let bStart = 0; + let aEnd = 0; + let bEnd = 0; + const pushCommonLine = (line) => { + const j = lines.length; + lines.push(printCommonLine(line, j === 0 || j === jLast, options)); + aEnd += 1; + bEnd += 1; + }; + const pushDeleteLine = (line) => { + const j = lines.length; + lines.push(printDeleteLine(line, j === 0 || j === jLast, options)); + aEnd += 1; + }; + const pushInsertLine = (line) => { + const j = lines.length; + lines.push(printInsertLine(line, j === 0 || j === jLast, options)); + bEnd += 1; + }; + i = 0; + while (i !== iLength) { + let iStart = i; + while (i !== iLength && diffs[i][0] === DIFF_EQUAL) + i += 1; + if (iStart !== i) { + if (iStart === 0) { + if (i > nContextLines) { + iStart = i - nContextLines; + aStart = iStart; + bStart = iStart; + aEnd = aStart; + bEnd = bStart; + } + for (let iCommon = iStart; iCommon !== i; iCommon += 1) + pushCommonLine(diffs[iCommon][1]); + } else if (i === iLength) { + const iEnd = i - iStart > nContextLines ? iStart + nContextLines : i; + for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) + pushCommonLine(diffs[iCommon][1]); + } else { + const nCommon = i - iStart; + if (nCommon > nContextLines2) { + const iEnd = iStart + nContextLines; + for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) + pushCommonLine(diffs[iCommon][1]); + lines[jPatchMark] = createPatchMark( + aStart, + aEnd, + bStart, + bEnd, + options + ); + jPatchMark = lines.length; + lines.push(""); + const nOmit = nCommon - nContextLines2; + aStart = aEnd + nOmit; + bStart = bEnd + nOmit; + aEnd = aStart; + bEnd = bStart; + for (let iCommon = i - nContextLines; iCommon !== i; iCommon += 1) + pushCommonLine(diffs[iCommon][1]); + } else { + for (let iCommon = iStart; iCommon !== i; iCommon += 1) + pushCommonLine(diffs[iCommon][1]); + } + } + } + while (i !== iLength && diffs[i][0] === DIFF_DELETE) { + pushDeleteLine(diffs[i][1]); + i += 1; + } + while (i !== iLength && diffs[i][0] === DIFF_INSERT) { + pushInsertLine(diffs[i][1]); + i += 1; + } + } + if (hasPatch) + lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); + return lines.join("\n"); +} +function joinAlignedDiffsExpand(diffs, options) { + return diffs.map((diff, i, diffs2) => { + const line = diff[1]; + const isFirstOrLast = i === 0 || i === diffs2.length - 1; + switch (diff[0]) { + case DIFF_DELETE: + return printDeleteLine(line, isFirstOrLast, options); + case DIFF_INSERT: + return printInsertLine(line, isFirstOrLast, options); + default: + return printCommonLine(line, isFirstOrLast, options); + } + }).join("\n"); +} + +const noColor = (string) => string; +const DIFF_CONTEXT_DEFAULT = 5; +const DIFF_TRUNCATE_THRESHOLD_DEFAULT = 0; +function getDefaultOptions() { + const c = getColors(); + return { + aAnnotation: "Expected", + aColor: c.green, + aIndicator: "-", + bAnnotation: "Received", + bColor: c.red, + bIndicator: "+", + changeColor: c.inverse, + changeLineTrailingSpaceColor: noColor, + commonColor: c.dim, + commonIndicator: " ", + commonLineTrailingSpaceColor: noColor, + compareKeys: void 0, + contextLines: DIFF_CONTEXT_DEFAULT, + emptyFirstOrLastLinePlaceholder: "", + expand: true, + includeChangeCounts: false, + omitAnnotationLines: false, + patchColor: c.yellow, + truncateThreshold: DIFF_TRUNCATE_THRESHOLD_DEFAULT, + truncateAnnotation: "... Diff result is truncated", + truncateAnnotationColor: noColor + }; +} +function getCompareKeys(compareKeys) { + return compareKeys && typeof compareKeys === "function" ? compareKeys : void 0; +} +function getContextLines(contextLines) { + return typeof contextLines === "number" && Number.isSafeInteger(contextLines) && contextLines >= 0 ? contextLines : DIFF_CONTEXT_DEFAULT; +} +function normalizeDiffOptions(options = {}) { + return { + ...getDefaultOptions(), + ...options, + compareKeys: getCompareKeys(options.compareKeys), + contextLines: getContextLines(options.contextLines) + }; +} + +function isEmptyString(lines) { + return lines.length === 1 && lines[0].length === 0; +} +function countChanges(diffs) { + let a = 0; + let b = 0; + diffs.forEach((diff2) => { + switch (diff2[0]) { + case DIFF_DELETE: + a += 1; + break; + case DIFF_INSERT: + b += 1; + break; + } + }); + return { a, b }; +} +function printAnnotation({ + aAnnotation, + aColor, + aIndicator, + bAnnotation, + bColor, + bIndicator, + includeChangeCounts, + omitAnnotationLines +}, changeCounts) { + if (omitAnnotationLines) + return ""; + let aRest = ""; + let bRest = ""; + if (includeChangeCounts) { + const aCount = String(changeCounts.a); + const bCount = String(changeCounts.b); + const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; + const aAnnotationPadding = " ".repeat(Math.max(0, baAnnotationLengthDiff)); + const bAnnotationPadding = " ".repeat(Math.max(0, -baAnnotationLengthDiff)); + const baCountLengthDiff = bCount.length - aCount.length; + const aCountPadding = " ".repeat(Math.max(0, baCountLengthDiff)); + const bCountPadding = " ".repeat(Math.max(0, -baCountLengthDiff)); + aRest = `${aAnnotationPadding} ${aIndicator} ${aCountPadding}${aCount}`; + bRest = `${bAnnotationPadding} ${bIndicator} ${bCountPadding}${bCount}`; + } + const a = `${aIndicator} ${aAnnotation}${aRest}`; + const b = `${bIndicator} ${bAnnotation}${bRest}`; + return `${aColor(a)} +${bColor(b)} + +`; +} +function printDiffLines(diffs, truncated, options) { + return printAnnotation(options, countChanges(diffs)) + (options.expand ? joinAlignedDiffsExpand(diffs, options) : joinAlignedDiffsNoExpand(diffs, options)) + (truncated ? options.truncateAnnotationColor(` +${options.truncateAnnotation}`) : ""); +} +function diffLinesUnified(aLines, bLines, options) { + const normalizedOptions = normalizeDiffOptions(options); + const [diffs, truncated] = diffLinesRaw( + isEmptyString(aLines) ? [] : aLines, + isEmptyString(bLines) ? [] : bLines, + normalizedOptions + ); + return printDiffLines( + diffs, + truncated, + normalizedOptions + ); +} +function diffLinesUnified2(aLinesDisplay, bLinesDisplay, aLinesCompare, bLinesCompare, options) { + if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) { + aLinesDisplay = []; + aLinesCompare = []; + } + if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) { + bLinesDisplay = []; + bLinesCompare = []; + } + if (aLinesDisplay.length !== aLinesCompare.length || bLinesDisplay.length !== bLinesCompare.length) { + return diffLinesUnified(aLinesDisplay, bLinesDisplay, options); + } + const [diffs, truncated] = diffLinesRaw(aLinesCompare, bLinesCompare, options); + let aIndex = 0; + let bIndex = 0; + diffs.forEach((diff2) => { + switch (diff2[0]) { + case DIFF_DELETE: + diff2[1] = aLinesDisplay[aIndex]; + aIndex += 1; + break; + case DIFF_INSERT: + diff2[1] = bLinesDisplay[bIndex]; + bIndex += 1; + break; + default: + diff2[1] = bLinesDisplay[bIndex]; + aIndex += 1; + bIndex += 1; + } + }); + return printDiffLines(diffs, truncated, normalizeDiffOptions(options)); +} +function diffLinesRaw(aLines, bLines, options) { + const truncate = (options == null ? void 0 : options.truncateThreshold) ?? false; + const truncateThreshold = Math.max(Math.floor((options == null ? void 0 : options.truncateThreshold) ?? 0), 0); + const aLength = truncate ? Math.min(aLines.length, truncateThreshold) : aLines.length; + const bLength = truncate ? Math.min(bLines.length, truncateThreshold) : bLines.length; + const truncated = aLength !== aLines.length || bLength !== bLines.length; + const isCommon = (aIndex2, bIndex2) => aLines[aIndex2] === bLines[bIndex2]; + const diffs = []; + let aIndex = 0; + let bIndex = 0; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + for (; aIndex !== aCommon; aIndex += 1) + diffs.push(new Diff(DIFF_DELETE, aLines[aIndex])); + for (; bIndex !== bCommon; bIndex += 1) + diffs.push(new Diff(DIFF_INSERT, bLines[bIndex])); + for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) + diffs.push(new Diff(DIFF_EQUAL, bLines[bIndex])); + }; + const diffSequences = diff$1.default.default || diff$1.default; + diffSequences(aLength, bLength, isCommon, foundSubsequence); + for (; aIndex !== aLength; aIndex += 1) + diffs.push(new Diff(DIFF_DELETE, aLines[aIndex])); + for (; bIndex !== bLength; bIndex += 1) + diffs.push(new Diff(DIFF_INSERT, bLines[bIndex])); + return [diffs, truncated]; +} + +function getNewLineSymbol(string) { + return string.includes("\r\n") ? "\r\n" : "\n"; +} +function diffStrings(a, b, options) { + const truncate = (options == null ? void 0 : options.truncateThreshold) ?? false; + const truncateThreshold = Math.max(Math.floor((options == null ? void 0 : options.truncateThreshold) ?? 0), 0); + let aLength = a.length; + let bLength = b.length; + if (truncate) { + const aMultipleLines = a.includes("\n"); + const bMultipleLines = b.includes("\n"); + const aNewLineSymbol = getNewLineSymbol(a); + const bNewLineSymbol = getNewLineSymbol(b); + const _a = aMultipleLines ? `${a.split(aNewLineSymbol, truncateThreshold).join(aNewLineSymbol)} +` : a; + const _b = bMultipleLines ? `${b.split(bNewLineSymbol, truncateThreshold).join(bNewLineSymbol)} +` : b; + aLength = _a.length; + bLength = _b.length; + } + const truncated = aLength !== a.length || bLength !== b.length; + const isCommon = (aIndex2, bIndex2) => a[aIndex2] === b[bIndex2]; + let aIndex = 0; + let bIndex = 0; + const diffs = []; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + if (aIndex !== aCommon) + diffs.push(new Diff(DIFF_DELETE, a.slice(aIndex, aCommon))); + if (bIndex !== bCommon) + diffs.push(new Diff(DIFF_INSERT, b.slice(bIndex, bCommon))); + aIndex = aCommon + nCommon; + bIndex = bCommon + nCommon; + diffs.push(new Diff(DIFF_EQUAL, b.slice(bCommon, bIndex))); + }; + const diffSequences = diff$1.default.default || diff$1.default; + diffSequences(aLength, bLength, isCommon, foundSubsequence); + if (aIndex !== aLength) + diffs.push(new Diff(DIFF_DELETE, a.slice(aIndex))); + if (bIndex !== bLength) + diffs.push(new Diff(DIFF_INSERT, b.slice(bIndex))); + return [diffs, truncated]; +} + +function concatenateRelevantDiffs(op, diffs, changeColor) { + return diffs.reduce( + (reduced, diff) => reduced + (diff[0] === DIFF_EQUAL ? diff[1] : diff[0] === op && diff[1].length !== 0 ? changeColor(diff[1]) : ""), + "" + ); +} +class ChangeBuffer { + op; + line; + // incomplete line + lines; + // complete lines + changeColor; + constructor(op, changeColor) { + this.op = op; + this.line = []; + this.lines = []; + this.changeColor = changeColor; + } + pushSubstring(substring) { + this.pushDiff(new Diff(this.op, substring)); + } + pushLine() { + this.lines.push( + this.line.length !== 1 ? new Diff( + this.op, + concatenateRelevantDiffs(this.op, this.line, this.changeColor) + ) : this.line[0][0] === this.op ? this.line[0] : new Diff(this.op, this.line[0][1]) + // was common diff + ); + this.line.length = 0; + } + isLineEmpty() { + return this.line.length === 0; + } + // Minor input to buffer. + pushDiff(diff) { + this.line.push(diff); + } + // Main input to buffer. + align(diff) { + const string = diff[1]; + if (string.includes("\n")) { + const substrings = string.split("\n"); + const iLast = substrings.length - 1; + substrings.forEach((substring, i) => { + if (i < iLast) { + this.pushSubstring(substring); + this.pushLine(); + } else if (substring.length !== 0) { + this.pushSubstring(substring); + } + }); + } else { + this.pushDiff(diff); + } + } + // Output from buffer. + moveLinesTo(lines) { + if (!this.isLineEmpty()) + this.pushLine(); + lines.push(...this.lines); + this.lines.length = 0; + } +} +class CommonBuffer { + deleteBuffer; + insertBuffer; + lines; + constructor(deleteBuffer, insertBuffer) { + this.deleteBuffer = deleteBuffer; + this.insertBuffer = insertBuffer; + this.lines = []; + } + pushDiffCommonLine(diff) { + this.lines.push(diff); + } + pushDiffChangeLines(diff) { + const isDiffEmpty = diff[1].length === 0; + if (!isDiffEmpty || this.deleteBuffer.isLineEmpty()) + this.deleteBuffer.pushDiff(diff); + if (!isDiffEmpty || this.insertBuffer.isLineEmpty()) + this.insertBuffer.pushDiff(diff); + } + flushChangeLines() { + this.deleteBuffer.moveLinesTo(this.lines); + this.insertBuffer.moveLinesTo(this.lines); + } + // Input to buffer. + align(diff) { + const op = diff[0]; + const string = diff[1]; + if (string.includes("\n")) { + const substrings = string.split("\n"); + const iLast = substrings.length - 1; + substrings.forEach((substring, i) => { + if (i === 0) { + const subdiff = new Diff(op, substring); + if (this.deleteBuffer.isLineEmpty() && this.insertBuffer.isLineEmpty()) { + this.flushChangeLines(); + this.pushDiffCommonLine(subdiff); + } else { + this.pushDiffChangeLines(subdiff); + this.flushChangeLines(); + } + } else if (i < iLast) { + this.pushDiffCommonLine(new Diff(op, substring)); + } else if (substring.length !== 0) { + this.pushDiffChangeLines(new Diff(op, substring)); + } + }); + } else { + this.pushDiffChangeLines(diff); + } + } + // Output from buffer. + getLines() { + this.flushChangeLines(); + return this.lines; + } +} +function getAlignedDiffs(diffs, changeColor) { + const deleteBuffer = new ChangeBuffer(DIFF_DELETE, changeColor); + const insertBuffer = new ChangeBuffer(DIFF_INSERT, changeColor); + const commonBuffer = new CommonBuffer(deleteBuffer, insertBuffer); + diffs.forEach((diff) => { + switch (diff[0]) { + case DIFF_DELETE: + deleteBuffer.align(diff); + break; + case DIFF_INSERT: + insertBuffer.align(diff); + break; + default: + commonBuffer.align(diff); + } + }); + return commonBuffer.getLines(); +} + +function hasCommonDiff(diffs, isMultiline) { + if (isMultiline) { + const iLast = diffs.length - 1; + return diffs.some( + (diff, i) => diff[0] === DIFF_EQUAL && (i !== iLast || diff[1] !== "\n") + ); + } + return diffs.some((diff) => diff[0] === DIFF_EQUAL); +} +function diffStringsUnified(a, b, options) { + if (a !== b && a.length !== 0 && b.length !== 0) { + const isMultiline = a.includes("\n") || b.includes("\n"); + const [diffs, truncated] = diffStringsRaw( + isMultiline ? `${a} +` : a, + isMultiline ? `${b} +` : b, + true, + // cleanupSemantic + options + ); + if (hasCommonDiff(diffs, isMultiline)) { + const optionsNormalized = normalizeDiffOptions(options); + const lines = getAlignedDiffs(diffs, optionsNormalized.changeColor); + return printDiffLines(lines, truncated, optionsNormalized); + } + } + return diffLinesUnified(a.split("\n"), b.split("\n"), options); +} +function diffStringsRaw(a, b, cleanup, options) { + const [diffs, truncated] = diffStrings(a, b, options); + if (cleanup) + diff_cleanupSemantic(diffs); + return [diffs, truncated]; +} + +function getCommonMessage(message, options) { + const { commonColor } = normalizeDiffOptions(options); + return commonColor(message); +} +const { + AsymmetricMatcher, + DOMCollection, + DOMElement, + Immutable, + ReactElement, + ReactTestComponent +} = plugins; +const PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + AsymmetricMatcher +]; +const FORMAT_OPTIONS = { + plugins: PLUGINS +}; +const FALLBACK_FORMAT_OPTIONS = { + callToJSON: false, + maxDepth: 10, + plugins: PLUGINS +}; +function diff(a, b, options) { + if (Object.is(a, b)) + return ""; + const aType = getType(a); + let expectedType = aType; + let omitDifference = false; + if (aType === "object" && typeof a.asymmetricMatch === "function") { + if (a.$$typeof !== Symbol.for("jest.asymmetricMatcher")) { + return null; + } + if (typeof a.getExpectedType !== "function") { + return null; + } + expectedType = a.getExpectedType(); + omitDifference = expectedType === "string"; + } + if (expectedType !== getType(b)) { + const { aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator } = normalizeDiffOptions(options); + const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options); + const aDisplay = format(a, formatOptions); + const bDisplay = format(b, formatOptions); + const aDiff = `${aColor(`${aIndicator} ${aAnnotation}:`)} +${aDisplay}`; + const bDiff = `${bColor(`${bIndicator} ${bAnnotation}:`)} +${bDisplay}`; + return `${aDiff} + +${bDiff}`; + } + if (omitDifference) + return null; + switch (aType) { + case "string": + return diffLinesUnified(a.split("\n"), b.split("\n"), options); + case "boolean": + case "number": + return comparePrimitive(a, b, options); + case "map": + return compareObjects(sortMap(a), sortMap(b), options); + case "set": + return compareObjects(sortSet(a), sortSet(b), options); + default: + return compareObjects(a, b, options); + } +} +function comparePrimitive(a, b, options) { + const aFormat = format(a, FORMAT_OPTIONS); + const bFormat = format(b, FORMAT_OPTIONS); + return aFormat === bFormat ? "" : diffLinesUnified(aFormat.split("\n"), bFormat.split("\n"), options); +} +function sortMap(map) { + return new Map(Array.from(map.entries()).sort()); +} +function sortSet(set) { + return new Set(Array.from(set.values()).sort()); +} +function compareObjects(a, b, options) { + let difference; + let hasThrown = false; + try { + const formatOptions = getFormatOptions(FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); + } catch { + hasThrown = true; + } + const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options); + if (difference === void 0 || difference === noDiffMessage) { + const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); + if (difference !== noDiffMessage && !hasThrown) { + difference = `${getCommonMessage( + SIMILAR_MESSAGE, + options + )} + +${difference}`; + } + } + return difference; +} +function getFormatOptions(formatOptions, options) { + const { compareKeys } = normalizeDiffOptions(options); + return { + ...formatOptions, + compareKeys + }; +} +function getObjectsDifference(a, b, formatOptions, options) { + const formatOptionsZeroIndent = { ...formatOptions, indent: 0 }; + const aCompare = format(a, formatOptionsZeroIndent); + const bCompare = format(b, formatOptionsZeroIndent); + if (aCompare === bCompare) { + return getCommonMessage(NO_DIFF_MESSAGE, options); + } else { + const aDisplay = format(a, formatOptions); + const bDisplay = format(b, formatOptions); + return diffLinesUnified2( + aDisplay.split("\n"), + bDisplay.split("\n"), + aCompare.split("\n"), + bCompare.split("\n"), + options + ); + } +} + +export { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diff, diffLinesRaw, diffLinesUnified, diffLinesUnified2, diffStringsRaw, diffStringsUnified }; diff --git a/node_modules/@vitest/utils/dist/error.d.ts b/node_modules/@vitest/utils/dist/error.d.ts new file mode 100644 index 0000000..49e4d77 --- /dev/null +++ b/node_modules/@vitest/utils/dist/error.d.ts @@ -0,0 +1,11 @@ +import { D as DiffOptions } from './types-9l4niLY8.js'; +import 'pretty-format'; + +declare function serializeError(val: any, seen?: WeakMap): any; +declare function processError(err: any, diffOptions?: DiffOptions): any; +declare function replaceAsymmetricMatcher(actual: any, expected: any, actualReplaced?: WeakSet, expectedReplaced?: WeakSet): { + replacedActual: any; + replacedExpected: any; +}; + +export { processError, replaceAsymmetricMatcher, serializeError }; diff --git a/node_modules/@vitest/utils/dist/error.js b/node_modules/@vitest/utils/dist/error.js new file mode 100644 index 0000000..05841e4 --- /dev/null +++ b/node_modules/@vitest/utils/dist/error.js @@ -0,0 +1,150 @@ +import { diff } from './diff.js'; +import { f as format, s as stringify } from './chunk-display.js'; +import { deepClone, getOwnProperties, getType } from './helpers.js'; +import 'pretty-format'; +import 'diff-sequences'; +import './chunk-colors.js'; +import 'loupe'; + +const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@"; +const IS_COLLECTION_SYMBOL = "@@__IMMUTABLE_ITERABLE__@@"; +function isImmutable(v) { + return v && (v[IS_COLLECTION_SYMBOL] || v[IS_RECORD_SYMBOL]); +} +const OBJECT_PROTO = Object.getPrototypeOf({}); +function getUnserializableMessage(err) { + if (err instanceof Error) + return `: ${err.message}`; + if (typeof err === "string") + return `: ${err}`; + return ""; +} +function serializeError(val, seen = /* @__PURE__ */ new WeakMap()) { + if (!val || typeof val === "string") + return val; + if (typeof val === "function") + return `Function<${val.name || "anonymous"}>`; + if (typeof val === "symbol") + return val.toString(); + if (typeof val !== "object") + return val; + if (isImmutable(val)) + return serializeError(val.toJSON(), seen); + if (val instanceof Promise || val.constructor && val.constructor.prototype === "AsyncFunction") + return "Promise"; + if (typeof Element !== "undefined" && val instanceof Element) + return val.tagName; + if (typeof val.asymmetricMatch === "function") + return `${val.toString()} ${format(val.sample)}`; + if (typeof val.toJSON === "function") + return val.toJSON(); + if (seen.has(val)) + return seen.get(val); + if (Array.isArray(val)) { + const clone = new Array(val.length); + seen.set(val, clone); + val.forEach((e, i) => { + try { + clone[i] = serializeError(e, seen); + } catch (err) { + clone[i] = getUnserializableMessage(err); + } + }); + return clone; + } else { + const clone = /* @__PURE__ */ Object.create(null); + seen.set(val, clone); + let obj = val; + while (obj && obj !== OBJECT_PROTO) { + Object.getOwnPropertyNames(obj).forEach((key) => { + if (key in clone) + return; + try { + clone[key] = serializeError(val[key], seen); + } catch (err) { + delete clone[key]; + clone[key] = getUnserializableMessage(err); + } + }); + obj = Object.getPrototypeOf(obj); + } + return clone; + } +} +function normalizeErrorMessage(message) { + return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, ""); +} +function processError(err, diffOptions) { + if (!err || typeof err !== "object") + return { message: err }; + if (err.stack) + err.stackStr = String(err.stack); + if (err.name) + err.nameStr = String(err.name); + if (err.showDiff || err.showDiff === void 0 && err.expected !== void 0 && err.actual !== void 0) { + const clonedActual = deepClone(err.actual, { forceWritable: true }); + const clonedExpected = deepClone(err.expected, { forceWritable: true }); + const { replacedActual, replacedExpected } = replaceAsymmetricMatcher(clonedActual, clonedExpected); + err.diff = diff(replacedExpected, replacedActual, { ...diffOptions, ...err.diffOptions }); + } + if (typeof err.expected !== "string") + err.expected = stringify(err.expected, 10); + if (typeof err.actual !== "string") + err.actual = stringify(err.actual, 10); + try { + if (typeof err.message === "string") + err.message = normalizeErrorMessage(err.message); + if (typeof err.cause === "object" && typeof err.cause.message === "string") + err.cause.message = normalizeErrorMessage(err.cause.message); + } catch { + } + try { + return serializeError(err); + } catch (e) { + return serializeError(new Error(`Failed to fully serialize error: ${e == null ? void 0 : e.message} +Inner error message: ${err == null ? void 0 : err.message}`)); + } +} +function isAsymmetricMatcher(data) { + const type = getType(data); + return type === "Object" && typeof data.asymmetricMatch === "function"; +} +function isReplaceable(obj1, obj2) { + const obj1Type = getType(obj1); + const obj2Type = getType(obj2); + return obj1Type === obj2Type && (obj1Type === "Object" || obj1Type === "Array"); +} +function replaceAsymmetricMatcher(actual, expected, actualReplaced = /* @__PURE__ */ new WeakSet(), expectedReplaced = /* @__PURE__ */ new WeakSet()) { + if (!isReplaceable(actual, expected)) + return { replacedActual: actual, replacedExpected: expected }; + if (actualReplaced.has(actual) || expectedReplaced.has(expected)) + return { replacedActual: actual, replacedExpected: expected }; + actualReplaced.add(actual); + expectedReplaced.add(expected); + getOwnProperties(expected).forEach((key) => { + const expectedValue = expected[key]; + const actualValue = actual[key]; + if (isAsymmetricMatcher(expectedValue)) { + if (expectedValue.asymmetricMatch(actualValue)) + actual[key] = expectedValue; + } else if (isAsymmetricMatcher(actualValue)) { + if (actualValue.asymmetricMatch(expectedValue)) + expected[key] = actualValue; + } else if (isReplaceable(actualValue, expectedValue)) { + const replaced = replaceAsymmetricMatcher( + actualValue, + expectedValue, + actualReplaced, + expectedReplaced + ); + actual[key] = replaced.replacedActual; + expected[key] = replaced.replacedExpected; + } + }); + return { + replacedActual: actual, + replacedExpected: expected + }; +} + +export { processError, replaceAsymmetricMatcher, serializeError }; diff --git a/node_modules/@vitest/utils/dist/helpers.d.ts b/node_modules/@vitest/utils/dist/helpers.d.ts new file mode 100644 index 0000000..c8f345a --- /dev/null +++ b/node_modules/@vitest/utils/dist/helpers.d.ts @@ -0,0 +1,35 @@ +import { Nullable, Arrayable } from './types.js'; + +interface CloneOptions { + forceWritable?: boolean; +} +declare function notNullish(v: T | null | undefined): v is NonNullable; +declare function assertTypes(value: unknown, name: string, types: string[]): void; +declare function isPrimitive(value: unknown): boolean; +declare function slash(path: string): string; +declare function parseRegexp(input: string): RegExp; +declare function toArray(array?: Nullable>): Array; +declare function isObject(item: unknown): boolean; +declare function getType(value: unknown): string; +declare function getOwnProperties(obj: any): (string | symbol)[]; +declare function deepClone(val: T, options?: CloneOptions): T; +declare function clone(val: T, seen: WeakMap, options?: CloneOptions): T; +declare function noop(): void; +declare function objectAttr(source: any, path: string, defaultValue?: undefined): any; +type DeferPromise = Promise & { + resolve: (value: T | PromiseLike) => void; + reject: (reason?: any) => void; +}; +declare function createDefer(): DeferPromise; +/** + * If code starts with a function call, will return its last index, respecting arguments. + * This will return 25 - last ending character of toMatch ")" + * Also works with callbacks + * ``` + * toMatch({ test: '123' }); + * toBeAliased('123') + * ``` + */ +declare function getCallLastIndex(code: string): number | null; + +export { type DeferPromise, assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray }; diff --git a/node_modules/@vitest/utils/dist/helpers.js b/node_modules/@vitest/utils/dist/helpers.js new file mode 100644 index 0000000..ca29785 --- /dev/null +++ b/node_modules/@vitest/utils/dist/helpers.js @@ -0,0 +1,154 @@ +function notNullish(v) { + return v != null; +} +function assertTypes(value, name, types) { + const receivedType = typeof value; + const pass = types.includes(receivedType); + if (!pass) + throw new TypeError(`${name} value must be ${types.join(" or ")}, received "${receivedType}"`); +} +function isPrimitive(value) { + return value === null || typeof value !== "function" && typeof value !== "object"; +} +function slash(path) { + return path.replace(/\\/g, "/"); +} +function parseRegexp(input) { + const m = input.match(/(\/?)(.+)\1([a-z]*)/i); + if (!m) + return /$^/; + if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) + return RegExp(input); + return new RegExp(m[2], m[3]); +} +function toArray(array) { + if (array === null || array === void 0) + array = []; + if (Array.isArray(array)) + return array; + return [array]; +} +function isObject(item) { + return item != null && typeof item === "object" && !Array.isArray(item); +} +function isFinalObj(obj) { + return obj === Object.prototype || obj === Function.prototype || obj === RegExp.prototype; +} +function getType(value) { + return Object.prototype.toString.apply(value).slice(8, -1); +} +function collectOwnProperties(obj, collector) { + const collect = typeof collector === "function" ? collector : (key) => collector.add(key); + Object.getOwnPropertyNames(obj).forEach(collect); + Object.getOwnPropertySymbols(obj).forEach(collect); +} +function getOwnProperties(obj) { + const ownProps = /* @__PURE__ */ new Set(); + if (isFinalObj(obj)) + return []; + collectOwnProperties(obj, ownProps); + return Array.from(ownProps); +} +const defaultCloneOptions = { forceWritable: false }; +function deepClone(val, options = defaultCloneOptions) { + const seen = /* @__PURE__ */ new WeakMap(); + return clone(val, seen, options); +} +function clone(val, seen, options = defaultCloneOptions) { + let k, out; + if (seen.has(val)) + return seen.get(val); + if (Array.isArray(val)) { + out = Array(k = val.length); + seen.set(val, out); + while (k--) + out[k] = clone(val[k], seen, options); + return out; + } + if (Object.prototype.toString.call(val) === "[object Object]") { + out = Object.create(Object.getPrototypeOf(val)); + seen.set(val, out); + const props = getOwnProperties(val); + for (const k2 of props) { + const descriptor = Object.getOwnPropertyDescriptor(val, k2); + if (!descriptor) + continue; + const cloned = clone(val[k2], seen, options); + if (options.forceWritable) { + Object.defineProperty(out, k2, { + enumerable: descriptor.enumerable, + configurable: true, + writable: true, + value: cloned + }); + } else if ("get" in descriptor) { + Object.defineProperty(out, k2, { + ...descriptor, + get() { + return cloned; + } + }); + } else { + Object.defineProperty(out, k2, { + ...descriptor, + value: cloned + }); + } + } + return out; + } + return val; +} +function noop() { +} +function objectAttr(source, path, defaultValue = void 0) { + const paths = path.replace(/\[(\d+)\]/g, ".$1").split("."); + let result = source; + for (const p of paths) { + result = Object(result)[p]; + if (result === void 0) + return defaultValue; + } + return result; +} +function createDefer() { + let resolve = null; + let reject = null; + const p = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + p.resolve = resolve; + p.reject = reject; + return p; +} +function getCallLastIndex(code) { + let charIndex = -1; + let inString = null; + let startedBracers = 0; + let endedBracers = 0; + let beforeChar = null; + while (charIndex <= code.length) { + beforeChar = code[charIndex]; + charIndex++; + const char = code[charIndex]; + const isCharString = char === '"' || char === "'" || char === "`"; + if (isCharString && beforeChar !== "\\") { + if (inString === char) + inString = null; + else if (!inString) + inString = char; + } + if (!inString) { + if (char === "(") + startedBracers++; + if (char === ")") + endedBracers++; + } + if (startedBracers && endedBracers && startedBracers === endedBracers) + return charIndex; + } + return null; +} + +export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray }; diff --git a/node_modules/@vitest/utils/dist/index.d.ts b/node_modules/@vitest/utils/dist/index.d.ts new file mode 100644 index 0000000..b39085b --- /dev/null +++ b/node_modules/@vitest/utils/dist/index.d.ts @@ -0,0 +1,110 @@ +export { DeferPromise, assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray } from './helpers.js'; +export { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, ErrorWithDiff, MergeInsertions, MutableArray, Nullable, ParsedStack } from './types.js'; +import { PrettyFormatOptions } from 'pretty-format'; + +declare function stringify(object: unknown, maxDepth?: number, { maxLength, ...options }?: PrettyFormatOptions & { + maxLength?: number; +}): string; + +declare function getSafeTimers(): { + nextTick: any; + setTimeout: any; + setInterval: any; + clearInterval: any; + clearTimeout: any; + setImmediate: any; + clearImmediate: any; +}; +declare function setSafeTimers(): void; + +declare function shuffle(array: T[], seed?: number): T[]; + +interface LoupeOptions { + showHidden?: boolean | undefined; + depth?: number | null | undefined; + colors?: boolean | undefined; + customInspect?: boolean | undefined; + showProxy?: boolean | undefined; + maxArrayLength?: number | null | undefined; + maxStringLength?: number | null | undefined; + breakLength?: number | undefined; + compact?: boolean | number | undefined; + sorted?: boolean | ((a: string, b: string) => number) | undefined; + getters?: 'get' | 'set' | boolean | undefined; + numericSeparator?: boolean | undefined; + truncate?: number; +} +declare function format(...args: unknown[]): string; +declare function inspect(obj: unknown, options?: LoupeOptions): string; +declare function objDisplay(obj: unknown, options?: LoupeOptions): string; + +declare const SAFE_TIMERS_SYMBOL: unique symbol; +declare const SAFE_COLORS_SYMBOL: unique symbol; + +declare const colorsMap: { + readonly bold: readonly ["\u001B[1m", "\u001B[22m", "\u001B[22m\u001B[1m"]; + readonly dim: readonly ["\u001B[2m", "\u001B[22m", "\u001B[22m\u001B[2m"]; + readonly italic: readonly ["\u001B[3m", "\u001B[23m"]; + readonly underline: readonly ["\u001B[4m", "\u001B[24m"]; + readonly inverse: readonly ["\u001B[7m", "\u001B[27m"]; + readonly hidden: readonly ["\u001B[8m", "\u001B[28m"]; + readonly strikethrough: readonly ["\u001B[9m", "\u001B[29m"]; + readonly black: readonly ["\u001B[30m", "\u001B[39m"]; + readonly red: readonly ["\u001B[31m", "\u001B[39m"]; + readonly green: readonly ["\u001B[32m", "\u001B[39m"]; + readonly yellow: readonly ["\u001B[33m", "\u001B[39m"]; + readonly blue: readonly ["\u001B[34m", "\u001B[39m"]; + readonly magenta: readonly ["\u001B[35m", "\u001B[39m"]; + readonly cyan: readonly ["\u001B[36m", "\u001B[39m"]; + readonly white: readonly ["\u001B[37m", "\u001B[39m"]; + readonly gray: readonly ["\u001B[90m", "\u001B[39m"]; + readonly bgBlack: readonly ["\u001B[40m", "\u001B[49m"]; + readonly bgRed: readonly ["\u001B[41m", "\u001B[49m"]; + readonly bgGreen: readonly ["\u001B[42m", "\u001B[49m"]; + readonly bgYellow: readonly ["\u001B[43m", "\u001B[49m"]; + readonly bgBlue: readonly ["\u001B[44m", "\u001B[49m"]; + readonly bgMagenta: readonly ["\u001B[45m", "\u001B[49m"]; + readonly bgCyan: readonly ["\u001B[46m", "\u001B[49m"]; + readonly bgWhite: readonly ["\u001B[47m", "\u001B[49m"]; +}; +type ColorName = keyof typeof colorsMap; +interface ColorMethod { + (input: unknown): string; + open: string; + close: string; +} +type ColorsMethods = { + [Key in ColorName]: ColorMethod; +}; +type Colors$1 = ColorsMethods & { + isColorSupported: boolean; + reset: (input: unknown) => string; +}; +declare function getDefaultColors(): Colors$1; +declare function getColors(): Colors$1; +declare function createColors(isTTY?: boolean): Colors$1; +declare function setupColors(colors: Colors$1): void; + +interface ErrorOptions { + message?: string; + stackTraceLimit?: number; +} +/** + * Get original stacktrace without source map support the most performant way. + * - Create only 1 stack frame. + * - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). + */ +declare function createSimpleStackTrace(options?: ErrorOptions): string; + +declare const lineSplitRE: RegExp; +declare function positionToOffset(source: string, lineNumber: number, columnNumber: number): number; +declare function offsetToLineNumber(source: string, offset: number): number; + +type Colors = Record string>; +interface HighlightOptions { + jsx?: boolean; + colors?: Colors; +} +declare function highlight(code: string, options?: HighlightOptions): string; + +export { type ColorMethod, type ColorName, type Colors$1 as Colors, type ColorsMethods, SAFE_COLORS_SYMBOL, SAFE_TIMERS_SYMBOL, createColors, createSimpleStackTrace, format, getColors, getDefaultColors, getSafeTimers, highlight, inspect, lineSplitRE, objDisplay, offsetToLineNumber, positionToOffset, setSafeTimers, setupColors, shuffle, stringify }; diff --git a/node_modules/@vitest/utils/dist/index.js b/node_modules/@vitest/utils/dist/index.js new file mode 100644 index 0000000..f0d512d --- /dev/null +++ b/node_modules/@vitest/utils/dist/index.js @@ -0,0 +1,643 @@ +export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray } from './helpers.js'; +export { f as format, i as inspect, o as objDisplay, s as stringify } from './chunk-display.js'; +import { S as SAFE_TIMERS_SYMBOL, g as getColors } from './chunk-colors.js'; +export { a as SAFE_COLORS_SYMBOL, c as createColors, b as getDefaultColors, s as setupColors } from './chunk-colors.js'; +import 'pretty-format'; +import 'loupe'; + +function getSafeTimers() { + const { + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate + } = globalThis[SAFE_TIMERS_SYMBOL] || globalThis; + const { + nextTick: safeNextTick + } = globalThis[SAFE_TIMERS_SYMBOL] || globalThis.process || { nextTick: (cb) => cb() }; + return { + nextTick: safeNextTick, + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate + }; +} +function setSafeTimers() { + const { + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate + } = globalThis; + const { + nextTick: safeNextTick + } = globalThis.process || { nextTick: (cb) => cb() }; + const timers = { + nextTick: safeNextTick, + setTimeout: safeSetTimeout, + setInterval: safeSetInterval, + clearInterval: safeClearInterval, + clearTimeout: safeClearTimeout, + setImmediate: safeSetImmediate, + clearImmediate: safeClearImmediate + }; + globalThis[SAFE_TIMERS_SYMBOL] = timers; +} + +const RealDate = Date; +function random(seed) { + const x = Math.sin(seed++) * 1e4; + return x - Math.floor(x); +} +function shuffle(array, seed = RealDate.now()) { + let length = array.length; + while (length) { + const index = Math.floor(random(seed) * length--); + const previous = array[length]; + array[length] = array[index]; + array[index] = previous; + ++seed; + } + return array; +} + +function createSimpleStackTrace(options) { + const { message = "error", stackTraceLimit = 1 } = options || {}; + const limit = Error.stackTraceLimit; + const prepareStackTrace = Error.prepareStackTrace; + Error.stackTraceLimit = stackTraceLimit; + Error.prepareStackTrace = (e) => e.stack; + const err = new Error(message); + const stackTrace = err.stack || ""; + Error.prepareStackTrace = prepareStackTrace; + Error.stackTraceLimit = limit; + return stackTrace; +} + +const lineSplitRE = /\r?\n/; +function positionToOffset(source, lineNumber, columnNumber) { + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let start = 0; + if (lineNumber > lines.length) + return source.length; + for (let i = 0; i < lineNumber - 1; i++) + start += lines[i].length + nl; + return start + columnNumber; +} +function offsetToLineNumber(source, offset) { + if (offset > source.length) { + throw new Error( + `offset is longer than source length! offset ${offset} > length ${source.length}` + ); + } + const lines = source.split(lineSplitRE); + const nl = /\r\n/.test(source) ? 2 : 1; + let counted = 0; + let line = 0; + for (; line < lines.length; line++) { + const lineLength = lines[line].length + nl; + if (counted + lineLength >= offset) + break; + counted += lineLength; + } + return line + 1; +} + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +// Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell +// License: MIT. +var Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace; +RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\\]).|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; +Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; +Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; +StringLiteral = /(['"])(?:(?!\1)[^\\\n\r]|\\(?:\r\n|[^]))*(\1)?/y; +NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; +Template = /[`}](?:[^`\\$]|\\[^]|\$(?!\{))*(`|\$\{)?/y; +WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/yu; +LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; +MultiLineComment = /\/\*(?:[^*]|\*(?!\/))*(\*\/)?/y; +SingleLineComment = /\/\/.*/y; +JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; +JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; +JSXString = /(['"])(?:(?!\1)[^])*(\1)?/y; +JSXText = /[^<>{}]+/y; +TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; +TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; +KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; +KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; +Newline = RegExp(LineTerminatorSequence.source); +var jsTokens_1 = function*(input, {jsx = false} = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [ + {tag: "JS"} + ]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }); + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield ({ + type: "TemplateMiddle", + value: match[0] + }); + } else { + stack.pop(); + postfixIncDec = true; + yield ({ + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "InterpolationInJSX": + if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield ({ + type: "JSXPunctuator", + value: "}" + }); + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({tag: "JSXTag"}); + lastIndex += 1; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: punctuator + }); + continue; + } + postfixIncDec = false; + break; + default: + postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "Punctuator", + value: punctuator + }); + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": + if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield ({ + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }); + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "NumericLiteral", + value: match[0] + }); + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield ({ + type: "TemplateHead", + value: match[0] + }); + } else { + postfixIncDec = true; + yield ({ + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({tag: "JSXTag"}); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({tag: "JSXChildren"}); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": + if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({tag: "JSXTagEnd"}); + } + } + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "JSXPunctuator", + value: match[0] + }); + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXIdentifier", + value: match[0] + }); + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXText", + value: match[0] + }); + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({tag: "JSXTag"}); + lastIndex++; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: "<" + }); + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield ({ + type: "JSXPunctuator", + value: "{" + }); + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield ({ + type: "WhiteSpace", + value: match[0] + }); + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield ({ + type: "LineTerminatorSequence", + value: match[0] + }); + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield ({ + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }); + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield ({ + type: "SingleLineComment", + value: match[0] + }); + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield ({ + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }); + } + return void 0; +}; + +var jsTokens = /*@__PURE__*/getDefaultExportFromCjs(jsTokens_1); + +// src/index.ts +var reservedWords = { + keyword: [ + "break", + "case", + "catch", + "continue", + "debugger", + "default", + "do", + "else", + "finally", + "for", + "function", + "if", + "return", + "switch", + "throw", + "try", + "var", + "const", + "while", + "with", + "new", + "this", + "super", + "class", + "extends", + "export", + "import", + "null", + "true", + "false", + "in", + "instanceof", + "typeof", + "void", + "delete" + ], + strict: [ + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield" + ] +}, keywords = new Set(reservedWords.keyword), reservedWordsStrictSet = new Set(reservedWords.strict), sometimesKeywords = /* @__PURE__ */ new Set(["as", "async", "from", "get", "of", "set"]); +function isReservedWord(word) { + return word === "await" || word === "enum"; +} +function isStrictReservedWord(word) { + return isReservedWord(word) || reservedWordsStrictSet.has(word); +} +function isKeyword(word) { + return keywords.has(word); +} +var BRACKET = /^[()[\]{}]$/, getTokenType = function(token) { + if (token.type === "IdentifierName") { + if (isKeyword(token.value) || isStrictReservedWord(token.value) || sometimesKeywords.has(token.value)) + return "Keyword"; + if (token.value[0] && token.value[0] !== token.value[0].toLowerCase()) + return "IdentifierCapitalized"; + } + return token.type === "Punctuator" && BRACKET.test(token.value) ? "Bracket" : token.type === "Invalid" && (token.value === "@" || token.value === "#") ? "Punctuator" : token.type; +}; +function getCallableType(token) { + if (token.type === "IdentifierName") + return "IdentifierCallable"; + if (token.type === "PrivateIdentifier") + return "PrivateIdentifierCallable"; + throw new Error("Not a callable token"); +} +var colorize = (defs, type, value) => { + let colorize2 = defs[type]; + return colorize2 ? colorize2(value) : value; +}, highlightTokens = (defs, text, jsx) => { + let highlighted = "", lastPotentialCallable = null, stackedHighlight = ""; + for (let token of jsTokens(text, { jsx })) { + let type = getTokenType(token); + if (type === "IdentifierName" || type === "PrivateIdentifier") { + lastPotentialCallable && (highlighted += colorize(defs, getTokenType(lastPotentialCallable), lastPotentialCallable.value) + stackedHighlight, stackedHighlight = ""), lastPotentialCallable = token; + continue; + } + if (lastPotentialCallable && (token.type === "WhiteSpace" || token.type === "LineTerminatorSequence" || token.type === "Punctuator" && (token.value === "?." || token.value === "!"))) { + stackedHighlight += colorize(defs, type, token.value); + continue; + } + if (stackedHighlight && !lastPotentialCallable && (highlighted += stackedHighlight, stackedHighlight = ""), lastPotentialCallable) { + let type2 = token.type === "Punctuator" && token.value === "(" ? getCallableType(lastPotentialCallable) : getTokenType(lastPotentialCallable); + highlighted += colorize(defs, type2, lastPotentialCallable.value) + stackedHighlight, stackedHighlight = "", lastPotentialCallable = null; + } + highlighted += colorize(defs, type, token.value); + } + return highlighted; +}; +function highlight$1(code, options = { jsx: !1, colors: {} }) { + return code && highlightTokens(options.colors || {}, code, options.jsx); +} + +function getDefs(c) { + const Invalid = (text) => c.white(c.bgRed(c.bold(text))); + return { + Keyword: c.magenta, + IdentifierCapitalized: c.yellow, + Punctuator: c.yellow, + StringLiteral: c.green, + NoSubstitutionTemplate: c.green, + MultiLineComment: c.gray, + SingleLineComment: c.gray, + RegularExpressionLiteral: c.cyan, + NumericLiteral: c.blue, + TemplateHead: (text) => c.green(text.slice(0, text.length - 2)) + c.cyan(text.slice(-2)), + TemplateTail: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1)), + TemplateMiddle: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1, text.length - 2)) + c.cyan(text.slice(-2)), + IdentifierCallable: c.blue, + PrivateIdentifierCallable: (text) => `#${c.blue(text.slice(1))}`, + Invalid, + JSXString: c.green, + JSXIdentifier: c.yellow, + JSXInvalid: Invalid, + JSXPunctuator: c.yellow + }; +} +function highlight(code, options = { jsx: false }) { + return highlight$1(code, { + jsx: options.jsx, + colors: getDefs(options.colors || getColors()) + }); +} + +export { SAFE_TIMERS_SYMBOL, createSimpleStackTrace, getColors, getSafeTimers, highlight, lineSplitRE, offsetToLineNumber, positionToOffset, setSafeTimers, shuffle }; diff --git a/node_modules/@vitest/utils/dist/source-map.d.ts b/node_modules/@vitest/utils/dist/source-map.d.ts new file mode 100644 index 0000000..b1fd926 --- /dev/null +++ b/node_modules/@vitest/utils/dist/source-map.d.ts @@ -0,0 +1,111 @@ +import { ParsedStack, ErrorWithDiff } from './types.js'; + +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; + +interface SourceMapV3 { + file?: string | null; + names: string[]; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + version: 3; +} +interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +interface DecodedSourceMap extends SourceMapV3 { + mappings: SourceMapSegment[][]; +} +type OriginalMapping = { + source: string | null; + line: number; + column: number; + name: string | null; +}; +type InvalidOriginalMapping = { + source: null; + line: null; + column: null; + name: null; +}; +type GeneratedMapping = { + line: number; + column: number; +}; +type InvalidGeneratedMapping = { + line: null; + column: null; +}; +type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND; +type SourceMapInput = string | Ro | Ro | TraceMap; +type Needle = { + line: number; + column: number; + bias?: Bias; +}; +type SourceNeedle = { + source: string; + line: number; + column: number; + bias?: Bias; +}; +declare abstract class SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + resolvedSources: SourceMapV3['sources']; +} +type Ro = T extends Array ? V[] | Readonly | RoArray | Readonly> : T extends object ? T | Readonly | RoObject | Readonly> : T; +type RoArray = Ro[]; +type RoObject = { + [K in keyof T]: T[K] | Ro; +}; + +declare const LEAST_UPPER_BOUND = -1; +declare const GREATEST_LOWER_BOUND = 1; +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +declare let originalPositionFor: (map: TraceMap, needle: Needle) => OriginalMapping | InvalidOriginalMapping; +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +declare let generatedPositionFor: (map: TraceMap, needle: SourceNeedle) => GeneratedMapping | InvalidGeneratedMapping; +declare class TraceMap implements SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + resolvedSources: string[]; + private _encoded; + private _decoded; + private _decodedMemo; + private _bySources; + private _bySourceMemos; + constructor(map: SourceMapInput, mapUrl?: string | null); +} + +interface StackTraceParserOptions { + ignoreStackEntries?: (RegExp | string)[]; + getSourceMap?: (file: string) => unknown; + frameFilter?: (error: Error, frame: ParsedStack) => boolean | void; +} +declare function parseSingleFFOrSafariStack(raw: string): ParsedStack | null; +declare function parseSingleStack(raw: string): ParsedStack | null; +declare function parseSingleV8Stack(raw: string): ParsedStack | null; +declare function parseStacktrace(stack: string, options?: StackTraceParserOptions): ParsedStack[]; +declare function parseErrorStacktrace(e: ErrorWithDiff, options?: StackTraceParserOptions): ParsedStack[]; + +export { type SourceMapInput, type StackTraceParserOptions, TraceMap, generatedPositionFor, originalPositionFor, parseErrorStacktrace, parseSingleFFOrSafariStack, parseSingleStack, parseSingleV8Stack, parseStacktrace }; diff --git a/node_modules/@vitest/utils/dist/source-map.js b/node_modules/@vitest/utils/dist/source-map.js new file mode 100644 index 0000000..bed71fb --- /dev/null +++ b/node_modules/@vitest/utils/dist/source-map.js @@ -0,0 +1,878 @@ +import { notNullish, isPrimitive } from './helpers.js'; + +function normalizeWindowsPath(input = "") { + if (!input || !input.includes("\\")) { + return input; + } + return input.replace(/\\/g, "/"); +} +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +function cwd() { + if (typeof process !== "undefined") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve$2 = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; + +const comma = ','.charCodeAt(0); +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decode(mappings) { + const state = new Int32Array(5); + const decoded = []; + let index = 0; + do { + const semi = indexOf(mappings, index); + const line = []; + let sorted = true; + let lastCol = 0; + state[0] = 0; + for (let i = index; i < semi; i++) { + let seg; + i = decodeInteger(mappings, i, state, 0); // genColumn + const col = state[0]; + if (col < lastCol) + sorted = false; + lastCol = col; + if (hasMoreVlq(mappings, i, semi)) { + i = decodeInteger(mappings, i, state, 1); // sourcesIndex + i = decodeInteger(mappings, i, state, 2); // sourceLine + i = decodeInteger(mappings, i, state, 3); // sourceColumn + if (hasMoreVlq(mappings, i, semi)) { + i = decodeInteger(mappings, i, state, 4); // namesIndex + seg = [col, state[1], state[2], state[3], state[4]]; + } + else { + seg = [col, state[1], state[2], state[3]]; + } + } + else { + seg = [col]; + } + line.push(seg); + } + if (!sorted) + sort(line); + decoded.push(line); + index = semi + 1; + } while (index <= mappings.length); + return decoded; +} +function indexOf(mappings, index) { + const idx = mappings.indexOf(';', index); + return idx === -1 ? mappings.length : idx; +} +function decodeInteger(mappings, pos, state, j) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = mappings.charCodeAt(pos++); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -0x80000000 | -value; + } + state[j] += value; + return pos; +} +function hasMoreVlq(mappings, i, length) { + if (i >= length) + return false; + return mappings.charCodeAt(i) !== comma; +} +function sort(line) { + line.sort(sortComparator$1); +} +function sortComparator$1(a, b) { + return a[0] - b[0]; +} + +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +var UrlType; +(function (UrlType) { + UrlType[UrlType["Empty"] = 1] = "Empty"; + UrlType[UrlType["Hash"] = 2] = "Hash"; + UrlType[UrlType["Query"] = 3] = "Query"; + UrlType[UrlType["RelativePath"] = 4] = "RelativePath"; + UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath"; + UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative"; + UrlType[UrlType["Absolute"] = 7] = "Absolute"; +})(UrlType || (UrlType = {})); +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: UrlType.Absolute, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = UrlType.SchemeRelative; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = UrlType.AbsolutePath; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? UrlType.Query + : input.startsWith('#') + ? UrlType.Hash + : UrlType.RelativePath + : UrlType.Empty; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= UrlType.RelativePath; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve$1(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== UrlType.Absolute) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case UrlType.Empty: + url.hash = baseUrl.hash; + // fall through + case UrlType.Hash: + url.query = baseUrl.query; + // fall through + case UrlType.Query: + case UrlType.RelativePath: + mergePaths(url, baseUrl); + // fall through + case UrlType.AbsolutePath: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case UrlType.SchemeRelative: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case UrlType.Hash: + case UrlType.Query: + return queryHash; + case UrlType.RelativePath: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case UrlType.AbsolutePath: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +function resolve(input, base) { + // The base is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + if (base && !base.endsWith('/')) + base += '/'; + return resolve$1(input, base); +} + +/** + * Removes everything after the last "/", but leaves the slash. + */ +function stripFilename(path) { + if (!path) + return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} + +const COLUMN = 0; +const SOURCES_INDEX = 1; +const SOURCE_LINE = 2; +const SOURCE_COLUMN = 3; +const NAMES_INDEX = 4; +const REV_GENERATED_LINE = 1; +const REV_GENERATED_COLUMN = 2; + +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) + return mappings; + // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If + // not, we do not want to modify the consumer's input array. + if (!owned) + mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) + return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) + line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +let found = false; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } + else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) + break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1, + }; +} +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + // lastIndex may be -1 if the previous needle was not found. + low = lastIndex === -1 ? 0 : lastIndex; + } + else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return (state.lastIndex = binarySearch(haystack, needle, low, high)); +} + +// Rebuilds the original source files, with mappings that are ordered by source line/column instead +// of generated line/column. +function buildBySources(decoded, memos) { + const sources = memos.map(buildNullArray); + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + if (seg.length === 1) + continue; + const sourceIndex = seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + const originalSource = sources[sourceIndex]; + const originalLine = (originalSource[sourceLine] || (originalSource[sourceLine] = [])); + const memo = memos[sourceIndex]; + // The binary search either found a match, or it found the left-index just before where the + // segment should go. Either way, we want to insert after that. And there may be multiple + // generated segments associated with an original location, so there may need to move several + // indexes before we find where we need to insert. + const index = upperBound(originalLine, sourceColumn, memoizedBinarySearch(originalLine, sourceColumn, memo, sourceLine)); + insert(originalLine, (memo.lastIndex = index + 1), [sourceColumn, i, seg[COLUMN]]); + } + } + return sources; +} +function insert(array, index, value) { + for (let i = array.length; i > index; i--) { + array[i] = array[i - 1]; + } + array[index] = value; +} +// Null arrays allow us to use ordered index keys without actually allocating contiguous memory like +// a real array. We use a null-prototype object to avoid prototype pollution and deoptimizations. +// Numeric properties on objects are magically sorted in ascending order by the engine regardless of +// the insertion order. So, by setting any numeric keys, even out of order, we'll get ascending +// order when iterating with for-in. +function buildNullArray() { + return { __proto__: null }; +} + +const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)'; +const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)'; +const LEAST_UPPER_BOUND = -1; +const GREATEST_LOWER_BOUND = 1; +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +let decodedMappings; +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +let originalPositionFor; +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +let generatedPositionFor; +class TraceMap { + constructor(map, mapUrl) { + const isString = typeof map === 'string'; + if (!isString && map._decodedMemo) + return map; + const parsed = (isString ? JSON.parse(map) : map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + const from = resolve(sourceRoot || '', stripFilename(mapUrl)); + this.resolvedSources = sources.map((s) => resolve(s || '', from)); + const { mappings } = parsed; + if (typeof mappings === 'string') { + this._encoded = mappings; + this._decoded = undefined; + } + else { + this._encoded = undefined; + this._decoded = maybeSort(mappings, isString); + } + this._decodedMemo = memoizedState(); + this._bySources = undefined; + this._bySourceMemos = undefined; + } +} +(() => { + decodedMappings = (map) => { + return (map._decoded || (map._decoded = decode(map._encoded))); + }; + originalPositionFor = (map, { line, column, bias }) => { + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) + return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal(segments, map._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND); + if (index === -1) + return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) + return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null); + }; + generatedPositionFor = (map, { source, line, column, bias }) => { + return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false); + }; + function generatedPosition(map, source, line, column, bias, all) { + line--; + if (line < 0) + throw new Error(LINE_GTR_ZERO); + if (column < 0) + throw new Error(COL_GTR_EQ_ZERO); + const { sources, resolvedSources } = map; + let sourceIndex = sources.indexOf(source); + if (sourceIndex === -1) + sourceIndex = resolvedSources.indexOf(source); + if (sourceIndex === -1) + return all ? [] : GMapping(null, null); + const generated = (map._bySources || (map._bySources = buildBySources(decodedMappings(map), (map._bySourceMemos = sources.map(memoizedState))))); + const segments = generated[sourceIndex][line]; + if (segments == null) + return all ? [] : GMapping(null, null); + const memo = map._bySourceMemos[sourceIndex]; + if (all) + return sliceGeneratedPositions(segments, memo, line, column, bias); + const index = traceSegmentInternal(segments, memo, line, column, bias); + if (index === -1) + return GMapping(null, null); + const segment = segments[index]; + return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]); + } +})(); +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function GMapping(line, column) { + return { line, column }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } + else if (bias === LEAST_UPPER_BOUND) + index++; + if (index === -1 || index === segments.length) + return -1; + return index; +} +function sliceGeneratedPositions(segments, memo, line, column, bias) { + let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND); + // We ignored the bias when tracing the segment so that we're guarnateed to find the first (in + // insertion order) segment that matched. Even if we did respect the bias when tracing, we would + // still need to call `lowerBound()` to find the first segment, which is slower than just looking + // for the GREATEST_LOWER_BOUND to begin with. The only difference that matters for us is when the + // binary search didn't match, in which case GREATEST_LOWER_BOUND just needs to increment to + // match LEAST_UPPER_BOUND. + if (!found && bias === LEAST_UPPER_BOUND) + min++; + if (min === -1 || min === segments.length) + return []; + // We may have found the segment that started at an earlier column. If this is the case, then we + // need to slice all generated segments that match _that_ column, because all such segments span + // to our desired column. + const matchedColumn = found ? column : segments[min][COLUMN]; + // The binary search is not guaranteed to find the lower bound when a match wasn't found. + if (!found) + min = lowerBound(segments, matchedColumn, min); + const max = upperBound(segments, matchedColumn, min); + const result = []; + for (; min <= max; min++) { + const segment = segments[min]; + result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN])); + } + return result; +} + +const CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/; +const stackIgnorePatterns = [ + "node:internal", + /\/packages\/\w+\/dist\//, + /\/@vitest\/\w+\/dist\//, + "/vitest/dist/", + "/vitest/src/", + "/vite-node/dist/", + "/vite-node/src/", + "/node_modules/chai/", + "/node_modules/tinypool/", + "/node_modules/tinyspy/", + "/deps/chai.js", + /__vitest_browser__/ +]; +function extractLocation(urlLike) { + if (!urlLike.includes(":")) + return [urlLike]; + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, "")); + if (!parts) + return [urlLike]; + let url = parts[1]; + if (url.startsWith("http:") || url.startsWith("https:")) { + const urlObj = new URL(url); + url = urlObj.pathname; + } + if (url.startsWith("/@fs/")) { + url = url.slice(typeof process !== "undefined" && process.platform === "win32" ? 5 : 4); + } + return [url, parts[2] || void 0, parts[3] || void 0]; +} +function parseSingleFFOrSafariStack(raw) { + let line = raw.trim(); + if (SAFARI_NATIVE_CODE_REGEXP.test(line)) + return null; + if (line.includes(" > eval")) + line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1"); + if (!line.includes("@") && !line.includes(":")) + return null; + const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/; + const matches = line.match(functionNameRegex); + const functionName = matches && matches[1] ? matches[1] : void 0; + const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, "")); + if (!url || !lineNumber || !columnNumber) + return null; + return { + file: url, + method: functionName || "", + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseSingleStack(raw) { + const line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) + return parseSingleFFOrSafariStack(line); + return parseSingleV8Stack(line); +} +function parseSingleV8Stack(raw) { + let line = raw.trim(); + if (!CHROME_IE_STACK_REGEXP.test(line)) + return null; + if (line.includes("(eval ")) + line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, ""); + let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, ""); + const location = sanitizedLine.match(/ (\(.+\)$)/); + sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine; + const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine); + let method = location && sanitizedLine || ""; + let file = url && ["eval", ""].includes(url) ? void 0 : url; + if (!file || !lineNumber || !columnNumber) + return null; + if (method.startsWith("async ")) + method = method.slice(6); + if (file.startsWith("file://")) + file = file.slice(7); + file = resolve$2(file); + if (method) + method = method.replace(/__vite_ssr_import_\d+__\./g, ""); + return { + method, + file, + line: Number.parseInt(lineNumber), + column: Number.parseInt(columnNumber) + }; +} +function parseStacktrace(stack, options = {}) { + const { ignoreStackEntries = stackIgnorePatterns } = options; + let stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack); + if (ignoreStackEntries.length) + stacks = stacks.filter((stack2) => !ignoreStackEntries.some((p) => stack2.file.match(p))); + return stacks.map((stack2) => { + var _a; + const map = (_a = options.getSourceMap) == null ? void 0 : _a.call(options, stack2.file); + if (!map || typeof map !== "object" || !map.version) + return stack2; + const traceMap = new TraceMap(map); + const { line, column } = originalPositionFor(traceMap, stack2); + if (line != null && column != null) + return { ...stack2, line, column }; + return stack2; + }); +} +function parseFFOrSafariStackTrace(stack) { + return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish); +} +function parseV8Stacktrace(stack) { + return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish); +} +function parseErrorStacktrace(e, options = {}) { + if (!e || isPrimitive(e)) + return []; + if (e.stacks) + return e.stacks; + const stackStr = e.stack || e.stackStr || ""; + let stackFrames = parseStacktrace(stackStr, options); + if (options.frameFilter) + stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false); + e.stacks = stackFrames; + return stackFrames; +} + +export { TraceMap, generatedPositionFor, originalPositionFor, parseErrorStacktrace, parseSingleFFOrSafariStack, parseSingleStack, parseSingleV8Stack, parseStacktrace }; diff --git a/node_modules/@vitest/utils/dist/types-9l4niLY8.d.ts b/node_modules/@vitest/utils/dist/types-9l4niLY8.d.ts new file mode 100644 index 0000000..830630b --- /dev/null +++ b/node_modules/@vitest/utils/dist/types-9l4niLY8.d.ts @@ -0,0 +1,35 @@ +import { CompareKeys } from 'pretty-format'; + +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +type DiffOptionsColor = (arg: string) => string; +interface DiffOptions { + aAnnotation?: string; + aColor?: DiffOptionsColor; + aIndicator?: string; + bAnnotation?: string; + bColor?: DiffOptionsColor; + bIndicator?: string; + changeColor?: DiffOptionsColor; + changeLineTrailingSpaceColor?: DiffOptionsColor; + commonColor?: DiffOptionsColor; + commonIndicator?: string; + commonLineTrailingSpaceColor?: DiffOptionsColor; + contextLines?: number; + emptyFirstOrLastLinePlaceholder?: string; + expand?: boolean; + includeChangeCounts?: boolean; + omitAnnotationLines?: boolean; + patchColor?: DiffOptionsColor; + compareKeys?: CompareKeys; + truncateThreshold?: number; + truncateAnnotation?: string; + truncateAnnotationColor?: DiffOptionsColor; +} + +export type { DiffOptions as D, DiffOptionsColor as a }; diff --git a/node_modules/@vitest/utils/dist/types.d.ts b/node_modules/@vitest/utils/dist/types.d.ts new file mode 100644 index 0000000..23e2a27 --- /dev/null +++ b/node_modules/@vitest/utils/dist/types.d.ts @@ -0,0 +1,39 @@ +type Awaitable = T | PromiseLike; +type Nullable = T | null | undefined; +type Arrayable = T | Array; +type ArgumentsType = T extends (...args: infer U) => any ? U : never; +type MergeInsertions = T extends object ? { + [K in keyof T]: MergeInsertions; +} : T; +type DeepMerge = MergeInsertions<{ + [K in keyof F | keyof S]: K extends keyof S & keyof F ? DeepMerge : K extends keyof S ? S[K] : K extends keyof F ? F[K] : never; +}>; +type MutableArray = { + -readonly [k in keyof T]: T[k]; +}; +interface Constructable { + new (...args: any[]): any; +} +interface ParsedStack { + method: string; + file: string; + line: number; + column: number; +} +interface ErrorWithDiff extends Error { + name: string; + nameStr?: string; + stack?: string; + stackStr?: string; + stacks?: ParsedStack[]; + showDiff?: boolean; + actual?: any; + expected?: any; + operator?: string; + type?: string; + frame?: string; + diff?: string; + codeFrame?: string; +} + +export type { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, ErrorWithDiff, MergeInsertions, MutableArray, Nullable, ParsedStack }; diff --git a/node_modules/@vitest/utils/dist/types.js b/node_modules/@vitest/utils/dist/types.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/node_modules/@vitest/utils/dist/types.js @@ -0,0 +1 @@ + diff --git a/node_modules/@vitest/utils/error.d.ts b/node_modules/@vitest/utils/error.d.ts new file mode 100644 index 0000000..9329baa --- /dev/null +++ b/node_modules/@vitest/utils/error.d.ts @@ -0,0 +1 @@ +export * from './dist/error.js' diff --git a/node_modules/@vitest/utils/helpers.d.ts b/node_modules/@vitest/utils/helpers.d.ts new file mode 100644 index 0000000..0add1d0 --- /dev/null +++ b/node_modules/@vitest/utils/helpers.d.ts @@ -0,0 +1 @@ +export * from './dist/helpers.js' diff --git a/node_modules/@vitest/utils/package.json b/node_modules/@vitest/utils/package.json new file mode 100644 index 0000000..91492cb --- /dev/null +++ b/node_modules/@vitest/utils/package.json @@ -0,0 +1,74 @@ +{ + "name": "@vitest/utils", + "type": "module", + "version": "1.6.1", + "description": "Shared Vitest utility functions", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/utils#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/utils" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./diff": { + "types": "./dist/diff.d.ts", + "default": "./dist/diff.js" + }, + "./ast": { + "types": "./dist/ast.d.ts", + "default": "./dist/ast.js" + }, + "./error": { + "types": "./dist/error.d.ts", + "default": "./dist/error.js" + }, + "./helpers": { + "types": "./dist/helpers.d.ts", + "default": "./dist/helpers.js" + }, + "./source-map": { + "types": "./dist/source-map.d.ts", + "default": "./dist/source-map.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "typesVersions": { + "*": { + "source-map": [ + "dist/source-map.d.ts" + ] + } + }, + "files": [ + "*.d.ts", + "dist" + ], + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "devDependencies": { + "@jridgewell/trace-mapping": "^0.3.22", + "@types/estree": "^1.0.5", + "tinyhighlight": "^0.3.2" + }, + "scripts": { + "build": "rimraf dist && rollup -c", + "dev": "rollup -c --watch" + } +} \ No newline at end of file diff --git a/node_modules/acorn-walk/CHANGELOG.md b/node_modules/acorn-walk/CHANGELOG.md new file mode 100644 index 0000000..de4168f --- /dev/null +++ b/node_modules/acorn-walk/CHANGELOG.md @@ -0,0 +1,209 @@ +## 8.3.5 (2026-02-19) + +### Bug fixes + +Emit a more informative error message when trying to walk a node type that has no walker function. + +Specify callbacks in types to receive `AnyNode` type, so that they can be narrowed more easily. + +Support import attributes. + +## 8.3.4 (2024-09-09) + +### Bug fixes + +Walk SwitchCase nodes as separate nodes. + +## 8.3.3 (2024-01-11) + +### Bug fixes + +Make acorn a dependency because acorn-walk uses the types from that package. + +## 8.3.2 (2024-01-11) + +### Bug fixes + +Add missing type for `findNodeBefore`. + +## 8.3.1 (2023-12-06) + +### Bug fixes + +Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error. + +Visitor functions are now called in such a way that their `this` refers to the object they are part of. + +## 8.3.0 (2023-10-26) + +### New features + +Use a set of new, much more precise, TypeScript types. + +## 8.2.0 (2021-09-06) + +### New features + +Add support for walking ES2022 class static blocks. + +## 8.1.1 (2021-06-29) + +### Bug fixes + +Include `base` in the type declarations. + +## 8.1.0 (2021-04-24) + +### New features + +Support node types for class fields and private methods. + +## 8.0.2 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.0 (2021-01-05) + +### Bug fixes + +Fix a bug where `full` and `fullAncestor` would skip nodes with overridden types. + +## 8.0.0 (2020-08-12) + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +## 7.2.0 (2020-06-17) + +### New features + +Support optional chaining and nullish coalescing. + +Support `import.meta`. + +Add support for `export * as ns from "source"`. + +## 7.1.1 (2020-02-13) + +### Bug fixes + +Clean up the type definitions to actually work well with the main parser. + +## 7.1.0 (2020-02-11) + +### New features + +Add a TypeScript definition file for the library. + +## 7.0.0 (2017-08-12) + +### New features + +Support walking `ImportExpression` nodes. + +## 6.2.0 (2017-07-04) + +### New features + +Add support for `Import` nodes. + +## 6.1.0 (2018-09-28) + +### New features + +The walker now walks `TemplateElement` nodes. + +## 6.0.1 (2018-09-14) + +### Bug fixes + +Fix bad "main" field in package.json. + +## 6.0.0 (2018-09-14) + +### Breaking changes + +This is now a separate package, `acorn-walk`, rather than part of the main `acorn` package. + +The `ScopeBody` and `ScopeExpression` meta-node-types are no longer supported. + +## 5.7.1 (2018-06-15) + +### Bug fixes + +Make sure the walker and bin files are rebuilt on release (the previous release didn't get the up-to-date versions). + +## 5.7.0 (2018-06-15) + +### Bug fixes + +Fix crash in walker when walking a binding-less catch node. + +## 5.6.2 (2018-06-05) + +### Bug fixes + +In the walker, go back to allowing the `baseVisitor` argument to be null to default to the default base everywhere. + +## 5.6.1 (2018-06-01) + +### Bug fixes + +Fix regression when passing `null` as fourth argument to `walk.recursive`. + +## 5.6.0 (2018-05-31) + +### Bug fixes + +Fix a bug in the walker that caused a crash when walking an object pattern spread. + +## 5.5.1 (2018-03-06) + +### Bug fixes + +Fix regression in walker causing property values in object patterns to be walked as expressions. + +## 5.5.0 (2018-02-27) + +### Bug fixes + +Support object spread in the AST walker. + +## 5.4.1 (2018-02-02) + +### Bug fixes + +5.4.0 somehow accidentally included an old version of walk.js. + +## 5.2.0 (2017-10-30) + +### Bug fixes + +The `full` and `fullAncestor` walkers no longer visit nodes multiple times. + +## 5.1.0 (2017-07-05) + +### New features + +New walker functions `full` and `fullAncestor`. + +## 3.2.0 (2016-06-07) + +### New features + +Make it possible to use `visit.ancestor` with a walk state. + +## 3.1.0 (2016-04-18) + +### New features + +The walker now allows defining handlers for `CatchClause` nodes. + +## 2.5.2 (2015-10-27) + +### Fixes + +Fix bug where the walker walked an exported `let` statement as an expression. diff --git a/node_modules/acorn-walk/LICENSE b/node_modules/acorn-walk/LICENSE new file mode 100644 index 0000000..d6be6db --- /dev/null +++ b/node_modules/acorn-walk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/acorn-walk/README.md b/node_modules/acorn-walk/README.md new file mode 100644 index 0000000..eaec57f --- /dev/null +++ b/node_modules/acorn-walk/README.md @@ -0,0 +1,124 @@ +# Acorn AST walker + +An abstract syntax tree walker for the +[ESTree](https://github.com/estree/estree) format. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn-walk/LICENSE). + +You are welcome to +[report bugs](https://github.com/acornjs/acorn/issues) or create pull +requests on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn-walk +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` + +## Interface + +An algorithm for recursing through a syntax tree is stored as an +object, with a property for each tree node type holding a function +that will recurse through such a node. There are several ways to run +such a walker. + +**simple**`(node, visitors, base, state)` does a 'simple' walk over a +tree. `node` should be the AST node to walk, and `visitors` an object +with properties whose names correspond to node types in the [ESTree +spec](https://github.com/estree/estree). The properties should contain +functions that will be called with the node object and, if applicable +the state at that point. The last two arguments are optional. `base` +is a walker algorithm, and `state` is a start state. The default +walker will simply visit all statements and expressions and not +produce a meaningful state. (An example of a use of state is to track +scope at each point in the tree.) + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.simple(acorn.parse("let x = 10"), { + Literal(node) { + console.log(`Found a literal: ${node.value}`) + } +}) +``` + +**ancestor**`(node, visitors, base, state)` does a 'simple' walk over +a tree, building up an array of ancestor nodes (including the current node) +and passing the array to the callbacks as a third parameter. + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.ancestor(acorn.parse("foo('hi')"), { + Literal(_node, _state, ancestors) { + console.log("This literal's ancestors are:", ancestors.map(n => n.type)) + } +}) +``` + +**recursive**`(node, state, functions, base)` does a 'recursive' +walk, where the walker functions are responsible for continuing the +walk on the child nodes of their target node. `state` is the start +state, and `functions` should contain an object that maps node types +to walker functions. Such functions are called with `(node, state, c)` +arguments, and can cause the walk to continue on a sub-node by calling +the `c` argument on it with `(node, state)` arguments. The optional +`base` argument provides the fallback walker functions for node types +that aren't handled in the `functions` object. If not given, the +default walkers will be used. + +**make**`(functions, base)` builds a new walker object by using the +walker functions in `functions` and filling in the missing ones by +taking defaults from `base`. + +**full**`(node, callback, base, state)` does a 'full' walk over a +tree, calling the callback with the arguments (node, state, type) for +each node + +**fullAncestor**`(node, callback, base, state)` does a 'full' walk +over a tree, building up an array of ancestor nodes (including the +current node) and passing the array to the callbacks as a third +parameter. + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.full(acorn.parse("1 + 1"), node => { + console.log(`There's a ${node.type} node at ${node.ch}`) +}) +``` + +**findNodeAt**`(node, start, end, test, base, state)` tries to locate +a node in a tree at the given start and/or end offsets, which +satisfies the predicate `test`. `start` and `end` can be either `null` +(as wildcard) or a number. `test` may be a string (indicating a node +type) or a function that takes `(nodeType, node)` arguments and +returns a boolean indicating whether this node is interesting. `base` +and `state` are optional, and can be used to specify a custom walker. +Nodes are tested from inner to outer, so if two nodes match the +boundaries, the inner one will be preferred. + +**findNodeAround**`(node, pos, test, base, state)` is a lot like +`findNodeAt`, but will match any node that exists 'around' (spanning) +the given position. + +**findNodeAfter**`(node, pos, test, base, state)` is similar to +`findNodeAround`, but will match all nodes *after* the given position +(testing outer nodes before inner nodes). diff --git a/node_modules/acorn-walk/dist/walk.d.mts b/node_modules/acorn-walk/dist/walk.d.mts new file mode 100644 index 0000000..199c8a0 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.d.mts @@ -0,0 +1,152 @@ +import * as acorn from "acorn" + +export type FullWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + type: string +) => void + +export type FullAncestorWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + ancestors: acorn.AnyNode[], + type: string +) => void + +type AggregateType = { + Expression: acorn.Expression, + Statement: acorn.Statement, + Function: acorn.Function, + Class: acorn.Class, + Pattern: acorn.Pattern, + ForInit: acorn.VariableDeclaration | acorn.Expression +} + +export type SimpleVisitors = { + [type in acorn.AnyNode["type"]]?: (node: Extract, state: TState) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState) => void +} + +export type AncestorVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, ancestors: acorn.AnyNode[] +) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, ancestors: acorn.AnyNode[]) => void +} + +export type WalkerCallback = (node: acorn.AnyNode, state: TState) => void + +export type RecursiveVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, callback: WalkerCallback) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, callback: WalkerCallback) => void +} + +export type FindPredicate = (type: string, node: acorn.AnyNode) => boolean + +export interface Found { + node: acorn.AnyNode, + state: TState +} + +/** + * does a 'simple' walk over a tree + * @param node the AST node to walk + * @param visitors an object with properties whose names correspond to node types in the {@link https://github.com/estree/estree | ESTree spec}. The properties should contain functions that will be called with the node object and, if applicable the state at that point. + * @param base a walker algorithm + * @param state a start state. The default walker will simply visit all statements and expressions and not produce a meaningful state. (An example of a use of state is to track scope at each point in the tree.) + */ +export function simple( + node: acorn.Node, + visitors: SimpleVisitors, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'simple' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function ancestor( + node: acorn.Node, + visitors: AncestorVisitors, + base?: RecursiveVisitors, + state?: TState + ): void + +/** + * does a 'recursive' walk, where the walker functions are responsible for continuing the walk on the child nodes of their target node. + * @param node + * @param state the start state + * @param functions contain an object that maps node types to walker functions + * @param base provides the fallback walker functions for node types that aren't handled in the {@link functions} object. If not given, the default walkers will be used. + */ +export function recursive( + node: acorn.Node, + state: TState, + functions: RecursiveVisitors, + base?: RecursiveVisitors +): void + +/** + * does a 'full' walk over a tree, calling the {@link callback} with the arguments (node, state, type) for each node + */ +export function full( + node: acorn.Node, + callback: FullWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'full' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function fullAncestor( + node: acorn.Node, + callback: FullAncestorWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * builds a new walker object by using the walker functions in {@link functions} and filling in the missing ones by taking defaults from {@link base}. + */ +export function make( + functions: RecursiveVisitors, + base?: RecursiveVisitors +): RecursiveVisitors + +/** + * tries to locate a node in a tree at the given start and/or end offsets, which satisfies the predicate test. {@link start} and {@link end} can be either `null` (as wildcard) or a `number`. {@link test} may be a string (indicating a node type) or a function that takes (nodeType, node) arguments and returns a boolean indicating whether this node is interesting. {@link base} and {@link state} are optional, and can be used to specify a custom walker. Nodes are tested from inner to outer, so if two nodes match the boundaries, the inner one will be preferred. + */ +export function findNodeAt( + node: acorn.Node, + start: number | undefined | null, + end?: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * like {@link findNodeAt}, but will match any node that exists 'around' (spanning) the given position. + */ +export function findNodeAround( + node: acorn.Node, + start: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * Find the outermost matching node after a given position. + */ +export const findNodeAfter: typeof findNodeAround + +/** + * Find the outermost matching node before a given position. + */ +export const findNodeBefore: typeof findNodeAround + +export const base: RecursiveVisitors diff --git a/node_modules/acorn-walk/dist/walk.d.ts b/node_modules/acorn-walk/dist/walk.d.ts new file mode 100644 index 0000000..199c8a0 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.d.ts @@ -0,0 +1,152 @@ +import * as acorn from "acorn" + +export type FullWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + type: string +) => void + +export type FullAncestorWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + ancestors: acorn.AnyNode[], + type: string +) => void + +type AggregateType = { + Expression: acorn.Expression, + Statement: acorn.Statement, + Function: acorn.Function, + Class: acorn.Class, + Pattern: acorn.Pattern, + ForInit: acorn.VariableDeclaration | acorn.Expression +} + +export type SimpleVisitors = { + [type in acorn.AnyNode["type"]]?: (node: Extract, state: TState) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState) => void +} + +export type AncestorVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, ancestors: acorn.AnyNode[] +) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, ancestors: acorn.AnyNode[]) => void +} + +export type WalkerCallback = (node: acorn.AnyNode, state: TState) => void + +export type RecursiveVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, callback: WalkerCallback) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, callback: WalkerCallback) => void +} + +export type FindPredicate = (type: string, node: acorn.AnyNode) => boolean + +export interface Found { + node: acorn.AnyNode, + state: TState +} + +/** + * does a 'simple' walk over a tree + * @param node the AST node to walk + * @param visitors an object with properties whose names correspond to node types in the {@link https://github.com/estree/estree | ESTree spec}. The properties should contain functions that will be called with the node object and, if applicable the state at that point. + * @param base a walker algorithm + * @param state a start state. The default walker will simply visit all statements and expressions and not produce a meaningful state. (An example of a use of state is to track scope at each point in the tree.) + */ +export function simple( + node: acorn.Node, + visitors: SimpleVisitors, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'simple' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function ancestor( + node: acorn.Node, + visitors: AncestorVisitors, + base?: RecursiveVisitors, + state?: TState + ): void + +/** + * does a 'recursive' walk, where the walker functions are responsible for continuing the walk on the child nodes of their target node. + * @param node + * @param state the start state + * @param functions contain an object that maps node types to walker functions + * @param base provides the fallback walker functions for node types that aren't handled in the {@link functions} object. If not given, the default walkers will be used. + */ +export function recursive( + node: acorn.Node, + state: TState, + functions: RecursiveVisitors, + base?: RecursiveVisitors +): void + +/** + * does a 'full' walk over a tree, calling the {@link callback} with the arguments (node, state, type) for each node + */ +export function full( + node: acorn.Node, + callback: FullWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'full' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function fullAncestor( + node: acorn.Node, + callback: FullAncestorWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * builds a new walker object by using the walker functions in {@link functions} and filling in the missing ones by taking defaults from {@link base}. + */ +export function make( + functions: RecursiveVisitors, + base?: RecursiveVisitors +): RecursiveVisitors + +/** + * tries to locate a node in a tree at the given start and/or end offsets, which satisfies the predicate test. {@link start} and {@link end} can be either `null` (as wildcard) or a `number`. {@link test} may be a string (indicating a node type) or a function that takes (nodeType, node) arguments and returns a boolean indicating whether this node is interesting. {@link base} and {@link state} are optional, and can be used to specify a custom walker. Nodes are tested from inner to outer, so if two nodes match the boundaries, the inner one will be preferred. + */ +export function findNodeAt( + node: acorn.Node, + start: number | undefined | null, + end?: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * like {@link findNodeAt}, but will match any node that exists 'around' (spanning) the given position. + */ +export function findNodeAround( + node: acorn.Node, + start: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * Find the outermost matching node after a given position. + */ +export const findNodeAfter: typeof findNodeAround + +/** + * Find the outermost matching node before a given position. + */ +export const findNodeBefore: typeof findNodeAround + +export const base: RecursiveVisitors diff --git a/node_modules/acorn-walk/dist/walk.js b/node_modules/acorn-walk/dist/walk.js new file mode 100644 index 0000000..fe4d197 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.js @@ -0,0 +1,485 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.acorn = global.acorn || {}, global.acorn.walk = {}))); +})(this, (function (exports) { 'use strict'; + + // AST walker module for ESTree compatible trees + + // A simple walk is one where you simply specify callbacks to be + // called on specific nodes. The last two arguments are optional. A + // simple use would be + // + // walk.simple(myTree, { + // Expression: function(node) { ... } + // }); + // + // to do something with all expressions. All ESTree node types + // can be used to identify node types, as well as Expression and + // Statement, which denote categories of nodes. + // + // The base argument can be used to pass a custom (recursive) + // walker, and state can be used to give this walked an initial + // state. + + function simple(node, visitors, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st); } + })(node, state, override); + } + + // An ancestor walk keeps an array of ancestor nodes (including the + // current node) and passes them to the callback as third parameter + // (and also as state parameter when no other state is present). + function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); + } + + // A recursive walk is one where your functions override the default + // walkers. They can modify and replace the state parameter that's + // threaded through the walk, and can opt how and whether to walk + // their child nodes (by calling their third argument on these + // nodes). + function recursive(node, state, funcs, baseVisitor, override) { + var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c); + })(node, state, override); + } + + function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } + } + + var Found = function Found(node, state) { this.node = node; this.state = state; }; + + // A full walk triggers the callback on each node + function full(node, callback, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st, type); + last = node; + } + })(node, state, override); + } + + // An fullAncestor walk is like an ancestor walk, but triggers + // the callback on each node + function fullAncestor(node, callback, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + var ancestors = [], last + ;(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } + if (isNew) { ancestors.pop(); } + })(node, state); + } + + // Find a node with a given start, end, and type (all are optional, + // null can be used as wildcard). Returns a {node, state} object, or + // undefined when it doesn't find a matching node. + function findNodeAt(node, start, end, test, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + test = makeTest(test); + try { + (function c(node, st, override) { + var type = override || node.type; + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + { visitNode(baseVisitor, type, node, st, c); } + if ((start == null || node.start === start) && + (end == null || node.end === end) && + test(type, node)) + { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the innermost node of a given type that contains the given + // position. Interface similar to findNodeAt. + function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + visitNode(baseVisitor, type, node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the outermost matching node after a given position. + function findNodeAfter(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + if (node.end < pos) { return } + var type = override || node.type; + if (node.start >= pos && test(type, node)) { throw new Found(node, st) } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the outermost matching node before a given position. + function findNodeBefore(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + var max + ;(function c(node, st, override) { + if (node.start > pos) { return } + var type = override || node.type; + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + { max = new Found(node, st); } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + return max + } + + // Used to create a custom walker. Will fill in all missing node + // type properties with the defaults. + function make(funcs, baseVisitor) { + var visitor = Object.create(baseVisitor || base); + for (var type in funcs) { visitor[type] = funcs[type]; } + return visitor + } + + function skipThrough(node, st, c) { c(node, st); } + function ignore(_node, _st, _c) {} + + function visitNode(baseVisitor, type, node, st, c) { + if (baseVisitor[type] == null) { throw new Error(("No walker function defined for node type " + type)) } + baseVisitor[type](node, st, c); + } + + // Node walkers. + + var base = {}; + + base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } + }; + base.Statement = skipThrough; + base.EmptyStatement = ignore; + base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; + base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } + }; + base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; + base.BreakStatement = base.ContinueStatement = ignore; + base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } + }; + base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } + }; + base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } + }; + base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; + base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } + }; + base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); + }; + base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); + }; + base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } + }; + base.DebuggerStatement = ignore; + + base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; + base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } + }; + base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } + }; + + base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); + }; + + base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } + }; + base.VariablePattern = ignore; + base.MemberPattern = skipThrough; + base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; + base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } + }; + base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } + }; + + base.Expression = skipThrough; + base.ThisExpression = base.Super = base.MetaProperty = ignore; + base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } + }; + base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } + }; + base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; + base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } + }; + base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } + }; + base.TemplateElement = ignore; + base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); + }; + base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); + }; + base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); + }; + base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); + }; + base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } + }; + base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } + }; + base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } + }; + base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } + }; + base.ImportAttribute = function (node, st, c) { + c(node.value, st, "Expression"); + }; + base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i$1 = 0, list$1 = node.attributes; i$1 < list$1.length; i$1 += 1) + { + var attr = list$1[i$1]; + + c(attr, st); + } } + }; + base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); + if (node.options) { c(node.options, st, "Expression"); } + }; + base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + + base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); + }; + base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; + base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); + }; + base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } + }; + base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } + }; + + exports.ancestor = ancestor; + exports.base = base; + exports.findNodeAfter = findNodeAfter; + exports.findNodeAround = findNodeAround; + exports.findNodeAt = findNodeAt; + exports.findNodeBefore = findNodeBefore; + exports.full = full; + exports.fullAncestor = fullAncestor; + exports.make = make; + exports.recursive = recursive; + exports.simple = simple; + +})); diff --git a/node_modules/acorn-walk/dist/walk.mjs b/node_modules/acorn-walk/dist/walk.mjs new file mode 100644 index 0000000..88f18bb --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.mjs @@ -0,0 +1,467 @@ +// AST walker module for ESTree compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All ESTree node types +// can be used to identify node types, as well as Expression and +// Statement, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +function simple(node, visitors, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st); } + })(node, state, override); +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +function recursive(node, state, funcs, baseVisitor, override) { + var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c); + })(node, state, override); +} + +function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } +} + +var Found = function Found(node, state) { this.node = node; this.state = state; }; + +// A full walk triggers the callback on each node +function full(node, callback, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st, type); + last = node; + } + })(node, state, override); +} + +// An fullAncestor walk is like an ancestor walk, but triggers +// the callback on each node +function fullAncestor(node, callback, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + var ancestors = [], last + ;(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } + if (isNew) { ancestors.pop(); } + })(node, state); +} + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +function findNodeAt(node, start, end, test, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + test = makeTest(test); + try { + (function c(node, st, override) { + var type = override || node.type; + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + { visitNode(baseVisitor, type, node, st, c); } + if ((start == null || node.start === start) && + (end == null || node.end === end) && + test(type, node)) + { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + visitNode(baseVisitor, type, node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node after a given position. +function findNodeAfter(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + if (node.end < pos) { return } + var type = override || node.type; + if (node.start >= pos && test(type, node)) { throw new Found(node, st) } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node before a given position. +function findNodeBefore(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + var max + ;(function c(node, st, override) { + if (node.start > pos) { return } + var type = override || node.type; + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + { max = new Found(node, st); } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + return max +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +function make(funcs, baseVisitor) { + var visitor = Object.create(baseVisitor || base); + for (var type in funcs) { visitor[type] = funcs[type]; } + return visitor +} + +function skipThrough(node, st, c) { c(node, st); } +function ignore(_node, _st, _c) {} + +function visitNode(baseVisitor, type, node, st, c) { + if (baseVisitor[type] == null) { throw new Error(("No walker function defined for node type " + type)) } + baseVisitor[type](node, st, c); +} + +// Node walkers. + +var base = {}; + +base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } +}; +base.Statement = skipThrough; +base.EmptyStatement = ignore; +base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } +}; +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; +base.BreakStatement = base.ContinueStatement = ignore; +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } +}; +base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } +}; +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } +}; +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } +}; +base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); +}; +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); +}; +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } +}; +base.DebuggerStatement = ignore; + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; +base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } +}; +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } +}; + +base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); +}; + +base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } +}; +base.VariablePattern = ignore; +base.MemberPattern = skipThrough; +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; +base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } +}; +base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } +}; + +base.Expression = skipThrough; +base.ThisExpression = base.Super = base.MetaProperty = ignore; +base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } +}; +base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } +}; +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; +base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } +}; +base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } +}; +base.TemplateElement = ignore; +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); +}; +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); +}; +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); +}; +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); +}; +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } +}; +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } +}; +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } +}; +base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } +}; +base.ImportAttribute = function (node, st, c) { + c(node.value, st, "Expression"); +}; +base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i$1 = 0, list$1 = node.attributes; i$1 < list$1.length; i$1 += 1) + { + var attr = list$1[i$1]; + + c(attr, st); + } } +}; +base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); + if (node.options) { c(node.options, st, "Expression"); } +}; +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); +}; +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; +base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); +}; +base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } +}; +base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } +}; + +export { ancestor, base, findNodeAfter, findNodeAround, findNodeAt, findNodeBefore, full, fullAncestor, make, recursive, simple }; diff --git a/node_modules/acorn-walk/package.json b/node_modules/acorn-walk/package.json new file mode 100644 index 0000000..362add8 --- /dev/null +++ b/node_modules/acorn-walk/package.json @@ -0,0 +1,50 @@ +{ + "name": "acorn-walk", + "description": "ECMAScript (ESTree) AST walker", + "homepage": "https://github.com/acornjs/acorn", + "main": "dist/walk.js", + "types": "dist/walk.d.ts", + "module": "dist/walk.mjs", + "exports": { + ".": [ + { + "import": "./dist/walk.mjs", + "require": "./dist/walk.js", + "default": "./dist/walk.js" + }, + "./dist/walk.js" + ], + "./package.json": "./package.json" + }, + "version": "8.3.5", + "engines": { + "node": ">=0.4.0" + }, + "dependencies": { + "acorn": "^8.11.0" + }, + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "https://marijnhaverbeke.nl" + }, + { + "name": "Ingvar Stepanyan", + "email": "me@rreverser.com", + "web": "https://rreverser.com/" + }, + { + "name": "Adrian Heine", + "web": "http://adrianheine.de" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/acornjs/acorn.git" + }, + "scripts": { + "prepare": "cd ..; npm run build:walk" + }, + "license": "MIT" +} diff --git a/node_modules/acorn/CHANGELOG.md b/node_modules/acorn/CHANGELOG.md new file mode 100644 index 0000000..6efbc33 --- /dev/null +++ b/node_modules/acorn/CHANGELOG.md @@ -0,0 +1,986 @@ +## 8.17.0 (2026-06-11) + +### New features + +The new `strict` option can be used to start script sources in strict mode. + +### Bug fixes + +Fix a number of corner case bugs when `using` or `await using` appear in `for` loop specs. + +Disallow `new super()` expressions. + +Don't allow the conditional in a ternary expression to be a (naked) arrow function. + +## 8.16.0 (2026-02-19) + +### New features + +The `sourceType` option can now be set to `"commonjs"` to have the parser treat the top level scope as a function scope. + +Add support for Unicode 17. + +### Bug fixes + +Don't recognize `await using` as contextual keywords when followed directly by a backslash. + +Fix an issue where the parser would allow `return` statements in `static` blocks when `allowReturnOutsideFunction` was enabled. + +Properly reject `using` declarations that appear directly in `switch` or `for` head scopes. + +Fix some corner case issues in the recognition of `using` syntax. + +## 8.15.0 (2025-06-08) + +### New features + +Support `using` and `await using` syntax. + +The `AnyNode` type is now defined in such a way that plugins can extend it. + +### Bug fixes + +Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format. + +The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint. + +## 8.14.1 (2025-03-05) + +### Bug fixes + +Fix an issue where `await` expressions in class field initializers were inappropriately allowed. + +Properly allow await inside an async arrow function inside a class field initializer. + +Mention the source file name in syntax error messages when given. + +Properly add an empty `attributes` property to every form of `ExportNamedDeclaration`. + +## 8.14.0 (2024-10-27) + +### New features + +Support ES2025 import attributes. + +Support ES2025 RegExp modifiers. + +### Bug fixes + +Support some missing Unicode properties. + +## 8.13.0 (2024-10-16) + +### New features + +Upgrade to Unicode 16.0. + +## 8.12.1 (2024-07-03) + +### Bug fixes + +Fix a regression that caused Acorn to no longer run on Node versions <8.10. + +## 8.12.0 (2024-06-14) + +### New features + +Support ES2025 duplicate capture group names in regular expressions. + +### Bug fixes + +Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error. + +Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name. + +Properly recognize \"use strict\" when preceded by a string with an escaped newline. + +Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors. + +Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled. + +Properly normalize line endings in raw strings of invalid template tokens. + +Properly track line numbers for escaped newlines in strings. + +Fix a bug that broke line number accounting after a template literal with invalid escape sequences. + +## 8.11.3 (2023-12-29) + +### Bug fixes + +Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error. + +Make sure `onToken` get an `import` keyword token when parsing `import.meta`. + +Fix a bug where `.loc.start` could be undefined for `new.target` `meta` nodes. + +## 8.11.2 (2023-10-27) + +### Bug fixes + +Fix a bug that caused regular expressions after colon tokens to not be properly tokenized in some circumstances. + +## 8.11.1 (2023-10-26) + +### Bug fixes + +Fix a regression where `onToken` would receive 'name' tokens for 'new' keyword tokens. + +## 8.11.0 (2023-10-26) + +### Bug fixes + +Fix an issue where tokenizing (without parsing) an object literal with a property named `class` or `function` could, in some circumstance, put the tokenizer into an invalid state. + +Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression. + +### New features + +Upgrade to Unicode 15.1. + +Use a set of new, much more precise, TypeScript types. + +## 8.10.0 (2023-07-05) + +### New features + +Add a `checkPrivateFields` option that disables strict checking of private property use. + +## 8.9.0 (2023-06-16) + +### Bug fixes + +Forbid dynamic import after `new`, even when part of a member expression. + +### New features + +Add Unicode properties for ES2023. + +Add support for the `v` flag to regular expressions. + +## 8.8.2 (2023-01-23) + +### Bug fixes + +Fix a bug that caused `allowHashBang` to be set to false when not provided, even with `ecmaVersion >= 14`. + +Fix an exception when passing no option object to `parse` or `new Parser`. + +Fix incorrect parse error on `if (0) let\n[astral identifier char]`. + +## 8.8.1 (2022-10-24) + +### Bug fixes + +Make type for `Comment` compatible with estree types. + +## 8.8.0 (2022-07-21) + +### Bug fixes + +Allow parentheses around spread args in destructuring object assignment. + +Fix an issue where the tree contained `directive` properties in when parsing with a language version that doesn't support them. + +### New features + +Support hashbang comments by default in ECMAScript 2023 and later. + +## 8.7.1 (2021-04-26) + +### Bug fixes + +Stop handling `"use strict"` directives in ECMAScript versions before 5. + +Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked. + +Add missing type for `tokTypes`. + +## 8.7.0 (2021-12-27) + +### New features + +Support quoted export names. + +Upgrade to Unicode 14. + +Add support for Unicode 13 properties in regular expressions. + +### Bug fixes + +Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code. + +## 8.6.0 (2021-11-18) + +### Bug fixes + +Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment. + +### New features + +Support class private fields with the `in` operator. + +## 8.5.0 (2021-09-06) + +### Bug fixes + +Improve context-dependent tokenization in a number of corner cases. + +Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number). + +Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators. + +Fix wrong end locations stored on SequenceExpression nodes. + +Implement restriction that `for`/`of` loop LHS can't start with `let`. + +### New features + +Add support for ES2022 class static blocks. + +Allow multiple input files to be passed to the CLI tool. + +## 8.4.1 (2021-06-24) + +### Bug fixes + +Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources. + +## 8.4.0 (2021-06-11) + +### New features + +A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context. + +## 8.3.0 (2021-05-31) + +### New features + +Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher. + +Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag. + +## 8.2.4 (2021-05-04) + +### Bug fixes + +Fix spec conformity in corner case 'for await (async of ...)'. + +## 8.2.3 (2021-05-04) + +### Bug fixes + +Fix an issue where the library couldn't parse 'for (async of ...)'. + +Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances. + +## 8.2.2 (2021-04-29) + +### Bug fixes + +Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield. + +## 8.2.1 (2021-04-24) + +### Bug fixes + +Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse. + +## 8.2.0 (2021-04-24) + +### New features + +Add support for ES2022 class fields and private methods. + +## 8.1.1 (2021-04-12) + +### Various + +Stop shipping source maps in the NPM package. + +## 8.1.0 (2021-03-09) + +### Bug fixes + +Fix a spurious error in nested destructuring arrays. + +### New features + +Expose `allowAwaitOutsideFunction` in CLI interface. + +Make `allowImportExportAnywhere` also apply to `import.meta`. + +## 8.0.5 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.4 (2020-10-05) + +### Bug fixes + +Make `await x ** y` an error, following the spec. + +Fix potentially exponential regular expression. + +## 8.0.3 (2020-10-02) + +### Bug fixes + +Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`. + +## 8.0.2 (2020-09-30) + +### Bug fixes + +Make the TypeScript types reflect the current allowed values for `ecmaVersion`. + +Fix another regexp/division tokenizer issue. + +## 8.0.1 (2020-08-12) + +### Bug fixes + +Provide the correct value in the `version` export. + +## 8.0.0 (2020-08-12) + +### Bug fixes + +Disallow expressions like `(a = b) = c`. + +Make non-octal escape sequences a syntax error in strict mode. + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +Update to the set of Unicode properties from ES2021. + +### Breaking changes + +The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release. + +Some changes to method signatures that may be used by plugins. + +## 7.4.0 (2020-08-03) + +### New features + +Add support for logical assignment operators. + +Add support for numeric separators. + +## 7.3.1 (2020-06-11) + +### Bug fixes + +Make the string in the `version` export match the actual library version. + +## 7.3.0 (2020-06-11) + +### Bug fixes + +Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail. + +### New features + +Add support for optional chaining (`?.`). + +## 7.2.0 (2020-05-09) + +### Bug fixes + +Fix precedence issue in parsing of async arrow functions. + +### New features + +Add support for nullish coalescing. + +Add support for `import.meta`. + +Support `export * as ...` syntax. + +Upgrade to Unicode 13. + +## 6.4.1 (2020-03-09) + +### Bug fixes + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.1 (2020-03-01) + +### Bug fixes + +Treat `\8` and `\9` as invalid escapes in template strings. + +Allow unicode escapes in property names that are keywords. + +Don't error on an exponential operator expression as argument to `await`. + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.0 (2019-09-24) + +### Bug fixes + +Disallow trailing object literal commas when ecmaVersion is less than 5. + +### New features + +Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on. + +## 7.0.0 (2019-08-13) + +### Breaking changes + +Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression). + +Makes 10 (ES2019) the default value for the `ecmaVersion` option. + +## 6.3.0 (2019-08-12) + +### New features + +`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard. + +## 6.2.1 (2019-07-21) + +### Bug fixes + +Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such. + +Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances. + +## 6.2.0 (2019-07-04) + +### Bug fixes + +Improve valid assignment checking in `for`/`in` and `for`/`of` loops. + +Disallow binding `let` in patterns. + +### New features + +Support bigint syntax with `ecmaVersion` >= 11. + +Support dynamic `import` syntax with `ecmaVersion` >= 11. + +Upgrade to Unicode version 12. + +## 6.1.1 (2019-02-27) + +### Bug fixes + +Fix bug that caused parsing default exports of with names to fail. + +## 6.1.0 (2019-02-08) + +### Bug fixes + +Fix scope checking when redefining a `var` as a lexical binding. + +### New features + +Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins. + +## 6.0.7 (2019-02-04) + +### Bug fixes + +Check that exported bindings are defined. + +Don't treat `\u180e` as a whitespace character. + +Check for duplicate parameter names in methods. + +Don't allow shorthand properties when they are generators or async methods. + +Forbid binding `await` in async arrow function's parameter list. + +## 6.0.6 (2019-01-30) + +### Bug fixes + +The content of class declarations and expressions is now always parsed in strict mode. + +Don't allow `let` or `const` to bind the variable name `let`. + +Treat class declarations as lexical. + +Don't allow a generator function declaration as the sole body of an `if` or `else`. + +Ignore `"use strict"` when after an empty statement. + +Allow string line continuations with special line terminator characters. + +Treat `for` bodies as part of the `for` scope when checking for conflicting bindings. + +Fix bug with parsing `yield` in a `for` loop initializer. + +Implement special cases around scope checking for functions. + +## 6.0.5 (2019-01-02) + +### Bug fixes + +Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type. + +Don't treat `let` as a keyword when the next token is `{` on the next line. + +Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on. + +## 6.0.4 (2018-11-05) + +### Bug fixes + +Further improvements to tokenizing regular expressions in corner cases. + +## 6.0.3 (2018-11-04) + +### Bug fixes + +Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression. + +Remove stray symlink in the package tarball. + +## 6.0.2 (2018-09-26) + +### Bug fixes + +Fix bug where default expressions could fail to parse inside an object destructuring assignment expression. + +## 6.0.1 (2018-09-14) + +### Bug fixes + +Fix wrong value in `version` export. + +## 6.0.0 (2018-09-14) + +### Bug fixes + +Better handle variable-redefinition checks for catch bindings and functions directly under if statements. + +Forbid `new.target` in top-level arrow functions. + +Fix issue with parsing a regexp after `yield` in some contexts. + +### New features + +The package now comes with TypeScript definitions. + +### Breaking changes + +The default value of the `ecmaVersion` option is now 9 (2018). + +Plugins work differently, and will have to be rewritten to work with this version. + +The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`). + +## 5.7.3 (2018-09-10) + +### Bug fixes + +Fix failure to tokenize regexps after expressions like `x.of`. + +Better error message for unterminated template literals. + +## 5.7.2 (2018-08-24) + +### Bug fixes + +Properly handle `allowAwaitOutsideFunction` in for statements. + +Treat function declarations at the top level of modules like let bindings. + +Don't allow async function declarations as the only statement under a label. + +## 5.7.0 (2018-06-15) + +### New features + +Upgraded to Unicode 11. + +## 5.6.0 (2018-05-31) + +### New features + +Allow U+2028 and U+2029 in string when ECMAVersion >= 10. + +Allow binding-less catch statements when ECMAVersion >= 10. + +Add `allowAwaitOutsideFunction` option for parsing top-level `await`. + +## 5.5.3 (2018-03-08) + +### Bug fixes + +A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps. + +## 5.5.2 (2018-03-08) + +### Bug fixes + +A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0. + +## 5.5.1 (2018-03-06) + +### Bug fixes + +Fix misleading error message for octal escapes in template strings. + +## 5.5.0 (2018-02-27) + +### New features + +The identifier character categorization is now based on Unicode version 10. + +Acorn will now validate the content of regular expressions, including new ES9 features. + +## 5.4.0 (2018-02-01) + +### Bug fixes + +Disallow duplicate or escaped flags on regular expressions. + +Disallow octal escapes in strings in strict mode. + +### New features + +Add support for async iteration. + +Add support for object spread and rest. + +## 5.3.0 (2017-12-28) + +### Bug fixes + +Fix parsing of floating point literals with leading zeroes in loose mode. + +Allow duplicate property names in object patterns. + +Don't allow static class methods named `prototype`. + +Disallow async functions directly under `if` or `else`. + +Parse right-hand-side of `for`/`of` as an assignment expression. + +Stricter parsing of `for`/`in`. + +Don't allow unicode escapes in contextual keywords. + +### New features + +Parsing class members was factored into smaller methods to allow plugins to hook into it. + +## 5.2.1 (2017-10-30) + +### Bug fixes + +Fix a token context corruption bug. + +## 5.2.0 (2017-10-30) + +### Bug fixes + +Fix token context tracking for `class` and `function` in property-name position. + +Make sure `%*` isn't parsed as a valid operator. + +Allow shorthand properties `get` and `set` to be followed by default values. + +Disallow `super` when not in callee or object position. + +### New features + +Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements. + +## 5.1.2 (2017-09-04) + +### Bug fixes + +Disable parsing of legacy HTML-style comments in modules. + +Fix parsing of async methods whose names are keywords. + +## 5.1.1 (2017-07-06) + +### Bug fixes + +Fix problem with disambiguating regexp and division after a class. + +## 5.1.0 (2017-07-05) + +### Bug fixes + +Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`. + +Parse zero-prefixed numbers with non-octal digits as decimal. + +Allow object/array patterns in rest parameters. + +Don't error when `yield` is used as a property name. + +Allow `async` as a shorthand object property. + +### New features + +Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9. + +## 5.0.3 (2017-04-01) + +### Bug fixes + +Fix spurious duplicate variable definition errors for named functions. + +## 5.0.2 (2017-03-30) + +### Bug fixes + +A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error. + +## 5.0.0 (2017-03-28) + +### Bug fixes + +Raise an error for duplicated lexical bindings. + +Fix spurious error when an assignement expression occurred after a spread expression. + +Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions. + +Allow labels in front or `var` declarations, even in strict mode. + +### Breaking changes + +Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`. + +## 4.0.11 (2017-02-07) + +### Bug fixes + +Allow all forms of member expressions to be parenthesized as lvalue. + +## 4.0.10 (2017-02-07) + +### Bug fixes + +Don't expect semicolons after default-exported functions or classes, even when they are expressions. + +Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode. + +## 4.0.9 (2017-02-06) + +### Bug fixes + +Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again. + +## 4.0.8 (2017-02-03) + +### Bug fixes + +Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet. + +## 4.0.7 (2017-02-02) + +### Bug fixes + +Accept invalidly rejected code like `(x).y = 2` again. + +Don't raise an error when a function _inside_ strict code has a non-simple parameter list. + +## 4.0.6 (2017-02-02) + +### Bug fixes + +Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check. + +## 4.0.5 (2017-02-02) + +### Bug fixes + +Disallow parenthesized pattern expressions. + +Allow keywords as export names. + +Don't allow the `async` keyword to be parenthesized. + +Properly raise an error when a keyword contains a character escape. + +Allow `"use strict"` to appear after other string literal expressions. + +Disallow labeled declarations. + +## 4.0.4 (2016-12-19) + +### Bug fixes + +Fix crash when `export` was followed by a keyword that can't be +exported. + +## 4.0.3 (2016-08-16) + +### Bug fixes + +Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode. + +Properly parse properties named `async` in ES2017 mode. + +Fix bug where reserved words were broken in ES2017 mode. + +## 4.0.2 (2016-08-11) + +### Bug fixes + +Don't ignore period or 'e' characters after octal numbers. + +Fix broken parsing for call expressions in default parameter values of arrow functions. + +## 4.0.1 (2016-08-08) + +### Bug fixes + +Fix false positives in duplicated export name errors. + +## 4.0.0 (2016-08-07) + +### Breaking changes + +The default `ecmaVersion` option value is now 7. + +A number of internal method signatures changed, so plugins might need to be updated. + +### Bug fixes + +The parser now raises errors on duplicated export names. + +`arguments` and `eval` can now be used in shorthand properties. + +Duplicate parameter names in non-simple argument lists now always produce an error. + +### New features + +The `ecmaVersion` option now also accepts year-style version numbers +(2015, etc). + +Support for `async`/`await` syntax when `ecmaVersion` is >= 8. + +Support for trailing commas in call expressions when `ecmaVersion` is >= 8. + +## 3.3.0 (2016-07-25) + +### Bug fixes + +Fix bug in tokenizing of regexp operator after a function declaration. + +Fix parser crash when parsing an array pattern with a hole. + +### New features + +Implement check against complex argument lists in functions that enable strict mode in ES7. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Improve handling of lack of unicode regexp support in host +environment. + +Properly reject shorthand properties whose name is a keyword. + +### New features + +Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Properly tokenize the division operator directly after a function expression. + +Allow trailing comma in destructuring arrays. + +## 3.0.4 (2016-02-25) + +### Fixes + +Allow update expressions as left-hand-side of the ES7 exponential operator. + +## 3.0.2 (2016-02-10) + +### Fixes + +Fix bug that accidentally made `undefined` a reserved word when parsing ES7. + +## 3.0.0 (2016-02-10) + +### Breaking changes + +The default value of the `ecmaVersion` option is now 6 (used to be 5). + +Support for comprehension syntax (which was dropped from the draft spec) has been removed. + +### Fixes + +`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code. + +A parenthesized class or function expression after `export default` is now parsed correctly. + +### New features + +When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`). + +The identifier character ranges are now based on Unicode 8.0.0. + +Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled. + +## 2.7.0 (2016-01-04) + +### Fixes + +Stop allowing rest parameters in setters. + +Disallow `y` rexexp flag in ES5. + +Disallow `\00` and `\000` escapes in strict mode. + +Raise an error when an import name is a reserved word. + +## 2.6.2 (2015-11-10) + +### Fixes + +Don't crash when no options object is passed. + +## 2.6.0 (2015-11-09) + +### Fixes + +Add `await` as a reserved word in module sources. + +Disallow `yield` in a parameter default value for a generator. + +Forbid using a comma after a rest pattern in an array destructuring. + +### New features + +Support parsing stdin in command-line tool. + +## 2.5.0 (2015-10-27) + +### Fixes + +Fix tokenizer support in the command-line tool. + +Stop allowing `new.target` outside of functions. + +Remove legacy `guard` and `guardedHandler` properties from try nodes. + +Stop allowing multiple `__proto__` properties on an object literal in strict mode. + +Don't allow rest parameters to be non-identifier patterns. + +Check for duplicate paramter names in arrow functions. diff --git a/node_modules/acorn/LICENSE b/node_modules/acorn/LICENSE new file mode 100644 index 0000000..9d71cc6 --- /dev/null +++ b/node_modules/acorn/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2022 by various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/acorn/README.md b/node_modules/acorn/README.md new file mode 100644 index 0000000..313acd6 --- /dev/null +++ b/node_modules/acorn/README.md @@ -0,0 +1,304 @@ +# Acorn + +A tiny, fast JavaScript parser written in JavaScript. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE). + +You are welcome to +[report bugs](https://github.com/acornjs/acorn/issues) or create pull +requests on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` +## Importing acorn + +ESM as well as CommonJS is supported for all 3: `acorn`, `acorn-walk` and `acorn-loose`. + +ESM example for `acorn`: + +```js +import * as acorn from "acorn" +``` + +CommonJS example for `acorn`: + +```js +let acorn = require("acorn") +``` + +ESM is preferred, as it allows better editor auto-completions by offering TypeScript support. +For this reason, following examples will use ESM imports. + +## Interface + +**parse**`(input, options)` is the main interface to the library. The +`input` parameter is a string, `options` must be an object setting +some of the options listed below. The return value will be an abstract +syntax tree object as specified by the [ESTree +spec](https://github.com/estree/estree). + +```javascript +import * as acorn from "acorn" +console.log(acorn.parse("1 + 1", {ecmaVersion: 2020})) +``` + +When encountering a syntax error, the parser will raise a +`SyntaxError` object with a meaningful message. The error object will +have a `pos` property that indicates the string offset at which the +error occurred, and a `loc` object that contains a `{line, column}` +object referring to that same position. + +Options are provided by in a second argument, which should be an +object containing any of these fields (only `ecmaVersion` is +required): + +- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a + number, either in year (`2022`) or plain version number (`6`) form, + or `"latest"` (the latest the library supports). This influences + support for strict mode, the set of reserved words, and support for + new syntax features. + + **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being + implemented by Acorn. Other proposed new features must be + implemented through plugins. + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"`, `"module"` or `"commonjs"`. This influences global strict mode + and parsing of `import` and `export` declarations. + + **NOTE**: If set to `"module"`, then static `import` / `export` syntax + will be valid, even if `ecmaVersion` is less than 6. If set to `"commonjs"`, + it is the same as `"script"` except that the top-level scope behaves like a function. + +- **strict**: When set to true, enable strict parsing mode even if + `sourceType` is `"script"`. + +- **onInsertedSemicolon**: If given a callback, that callback will be + called whenever a missing semicolon is inserted by the parser. The + callback will be given the character offset of the point where the + semicolon is inserted as argument, and if `locations` is on, also a + `{line, column}` object representing this position. + +- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing + commas. + +- **allowReserved**: If `false`, using a reserved word will generate + an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher + versions. When given the value `"never"`, reserved words and + keywords can also not be used as property names (as in Internet + Explorer's old parser). + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed, + and also allows `import.meta` expressions to appear in scripts + (when `sourceType` is not `"module"`). + +- **allowAwaitOutsideFunction**: If `false`, `await` expressions can + only appear inside `async` functions. Defaults to `true` in modules + for `ecmaVersion` 2022 and later, `false` for lower versions. + Setting this option to `true` allows to have top-level `await` + expressions. They are still not allowed in non-`async` functions, + though. Setting this option to `true` is not allowed when `sourceType: "commonjs"`. + +- **allowSuperOutsideMethod**: By default, `super` outside a method + raises an error. Set this to `true` to accept such code. + +- **allowHashBang**: When this is enabled, if the code starts with the + characters `#!` (as in a shellscript), the first line will be + treated as a comment. Defaults to true when `ecmaVersion` >= 2023. + +- **checkPrivateFields**: By default, the parser will verify that + private properties are only used in places where they are valid and + have been declared. Set this to false to turn such checks off. + +- **locations**: When `true`, each node has a `loc` object attached + with `start` and `end` subobjects, each of which contains the + one-based line and zero-based column numbers in `{line, column}` + form. Default is `false`. + +- **onToken**: If a function is passed for this option, each found + token will be passed in same format as tokens returned from + `tokenizer().getToken()`. + + If array is passed, each found token is pushed to it. + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **onComment**: If a function is passed for this option, whenever a + comment is encountered the function will be called with the + following parameters: + + - `block`: `true` if the comment is a block comment, false if it + is a line comment. + - `text`: The content of the comment. + - `start`: Character offset of the start of the comment. + - `end`: Character offset of the end of the comment. + + When the `locations` options is on, the `{line, column}` locations + of the comment’s start and end are passed as two additional + parameters. + + If array is passed for this option, each found comment is pushed + to it as object in Esprima format: + + ```javascript + { + "type": "Line" | "Block", + "value": "comment text", + "start": Number, + "end": Number, + // If `locations` option is on: + "loc": { + "start": {line: Number, column: Number} + "end": {line: Number, column: Number} + }, + // If `ranges` option is on: + "range": [Number, Number] + } + ``` + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **ranges**: Nodes have their start and end characters offsets + recorded in `start` and `end` properties (directly on the node, + rather than the `loc` object, which holds line/column data. To also + add a + [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678) + `range` property holding a `[start, end]` array with the same + numbers, set the `ranges` option to `true`. + +- **program**: It is possible to parse multiple files into a single + AST by passing the tree produced by parsing the first file as the + `program` option in subsequent parses. This will add the toplevel + forms of the parsed file to the "Program" (top) node of an existing + parse tree. + +- **sourceFile**: When the `locations` option is `true`, you can pass + this option to add a `source` attribute in every node’s `loc` + object. Note that the contents of this option are not examined or + processed in any way; you are free to use whatever format you + choose. + +- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property + will be added (regardless of the `location` option) directly to the + nodes, rather than the `loc` object. + +- **preserveParens**: If this option is `true`, parenthesized expressions + are represented by (non-standard) `ParenthesizedExpression` nodes + that have a single `expression` property containing the expression + inside parentheses. + +**parseExpressionAt**`(input, offset, options)` will parse a single +expression in a string, and return its AST. It will not complain if +there is more of the string left after the expression. + +**tokenizer**`(input, options)` returns an object with a `getToken` +method that can be called repeatedly to get the next token, a `{start, +end, type, value}` object (with added `loc` property when the +`locations` option is enabled and `range` property when the `ranges` +option is enabled). When the token's type is `tokTypes.eof`, you +should stop calling the method, since it will keep returning that same +token forever. + +Note that tokenizing JavaScript without parsing it is, in modern +versions of the language, not really possible due to the way syntax is +overloaded in ways that can only be disambiguated by the parse +context. This package applies a bunch of heuristics to try and do a +reasonable job, but you are advised to use `parse` with the `onToken` +option instead of this. + +In ES6 environment, returned result can be used as any other +protocol-compliant iterable: + +```javascript +for (let token of acorn.tokenizer(str)) { + // iterate over the tokens +} + +// transform code to array of tokens: +var tokens = [...acorn.tokenizer(str)] +``` + +**tokTypes** holds an object mapping names to the token type objects +that end up in the `type` properties of tokens. + +**getLineInfo**`(input, offset)` can be used to get a `{line, +column}` object for a given program string and offset. + +### The `Parser` class + +Instances of the **`Parser`** class contain all the state and logic +that drives a parse. It has static methods `parse`, +`parseExpressionAt`, and `tokenizer` that match the top-level +functions by the same name. + +When extending the parser with plugins, you need to call these methods +on the extended version of the class. To extend a parser with plugins, +you can use its static `extend` method. + +```javascript +var acorn = require("acorn") +var jsx = require("acorn-jsx") +var JSXParser = acorn.Parser.extend(jsx()) +JSXParser.parse("foo()", {ecmaVersion: 2020}) +``` + +The `extend` method takes any number of plugin values, and returns a +new `Parser` class that includes the extra parser logic provided by +the plugins. + +## Command line interface + +The `bin/acorn` utility can be used to parse a file from the command +line. It accepts as arguments its input file and the following +options: + +- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version + to parse. Default is version 9. + +- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise. + +- `--locations`: Attaches a "loc" object to each node with "start" and + "end" subobjects, each of which contains the one-based line and + zero-based column numbers in `{line, column}` form. + +- `--allow-hash-bang`: If the code starts with the characters #! (as + in a shellscript), the first line will be treated as a comment. + +- `--allow-await-outside-function`: Allows top-level `await` expressions. + See the `allowAwaitOutsideFunction` option for more information. + +- `--compact`: No whitespace is used in the AST output. + +- `--silent`: Do not output the AST, just return the exit status. + +- `--help`: Print the usage information and quit. + +The utility spits out the syntax tree as JSON data. + +## Existing plugins + + - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx) diff --git a/node_modules/acorn/bin/acorn b/node_modules/acorn/bin/acorn new file mode 100755 index 0000000..3ef3c12 --- /dev/null +++ b/node_modules/acorn/bin/acorn @@ -0,0 +1,4 @@ +#!/usr/bin/env node +"use strict" + +require("../dist/bin.js") diff --git a/node_modules/acorn/dist/acorn.d.mts b/node_modules/acorn/dist/acorn.d.mts new file mode 100644 index 0000000..35a4a2f --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.mts @@ -0,0 +1,889 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" | "commonjs" + + /** + * When set to true, enable strict parsing mode even if `sourceType` + * is `"script"`. + */ + strict?: boolean + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.d.ts b/node_modules/acorn/dist/acorn.d.ts new file mode 100644 index 0000000..35a4a2f --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.ts @@ -0,0 +1,889 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" | "commonjs" + + /** + * When set to true, enable strict parsing mode even if `sourceType` + * is `"script"`. + */ + strict?: boolean + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.js b/node_modules/acorn/dist/acorn.js new file mode 100644 index 0000000..d7eba90 --- /dev/null +++ b/node_modules/acorn/dist/acorn.js @@ -0,0 +1,6333 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.acorn = {})); +})(this, (function (exports) { 'use strict'; + + // This file was generated. Do not modify manually! + var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + // This file was generated. Do not modify manually! + var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489]; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1add\u1ae0-\u1aeb\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088f\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5c\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdc-\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7dc\ua7f1-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + + // These are a run-length and offset encoded representation of the + // >0xffff code points that are a valid part of identifiers. The + // offset starts at 0x10000, and each pair of numbers represents an + // offset to the next range, and then a size of the range. + + // Reserved word lists for various dialects of the language + + var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" + }; + + // And the keywords + + var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + + var keywords$1 = { + 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } + return false + } + + // Test whether a given character code starts an identifier. + + function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) + } + + // Test whether a given character is part of an identifier. + + function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) + } + + // ## Token types + + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. + + // All token type variables start with an underscore, to make them + // easy to recognize. + + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. + + var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; + }; + + function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) + } + var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; + + // Map keyword names to token types. + + var keywords = {}; + + // Succinct definitions of keyword token types + function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords[name] = new TokenType(name, options) + } + + var types$1 = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import", startsExpr), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + }; + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + var lineBreak = /\r\n?|\n|\u2028|\u2029/; + var lineBreakG = new RegExp(lineBreak.source, "g"); + + function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 + } + + function nextLineBreak(code, from, end) { + if ( end === void 0 ) end = code.length; + + for (var i = from; i < end; i++) { + var next = code.charCodeAt(i); + if (isNewLine(next)) + { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 } + } + return -1 + } + + var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + + var hasOwn = Object.hasOwn || (function (obj, propName) { return ( + hasOwnProperty.call(obj, propName) + ); }); + + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + + var regexpCache = Object.create(null); + + function wordsRegexp(words) { + return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")) + } + + function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) { return String.fromCharCode(code) } + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) + } + + var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/; + + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. + + var Position = function Position(line, col) { + this.line = line; + this.column = col; + }; + + Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) + }; + + var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } + }; + + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + var nextBreak = nextLineBreak(input, cur, offset); + if (nextBreak < 0) { return new Position(line, offset - cur) } + ++line; + cur = nextBreak; + } + } + + // A second argument must be given to configure the parser process. + // These options are recognized (only `ecmaVersion` is required): + + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` + // (the latest version the library supports). This influences + // support for strict mode, the set of reserved words, and support + // for new syntax features. + ecmaVersion: null, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // When set to true, enable strict parsing mode even if `sourceType` + // is `"script"`. + strict: false, + // `onInsertedSemicolon` can be a callback that will be called when + // a semicolon is automatically inserted. It will be passed the + // position of the inserted semicolon as an offset, and if + // `locations` is enabled, it is given the location as a `{line, + // column}` object as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. + allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, + // When enabled, hashbang directive in the beginning of file is + // allowed and treated as a line comment. Enabled by default when + // `ecmaVersion` >= 2023. + allowHashBang: false, + // By default, the parser will verify that private properties are + // only used in places where they are valid and have been declared. + // Set this to false to turn such checks off. + checkPrivateFields: true, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + // When this option has an array as value, objects representing the + // comments are pushed to it. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; + + // Interpret and default an options object + + var warnedAboutEcmaVersion = false; + + function getOptions(opts) { + var options = {}; + + for (var opt in defaultOptions) + { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; } + + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (!opts || opts.allowHashBang == null) + { options.allowHashBang = options.ecmaVersion >= 14; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + + if (options.sourceType === "commonjs" && options.allowAwaitOutsideFunction) + { throw new Error("Cannot use allowAwaitOutsideFunction with sourceType: commonjs") } + + return options + } + + function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } + } + + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128, + SCOPE_CLASS_STATIC_BLOCK = 256, + SCOPE_CLASS_FIELD_INIT = 512, + SCOPE_SWITCH = 1024, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK; + + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } + + // Used in checkLVal* and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + + // Properties of the current token: + // Its type + this.type = types$1.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || options.strict === true || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = Object.create(null); + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope( + this.options.sourceType === "commonjs" + // In commonjs, the top-level scope behaves like a function scope + ? SCOPE_FUNCTION + : SCOPE_TOP + ); + + // For RegExp validation + this.regexpState = null; + + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; + }; + + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowReturn: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },allowUsing: { configurable: true },inClassStaticBlock: { configurable: true } }; + + Parser.prototype.parse = function parse () { + var this$1$1 = this; + + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.catchStackOverflow(function () { return this$1$1.parseTopLevel(node); }) + }; + + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; + + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; + + prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT)) { return false } + if (flags & SCOPE_FUNCTION) { return (flags & SCOPE_ASYNC) > 0 } + } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction + }; + + prototypeAccessors.allowReturn.get = function () { + if (this.inFunction) { return true } + if (this.options.allowReturnOutsideFunction && this.currentVarScope().flags & SCOPE_TOP) { return true } + return false + }; + + prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + return (flags & SCOPE_SUPER) > 0 || this.options.allowSuperOutsideMethod + }; + + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; + + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + + prototypeAccessors.allowNewDotTarget.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT) || + ((flags & SCOPE_FUNCTION) && !(flags & SCOPE_ARROW))) { return true } + } + return false + }; + + prototypeAccessors.allowUsing.get = function () { + var ref = this.currentScope(); + var flags = ref.flags; + if (flags & SCOPE_SWITCH) { return false } + if (!this.inModule && flags & SCOPE_TOP) { return false } + return true + }; + + prototypeAccessors.inClassStaticBlock.get = function () { + return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0 + }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp$9 = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; + pp$9.strictDirective = function(start) { + if (this.options.ecmaVersion < 5) { return false } + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } + }; + + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. + + pp$9.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } + }; + + // Tests whether parsed token is a contextual keyword. + + pp$9.isContextual = function(name) { + return this.type === types$1.name && this.value === name && !this.containsEsc + }; + + // Consumes contextual keyword if possible. + + pp$9.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + + pp$9.catchStackOverflow = function(f) { + try { + return f() + } catch (e) { + if (e instanceof Error && (/\bstack\b.*\b(exceeded|overflow)\b/i.test(e.message) || /\btoo much recursion\b/i.test(e.message))) + { this.raise(this.start, "Not enough stack space to parse input"); } + else + { throw e } + } + }; + + // Asserts that following token is given contextual keyword. + + pp$9.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + + // Test whether a semicolon can be inserted at the current position. + + pp$9.canInsertSemicolon = function() { + return this.type === types$1.eof || + this.type === types$1.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + pp$9.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } + }; + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + pp$9.semicolon = function() { + if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); } + }; + + pp$9.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } + }; + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. + + pp$9.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + pp$9.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); + }; + + var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; + }; + + pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); } + }; + + pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + }; + + pp$9.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } + }; + + pp$9.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" + }; + + var pp$8 = Parser.prototype; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$8.parseTopLevel = function(node) { + var exports$1 = Object.create(null); + if (!node.body) { node.body = []; } + while (this.type !== types$1.eof) { + var stmt = this.parseStatement(null, true, exports$1); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType === "commonjs" ? "script" : this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$8.isLet = function(context) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.fullCharCodeAt(next); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' + if (context) { return false } + + if (nextCh === 123) { return true } // '{' + if (isIdentifierStart(nextCh)) { + var start = next; + do { next += nextCh <= 0xffff ? 1 : 2; } + while (isIdentifierChar(nextCh = this.fullCharCodeAt(next))) + if (nextCh === 92) { return true } + var ident = this.input.slice(start, next); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false + }; + + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + pp$8.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, after; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.fullCharCodeAt(next + 8)) || after === 92 /* '\' */)) + }; + + pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } + + if (isAwaitUsing) { + var usingEndPos = next + 5 /* using */, after; + if (this.input.slice(next, usingEndPos) !== "using" || + usingEndPos === this.input.length || + isIdentifierChar(after = this.fullCharCodeAt(usingEndPos)) || + after === 92 /* '\' */ + ) { return false } + + skipWhiteSpace.lastIndex = usingEndPos; + var skipAfterUsing = skipWhiteSpace.exec(this.input); + next = usingEndPos + skipAfterUsing[0].length; + if (skipAfterUsing && lineBreak.test(this.input.slice(usingEndPos, next))) { return false } + } + + var ch = this.fullCharCodeAt(next); + if (!isIdentifierStart(ch) && ch !== 92 /* '\' */) { return false } + var idStart = next; + do { next += ch <= 0xffff ? 1 : 2; } + while (isIdentifierChar(ch = this.fullCharCodeAt(next))) + if (ch === 92) { return true } + var id = this.input.slice(idStart, next); + if (keywordRelationalOperator.test(id)) { return false } + if (isFor && !isAwaitUsing && id === "of") { + // Look ahead for using declaration with initializer, i.e., `for (using of = ...)` + skipWhiteSpace.lastIndex = next; + var skipAfterOf = skipWhiteSpace.exec(this.input); + next = next + skipAfterOf[0].length; + if (this.input.charCodeAt(next) !== 61 /* '=' */ || + // Check for ==, === and => operators + (ch = this.input.charCodeAt(next + 1)) === 61 /* '=' */ || ch === 62 /* '>' */) { + return false + } + } + return true + }; + + pp$8.isAwaitUsing = function(isFor) { + return this.isUsingKeyword(true, isFor) + }; + + pp$8.isUsing = function(isFor) { + return this.isUsingKeyword(false, isFor) + }; + + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. + + pp$8.parseStatement = function(context, topLevel, exports$1) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types$1._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types$1._debugger: return this.parseDebuggerStatement(node) + case types$1._do: return this.parseDoStatement(node) + case types$1._for: return this.parseForStatement(node) + case types$1._function: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types$1._class: + if (context) { this.unexpected(); } + return this.parseClass(node, true) + case types$1._if: return this.parseIfStatement(node) + case types$1._return: return this.parseReturnStatement(node) + case types$1._switch: return this.parseSwitchStatement(node) + case types$1._throw: return this.parseThrowStatement(node) + case types$1._try: return this.parseTryStatement(node) + case types$1._const: case types$1._var: + kind = kind || this.value; + if (context && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types$1._while: return this.parseWhileStatement(node) + case types$1._with: return this.parseWithStatement(node) + case types$1.braceL: return this.parseBlock(true, node) + case types$1.semi: return this.parseEmptyStatement(node) + case types$1._export: + case types$1._import: + if (this.options.ecmaVersion > 10 && starttype === types$1._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports$1) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; + if (usingKind) { + if (!this.allowUsing) { + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script` or in the bare case statement"); + } + if (context) { + // Cases like `for (;;) using x = ...;`, `if (true) await using x = ...;`, etc. are not allowed. + this.raise(this.start, "Using declaration is not allowed in single-statement positions"); + } + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.next(); + this.parseVar(node, false, usingKind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + + pp$8.parseBreakContinueStatement = function(node, keyword) { + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types$1.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + }; + + pp$8.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + }; + + pp$8.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement("do"); + this.labels.pop(); + this.expect(types$1._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types$1.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + pp$8.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterScope(0); + this.expect(types$1.parenL); + if (this.type === types$1.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types$1._var || this.type === types$1._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + return this.parseForAfterInit(node, init$1, awaitAt) + } + var startsWithLet = this.isContextual("let"), isForOf = false; + + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; + if (usingKind) { + var init$2 = this.startNode(); + this.next(); + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.parseVar(init$2, true, usingKind); + this.finishNode(init$2, "VariableDeclaration"); + return this.parseForAfterInit(node, init$2, awaitAt) + } + var containsEsc = this.containsEsc; + var refDestructuringErrors = new DestructuringErrors; + var initPos = this.start; + var init = awaitAt > -1 + ? this.parseExprSubscripts(refDestructuringErrors, "await") + : this.parseExpression(true, refDestructuringErrors); + if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt) + if (this.type === types$1._in) { this.unexpected(awaitAt); } + node.await = true; + } else if (isForOf && this.options.ecmaVersion >= 8) { + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } + else if (this.options.ecmaVersion >= 9) { node.await = false; } + } + if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLValPattern(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + // Helper method to parse for loop after variable initialization + pp$8.parseForAfterInit = function(node, init, awaitAt) { + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { + if (this.type === types$1._in) { + if ((init.kind === "using" || init.kind === "await using") && !init.declarations[0].init) { + this.raise(this.start, "Using declaration is not allowed in for-in loops"); + } + if (this.options.ecmaVersion >= 9 && awaitAt > -1) { this.unexpected(awaitAt); } + } else if (this.options.ecmaVersion >= 9) { node.await = awaitAt > -1; } + return this.parseForIn(node, init) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; + + pp$8.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement") + }; + + pp$8.parseReturnStatement = function(node) { + if (!this.allowReturn) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + }; + + pp$8.parseSwitchStatement = function(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types$1.braceL); + this.labels.push(switchLabel); + this.enterScope(SCOPE_SWITCH); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types$1.braceR;) { + if (this.type === types$1._case || this.type === types$1._default) { + var isCase = this.type === types$1._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types$1.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") + }; + + pp$8.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + }; + + // Reused empty array added for node fields that are always empty. + + var empty$1 = []; + + pp$8.parseCatchClauseParam = function() { + var param = this.parseBindingAtom(); + var simple = param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types$1.parenR); + + return param + }; + + pp$8.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types$1._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types$1.parenL)) { + clause.param = this.parseCatchClauseParam(); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") + }; + + pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) { + this.next(); + this.parseVar(node, false, kind, allowMissingInitializer); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + }; + + pp$8.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement("while"); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") + }; + + pp$8.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement("with"); + return this.finishNode(node, "WithStatement") + }; + + pp$8.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + + pp$8.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + }; + + pp$8.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + }; + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types$1.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + pp$8.parseFor = function(node, init) { + node.init = init; + this.expect(types$1.semi); + node.test = this.type === types$1.semi ? null : this.parseExpression(); + this.expect(types$1.semi); + node.update = this.type === types$1.parenR ? null : this.parseExpression(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + pp$8.parseForIn = function(node, init) { + var isForIn = this.type === types$1._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; + + // Parse a list of variable declarations. + + pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types$1.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); + } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types$1.comma)) { break } + } + return node + }; + + pp$8.parseVarId = function(decl, kind) { + decl.id = kind === "using" || kind === "await using" + ? this.parseIdent() + : this.parseBindingAtom(); + + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; + + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). + + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types$1.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types$1.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; + + pp$8.parseFunctionParams = function(node) { + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + pp$8.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types$1.braceL); + while (this.type !== types$1.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + pp$8.parseClassElement = function(constructorAllowsSuper) { + if (this.eat(types$1.semi)) { return null } + + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(types$1.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.type === types$1.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } + + // Parse element value + if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } + + return node + }; + + pp$8.isClassElementNameStart = function() { + return ( + this.type === types$1.name || + this.type === types$1.privateId || + this.type === types$1.num || + this.type === types$1.string || + this.type === types$1.bracketL || + this.type.keyword + ) + }; + + pp$8.parseClassElementName = function(element) { + if (this.type === types$1.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; + + pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags + var key = method.key; + if (method.kind === "constructor") { + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + } else if (method.static && checkKeyName(method, "prototype")) { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + + return this.finishNode(method, "MethodDefinition") + }; + + pp$8.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types$1.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + this.enterScope(SCOPE_CLASS_FIELD_INIT | SCOPE_SUPER); + field.value = this.parseMaybeAssign(); + this.exitScope(); + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") + }; + + pp$8.parseClassStaticBlock = function(node) { + node.body = []; + + var oldLabels = this.labels; + this.labels = []; + this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER); + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + this.next(); + this.exitScope(); + this.labels = oldLabels; + + return this.finishNode(node, "StaticBlock") + }; + + pp$8.parseClassId = function(node, isStatement) { + if (this.type === types$1.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } + }; + + pp$8.parseClassSuper = function(node) { + node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null; + }; + + pp$8.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared + }; + + pp$8.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + if (!this.options.checkPrivateFields) { return } + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!hasOwn(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } + } + }; + + function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; + + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; + } + + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true + } + } + + function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) + } + + // Parses module export declaration. + + pp$8.parseExportAllDeclaration = function(node, exports$1) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseModuleExportName(); + this.checkExport(exports$1, node.exported, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + }; + + pp$8.parseExport = function(node, exports$1) { + this.next(); + // export * from '...' + if (this.eat(types$1.star)) { + return this.parseExportAllDeclaration(node, exports$1) + } + if (this.eat(types$1._default)) { // export default ... + this.checkExport(exports$1, "default", this.lastTokStart); + node.declaration = this.parseExportDefaultDeclaration(); + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseExportDeclaration(node); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports$1, node.declaration.declarations); } + else + { this.checkExport(exports$1, node.declaration.id, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports$1); + if (this.eatContextual("from")) { + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + + if (spec.local.type === "Literal") { + this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`."); + } + } + + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; + + pp$8.parseExportDeclaration = function(node) { + return this.parseStatement(null) + }; + + pp$8.parseExportDefaultDeclaration = function() { + var isAsync; + if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync) + } else if (this.type === types$1._class) { + var cNode = this.startNode(); + return this.parseClass(cNode, "nullableID") + } else { + var declaration = this.parseMaybeAssign(); + this.semicolon(); + return declaration + } + }; + + pp$8.checkExport = function(exports$1, name, pos) { + if (!exports$1) { return } + if (typeof name !== "string") + { name = name.type === "Identifier" ? name.name : name.value; } + if (hasOwn(exports$1, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports$1[name] = true; + }; + + pp$8.checkPatternExport = function(exports$1, pat) { + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports$1, pat, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.checkPatternExport(exports$1, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + + if (elt) { this.checkPatternExport(exports$1, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports$1, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports$1, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports$1, pat.argument); } + }; + + pp$8.checkVariableExport = function(exports$1, decls) { + if (!exports$1) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.checkPatternExport(exports$1, decl.id); + } + }; + + pp$8.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() + }; + + // Parses a comma-separated list of module exports. + + pp$8.parseExportSpecifier = function(exports$1) { + var node = this.startNode(); + node.local = this.parseModuleExportName(); + + node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local; + this.checkExport( + exports$1, + node.exported, + node.exported.start + ); + + return this.finishNode(node, "ExportSpecifier") + }; + + pp$8.parseExportSpecifiers = function(exports$1) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseExportSpecifier(exports$1)); + } + return nodes + }; + + // Parses import declaration. + + pp$8.parseImport = function(node) { + this.next(); + + // import '...' + if (this.type === types$1.string) { + node.specifiers = empty$1; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); + } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") + }; + + // Parses a comma-separated list of module imports. + + pp$8.parseImportSpecifier = function() { + var node = this.startNode(); + node.imported = this.parseModuleExportName(); + + if (this.eatContextual("as")) { + node.local = this.parseIdent(); + } else { + this.checkUnreserved(node.imported); + node.local = node.imported; + } + this.checkLValSimple(node.local, BIND_LEXICAL); + + return this.finishNode(node, "ImportSpecifier") + }; + + pp$8.parseImportDefaultSpecifier = function() { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportDefaultSpecifier") + }; + + pp$8.parseImportNamespaceSpecifier = function() { + var node = this.startNode(); + this.next(); + this.expectContextual("as"); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportNamespaceSpecifier") + }; + + pp$8.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types$1.name) { + nodes.push(this.parseImportDefaultSpecifier()); + if (!this.eat(types$1.comma)) { return nodes } + } + if (this.type === types$1.star) { + nodes.push(this.parseImportNamespaceSpecifier()); + return nodes + } + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseImportSpecifier()); + } + return nodes + }; + + pp$8.parseWithClause = function() { + var nodes = []; + if (!this.eat(types$1._with)) { + return nodes + } + this.expect(types$1.braceL); + var attributeKeys = {}; + var first = true; + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var attr = this.parseImportAttribute(); + var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value; + if (hasOwn(attributeKeys, keyName)) + { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); } + attributeKeys[keyName] = true; + nodes.push(attr); + } + return nodes + }; + + pp$8.parseImportAttribute = function() { + var node = this.startNode(); + node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + this.expect(types$1.colon); + if (this.type !== types$1.string) { + this.unexpected(); + } + node.value = this.parseExprAtom(); + return this.finishNode(node, "ImportAttribute") + }; + + pp$8.parseModuleExportName = function() { + if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { + var stringLiteral = this.parseLiteral(this.value); + if (loneSurrogate.test(stringLiteral.value)) { + this.raise(stringLiteral.start, "An export name cannot include a lone surrogate."); + } + return stringLiteral + } + return this.parseIdent(true) + }; + + // Set `ExpressionStatement#directive` property for directive prologues. + pp$8.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } + }; + pp$8.isDirectiveCandidate = function(statement) { + return ( + this.options.ecmaVersion >= 5 && + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + + var pp$7 = Parser.prototype; + + // Convert existing expression atom to assignable pattern + // if possible. + + pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } + break + + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break + + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + + // Convert list of expression atoms to binding list. + + pp$7.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList + }; + + // Parses spread element. + + pp$7.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") + }; + + pp$7.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types$1.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") + }; + + // Parses lvalue (assignable) atom. + + pp$7.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types$1.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types$1.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types$1.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() + }; + + pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) { + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types$1.comma); } + if (allowEmpty && this.type === types$1.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types$1.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + elts.push(this.parseAssignableListItem(allowModifiers)); + } + } + return elts + }; + + pp$7.parseAssignableListItem = function(allowModifiers) { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + return elem + }; + + pp$7.parseBindingListItem = function(param) { + return param + }; + + // Parses assignment pattern around given atom if possible. + + pp$7.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") + }; + + // The following three functions all verify that a node is an lvalue — + // something that can be bound, or assigned to. In order to do so, they perform + // a variety of checks: + // + // - Check that none of the bound/assigned-to identifiers are reserved words. + // - Record name declarations for bindings in the appropriate scope. + // - Check duplicate argument names, if checkClashes is set. + // + // If a complex binding pattern is encountered (e.g., object and array + // destructuring), the entire pattern is recursively checked. + // + // There are three versions of checkLVal*() appropriate for different + // circumstances: + // + // - checkLValSimple() shall be used if the syntactic construct supports + // nothing other than identifiers and member expressions. Parenthesized + // expressions are also correctly handled. This is generally appropriate for + // constructs for which the spec says + // + // > It is a Syntax Error if AssignmentTargetType of [the production] is not + // > simple. + // + // It is also appropriate for checking if an identifier is valid and not + // defined elsewhere, like import declarations or function/class identifiers. + // + // Examples where this is used include: + // a += …; + // import a from '…'; + // where a is the node to be checked. + // + // - checkLValPattern() shall be used if the syntactic construct supports + // anything checkLValSimple() supports, as well as object and array + // destructuring patterns. This is generally appropriate for constructs for + // which the spec says + // + // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor + // > an ArrayLiteral and AssignmentTargetType of [the production] is not + // > simple. + // + // Examples where this is used include: + // (a = …); + // const a = …; + // try { … } catch (a) { … } + // where a is the node to be checked. + // + // - checkLValInnerPattern() shall be used if the syntactic construct supports + // anything checkLValPattern() supports, as well as default assignment + // patterns, rest elements, and other constructs that may appear within an + // object or array destructuring pattern. + // + // As a special case, function parameters also use checkLValInnerPattern(), + // as they also support defaults and rest constructs. + // + // These functions deliberately support both assignment and binding constructs, + // as the logic for both is exceedingly similar. If the node is the target of + // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it + // should be set to the appropriate BIND_* constant, like BIND_VAR or + // BIND_LEXICAL. + // + // If the function is called with a non-BIND_NONE bindingType, then + // additionally a checkClashes object may be specified to allow checking for + // duplicate argument names. checkClashes is ignored if the provided construct + // is an assignment (i.e., bindingType is BIND_NONE). + + pp$7.checkLValSimple = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + var isBind = bindingType !== BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (hasOwn(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break + + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) + + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); + } + }; + + pp$7.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } + break + + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } + } + break + + default: + this.checkLValSimple(expr, bindingType, checkClashes); + } + }; + + pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); + break + + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); + break + + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); + break + + default: + this.checkLValPattern(expr, bindingType, checkClashes); + } + }; + + // The algorithm used to determine whether a regexp can appear at a + // given point in the program is loosely based on sweet.js' approach. + // See https://github.com/mozilla/sweet.js/wiki/design + + + var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; + }; + + var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) + }; + + var pp$6 = Parser.prototype; + + pp$6.initialContext = function() { + return [types.b_stat] + }; + + pp$6.curContext = function() { + return this.context[this.context.length - 1] + }; + + pp$6.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types.f_expr || parent === types.f_stat) + { return true } + if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr)) + { return !parent.isExpr } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow) + { return true } + if (prevType === types$1.braceL) + { return parent === types.b_stat } + if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name) + { return false } + return !this.exprAllowed + }; + + pp$6.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.context[i]; + if (context.token === "function") + { return context.generator } + } + return false + }; + + pp$6.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types$1.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } + }; + + // Used to handle edge cases when token context could not be inferred correctly during tokenization phase + + pp$6.overrideContext = function(tokenCtx) { + if (this.curContext() !== tokenCtx) { + this.context[this.context.length - 1] = tokenCtx; + } + }; + + // Token-specific context update code + + types$1.parenR.updateContext = types$1.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; + }; + + types$1.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr); + this.exprAllowed = true; + }; + + types$1.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl); + this.exprAllowed = true; + }; + + types$1.parenL.updateContext = function(prevType) { + var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while; + this.context.push(statementParens ? types.p_stat : types.p_expr); + this.exprAllowed = true; + }; + + types$1.incDec.updateContext = function() { + // tokExprAllowed stays unchanged + }; + + types$1._function.updateContext = types$1._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types$1._else && + !(prevType === types$1.semi && this.curContext() !== types.p_stat) && + !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) + { this.context.push(types.f_expr); } + else + { this.context.push(types.f_stat); } + this.exprAllowed = false; + }; + + types$1.colon.updateContext = function() { + if (this.curContext().token === "function") { this.context.pop(); } + this.exprAllowed = true; + }; + + types$1.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types.q_tmpl); } + this.exprAllowed = false; + }; + + types$1.star.updateContext = function(prevType) { + if (prevType === types$1._function) { + var index = this.context.length - 1; + if (this.context[index] === types.f_expr) + { this.context[index] = types.f_expr_gen; } + else + { this.context[index] = types.f_gen; } + } + this.exprAllowed = true; + }; + + types$1.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; + }; + + // A recursive descent parser operates by defining functions for all + // syntactic elements, and recursively calling those, each function + // advancing the input stream and returning an AST node. Precedence + // of constructs (for example, the fact that `!x[1]` means `!(x[1])` + // instead of `(!x)[1]` is handled by the fact that the parser + // function that parses unary prefix operators is called first, and + // in turn calls the function that parses `[]` subscripts — that + // way, it'll receive the node for `x[1]` already parsed, and wraps + // *that* in the unary operator node. + // + // Acorn uses an [operator precedence parser][opp] to handle binary + // operator precedence, because it is much more compact than using + // the technique outlined above, which uses different, nesting + // functions to specify precedence, for all of the ten binary + // precedence levels that JavaScript defines. + // + // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + + + var pp$5 = Parser.prototype; + + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. + + pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors) { + if (refDestructuringErrors.doubleProto < 0) { + refDestructuringErrors.doubleProto = key.start; + } + } else { + this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); + } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; + } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; + } + other[kind] = true; + }; + + // ### Expression parsing + + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + pp$5.parseExpression = function(forInit, refDestructuringErrors) { + var this$1$1 = this; + + return this.catchStackOverflow(function () { + var startPos = this$1$1.start, startLoc = this$1$1.startLoc; + var expr = this$1$1.parseMaybeAssign(forInit, refDestructuringErrors); + if (this$1$1.type === types$1.comma) { + var node = this$1$1.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this$1$1.eat(types$1.comma)) { node.expressions.push(this$1$1.parseMaybeAssign(forInit, refDestructuringErrors)); } + return this$1$1.finishNode(node, "SequenceExpression") + } + return expr + }) + }; + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(forInit) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + oldDoubleProto = refDestructuringErrors.doubleProto; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types$1.parenL || this.type === types$1.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + if (this.type === types$1.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } + if (!ownDestructuringErrors) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + if (this.type === types$1.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; + this.next(); + node.right = this.parseMaybeAssign(forInit); + if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; } + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left + }; + + // Parse a ternary conditional (`?:`) operator. + + pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(forInit, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (!(expr.type === "ArrowFunctionExpression" && expr.start === startPos) && this.eat(types$1.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types$1.colon); + node.alternate = this.parseMaybeAssign(forInit); + return this.finishNode(node, "ConditionalExpression") + } + return expr + }; + + // Start the precedence parser. + + pp$5.parseExprOps = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) + }; + + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. + + pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { + var prec = this.type.binop; + if (prec != null && (!forInit || this.type !== types$1._in)) { + if (prec > minPrec) { + var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND; + var coalesce = this.type === types$1.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types$1.logicalAND.binop; + } + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) + } + } + return left + }; + + pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) { + if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + }; + + // Parse unary operators, both prefix and postfix. + + pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) { + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && this.canAwait) { + expr = this.parseAwait(forInit); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types$1.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true, update, forInit); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLValSimple(node.argument); } + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (!sawUnary && this.type === types$1.privateId) { + if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); } + expr = this.parsePrivateIdent(); + // only could be private fields in 'in', such as #x in obj + if (this.type !== types$1._in) { this.unexpected(); } + } else { + expr = this.parseExprSubscripts(refDestructuringErrors, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLValSimple(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!incDec && this.eat(types$1.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) } + } else { + return expr + } + }; + + function isLocalVariableAccess(node) { + return ( + node.type === "Identifier" || + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) + ) + } + + function isPrivateFieldAccess(node) { + return ( + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) || + node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression) + ) + } + + // Parse call, dot, and `[]`-subscript expressions. + + pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors, forInit); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } + } + return result + }; + + pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) { + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } + }; + + pp$5.shouldParseAsyncArrow = function() { + return !this.canInsertSemicolon() && this.eat(types$1.arrow) + }; + + pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit) + }; + + pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types$1.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types$1.bracketL); + if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + if (computed) { + node.property = this.parseExpression(); + this.expect(types$1.bracketR); + } else if (this.type === types$1.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } + node.computed = !!computed; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types$1.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types$1.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base + }; + + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. + + pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types$1.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types$1._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types$1.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + + case types$1._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") + + case types$1.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) { + this.overrideContext(types.f_expr); + return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit) + } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types$1.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { + id = this.parseIdent(false); + if (this.canInsertSemicolon() || !this.eat(types$1.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit) + } + } + return id + + case types$1.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + + case types$1.num: case types$1.string: + return this.parseLiteral(this.value) + + case types$1._null: case types$1._true: case types$1._false: + node = this.startNode(); + node.value = this.type === types$1._null ? null : this.type === types$1._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case types$1.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + + case types$1.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + + case types$1.braceL: + this.overrideContext(types.b_expr); + return this.parseObj(false, refDestructuringErrors) + + case types$1._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, 0) + + case types$1._class: + return this.parseClass(this.startNode(), false) + + case types$1._new: + return this.parseNew() + + case types$1.backQuote: + return this.parseTemplate() + + case types$1._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport(forNew) + } else { + return this.unexpected() + } + + default: + return this.parseExprAtomDefault() + } + }; + + pp$5.parseExprAtomDefault = function() { + this.unexpected(); + }; + + pp$5.parseExprImport = function(forNew) { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + this.next(); + + if (this.type === types$1.parenL && !forNew) { + return this.parseDynamicImport(node) + } else if (this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "import"; + node.meta = this.finishNode(meta, "Identifier"); + return this.parseImportMeta(node) + } else { + this.unexpected(); + } + }; + + pp$5.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + if (this.options.ecmaVersion >= 16) { + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + node.options = this.parseMaybeAssign(); + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + this.unexpected(); + } + } + } else { + node.options = null; + } + } else { + node.options = null; + } + } else { + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + } + + return this.finishNode(node, "ImportExpression") + }; + + pp$5.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + + pp$5.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + }; + + pp$5.parseParenExpression = function() { + this.expect(types$1.parenL); + var val = this.parseExpression(); + this.expect(types$1.parenR); + return val + }; + + pp$5.shouldParseArrow = function(exprList) { + return !this.canInsertSemicolon() + }; + + pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) { + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types$1.parenR) { + first ? first = false : this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types$1.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types$1.comma) { + this.raiseRecoverable( + this.start, + "Comma is not permitted after the rest element" + ); + } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + } + } + var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc; + this.expect(types$1.parenR); + + if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList, forInit) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } + }; + + pp$5.parseParenItem = function(item) { + return item + }; + + pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit) + }; + + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. + + var empty = []; + + pp$5.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + var node = this.startNode(); + this.next(); + if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "new"; + node.meta = this.finishNode(meta, "Identifier"); + this.next(); + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.allowNewDotTarget) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false); + if (node.callee.type === "Super") + { this.raiseRecoverable(startPos, "Invalid use of 'super'"); } + if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty; } + return this.finishNode(node, "NewExpression") + }; + + // Parse template expression. + + pp$5.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types$1.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value.replace(/\r\n?/g, "\n"), + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; + } + this.next(); + elem.tail = this.type === types$1.backQuote; + return this.finishNode(elem, "TemplateElement") + }; + + pp$5.parseTemplate = function(ref) { + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types$1.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types$1.braceR); + node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") + }; + + pp$5.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + // Parse an object literal or binding pattern. + + pp$5.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + }; + + pp$5.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types$1.comma) { + this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") + } + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types$1.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star); + this.parsePropertyName(prop); + } else { + isAsync = false; + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") + }; + + pp$5.parseGetterSetter = function(prop) { + var kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + prop.kind = kind; + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + }; + + pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types$1.colon) + { this.unexpected(); } + + if (this.eat(types$1.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) { + if (isPattern) { this.unexpected(); } + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + prop.kind = "init"; + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) { + if (isGenerator || isAsync) { this.unexpected(); } + this.parseGetterSetter(prop); + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else if (this.type === types$1.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else { + prop.value = this.copyNode(prop.key); + } + prop.kind = "init"; + prop.shorthand = true; + } else { this.unexpected(); } + }; + + pp$5.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types$1.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types$1.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; + + // Initialize empty function node. + + pp$5.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; + + // Parse object or class method. + + pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; + + // Parse arrow function expression with given parameters. + + pp$5.parseArrowExpression = function(node, params, isAsync, forInit) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + // Parse function body and check parameters. + + pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) { + var isExpression = isArrowFunction && this.type !== types$1.braceL; + var oldStrict = this.strict, useStrict = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(forInit); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; + + pp$5.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + + if (param.type !== "Identifier") { return false + } } + return true + }; + + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. + + pp$5.checkParams = function(node, allowDuplicates) { + var nameHash = Object.create(null); + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); + } + }; + + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types$1.comma) + { elt = null; } + else if (this.type === types$1.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts + }; + + pp$5.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (!(this.currentThisScope().flags & SCOPE_VAR) && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } + if (this.inClassStaticBlock && (name === "arguments" || name === "await")) + { this.raise(start, ("Cannot use " + name + " in class static initialization block")); } + if (this.keywords.test(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. + + pp$5.parseIdent = function(liberal) { + var node = this.parseIdentNode(); + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node + }; + + pp$5.parseIdentNode = function() { + var node = this.startNode(); + if (this.type === types$1.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + this.type = types$1.name; + } else { + this.unexpected(); + } + return node + }; + + pp$5.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types$1.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); + + // For validating existence + if (this.options.checkPrivateFields) { + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } + } + + return node + }; + + // Parses yield expression inside generator. + + pp$5.parseYield = function(forInit) { + if (!this.yieldPos) { this.yieldPos = this.start; } + + var node = this.startNode(); + this.next(); + if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types$1.star); + node.argument = this.parseMaybeAssign(forInit); + } + return this.finishNode(node, "YieldExpression") + }; + + pp$5.parseAwait = function(forInit) { + if (!this.awaitPos) { this.awaitPos = this.start; } + + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true, false, forInit); + return this.finishNode(node, "AwaitExpression") + }; + + var pp$4 = Parser.prototype; + + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + if (this.sourceFile) { + message += " in " + this.sourceFile; + } + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err + }; + + pp$4.raiseRecoverable = pp$4.raise; + + pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } + }; + + var pp$3 = Parser.prototype; + + var Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + }; + + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + + pp$3.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); + }; + + pp$3.exitScope = function() { + this.scopeStack.pop(); + }; + + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$3.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + }; + + pp$3.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + }; + + pp$3.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } + }; + + pp$3.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; + + pp$3.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK)) { return scope } + } + }; + + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$3.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK) && + !(scope.flags & SCOPE_ARROW)) { return scope } + } + }; + + var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } + }; + + // Start an AST node, attaching a start offset. + + var pp$2 = Parser.prototype; + + pp$2.startNode = function() { + return new Node(this, this.start, this.startLoc) + }; + + pp$2.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) + }; + + // Finish an AST node, adding `type` and `end` properties. + + function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node + } + + pp$2.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) + }; + + // Finish node at given position + + pp$2.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + + pp$2.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode + }; + + // This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually! + var scriptValuesAddedInUnicode = "Berf Beria_Erfe Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sidetic Sidt Sunu Sunuwar Tai_Yo Tayo Todhri Todr Tolong_Siki Tols Tulu_Tigalari Tutg Unknown Zzzz"; + + // This file contains Unicode properties extracted from the ECMAScript specification. + // The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; + var ecma13BinaryProperties = ecma12BinaryProperties; + var ecma14BinaryProperties = ecma13BinaryProperties; + + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties, + 13: ecma13BinaryProperties, + 14: ecma14BinaryProperties + }; + + // #table-binary-unicode-properties-of-strings + var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"; + + var unicodeBinaryPropertiesOfStrings = { + 9: "", + 10: "", + 11: "", + 12: "", + 13: "", + 14: ecma14BinaryPropertiesOfStrings + }; + + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; + + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; + var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; + var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode; + + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues, + 12: ecma12ScriptValues, + 13: ecma13ScriptValues, + 14: ecma14ScriptValues + }; + + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } + + for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { + var ecmaVersion = list[i]; + + buildUnicodeData(ecmaVersion); + } + + var pp$1 = Parser.prototype; + + // Track disjunction structure to determine whether a duplicate + // capture group name is allowed because it is in a separate branch. + var BranchID = function BranchID(parent, base) { + // Parent disjunction branch + this.parent = parent; + // Identifies this set of sibling branches + this.base = base || this; + }; + + BranchID.prototype.separatedFrom = function separatedFrom (alt) { + // A branch is separate from another branch if they or any of + // their parents are siblings in a given disjunction + for (var self = this; self; self = self.parent) { + for (var other = alt; other; other = other.parent) { + if (self.base === other.base && self !== other) { return true } + } + } + return false + }; + + BranchID.prototype.sibling = function sibling () { + return new BranchID(this.parent, this.base) + }; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion]; + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchV = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = Object.create(null); + this.backReferenceNames = []; + this.branchID = null; + }; + + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicodeSets = flags.indexOf("v") !== -1; + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + if (unicodeSets && this.parser.options.ecmaVersion >= 15) { + this.switchU = true; + this.switchV = true; + this.switchN = true; + } else { + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchV = false; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; + } + }; + + RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + }; + + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + }; + + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 + }; + + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) + }; + + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) + }; + + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); + }; + + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false + }; + + RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) { + if ( forceU === void 0 ) forceU = false; + + var pos = this.pos; + for (var i = 0, list = chs; i < list.length; i += 1) { + var ch = list[i]; + + var current = this.at(pos, forceU); + if (current === -1 || current !== ch) { + return false + } + pos = this.nextIndex(pos, forceU); + } + this.pos = pos; + return true + }; + + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpFlags = function(state) { + var validFlags = state.validFlags; + var flags = state.flags; + + var u = false; + var v = false; + + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + if (flag === "u") { u = true; } + if (flag === "v") { v = true; } + } + if (this.options.ecmaVersion >= 15 && u && v) { + this.raise(state.start, "Invalid regular expression flag"); + } + }; + + function hasProp(obj) { + for (var _ in obj) { return true } + return false + } + + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) { + state.switchN = true; + this.regexp_pattern(state); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$1.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames = Object.create(null); + state.backReferenceNames.length = 0; + state.branchID = null; + + this.regexp_disjunction(state); + + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + + if (!state.groupNames[name]) { + state.raise("Invalid named capture referenced"); + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$1.regexp_disjunction = function(state) { + var trackDisjunction = this.options.ecmaVersion >= 16; + if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); } + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + if (trackDisjunction) { state.branchID = state.branchID.sibling(); } + this.regexp_alternative(state); + } + if (trackDisjunction) { state.branchID = state.branchID.parent; } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$1.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$1.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$1.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } + } + + state.pos = start; + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$1.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$1.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$1.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$1.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) + }; + pp$1.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */)) { + if (this.options.ecmaVersion >= 16) { + var addModifiers = this.regexp_eatModifiers(state); + var hasHyphen = state.eat(0x2D /* - */); + if (addModifiers || hasHyphen) { + for (var i = 0; i < addModifiers.length; i++) { + var modifier = addModifiers.charAt(i); + if (addModifiers.indexOf(modifier, i + 1) > -1) { + state.raise("Duplicate regular expression modifiers"); + } + } + if (hasHyphen) { + var removeModifiers = this.regexp_eatModifiers(state); + if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) { + state.raise("Invalid regular expression modifiers"); + } + for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) { + var modifier$1 = removeModifiers.charAt(i$1); + if ( + removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 || + addModifiers.indexOf(modifier$1) > -1 + ) { + state.raise("Duplicate regular expression modifiers"); + } + } + } + } + } + if (state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false + }; + // RegularExpressionModifiers :: + // [empty] + // RegularExpressionModifiers RegularExpressionModifier + pp$1.regexp_eatModifiers = function(state) { + var modifiers = ""; + var ch = 0; + while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) { + modifiers += codePointToString(ch); + state.advance(); + } + return modifiers + }; + // RegularExpressionModifier :: one of + // `i` `m` `s` + function isRegularExpressionModifier(ch) { + return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$1.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$1.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$1.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$1.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$1.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true + } + return false + }; + + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$1.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); } + var trackDisjunction = this.options.ecmaVersion >= 16; + var known = state.groupNames[state.lastStringValue]; + if (known) { + if (trackDisjunction) { + for (var i = 0, list = known; i < list.length; i += 1) { + var altID = list[i]; + + if (!altID.separatedFrom(state.branchID)) + { state.raise("Duplicate capture group name"); } + } + } else { + state.raise("Duplicate capture group name"); + } + } + if (trackDisjunction) { + (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID); + } else { + state.groupNames[state.lastStringValue] = true; + } + } + }; + + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false + }; + + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false + }; + + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$1.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ + } + + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$1.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$1.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$1.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$1.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$1.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$1.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$1.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$1.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$1.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false + }; + + // Return values used by character set parsing methods, needed to + // forbid negation of sets that can match strings. + var CharSetNone = 0; // Nothing parsed + var CharSetOk = 1; // Construct parsed, cannot contain strings + var CharSetString = 2; // Construct parsed, can contain strings + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$1.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return CharSetOk + } + + var negate = false; + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + ((negate = ch === 0x50 /* P */) || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + var result; + if ( + state.eat(0x7B /* { */) && + (result = this.regexp_eatUnicodePropertyValueExpression(state)) && + state.eat(0x7D /* } */) + ) { + if (negate && result === CharSetString) { state.raise("Invalid property name"); } + return result + } + state.raise("Invalid property name"); + } + + return CharSetNone + }; + + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } + + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$1.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return CharSetOk + } + } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue) + } + return CharSetNone + }; + + pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!hasOwn(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + + pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk } + if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString } + state.raise("Invalid property name"); + }; + + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$1.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } + + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } + + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$1.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (!state.eat(0x5D /* ] */)) + { state.raise("Unterminated character class"); } + if (negate && result === CharSetString) + { state.raise("Negated character class may contain strings"); } + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassContents + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + pp$1.regexp_classContents = function(state) { + if (state.current() === 0x5D /* ] */) { return CharSetOk } + if (state.switchV) { return this.regexp_classSetExpression(state) } + this.regexp_nonEmptyClassRanges(state); + return CharSetOk + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$1.regexp_nonEmptyClassRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$1.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + + var ch = state.current(); + if (ch !== 0x5D /* ] */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$1.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + + // https://tc39.es/ecma262/#prod-ClassSetExpression + // https://tc39.es/ecma262/#prod-ClassUnion + // https://tc39.es/ecma262/#prod-ClassIntersection + // https://tc39.es/ecma262/#prod-ClassSubtraction + pp$1.regexp_classSetExpression = function(state) { + var result = CharSetOk, subResult; + if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) { + if (subResult === CharSetString) { result = CharSetString; } + // https://tc39.es/ecma262/#prod-ClassIntersection + var start = state.pos; + while (state.eatChars([0x26, 0x26] /* && */)) { + if ( + state.current() !== 0x26 /* & */ && + (subResult = this.regexp_eatClassSetOperand(state)) + ) { + if (subResult !== CharSetString) { result = CharSetOk; } + continue + } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + // https://tc39.es/ecma262/#prod-ClassSubtraction + while (state.eatChars([0x2D, 0x2D] /* -- */)) { + if (this.regexp_eatClassSetOperand(state)) { continue } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + } else { + state.raise("Invalid character in character class"); + } + // https://tc39.es/ecma262/#prod-ClassUnion + for (;;) { + if (this.regexp_eatClassSetRange(state)) { continue } + subResult = this.regexp_eatClassSetOperand(state); + if (!subResult) { return result } + if (subResult === CharSetString) { result = CharSetString; } + } + }; + + // https://tc39.es/ecma262/#prod-ClassSetRange + pp$1.regexp_eatClassSetRange = function(state) { + var start = state.pos; + if (this.regexp_eatClassSetCharacter(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassSetCharacter(state)) { + var right = state.lastIntValue; + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + return true + } + state.pos = start; + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetOperand + pp$1.regexp_eatClassSetOperand = function(state) { + if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk } + return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state) + }; + + // https://tc39.es/ecma262/#prod-NestedClass + pp$1.regexp_eatNestedClass = function(state) { + var start = state.pos; + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (state.eat(0x5D /* ] */)) { + if (negate && result === CharSetString) { + state.raise("Negated character class may contain strings"); + } + return result + } + state.pos = start; + } + if (state.eat(0x5C /* \ */)) { + var result$1 = this.regexp_eatCharacterClassEscape(state); + if (result$1) { + return result$1 + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunction + pp$1.regexp_eatClassStringDisjunction = function(state) { + var start = state.pos; + if (state.eatChars([0x5C, 0x71] /* \q */)) { + if (state.eat(0x7B /* { */)) { + var result = this.regexp_classStringDisjunctionContents(state); + if (state.eat(0x7D /* } */)) { + return result + } + } else { + // Make the same message as V8. + state.raise("Invalid escape"); + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunctionContents + pp$1.regexp_classStringDisjunctionContents = function(state) { + var result = this.regexp_classString(state); + while (state.eat(0x7C /* | */)) { + if (this.regexp_classString(state) === CharSetString) { result = CharSetString; } + } + return result + }; + + // https://tc39.es/ecma262/#prod-ClassString + // https://tc39.es/ecma262/#prod-NonEmptyClassString + pp$1.regexp_classString = function(state) { + var count = 0; + while (this.regexp_eatClassSetCharacter(state)) { count++; } + return count === 1 ? CharSetOk : CharSetString + }; + + // https://tc39.es/ecma262/#prod-ClassSetCharacter + pp$1.regexp_eatClassSetCharacter = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if ( + this.regexp_eatCharacterEscape(state) || + this.regexp_eatClassSetReservedPunctuator(state) + ) { + return true + } + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + state.pos = start; + return false + } + var ch = state.current(); + if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false } + if (isClassSetSyntaxCharacter(ch)) { return false } + state.advance(); + state.lastIntValue = ch; + return true + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedDoublePunctuator + function isClassSetReservedDoublePunctuatorCharacter(ch) { + return ( + ch === 0x21 /* ! */ || + ch >= 0x23 /* # */ && ch <= 0x26 /* & */ || + ch >= 0x2A /* * */ && ch <= 0x2C /* , */ || + ch === 0x2E /* . */ || + ch >= 0x3A /* : */ && ch <= 0x40 /* @ */ || + ch === 0x5E /* ^ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetSyntaxCharacter + function isClassSetSyntaxCharacter(ch) { + return ( + ch === 0x28 /* ( */ || + ch === 0x29 /* ) */ || + ch === 0x2D /* - */ || + ch === 0x2F /* / */ || + ch >= 0x5B /* [ */ && ch <= 0x5D /* ] */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + pp$1.regexp_eatClassSetReservedPunctuator = function(state) { + var ch = state.current(); + if (isClassSetReservedPunctuator(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + function isClassSetReservedPunctuator(ch) { + return ( + ch === 0x21 /* ! */ || + ch === 0x23 /* # */ || + ch === 0x25 /* % */ || + ch === 0x26 /* & */ || + ch === 0x2C /* , */ || + ch === 0x2D /* - */ || + ch >= 0x3A /* : */ && ch <= 0x3E /* > */ || + ch === 0x40 /* @ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$1.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$1.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$1.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start + }; + function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$1.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true + }; + + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. + + var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } + }; + + // ## Tokenizer + + var pp = Parser.prototype; + + // Move to the next token + + pp.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); + }; + + pp.getToken = function() { + this.next(); + return new Token(this) + }; + + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp[Symbol.iterator] = function() { + var this$1$1 = this; + + return { + next: function () { + var token = this$1$1.getToken(); + return { + done: token.type === types$1.eof, + value: token + } + } + } + }; } + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + // Read a single token, updating the parser object's token-related + // properties. + + pp.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } + }; + + pp.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) + }; + + pp.fullCharCodeAt = function(pos) { + var code = this.input.charCodeAt(pos); + if (code <= 0xd7ff || code >= 0xdc00) { return code } + var next = this.input.charCodeAt(pos + 1); + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 + }; + + pp.fullCharCodeAtPos = function() { + return this.fullCharCodeAt(this.pos) + }; + + pp.skipBlockComment = function() { + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) { + ++this.curLine; + pos = this.lineStart = nextBreak; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } + }; + + pp.skipLineComment = function(startSkip) { + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + pp.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + pp.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types$1.ellipsis) + } else { + ++this.pos; + return this.finishToken(types$1.dot) + } + }; + + pp.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.slash, 1) + }; + + pp.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types$1.star : types$1.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types$1.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(tokentype, size) + }; + + pp.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types$1.assign, 3) } + } + return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1) + }; + + pp.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.bitwiseXOR, 1) + }; + + pp.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) + }; + + pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) +}; + +pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // ` + +- [Install](#install) +- [Usage](#usage) + - [Simple Parsing](#simple-parsing) + - [Display Help Message and Version](#display-help-message-and-version) + - [Command-specific Options](#command-specific-options) + - [Dash in option names](#dash-in-option-names) + - [Brackets](#brackets) + - [Negated Options](#negated-options) + - [Variadic Arguments](#variadic-arguments) + - [Dot-nested Options](#dot-nested-options) + - [Default Command](#default-command) + - [Supply an array as option value](#supply-an-array-as-option-value) + - [Error Handling](#error-handling) + - [With TypeScript](#with-typescript) + - [With Deno](#with-deno) +- [Projects Using CAC](#projects-using-cac) +- [References](#references) + - [CLI Instance](#cli-instance) + - [cac(name?)](#cacname) + - [cli.command(name, description, config?)](#clicommandname-description-config) + - [cli.option(name, description, config?)](#clioptionname-description-config) + - [cli.parse(argv?)](#cliparseargv) + - [cli.version(version, customFlags?)](#cliversionversion-customflags) + - [cli.help(callback?)](#clihelpcallback) + - [cli.outputHelp()](#clioutputhelp) + - [cli.usage(text)](#cliusagetext) + - [Command Instance](#command-instance) + - [command.option()](#commandoption) + - [command.action(callback)](#commandactioncallback) + - [command.alias(name)](#commandaliasname) + - [command.allowUnknownOptions()](#commandallowunknownoptions) + - [command.example(example)](#commandexampleexample) + - [command.usage(text)](#commandusagetext) + - [Events](#events) +- [FAQ](#faq) + - [How is the name written and pronounced?](#how-is-the-name-written-and-pronounced) + - [Why not use Commander.js?](#why-not-use-commanderjs) +- [Project Stats](#project-stats) +- [Contributing](#contributing) +- [Author](#author) + + + +## Install + +```bash +yarn add cac +``` + +## Usage + +### Simple Parsing + +Use CAC as simple argument parser: + +```js +// examples/basic-usage.js +const cli = require('cac')() + +cli.option('--type ', 'Choose a project type', { + default: 'node', +}) + +const parsed = cli.parse() + +console.log(JSON.stringify(parsed, null, 2)) +``` + +2018-11-26 12 28 03 + +### Display Help Message and Version + +```js +// examples/help.js +const cli = require('cac')() + +cli.option('--type [type]', 'Choose a project type', { + default: 'node', +}) +cli.option('--name ', 'Provide your name') + +cli.command('lint [...files]', 'Lint files').action((files, options) => { + console.log(files, options) +}) + +// Display help message when `-h` or `--help` appears +cli.help() +// Display version number when `-v` or `--version` appears +// It's also used in help message +cli.version('0.0.0') + +cli.parse() +``` + +2018-11-25 8 21 14 + +### Command-specific Options + +You can attach options to a command. + +```js +const cli = require('cac')() + +cli + .command('rm ', 'Remove a dir') + .option('-r, --recursive', 'Remove recursively') + .action((dir, options) => { + console.log('remove ' + dir + (options.recursive ? ' recursively' : '')) + }) + +cli.help() + +cli.parse() +``` + +A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated. If you really want to use unknown options, use [`command.allowUnknownOptions`](#commandallowunknownoptions). + +command options + +### Dash in option names + +Options in kebab-case should be referenced in camelCase in your code: + +```js +cli + .command('dev', 'Start dev server') + .option('--clear-screen', 'Clear screen') + .action((options) => { + console.log(options.clearScreen) + }) +``` + +In fact `--clear-screen` and `--clearScreen` are both mapped to `options.clearScreen`. + +### Brackets + +When using brackets in command name, angled brackets indicate required command arguments, while square bracket indicate optional arguments. + +When using brackets in option name, angled brackets indicate that a string / number value is required, while square bracket indicate that the value can also be `true`. + +```js +const cli = require('cac')() + +cli + .command('deploy ', 'Deploy a folder to AWS') + .option('--scale [level]', 'Scaling level') + .action((folder, options) => { + // ... + }) + +cli + .command('build [project]', 'Build a project') + .option('--out ', 'Output directory') + .action((folder, options) => { + // ... + }) + +cli.parse() +``` + +### Negated Options + +To allow an option whose value is `false`, you need to manually specify a negated option: + +```js +cli + .command('build [project]', 'Build a project') + .option('--no-config', 'Disable config file') + .option('--config ', 'Use a custom config file') +``` + +This will let CAC set the default value of `config` to true, and you can use `--no-config` flag to set it to `false`. + +### Variadic Arguments + +The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to add `...` to the start of argument name, just like the rest operator in JavaScript. Here is an example: + +```js +const cli = require('cac')() + +cli + .command('build [...otherFiles]', 'Build your app') + .option('--foo', 'Foo option') + .action((entry, otherFiles, options) => { + console.log(entry) + console.log(otherFiles) + console.log(options) + }) + +cli.help() + +cli.parse() +``` + +2018-11-25 8 25 30 + +### Dot-nested Options + +Dot-nested options will be merged into a single option. + +```js +const cli = require('cac')() + +cli + .command('build', 'desc') + .option('--env ', 'Set envs') + .example('--env.API_SECRET xxx') + .action((options) => { + console.log(options) + }) + +cli.help() + +cli.parse() +``` + +2018-11-25 9 37 53 + +### Default Command + +Register a command that will be used when no other command is matched. + +```js +const cli = require('cac')() + +cli + // Simply omit the command name, just brackets + .command('[...files]', 'Build files') + .option('--minimize', 'Minimize output') + .action((files, options) => { + console.log(files) + console.log(options.minimize) + }) + +cli.parse() +``` + +### Supply an array as option value + +```bash +node cli.js --include project-a +# The parsed options will be: +# { include: 'project-a' } + +node cli.js --include project-a --include project-b +# The parsed options will be: +# { include: ['project-a', 'project-b'] } +``` + +### Error Handling + +To handle command errors globally: + +```js +try { + // Parse CLI args without running the command + cli.parse(process.argv, { run: false }) + // Run the command yourself + // You only need `await` when your command action returns a Promise + await cli.runMatchedCommand() +} catch (error) { + // Handle error here.. + // e.g. + // console.error(error.stack) + // process.exit(1) +} +``` + +### With TypeScript + +First you need `@types/node` to be installed as a dev dependency in your project: + +```bash +yarn add @types/node --dev +``` + +Then everything just works out of the box: + +```js +const { cac } = require('cac') +// OR ES modules +import { cac } from 'cac' +``` + +### With Deno + +```ts +import { cac } from 'https://unpkg.com/cac/mod.ts' + +const cli = cac('my-program') +``` + +## Projects Using CAC + +Projects that use **CAC**: + +- [VuePress](https://github.com/vuejs/vuepress): :memo: Minimalistic Vue-powered static site generator. +- [SAO](https://github.com/egoist/sao): ⚔️ Futuristic scaffolding tool. +- [DocPad](https://github.com/docpad/docpad): 🏹 Powerful Static Site Generator. +- [Poi](https://github.com/egoist/poi): ⚡️ Delightful web development. +- [bili](https://github.com/egoist/bili): 🥂 Schweizer Armeemesser for bundling JavaScript libraries. +- [Lad](https://github.com/ladjs/lad): 👦 Lad scaffolds a Koa webapp and API framework for Node.js. +- [Lass](https://github.com/lassjs/lass): 💁🏻 Scaffold a modern package boilerplate for Node.js. +- [Foy](https://github.com/zaaack/foy): 🏗 A lightweight and modern task runner and build tool for general purpose. +- [Vuese](https://github.com/vuese/vuese): 🤗 One-stop solution for vue component documentation. +- [NUT](https://github.com/nut-project/nut): 🌰 A framework born for microfrontends +- Feel free to add yours here... + +## References + +**💁 Check out [the generated docs](https://cac-api-doc.egoist.sh/classes/_cac_.cac.html) from source code if you want a more in-depth API references.** + +Below is a brief overview. + +### CLI Instance + +CLI instance is created by invoking the `cac` function: + +```js +const cac = require('cac') +const cli = cac() +``` + +#### cac(name?) + +Create a CLI instance, optionally specify the program name which will be used to display in help and version message. When not set we use the basename of `argv[1]`. + +#### cli.command(name, description, config?) + +- Type: `(name: string, description: string) => Command` + +Create a command instance. + +The option also accepts a third argument `config` for additional command config: + +- `config.allowUnknownOptions`: `boolean` Allow unknown options in this command. +- `config.ignoreOptionDefaultValue`: `boolean` Don't use the options's default value in parsed options, only display them in help message. + +#### cli.option(name, description, config?) + +- Type: `(name: string, description: string, config?: OptionConfig) => CLI` + +Add a global option. + +The option also accepts a third argument `config` for additional option config: + +- `config.default`: Default value for the option. +- `config.type`: `any[]` When set to `[]`, the option value returns an array type. You can also use a conversion function such as `[String]`, which will invoke the option value with `String`. + +#### cli.parse(argv?) + +- Type: `(argv = process.argv) => ParsedArgv` + +```ts +interface ParsedArgv { + args: string[] + options: { + [k: string]: any + } +} +``` + +When this method is called, `cli.rawArgs` `cli.args` `cli.options` `cli.matchedCommand` will also be available. + +#### cli.version(version, customFlags?) + +- Type: `(version: string, customFlags = '-v, --version') => CLI` + +Output version number when `-v, --version` flag appears. + +#### cli.help(callback?) + +- Type: `(callback?: HelpCallback) => CLI` + +Output help message when `-h, --help` flag appears. + +Optional `callback` allows post-processing of help text before it is displayed: + +```ts +type HelpCallback = (sections: HelpSection[]) => void + +interface HelpSection { + title?: string + body: string +} +``` + +#### cli.outputHelp() + +- Type: `() => CLI` + +Output help message. + +#### cli.usage(text) + +- Type: `(text: string) => CLI` + +Add a global usage text. This is not used by sub-commands. + +### Command Instance + +Command instance is created by invoking the `cli.command` method: + +```js +const command = cli.command('build [...files]', 'Build given files') +``` + +#### command.option() + +Basically the same as `cli.option` but this adds the option to specific command. + +#### command.action(callback) + +- Type: `(callback: ActionCallback) => Command` + +Use a callback function as the command action when the command matches user inputs. + +```ts +type ActionCallback = ( + // Parsed CLI args + // The last arg will be an array if it's a variadic argument + ...args: string | string[] | number | number[] + // Parsed CLI options + options: Options +) => any + +interface Options { + [k: string]: any +} +``` + +#### command.alias(name) + +- Type: `(name: string) => Command` + +Add an alias name to this command, the `name` here can't contain brackets. + +#### command.allowUnknownOptions() + +- Type: `() => Command` + +Allow unknown options in this command, by default CAC will log an error when unknown options are used. + +#### command.example(example) + +- Type: `(example: CommandExample) => Command` + +Add an example which will be displayed at the end of help message. + +```ts +type CommandExample = ((name: string) => string) | string +``` + +#### command.usage(text) + +- Type: `(text: string) => Command` + +Add a usage text for this command. + +### Events + +Listen to commands: + +```js +// Listen to the `foo` command +cli.on('command:foo', () => { + // Do something +}) + +// Listen to the default command +cli.on('command:!', () => { + // Do something +}) + +// Listen to unknown commands +cli.on('command:*', () => { + console.error('Invalid command: %s', cli.args.join(' ')) + process.exit(1) +}) +``` + +## FAQ + +### How is the name written and pronounced? + +CAC, or cac, pronounced `C-A-C`. + +This project is dedicated to our lovely C.C. sama. Maybe CAC stands for C&C as well :P + + + +### Why not use Commander.js? + +CAC is very similar to Commander.js, while the latter does not support dot nested options, i.e. something like `--env.API_SECRET foo`. Besides, you can't use unknown options in Commander.js either. + +_And maybe more..._ + +Basically I made CAC to fulfill my own needs for building CLI apps like [Poi](https://poi.js.org), [SAO](https://sao.vercel.app) and all my CLI apps. It's small, simple but powerful :P + +## Project Stats + +![Alt](https://repobeats.axiom.co/api/embed/58caf6203631bcdb9bbe22f0728a0af1683dc0bb.svg 'Repobeats analytics image') + +## Contributing + +1. Fork it! +2. Create your feature branch: `git checkout -b my-new-feature` +3. Commit your changes: `git commit -am 'Add some feature'` +4. Push to the branch: `git push origin my-new-feature` +5. Submit a pull request :D + +## Author + +**CAC** © [EGOIST](https://github.com/egoist), Released under the [MIT](./LICENSE) License.
+Authored and maintained by egoist with help from contributors ([list](https://github.com/cacjs/cac/contributors)). + +> [Website](https://egoist.sh) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\_egoistlily](https://twitter.com/_egoistlily) diff --git a/node_modules/cac/deno/CAC.ts b/node_modules/cac/deno/CAC.ts new file mode 100644 index 0000000..0ced3b1 --- /dev/null +++ b/node_modules/cac/deno/CAC.ts @@ -0,0 +1,331 @@ +import { EventEmitter } from "https://deno.land/std@0.114.0/node/events.ts"; +import mri from "https://cdn.skypack.dev/mri"; +import Command, { GlobalCommand, CommandConfig, HelpCallback, CommandExample } from "./Command.ts"; +import { OptionConfig } from "./Option.ts"; +import { getMriOptions, setDotProp, setByType, getFileName, camelcaseOptionName } from "./utils.ts"; +import { processArgs } from "./deno.ts"; +interface ParsedArgv { + args: ReadonlyArray; + options: { + [k: string]: any; + }; +} + +class CAC extends EventEmitter { + /** The program name to display in help and version message */ + name: string; + commands: Command[]; + globalCommand: GlobalCommand; + matchedCommand?: Command; + matchedCommandName?: string; + /** + * Raw CLI arguments + */ + + rawArgs: string[]; + /** + * Parsed CLI arguments + */ + + args: ParsedArgv['args']; + /** + * Parsed CLI options, camelCased + */ + + options: ParsedArgv['options']; + showHelpOnExit?: boolean; + showVersionOnExit?: boolean; + /** + * @param name The program name to display in help and version message + */ + + constructor(name = '') { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(' [options]'); + } + /** + * Add a global usage text. + * + * This is not used by sub-commands. + */ + + + usage(text: string) { + this.globalCommand.usage(text); + return this; + } + /** + * Add a sub-command + */ + + + command(rawName: string, description?: string, config?: CommandConfig) { + const command = new Command(rawName, description || '', config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + /** + * Add a global CLI option. + * + * Which is also applied to sub-commands. + */ + + + option(rawName: string, description: string, config?: OptionConfig) { + this.globalCommand.option(rawName, description, config); + return this; + } + /** + * Show help message when `-h, --help` flags appear. + * + */ + + + help(callback?: HelpCallback) { + this.globalCommand.option('-h, --help', 'Display this message'); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + /** + * Show version number when `-v, --version` flags appear. + * + */ + + + version(version: string, customFlags = '-v, --version') { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + /** + * Add a global example. + * + * This example added here will not be used by sub-commands. + */ + + + example(example: CommandExample) { + this.globalCommand.example(example); + return this; + } + /** + * Output the corresponding help message + * When a sub-command is matched, output the help message for the command + * Otherwise output the global one. + * + */ + + + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + /** + * Output the version number. + * + */ + + + outputVersion() { + this.globalCommand.outputVersion(); + } + + private setParsedInfo({ + args, + options + }: ParsedArgv, matchedCommand?: Command, matchedCommandName?: string) { + this.args = args; + this.options = options; + + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + + return this; + } + + unsetMatchedCommand() { + this.matchedCommand = undefined; + this.matchedCommandName = undefined; + } + /** + * Parse argv + */ + + + parse(argv = processArgs, { + /** Whether to run the action for matched command */ + run = true + } = {}): ParsedArgv { + this.rawArgs = argv; + + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : 'cli'; + } + + let shouldParse = true; // Search sub-commands + + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = { ...parsed, + args: parsed.args.slice(1) + }; + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + + if (shouldParse) { + // Search the default command + for (const command of this.commands) { + if (command.name === '') { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + + const parsedArgv = { + args: this.args, + options: this.options + }; + + if (run) { + this.runMatchedCommand(); + } + + if (!this.matchedCommand && this.args[0]) { + this.emit('command:*'); + } + + return parsedArgv; + } + + private mri(argv: string[], + /** Matched command */ + command?: Command): ParsedArgv { + // All added options + const cliOptions = [...this.globalCommand.options, ...(command ? command.options : [])]; + const mriOptions = getMriOptions(cliOptions); // Extract everything after `--` since mri doesn't support it + + let argsAfterDoubleDashes: string[] = []; + const doubleDashesIndex = argv.indexOf('--'); + + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + + let parsed = mri(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return { ...res, + [camelcaseOptionName(name)]: parsed[name] + }; + }, { + _: [] + }); + const args = parsed._; + const options: { + [k: string]: any; + } = { + '--': argsAfterDoubleDashes + }; // Set option default value + + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== undefined) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } // If options type is defined + + + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === undefined) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]['shouldTransform'] = true; + transforms[cliOption.name]['transformFunction'] = cliOption.config.type[0]; + } + } + } // Set option values (support dot-nested property name) + + + for (const key of Object.keys(parsed)) { + if (key !== '_') { + const keys = key.split('.'); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + + return { + args, + options + }; + } + + runMatchedCommand() { + const { + args, + options, + matchedCommand: command + } = this; + if (!command || !command.commandAction) return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs: any[] = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } + +} + +export default CAC; \ No newline at end of file diff --git a/node_modules/cac/deno/Command.ts b/node_modules/cac/deno/Command.ts new file mode 100644 index 0000000..3fd04a0 --- /dev/null +++ b/node_modules/cac/deno/Command.ts @@ -0,0 +1,269 @@ +import CAC from "./CAC.ts"; +import Option, { OptionConfig } from "./Option.ts"; +import { removeBrackets, findAllBrackets, findLongest, padRight, CACError } from "./utils.ts"; +import { platformInfo } from "./deno.ts"; +interface CommandArg { + required: boolean; + value: string; + variadic: boolean; +} +interface HelpSection { + title?: string; + body: string; +} +interface CommandConfig { + allowUnknownOptions?: boolean; + ignoreOptionDefaultValue?: boolean; +} +type HelpCallback = (sections: HelpSection[]) => void | HelpSection[]; +type CommandExample = ((bin: string) => string) | string; + +class Command { + options: Option[]; + aliasNames: string[]; + /* Parsed command name */ + + name: string; + args: CommandArg[]; + commandAction?: (...args: any[]) => any; + usageText?: string; + versionNumber?: string; + examples: CommandExample[]; + helpCallback?: HelpCallback; + globalCommand?: GlobalCommand; + + constructor(public rawName: string, public description: string, public config: CommandConfig = {}, public cli: CAC) { + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + + usage(text: string) { + this.usageText = text; + return this; + } + + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + + version(version: string, customFlags = '-v, --version') { + this.versionNumber = version; + this.option(customFlags, 'Display version number'); + return this; + } + + example(example: CommandExample) { + this.examples.push(example); + return this; + } + /** + * Add a option for this command + * @param rawName Raw option name(s) + * @param description Option description + * @param config Option config + */ + + + option(rawName: string, description: string, config?: OptionConfig) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + + alias(name: string) { + this.aliasNames.push(name); + return this; + } + + action(callback: (...args: any[]) => any) { + this.commandAction = callback; + return this; + } + /** + * Check if a command name is matched by this command + * @param name Command name + */ + + + isMatched(name: string) { + return this.name === name || this.aliasNames.includes(name); + } + + get isDefaultCommand() { + return this.name === '' || this.aliasNames.includes('!'); + } + + get isGlobalCommand(): boolean { + return this instanceof GlobalCommand; + } + /** + * Check if an option is registered in this command + * @param name Option name + */ + + + hasOption(name: string) { + name = name.split('.')[0]; + return this.options.find(option => { + return option.names.includes(name); + }); + } + + outputHelp() { + const { + name, + commands + } = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections: HelpSection[] = [{ + body: `${name}${versionNumber ? `/${versionNumber}` : ''}` + }]; + sections.push({ + title: 'Usage', + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + + if (showCommands) { + const longestCommandName = findLongest(commands.map(command => command.rawName)); + sections.push({ + title: 'Commands', + body: commands.map(command => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join('\n') + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map(command => ` $ ${name}${command.name === '' ? '' : ` ${command.name}`} --help`).join('\n') + }); + } + + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...(globalOptions || [])]; + + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter(option => option.name !== 'version'); + } + + if (options.length > 0) { + const longestOptionName = findLongest(options.map(option => option.rawName)); + sections.push({ + title: 'Options', + body: options.map(option => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? '' : `(default: ${option.config.default})`}`; + }).join('\n') + }); + } + + if (this.examples.length > 0) { + sections.push({ + title: 'Examples', + body: this.examples.map(example => { + if (typeof example === 'function') { + return example(name); + } + + return example; + }).join('\n') + }); + } + + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + + console.log(sections.map(section => { + return section.title ? `${section.title}:\n${section.body}` : section.body; + }).join('\n\n')); + } + + outputVersion() { + const { + name + } = this.cli; + const { + versionNumber + } = this.cli.globalCommand; + + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + + checkRequiredArgs() { + const minimalArgsCount = this.args.filter(arg => arg.required).length; + + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + /** + * Check if the parsed options contain any unknown options + * + * Exit and output error when true + */ + + + checkUnknownOptions() { + const { + options, + globalCommand + } = this.cli; + + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== '--' && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + /** + * Check if the required string-type options exist + */ + + + checkOptionValue() { + const { + options: parsedOptions, + globalCommand + } = this.cli; + const options = [...globalCommand.options, ...this.options]; + + for (const option of options) { + const value = parsedOptions[option.name.split('.')[0]]; // Check required option value + + if (option.required) { + const hasNegated = options.some(o => o.negated && o.names.includes(option.name)); + + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } + +} + +class GlobalCommand extends Command { + constructor(cli: CAC) { + super('@@global@@', '', {}, cli); + } + +} + +export type { HelpCallback, CommandExample, CommandConfig }; +export { GlobalCommand }; +export default Command; \ No newline at end of file diff --git a/node_modules/cac/deno/Option.ts b/node_modules/cac/deno/Option.ts new file mode 100644 index 0000000..ee7ed2d --- /dev/null +++ b/node_modules/cac/deno/Option.ts @@ -0,0 +1,52 @@ +import { removeBrackets, camelcaseOptionName } from "./utils.ts"; +interface OptionConfig { + default?: any; + type?: any[]; +} +export default class Option { + /** Option name */ + name: string; + /** Option name and aliases */ + + names: string[]; + isBoolean?: boolean; // `required` will be a boolean for options with brackets + + required?: boolean; + config: OptionConfig; + negated: boolean; + + constructor(public rawName: string, public description: string, config?: OptionConfig) { + this.config = Object.assign({}, config); // You may use cli.option('--env.* [value]', 'desc') to denote a dot-nested option + + rawName = rawName.replace(/\.\*/g, ''); + this.negated = false; + this.names = removeBrackets(rawName).split(',').map((v: string) => { + let name = v.trim().replace(/^-{1,2}/, ''); + + if (name.startsWith('no-')) { + this.negated = true; + name = name.replace(/^no-/, ''); + } + + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); // Sort names + // Use the longest name (last one) as actual option name + + this.name = this.names[this.names.length - 1]; + + if (this.negated && this.config.default == null) { + this.config.default = true; + } + + if (rawName.includes('<')) { + this.required = true; + } else if (rawName.includes('[')) { + this.required = false; + } else { + // No arg needed, it's boolean flag + this.isBoolean = true; + } + } + +} +export type { OptionConfig }; \ No newline at end of file diff --git a/node_modules/cac/deno/deno.ts b/node_modules/cac/deno/deno.ts new file mode 100644 index 0000000..2f8e7d9 --- /dev/null +++ b/node_modules/cac/deno/deno.ts @@ -0,0 +1,4 @@ +// Ignore the TypeScript errors +// Since this file will only be used in Deno runtime +export const processArgs = ['deno', 'cli'].concat(Deno.args); +export const platformInfo = `${Deno.build.os}-${Deno.build.arch} deno-${Deno.version.deno}`; \ No newline at end of file diff --git a/node_modules/cac/deno/index.ts b/node_modules/cac/deno/index.ts new file mode 100644 index 0000000..55aa29b --- /dev/null +++ b/node_modules/cac/deno/index.ts @@ -0,0 +1,10 @@ +import CAC from "./CAC.ts"; +import Command from "./Command.ts"; +/** + * @param name The program name to display in help and version message + */ + +const cac = (name = '') => new CAC(name); + +export default cac; +export { cac, CAC, Command }; \ No newline at end of file diff --git a/node_modules/cac/deno/utils.ts b/node_modules/cac/deno/utils.ts new file mode 100644 index 0000000..d75847b --- /dev/null +++ b/node_modules/cac/deno/utils.ts @@ -0,0 +1,145 @@ +import Option from "./Option.ts"; +export const removeBrackets = (v: string) => v.replace(/[<[].+/, '').trim(); +export const findAllBrackets = (v: string) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + + const parse = (match: string[]) => { + let variadic = false; + let value = match[1]; + + if (value.startsWith('...')) { + value = value.slice(3); + variadic = true; + } + + return { + required: match[0].startsWith('<'), + value, + variadic + }; + }; + + let angledMatch; + + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + + let squareMatch; + + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + + return res; +}; +interface MriOptions { + alias: { + [k: string]: string[]; + }; + boolean: string[]; +} +export const getMriOptions = (options: Option[]) => { + const result: MriOptions = { + alias: {}, + boolean: [] + }; + + for (const [index, option] of options.entries()) { + // We do not set default values in mri options + // Since its type (typeof) will be used to cast parsed arguments. + // Which mean `--foo foo` will be parsed as `{foo: true}` if we have `{default:{foo: true}}` + // Set alias + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } // Set boolean + + + if (option.isBoolean) { + if (option.negated) { + // For negated option + // We only set it to `boolean` type when there's no string-type option with the same name + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some(name => option.names.includes(name)) && typeof o.required === 'boolean'; + }); + + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + + return result; +}; +export const findLongest = (arr: string[]) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +export const padRight = (str: string, length: number) => { + return str.length >= length ? str : `${str}${' '.repeat(length - str.length)}`; +}; +export const camelcase = (input: string) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +export const setDotProp = (obj: { + [k: string]: any; +}, keys: string[], val: any) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf('.') || !(+keys[i + 1] > -1) ? {} : []; + } +}; +export const setByType = (obj: { + [k: string]: any; +}, transforms: { + [k: string]: any; +}) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + + if (typeof transform.transformFunction === 'function') { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +export const getFileName = (input: string) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ''; +}; +export const camelcaseOptionName = (name: string) => { + // Camelcase the option name + // Don't camelcase anything after the dot `.` + return name.split('.').map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join('.'); +}; +export class CACError extends Error { + constructor(message: string) { + super(message); + this.name = this.constructor.name; + + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } + +} \ No newline at end of file diff --git a/node_modules/cac/dist/index.d.ts b/node_modules/cac/dist/index.d.ts new file mode 100644 index 0000000..84dcb66 --- /dev/null +++ b/node_modules/cac/dist/index.d.ts @@ -0,0 +1,191 @@ +import { EventEmitter } from 'events'; + +interface OptionConfig { + default?: any; + type?: any[]; +} +declare class Option { + rawName: string; + description: string; + /** Option name */ + name: string; + /** Option name and aliases */ + names: string[]; + isBoolean?: boolean; + required?: boolean; + config: OptionConfig; + negated: boolean; + constructor(rawName: string, description: string, config?: OptionConfig); +} + +interface CommandArg { + required: boolean; + value: string; + variadic: boolean; +} +interface HelpSection { + title?: string; + body: string; +} +interface CommandConfig { + allowUnknownOptions?: boolean; + ignoreOptionDefaultValue?: boolean; +} +declare type HelpCallback = (sections: HelpSection[]) => void | HelpSection[]; +declare type CommandExample = ((bin: string) => string) | string; +declare class Command { + rawName: string; + description: string; + config: CommandConfig; + cli: CAC; + options: Option[]; + aliasNames: string[]; + name: string; + args: CommandArg[]; + commandAction?: (...args: any[]) => any; + usageText?: string; + versionNumber?: string; + examples: CommandExample[]; + helpCallback?: HelpCallback; + globalCommand?: GlobalCommand; + constructor(rawName: string, description: string, config: CommandConfig, cli: CAC); + usage(text: string): this; + allowUnknownOptions(): this; + ignoreOptionDefaultValue(): this; + version(version: string, customFlags?: string): this; + example(example: CommandExample): this; + /** + * Add a option for this command + * @param rawName Raw option name(s) + * @param description Option description + * @param config Option config + */ + option(rawName: string, description: string, config?: OptionConfig): this; + alias(name: string): this; + action(callback: (...args: any[]) => any): this; + /** + * Check if a command name is matched by this command + * @param name Command name + */ + isMatched(name: string): boolean; + get isDefaultCommand(): boolean; + get isGlobalCommand(): boolean; + /** + * Check if an option is registered in this command + * @param name Option name + */ + hasOption(name: string): Option | undefined; + outputHelp(): void; + outputVersion(): void; + checkRequiredArgs(): void; + /** + * Check if the parsed options contain any unknown options + * + * Exit and output error when true + */ + checkUnknownOptions(): void; + /** + * Check if the required string-type options exist + */ + checkOptionValue(): void; +} +declare class GlobalCommand extends Command { + constructor(cli: CAC); +} + +interface ParsedArgv { + args: ReadonlyArray; + options: { + [k: string]: any; + }; +} +declare class CAC extends EventEmitter { + /** The program name to display in help and version message */ + name: string; + commands: Command[]; + globalCommand: GlobalCommand; + matchedCommand?: Command; + matchedCommandName?: string; + /** + * Raw CLI arguments + */ + rawArgs: string[]; + /** + * Parsed CLI arguments + */ + args: ParsedArgv['args']; + /** + * Parsed CLI options, camelCased + */ + options: ParsedArgv['options']; + showHelpOnExit?: boolean; + showVersionOnExit?: boolean; + /** + * @param name The program name to display in help and version message + */ + constructor(name?: string); + /** + * Add a global usage text. + * + * This is not used by sub-commands. + */ + usage(text: string): this; + /** + * Add a sub-command + */ + command(rawName: string, description?: string, config?: CommandConfig): Command; + /** + * Add a global CLI option. + * + * Which is also applied to sub-commands. + */ + option(rawName: string, description: string, config?: OptionConfig): this; + /** + * Show help message when `-h, --help` flags appear. + * + */ + help(callback?: HelpCallback): this; + /** + * Show version number when `-v, --version` flags appear. + * + */ + version(version: string, customFlags?: string): this; + /** + * Add a global example. + * + * This example added here will not be used by sub-commands. + */ + example(example: CommandExample): this; + /** + * Output the corresponding help message + * When a sub-command is matched, output the help message for the command + * Otherwise output the global one. + * + */ + outputHelp(): void; + /** + * Output the version number. + * + */ + outputVersion(): void; + private setParsedInfo; + unsetMatchedCommand(): void; + /** + * Parse argv + */ + parse(argv?: string[], { + /** Whether to run the action for matched command */ + run, }?: { + run?: boolean | undefined; + }): ParsedArgv; + private mri; + runMatchedCommand(): any; +} + +/** + * @param name The program name to display in help and version message + */ +declare const cac: (name?: string) => CAC; + +export default cac; +export { CAC, Command, cac }; diff --git a/node_modules/cac/dist/index.js b/node_modules/cac/dist/index.js new file mode 100644 index 0000000..8582dbf --- /dev/null +++ b/node_modules/cac/dist/index.js @@ -0,0 +1,623 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var events = require('events'); + +function toArr(any) { + return any == null ? [] : Array.isArray(any) ? any : [any]; +} + +function toVal(out, key, val, opts) { + var x, old=out[key], nxt=( + !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) + : typeof val === 'boolean' ? val + : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) + : (x = +val,x * 0 === 0) ? x : val + ); + out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); +} + +function mri2 (args, opts) { + args = args || []; + opts = opts || {}; + + var k, arr, arg, name, val, out={ _:[] }; + var i=0, j=0, idx=0, len=args.length; + + const alibi = opts.alias !== void 0; + const strict = opts.unknown !== void 0; + const defaults = opts.default !== void 0; + + opts.alias = opts.alias || {}; + opts.string = toArr(opts.string); + opts.boolean = toArr(opts.boolean); + + if (alibi) { + for (k in opts.alias) { + arr = opts.alias[k] = toArr(opts.alias[k]); + for (i=0; i < arr.length; i++) { + (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); + } + } + } + + for (i=opts.boolean.length; i-- > 0;) { + arr = opts.alias[opts.boolean[i]] || []; + for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]); + } + + for (i=opts.string.length; i-- > 0;) { + arr = opts.alias[opts.string[i]] || []; + for (j=arr.length; j-- > 0;) opts.string.push(arr[j]); + } + + if (defaults) { + for (k in opts.default) { + name = typeof opts.default[k]; + arr = opts.alias[k] = opts.alias[k] || []; + if (opts[name] !== void 0) { + opts[name].push(k); + for (i=0; i < arr.length; i++) { + opts[name].push(arr[i]); + } + } + } + } + + const keys = strict ? Object.keys(opts.alias) : []; + + for (i=0; i < len; i++) { + arg = args[i]; + + if (arg === '--') { + out._ = out._.concat(args.slice(++i)); + break; + } + + for (j=0; j < arg.length; j++) { + if (arg.charCodeAt(j) !== 45) break; // "-" + } + + if (j === 0) { + out._.push(arg); + } else if (arg.substring(j, j + 3) === 'no-') { + name = arg.substring(j + 3); + if (strict && !~keys.indexOf(name)) { + return opts.unknown(arg); + } + out[name] = false; + } else { + for (idx=j+1; idx < arg.length; idx++) { + if (arg.charCodeAt(idx) === 61) break; // "=" + } + + name = arg.substring(j, idx); + val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); + arr = (j === 2 ? [name] : name); + + for (idx=0; idx < arr.length; idx++) { + name = arr[idx]; + if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); + toVal(out, name, (idx + 1 < arr.length) || val, opts); + } + } + } + + if (defaults) { + for (k in opts.default) { + if (out[k] === void 0) { + out[k] = opts.default[k]; + } + } + } + + if (alibi) { + for (k in out) { + arr = opts.alias[k] || []; + while (arr.length > 0) { + out[arr.shift()] = out[k]; + } + } + } + + return out; +} + +const removeBrackets = (v) => v.replace(/[<[].+/, "").trim(); +const findAllBrackets = (v) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + const parse = (match) => { + let variadic = false; + let value = match[1]; + if (value.startsWith("...")) { + value = value.slice(3); + variadic = true; + } + return { + required: match[0].startsWith("<"), + value, + variadic + }; + }; + let angledMatch; + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + let squareMatch; + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + return res; +}; +const getMriOptions = (options) => { + const result = {alias: {}, boolean: []}; + for (const [index, option] of options.entries()) { + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } + if (option.isBoolean) { + if (option.negated) { + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean"; + }); + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + return result; +}; +const findLongest = (arr) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +const padRight = (str, length) => { + return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`; +}; +const camelcase = (input) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +const setDotProp = (obj, keys, val) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []; + } +}; +const setByType = (obj, transforms) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + if (typeof transform.transformFunction === "function") { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +const getFileName = (input) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ""; +}; +const camelcaseOptionName = (name) => { + return name.split(".").map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join("."); +}; +class CACError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } +} + +class Option { + constructor(rawName, description, config) { + this.rawName = rawName; + this.description = description; + this.config = Object.assign({}, config); + rawName = rawName.replace(/\.\*/g, ""); + this.negated = false; + this.names = removeBrackets(rawName).split(",").map((v) => { + let name = v.trim().replace(/^-{1,2}/, ""); + if (name.startsWith("no-")) { + this.negated = true; + name = name.replace(/^no-/, ""); + } + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); + this.name = this.names[this.names.length - 1]; + if (this.negated && this.config.default == null) { + this.config.default = true; + } + if (rawName.includes("<")) { + this.required = true; + } else if (rawName.includes("[")) { + this.required = false; + } else { + this.isBoolean = true; + } + } +} + +const processArgs = process.argv; +const platformInfo = `${process.platform}-${process.arch} node-${process.version}`; + +class Command { + constructor(rawName, description, config = {}, cli) { + this.rawName = rawName; + this.description = description; + this.config = config; + this.cli = cli; + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + usage(text) { + this.usageText = text; + return this; + } + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.versionNumber = version; + this.option(customFlags, "Display version number"); + return this; + } + example(example) { + this.examples.push(example); + return this; + } + option(rawName, description, config) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + alias(name) { + this.aliasNames.push(name); + return this; + } + action(callback) { + this.commandAction = callback; + return this; + } + isMatched(name) { + return this.name === name || this.aliasNames.includes(name); + } + get isDefaultCommand() { + return this.name === "" || this.aliasNames.includes("!"); + } + get isGlobalCommand() { + return this instanceof GlobalCommand; + } + hasOption(name) { + name = name.split(".")[0]; + return this.options.find((option) => { + return option.names.includes(name); + }); + } + outputHelp() { + const {name, commands} = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections = [ + { + body: `${name}${versionNumber ? `/${versionNumber}` : ""}` + } + ]; + sections.push({ + title: "Usage", + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + if (showCommands) { + const longestCommandName = findLongest(commands.map((command) => command.rawName)); + sections.push({ + title: "Commands", + body: commands.map((command) => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join("\n") + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n") + }); + } + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []]; + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter((option) => option.name !== "version"); + } + if (options.length > 0) { + const longestOptionName = findLongest(options.map((option) => option.rawName)); + sections.push({ + title: "Options", + body: options.map((option) => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`; + }).join("\n") + }); + } + if (this.examples.length > 0) { + sections.push({ + title: "Examples", + body: this.examples.map((example) => { + if (typeof example === "function") { + return example(name); + } + return example; + }).join("\n") + }); + } + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + console.log(sections.map((section) => { + return section.title ? `${section.title}: +${section.body}` : section.body; + }).join("\n\n")); + } + outputVersion() { + const {name} = this.cli; + const {versionNumber} = this.cli.globalCommand; + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + checkRequiredArgs() { + const minimalArgsCount = this.args.filter((arg) => arg.required).length; + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + checkUnknownOptions() { + const {options, globalCommand} = this.cli; + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + checkOptionValue() { + const {options: parsedOptions, globalCommand} = this.cli; + const options = [...globalCommand.options, ...this.options]; + for (const option of options) { + const value = parsedOptions[option.name.split(".")[0]]; + if (option.required) { + const hasNegated = options.some((o) => o.negated && o.names.includes(option.name)); + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } +} +class GlobalCommand extends Command { + constructor(cli) { + super("@@global@@", "", {}, cli); + } +} + +var __assign = Object.assign; +class CAC extends events.EventEmitter { + constructor(name = "") { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(" [options]"); + } + usage(text) { + this.globalCommand.usage(text); + return this; + } + command(rawName, description, config) { + const command = new Command(rawName, description || "", config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + option(rawName, description, config) { + this.globalCommand.option(rawName, description, config); + return this; + } + help(callback) { + this.globalCommand.option("-h, --help", "Display this message"); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + example(example) { + this.globalCommand.example(example); + return this; + } + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + outputVersion() { + this.globalCommand.outputVersion(); + } + setParsedInfo({args, options}, matchedCommand, matchedCommandName) { + this.args = args; + this.options = options; + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + return this; + } + unsetMatchedCommand() { + this.matchedCommand = void 0; + this.matchedCommandName = void 0; + } + parse(argv = processArgs, { + run = true + } = {}) { + this.rawArgs = argv; + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : "cli"; + } + let shouldParse = true; + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = __assign(__assign({}, parsed), { + args: parsed.args.slice(1) + }); + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + if (shouldParse) { + for (const command of this.commands) { + if (command.name === "") { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + const parsedArgv = {args: this.args, options: this.options}; + if (run) { + this.runMatchedCommand(); + } + if (!this.matchedCommand && this.args[0]) { + this.emit("command:*"); + } + return parsedArgv; + } + mri(argv, command) { + const cliOptions = [ + ...this.globalCommand.options, + ...command ? command.options : [] + ]; + const mriOptions = getMriOptions(cliOptions); + let argsAfterDoubleDashes = []; + const doubleDashesIndex = argv.indexOf("--"); + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + let parsed = mri2(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return __assign(__assign({}, res), { + [camelcaseOptionName(name)]: parsed[name] + }); + }, {_: []}); + const args = parsed._; + const options = { + "--": argsAfterDoubleDashes + }; + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== void 0) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === void 0) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]["shouldTransform"] = true; + transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0]; + } + } + } + for (const key of Object.keys(parsed)) { + if (key !== "_") { + const keys = key.split("."); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + return { + args, + options + }; + } + runMatchedCommand() { + const {args, options, matchedCommand: command} = this; + if (!command || !command.commandAction) + return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } +} + +const cac = (name = "") => new CAC(name); + +exports.CAC = CAC; +exports.Command = Command; +exports.cac = cac; +exports.default = cac; diff --git a/node_modules/cac/dist/index.mjs b/node_modules/cac/dist/index.mjs new file mode 100644 index 0000000..7c1c444 --- /dev/null +++ b/node_modules/cac/dist/index.mjs @@ -0,0 +1,617 @@ +import { EventEmitter } from 'events'; + +function toArr(any) { + return any == null ? [] : Array.isArray(any) ? any : [any]; +} + +function toVal(out, key, val, opts) { + var x, old=out[key], nxt=( + !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) + : typeof val === 'boolean' ? val + : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) + : (x = +val,x * 0 === 0) ? x : val + ); + out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); +} + +function mri2 (args, opts) { + args = args || []; + opts = opts || {}; + + var k, arr, arg, name, val, out={ _:[] }; + var i=0, j=0, idx=0, len=args.length; + + const alibi = opts.alias !== void 0; + const strict = opts.unknown !== void 0; + const defaults = opts.default !== void 0; + + opts.alias = opts.alias || {}; + opts.string = toArr(opts.string); + opts.boolean = toArr(opts.boolean); + + if (alibi) { + for (k in opts.alias) { + arr = opts.alias[k] = toArr(opts.alias[k]); + for (i=0; i < arr.length; i++) { + (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); + } + } + } + + for (i=opts.boolean.length; i-- > 0;) { + arr = opts.alias[opts.boolean[i]] || []; + for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]); + } + + for (i=opts.string.length; i-- > 0;) { + arr = opts.alias[opts.string[i]] || []; + for (j=arr.length; j-- > 0;) opts.string.push(arr[j]); + } + + if (defaults) { + for (k in opts.default) { + name = typeof opts.default[k]; + arr = opts.alias[k] = opts.alias[k] || []; + if (opts[name] !== void 0) { + opts[name].push(k); + for (i=0; i < arr.length; i++) { + opts[name].push(arr[i]); + } + } + } + } + + const keys = strict ? Object.keys(opts.alias) : []; + + for (i=0; i < len; i++) { + arg = args[i]; + + if (arg === '--') { + out._ = out._.concat(args.slice(++i)); + break; + } + + for (j=0; j < arg.length; j++) { + if (arg.charCodeAt(j) !== 45) break; // "-" + } + + if (j === 0) { + out._.push(arg); + } else if (arg.substring(j, j + 3) === 'no-') { + name = arg.substring(j + 3); + if (strict && !~keys.indexOf(name)) { + return opts.unknown(arg); + } + out[name] = false; + } else { + for (idx=j+1; idx < arg.length; idx++) { + if (arg.charCodeAt(idx) === 61) break; // "=" + } + + name = arg.substring(j, idx); + val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); + arr = (j === 2 ? [name] : name); + + for (idx=0; idx < arr.length; idx++) { + name = arr[idx]; + if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); + toVal(out, name, (idx + 1 < arr.length) || val, opts); + } + } + } + + if (defaults) { + for (k in opts.default) { + if (out[k] === void 0) { + out[k] = opts.default[k]; + } + } + } + + if (alibi) { + for (k in out) { + arr = opts.alias[k] || []; + while (arr.length > 0) { + out[arr.shift()] = out[k]; + } + } + } + + return out; +} + +const removeBrackets = (v) => v.replace(/[<[].+/, "").trim(); +const findAllBrackets = (v) => { + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + const parse = (match) => { + let variadic = false; + let value = match[1]; + if (value.startsWith("...")) { + value = value.slice(3); + variadic = true; + } + return { + required: match[0].startsWith("<"), + value, + variadic + }; + }; + let angledMatch; + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + let squareMatch; + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + return res; +}; +const getMriOptions = (options) => { + const result = {alias: {}, boolean: []}; + for (const [index, option] of options.entries()) { + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } + if (option.isBoolean) { + if (option.negated) { + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean"; + }); + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); + } + } else { + result.boolean.push(option.names[0]); + } + } + } + return result; +}; +const findLongest = (arr) => { + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; +}; +const padRight = (str, length) => { + return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`; +}; +const camelcase = (input) => { + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); +}; +const setDotProp = (obj, keys, val) => { + let i = 0; + let length = keys.length; + let t = obj; + let x; + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []; + } +}; +const setByType = (obj, transforms) => { + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + if (typeof transform.transformFunction === "function") { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } +}; +const getFileName = (input) => { + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ""; +}; +const camelcaseOptionName = (name) => { + return name.split(".").map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join("."); +}; +class CACError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } +} + +class Option { + constructor(rawName, description, config) { + this.rawName = rawName; + this.description = description; + this.config = Object.assign({}, config); + rawName = rawName.replace(/\.\*/g, ""); + this.negated = false; + this.names = removeBrackets(rawName).split(",").map((v) => { + let name = v.trim().replace(/^-{1,2}/, ""); + if (name.startsWith("no-")) { + this.negated = true; + name = name.replace(/^no-/, ""); + } + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); + this.name = this.names[this.names.length - 1]; + if (this.negated && this.config.default == null) { + this.config.default = true; + } + if (rawName.includes("<")) { + this.required = true; + } else if (rawName.includes("[")) { + this.required = false; + } else { + this.isBoolean = true; + } + } +} + +const processArgs = process.argv; +const platformInfo = `${process.platform}-${process.arch} node-${process.version}`; + +class Command { + constructor(rawName, description, config = {}, cli) { + this.rawName = rawName; + this.description = description; + this.config = config; + this.cli = cli; + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + usage(text) { + this.usageText = text; + return this; + } + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.versionNumber = version; + this.option(customFlags, "Display version number"); + return this; + } + example(example) { + this.examples.push(example); + return this; + } + option(rawName, description, config) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + alias(name) { + this.aliasNames.push(name); + return this; + } + action(callback) { + this.commandAction = callback; + return this; + } + isMatched(name) { + return this.name === name || this.aliasNames.includes(name); + } + get isDefaultCommand() { + return this.name === "" || this.aliasNames.includes("!"); + } + get isGlobalCommand() { + return this instanceof GlobalCommand; + } + hasOption(name) { + name = name.split(".")[0]; + return this.options.find((option) => { + return option.names.includes(name); + }); + } + outputHelp() { + const {name, commands} = this.cli; + const { + versionNumber, + options: globalOptions, + helpCallback + } = this.cli.globalCommand; + let sections = [ + { + body: `${name}${versionNumber ? `/${versionNumber}` : ""}` + } + ]; + sections.push({ + title: "Usage", + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + if (showCommands) { + const longestCommandName = findLongest(commands.map((command) => command.rawName)); + sections.push({ + title: "Commands", + body: commands.map((command) => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join("\n") + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n") + }); + } + let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []]; + if (!this.isGlobalCommand && !this.isDefaultCommand) { + options = options.filter((option) => option.name !== "version"); + } + if (options.length > 0) { + const longestOptionName = findLongest(options.map((option) => option.rawName)); + sections.push({ + title: "Options", + body: options.map((option) => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`; + }).join("\n") + }); + } + if (this.examples.length > 0) { + sections.push({ + title: "Examples", + body: this.examples.map((example) => { + if (typeof example === "function") { + return example(name); + } + return example; + }).join("\n") + }); + } + if (helpCallback) { + sections = helpCallback(sections) || sections; + } + console.log(sections.map((section) => { + return section.title ? `${section.title}: +${section.body}` : section.body; + }).join("\n\n")); + } + outputVersion() { + const {name} = this.cli; + const {versionNumber} = this.cli.globalCommand; + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + checkRequiredArgs() { + const minimalArgsCount = this.args.filter((arg) => arg.required).length; + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + checkUnknownOptions() { + const {options, globalCommand} = this.cli; + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + checkOptionValue() { + const {options: parsedOptions, globalCommand} = this.cli; + const options = [...globalCommand.options, ...this.options]; + for (const option of options) { + const value = parsedOptions[option.name.split(".")[0]]; + if (option.required) { + const hasNegated = options.some((o) => o.negated && o.names.includes(option.name)); + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } +} +class GlobalCommand extends Command { + constructor(cli) { + super("@@global@@", "", {}, cli); + } +} + +var __assign = Object.assign; +class CAC extends EventEmitter { + constructor(name = "") { + super(); + this.name = name; + this.commands = []; + this.rawArgs = []; + this.args = []; + this.options = {}; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(" [options]"); + } + usage(text) { + this.globalCommand.usage(text); + return this; + } + command(rawName, description, config) { + const command = new Command(rawName, description || "", config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + option(rawName, description, config) { + this.globalCommand.option(rawName, description, config); + return this; + } + help(callback) { + this.globalCommand.option("-h, --help", "Display this message"); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + example(example) { + this.globalCommand.example(example); + return this; + } + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + outputVersion() { + this.globalCommand.outputVersion(); + } + setParsedInfo({args, options}, matchedCommand, matchedCommandName) { + this.args = args; + this.options = options; + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + return this; + } + unsetMatchedCommand() { + this.matchedCommand = void 0; + this.matchedCommandName = void 0; + } + parse(argv = processArgs, { + run = true + } = {}) { + this.rawArgs = argv; + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : "cli"; + } + let shouldParse = true; + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = __assign(__assign({}, parsed), { + args: parsed.args.slice(1) + }); + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + if (shouldParse) { + for (const command of this.commands) { + if (command.name === "") { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + this.unsetMatchedCommand(); + } + if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) { + this.outputVersion(); + run = false; + this.unsetMatchedCommand(); + } + const parsedArgv = {args: this.args, options: this.options}; + if (run) { + this.runMatchedCommand(); + } + if (!this.matchedCommand && this.args[0]) { + this.emit("command:*"); + } + return parsedArgv; + } + mri(argv, command) { + const cliOptions = [ + ...this.globalCommand.options, + ...command ? command.options : [] + ]; + const mriOptions = getMriOptions(cliOptions); + let argsAfterDoubleDashes = []; + const doubleDashesIndex = argv.indexOf("--"); + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + let parsed = mri2(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return __assign(__assign({}, res), { + [camelcaseOptionName(name)]: parsed[name] + }); + }, {_: []}); + const args = parsed._; + const options = { + "--": argsAfterDoubleDashes + }; + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== void 0) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === void 0) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]["shouldTransform"] = true; + transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0]; + } + } + } + for (const key of Object.keys(parsed)) { + if (key !== "_") { + const keys = key.split("."); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + } + return { + args, + options + }; + } + runMatchedCommand() { + const {args, options, matchedCommand: command} = this; + if (!command || !command.commandAction) + return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } +} + +const cac = (name = "") => new CAC(name); + +export default cac; +export { CAC, Command, cac }; diff --git a/node_modules/cac/index-compat.js b/node_modules/cac/index-compat.js new file mode 100644 index 0000000..6b8a78d --- /dev/null +++ b/node_modules/cac/index-compat.js @@ -0,0 +1,11 @@ +const { cac, CAC, Command } = require('./dist/index') + +// For backwards compatibility +module.exports = cac + +Object.assign(module.exports, { + default: cac, + cac, + CAC, + Command, +}) diff --git a/node_modules/cac/mod.js b/node_modules/cac/mod.js new file mode 100644 index 0000000..9d0e894 --- /dev/null +++ b/node_modules/cac/mod.js @@ -0,0 +1,2 @@ +// Deno users should use mod.ts instead +export * from './deno/index.ts' \ No newline at end of file diff --git a/node_modules/cac/mod.ts b/node_modules/cac/mod.ts new file mode 100644 index 0000000..8fac7d9 --- /dev/null +++ b/node_modules/cac/mod.ts @@ -0,0 +1,2 @@ +// For Deno +export * from './deno/index.ts' diff --git a/node_modules/cac/package.json b/node_modules/cac/package.json new file mode 100644 index 0000000..2306bf3 --- /dev/null +++ b/node_modules/cac/package.json @@ -0,0 +1,104 @@ +{ + "name": "cac", + "version": "6.7.14", + "description": "Simple yet powerful framework for building command-line apps.", + "repository": { + "url": "egoist/cac", + "type": "git" + }, + "main": "index-compat.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./index-compat.js" + }, + "./package.json": "./package.json", + "./*": "./*" + }, + "files": [ + "dist", + "!**/__test__/**", + "/mod.js", + "/mod.ts", + "/deno", + "/index-compat.js" + ], + "scripts": { + "test": "jest", + "test:cov": "jest --coverage", + "build:deno": "node -r sucrase/register scripts/build-deno.ts", + "build:node": "rollup -c", + "build": "yarn build:deno && yarn build:node", + "toc": "markdown-toc -i README.md", + "prepublishOnly": "npm run build && cp mod.js mod.mjs", + "docs:api": "typedoc --out api-doc --readme none --exclude \"**/__test__/**\" --theme minimal" + }, + "author": "egoist <0x142857@gmail.com>", + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.12.10", + "@babel/plugin-syntax-typescript": "^7.12.1", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "@types/fs-extra": "^9.0.5", + "@types/jest": "^26.0.19", + "@types/mri": "^1.1.0", + "cz-conventional-changelog": "^2.1.0", + "esbuild": "^0.8.21", + "eslint-config-rem": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^9.0.1", + "globby": "^11.0.1", + "husky": "^1.2.0", + "jest": "^24.9.0", + "lint-staged": "^8.1.0", + "markdown-toc": "^1.2.0", + "mri": "^1.1.6", + "prettier": "^2.2.1", + "rollup": "^2.34.2", + "rollup-plugin-dts": "^2.0.1", + "rollup-plugin-esbuild": "^2.6.1", + "semantic-release": "^17.3.0", + "sucrase": "^3.16.0", + "ts-jest": "^26.4.4", + "ts-node": "^9.1.1", + "typedoc": "^0.19.2", + "typescript": "^4.1.2" + }, + "engines": { + "node": ">=8" + }, + "release": { + "branch": "master" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "lint-staged": { + "linters": { + "*.{js,json,ts}": [ + "prettier --write", + "git add" + ], + "*.md": [ + "markdown-toc -i", + "prettier --write", + "git add" + ] + }, + "ignore": [ + "dist/**", + "mod.js" + ] + }, + "husky": { + "hooks": { + "pre-commit": "npm t && lint-staged" + } + } +} diff --git a/node_modules/chai/CODEOWNERS b/node_modules/chai/CODEOWNERS new file mode 100644 index 0000000..ea74b66 --- /dev/null +++ b/node_modules/chai/CODEOWNERS @@ -0,0 +1 @@ +* @chaijs/chai diff --git a/node_modules/chai/CODE_OF_CONDUCT.md b/node_modules/chai/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..074addc --- /dev/null +++ b/node_modules/chai/CODE_OF_CONDUCT.md @@ -0,0 +1,58 @@ +# Contributor Code of Conduct + +> Read in: [Español](http://contributor-covenant.org/version/1/3/0/es/) | +[Français](http://contributor-covenant.org/version/1/3/0/fr/) | +[Italiano](http://contributor-covenant.org/version/1/3/0/it/) | +[Magyar](http://contributor-covenant.org/version/1/3/0/hu/) | +[Polskie](http://contributor-covenant.org/version/1/3/0/pl/) | +[Português](http://contributor-covenant.org/version/1/3/0/pt/) | +[Português do Brasil](http://contributor-covenant.org/version/1/3/0/pt_br/) + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer at chaijs@keithcirkel.co.uk. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/node_modules/chai/CONTRIBUTING.md b/node_modules/chai/CONTRIBUTING.md new file mode 100644 index 0000000..258766e --- /dev/null +++ b/node_modules/chai/CONTRIBUTING.md @@ -0,0 +1,212 @@ +# Chai Contribution Guidelines + +We like to encourage you to contribute to the Chai.js repository. This should be as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request or open an issue. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. + +#### Table of Contents + +- [TLDR;](#tldr) +- [Contributing](#contributing) + - [Bug Reports](#bugs) + - [Feature Requests](#features) + - [Pull Requests](#pull-requests) +- [Releasing](#releasing) +- [Support](#support) + - [Resources](#resources) + - [Core Contributors](#contributors) + + +## TLDR; + +- Creating an Issue or Pull Request requires a [GitHub](http://github.com) account. +- Issue reports should be **clear**, **concise** and **reproducible**. Check to see if your issue has already been resolved in the [master]() branch or already reported in Chai's [GitHub Issue Tracker](https://github.com/chaijs/chai/issues). +- In general, avoid submitting PRs for new Assertions without asking core contributors first. More than likely it would be better implemented as a plugin. +- Additional support is available via the [Google Group](http://groups.google.com/group/chaijs) or on irc.freenode.net#chaijs. +- **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + + + +## Contributing + +The issue tracker is the preferred channel for [bug reports](#bugs), +[feature requests](#features) and [submitting pull +requests](#pull-requests), but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests (use + [Google Group](https://groups.google.com/forum/#!forum/chaijs) or IRC). +* Please **do not** derail or troll issues. Keep the discussion on topic and + respect the opinions of others + + +### Bug Reports + +A bug is a **demonstrable problem** that is caused by the code in the repository. + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been reported. +2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. +3. **Isolate the problem** — create a test case to demonstrate your issue. Provide either a repo, gist, or code sample to demonstrate you problem. + +A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and/or Node.js versions experience the problem? What would you expect to be the outcome? All these details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case OR +> ```js +> expect(a).to.equal('a'); +> // code sample +> ``` +> +> Any other information you want to share that is relevant to the issue being reported. This might include the lines of code that you have identified as causing the bug, and potential solutions (and your opinions on their merits). + + +### Feature Requests + +Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. + +Furthermore, since Chai.js has a [robust plugin API](http://chaijs.com/guide/plugins/), we encourage you to publish **new Assertions** as plugins. If your feature is an enhancement to an **existing Assertion**, please propose your changes as an issue prior to opening a pull request. If the core Chai.js contributors feel your plugin would be better suited as a core assertion, they will invite you to open a PR in [chaijs/chai](https://github.com/chaijs/chai). + + +### Pull Requests + +- PRs for new core-assertions are advised against. +- PRs for core-assertion bug fixes are always welcome. +- PRs for enhancing the interfaces are always welcome. +- PRs that increase test coverage are always welcome. +- PRs are scrutinized for coding-style. + +Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. + +**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). + +Follow this process if you'd like your work considered for inclusion in the project: + +1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes: + +```bash +# Clone your fork of the repo into the current directory +git clone https://github.com// +# Navigate to the newly cloned directory +cd +# Assign the original repo to a remote called "upstream" +git remote add upstream https://github.com// +``` + +2. If you cloned a while ago, get the latest changes from upstream: + +```bash +git checkout +git pull upstream +``` + +3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: + +```bash +git checkout -b +``` + +4. Commit your changes in logical chunks. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. + +5. Run you code to make sure it works. If you're still having problems please try to run `make clean` and then test your code again. + +```bash +npm test +# when finished running tests... +git checkout chai.js +``` + +6. Locally merge (or rebase) the upstream development branch into your topic branch: + +```bash +git pull [--rebase] upstream +``` + +7. Push your topic branch up to your fork: + +```bash +git push origin +``` + +8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description. + +**IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + +## Releasing + +Releases can be **prepared** by anyone with access to the code. + +Simply run `make release-major`, `make release-minor`, or `make-release-patch` +and it will automatically do the following: + + - Build chai.js + - Bump the version numbers across the project + - Make a commit within git + +All you need to do is push the commit up and make a pull request, one of the core contributors will merge it and publish a release. + +### Publishing a Release + +Anyone who is a core contributor (see the [Core Contributors Heading in the Readme](https://github.com/chaijs/chai#core-contributors)) can publish a release: + +1. Go to the [Releases page on Github](https://github.com/chaijs/chai/releases) +2. Hit "Draft a new release" (if you can't see this, you're not a core contributor!) +3. Write human-friendly Release Notes based on changelog. + - The release title is "x.x.x / YYYY-MM-DD" (where x.x.x is the version number) + - If breaking changes, write migration tutorial(s) and reasoning. + - Callouts for community contributions (PRs) with links to PR and contributing user. + - Callouts for other fixes made by core contributors with links to issue. +4. Hit "Save Draft" and get other core contributors to check your work, or alternatively hit "Publish release" +5. That's it! + + +## Support + + +### Resources + +For most of the documentation you are going to want to visit [ChaiJS.com](http://chaijs.com). + +- [Getting Started Guide](http://chaijs.com/guide/) +- [API Reference](http://chaijs.com/api/) +- [Plugins](http://chaijs.com/plugins/) + +Or finally, you may find a core-contributor or like-minded developer in any of our support channels. + +- IRC: irc.freenode.org #chaijs +- [Mailing List / Google Group](https://groups.google.com/forum/#!forum/chaijs) + + +### Core Contributors + +Feel free to reach out to any of the core-contributors with you questions or concerns. We will do our best to respond in a timely manner. + +- Jake Luer + - GH: [@logicalparadox](https://github.com/logicalparadox) + - TW: [@jakeluer](http://twitter.com/jakeluer) + - IRC: logicalparadox +- Veselin Todorov + - GH: [@vesln](https://github.com/vesln/) + - TW: [@vesln](http://twitter.com/vesln) + - IRC: vesln +- Keith Cirkel + - GH: [@keithamus](https://github.com/keithamus) + - TW: [@keithamus](http://twitter.com/keithamus) + - IRC: keithamus +- Lucas Fernandes da Costa + - GH: [@lucasfcosta](https://github.com/lucasfcosta) + - TW: [@lfernandescosta](https://twitter.com/lfernandescosta) + - IRC: lucasfcosta diff --git a/node_modules/chai/History.md b/node_modules/chai/History.md new file mode 100644 index 0000000..5b5ae7b --- /dev/null +++ b/node_modules/chai/History.md @@ -0,0 +1,1059 @@ +### Note + +As of 3.0.0, the History.md file has been deprecated. [Please refer to the full +commit logs available on GitHub](https://github.com/chaijs/chai/commits). + +--- + +2.3.0 / 2015-04-26 +================== + + * Merge pull request #423 from ehntoo/patch-1 + * Merge pull request #422 from ljharb/fix_descriptor_tests + * Fix a small bug in the .null assertion docs + * Use a regex to account for property ordering issues across engines. + * Add `make test-firefox` + * Merge pull request #417 from astorije/astorije/minimalist-typo + * Remove trailing whitespaces + * Fix super minor typo in an example + * Merge pull request #408 from ljharb/enumerableProperty + * Add `ownPropertyDescriptor` assertion. + +2.2.0 / 2015-03-26 +================== + + * Merge pull request #405 from chaijs/deep-escape-doc-tweaks + * Tweak documentation on `.deep` flag. + * Merge pull request #402 from umireon/escaping-dot-should-be-taken + * Documentation of escaping in `.deep` flag. + * take regular expression apart + * Feature: backslash-escaping in `.deep.property` + * Escaping dot should be taken in deep property + +2.1.2 / 2015-03-15 +================== + + * Merge pull request #396 from chaijs/add-keith-cirkel-contributing-md + * Add Keith Cirkel to CONTRIBUTING.md + * Merge pull request #395 from cjqed/386-assert-operator-no-eval + * No longer using eval on assert operator #386 + * Merge pull request #389 from chaijs/update-git-summary + * Update `git summary` in README + +2.1.1 / 2015-03-04 +================== + + * Merge pull request #385 from eldritch-fossicker/master + * updates to reflect code style preference from @keithamus + * fix indexing into array with deep propery + * Merge pull request #382 from astorije/patch-2 + * Merge pull request #383 from gurdiga/config-doc-wording-improvement + * config.truncateThreshold docs: simpler wording + * Add missing docstring for showDiff argument of assert + * Merge pull request #381 from astorije/patch-1 + * Add a minor precision that empty asserts on strings too. + * Merge pull request #379 from dcneiner/should-primitive-fix + * Primitives now use valueOf in shouldGetter + +2.1.0 / 2015-02-23 +================== + + * Merge pull request #374 from jmm/v2.0.1 + * Increment version to 2.0.1. + * Merge pull request #365 from chaijs/fix-travis + * Fix travis.yml deploy + * Merge pull request #356 from Soviut/master + * documented fail methods for expect and should interfaces + * fail method added directly to expect + +2.0.0 / 2015-02-09 +================== + + * Merge pull request #361 from gregglind/b265-keys-object + * fix #359. Add `.keys(object)` + * Merge pull request #359 from gregglind/b359-unexpected-keys-sort + * Fix #359 keys() sorts input unexpectedly + * contrib: publish release strategy and travis npm creds #337 + * Merge pull request #357 from danilovaz/master + * Update copyright date + * Merge pull request #349 from toastynerd/add-which-chain-method + * add the which chain method as per issue #347 + * Merge pull request #333 from cmpolis/change-assertions + * more `by` cleanup + * cleaned out `.by` for #333 + * Merge pull request #335 from DingoEatingFuzz/expose-util + * Expose chai util through the chai object + * cleanup (per notes on pr #333) + * updated `change` to work w/ non-number values + tests + * Merge pull request #334 from hurrymaplelad/patch-1 + * Typo, the flag is called 'contains' with an 's' + * updated assertion interface with `change` (#330) + * added `change`,`increase`,`decrease` assertions (#330) + * assert tests for `change`,`increase`,`decrease` + * expect/should tests for `change`,`increase`,`decrease` + * Merge pull request #328 from lo1tuma/issue-327 + * Add includes and contains alias (fixes #327) + * Merge pull request #325 from chasenlehara/overwriteChainableMethodDocs + * Fix docs for overwriteChainableMethod parameters + * Merge pull request #317 from jasonkarns/patch-2 + * Merge pull request #318 from jasonkarns/patch-3 + * Merge pull request #316 from jasonkarns/patch-1 + * typos in docs + * minor docs typo + * update docs: getAllFlags -> transferFlags + * Merge pull request #313 from cjqed/254-expect-any-all + * Added the all and any flags for keys assertion, with all being the default behavior + * Merge pull request #312 from cjqed/291-assert-same-deep-members + * Changed public comment of sameDeepMemebers to be more clear + * Fixes issue #291, adds assert.sameDeepMembers + * Merge pull request #311 from cjqed/305-above-below-on-assert + * Merge pull request #308 from prodatakey/hasproperty + * Issue #305 fixed, added assert.isAbove and assert.isBelow + * Fix typo + * More unit tests for new utility functions + * Refactor common functionality, document, test + * Refactor if statement out + * Small unit test fix + * Handle array indexing terminating paths + * Merge pull request #309 from ericdouglas/iterableEqual-couting-once + * couting variables just once + * Fix properties with `undefined` value pass property assertion + * Merge pull request #306 from chaijs/revert-297-noopchainfunc + * Revert "Allows writing lint-friendly tests" + +1.10.0 / 2014-11-10 +================== + + * Merge pull request #297 from prodatakey/noopchainfunc + * Merge pull request #300 from julienw/299-fix-getMessage-test + * Fix #299: the test is defining global variables + * Add a couple more unit tests + * Add unit tests for chained terminating property asserts + * Revise documentation wording + * Add docs for function style NOOP asserts + * Make the NOOP function a shared constant + * Merge pull request #298 from dasilvacontin/negativeZeroLogging + * why not more assertions + * added test for inspecting `-0` + * a more readable/simple condition statement, as pointed out by @keithamus + * added check for logging negative zero + * Change test to not trigger argument bug + * Allows writing lint-friendly tests + * readme: update contributors for 1.9.2 + +1.9.2 / 2014-09-29 +================== + + * Merge pull request #268 from charlierudolph/cr-lazyMessages + * Merge pull request #269 from charlierudolph/cr-codeCleanup + * Merge pull request #277 from charlierudolph/fix-doc + * Merge pull request #279 from mohayonao/fix-closeTo + * Merge pull request #292 from boneskull/mocha + * resolves #255: upgrade mocha + * Merge pull request #289 from charlierudolph/cr-dryUpCode + * Dry up code + * Merge pull request #275 from DrRataplan/master + * assert: .closeTo() verify value's type before assertion + * Rewrite pretty-printing HTML elements to prevent throwing internal errors Fixes errors occuring when using a non-native DOM implementation + * Fix assert documentation + * Remove unused argument + * Allow messages to be functions + * Merge pull request #267 from shinnn/master + * Use SVG badge + * Merge pull request #264 from cjthompson/keys_diff + * Show diff for keys assertion + +1.9.1 / 2014-03-19 +================== + + * deps update + * util: [getActual] select actual logic now allows undefined for actual. Closes #183 + * docs: [config] make public, express param type + * Merge pull request #251 from romario333/threshold3 + * Fix issue #166 - configurable threshold in objDisplay. + * Move configuration options to config.js. + * Merge pull request #233 from Empeeric/master + * Merge pull request #244 from leider/fix_for_contains + * Merge pull request #247 from didoarellano/typo-fixes + * Fix typos + * Merge pull request #245 from lfac-pt/patch-1 + * Update `exports.version` to 1.9.0 + * aborting loop on finding + * declaring variable only once + * additional test finds incomplete implementation + * simplified code + * fixing #239 (without changing chai.js) + * ssfi as it should be + * Merge pull request #228 from duncanbeevers/deep_members + * Deep equality check for collection membership + +1.9.0 / 2014-01-29 +================== + + * docs: add contributing.md #238 + * assert: .throws() returns thrown error. Closes #185 + * Merge pull request #232 from laconbass/assert-throws + * assert: .fail() parameter mismatch. Closes #206 + * Merge branch 'karma-fixes' + * Add karma phantomjs launcher + * Use latest karma and sauce launcher + * Karma tweaks + * Merge pull request #230 from jkroso/include + * Merge pull request #237 from chaijs/coverage + * Add coverage to npmignore + * Remove lib-cov from test-travisci dependents + * Remove the not longer needed lcov reporter + * Test coverage with istanbul + * Remove jscoverage + * Remove coveralls + * Merge pull request #226 from duncanbeevers/add_has + * Avoid error instantiation if possible on assert.throws + * Merge pull request #231 from duncanbeevers/update_copyright_year + * Update Copyright notices to 2014 + * handle negation correctly + * add failing test case + * support `{a:1,b:2}.should.include({a:1})` + * Merge pull request #224 from vbardales/master + * Add `has` to language chains + * Merge pull request #219 from demands/overwrite_chainable + * return error on throw method to chain on error properties, possibly different from message + * util: store chainable behavior in a __methods object on ctx + * util: code style fix + * util: add overwriteChainableMethod utility (for #215) + * Merge pull request #217 from demands/test_cleanup + * test: make it possible to run utilities tests with --watch + * makefile: change location of karma-runner bin script + * Merge pull request #202 from andreineculau/patch-2 + * test: add tests for throwing custom errors + * Merge pull request #201 from andreineculau/patch-1 + * test: updated for the new assertion errors + * core: improve message for assertion errors (throw assertion) + +1.8.1 / 2013-10-10 +================== + + * pkg: update deep-eql version + +1.8.0 / 2013-09-18 +================== + + * test: [sauce] add a few more browsers + * Merge branch 'refactor/deep-equal' + * util: remove embedded deep equal utility + * util: replace embedded deep equal with external module + * Merge branch 'feature/karma' + * docs: add sauce badge to readme [ci skip] + * test: [sauce] use karma@canary to prevent timeouts + * travis: only run on node 0.10 + * test: [karma] use karma phantomjs runner + * Merge pull request #181 from tricknotes/fix-highlight + * Fix highlight for example code + +1.7.2 / 2013-06-27 +================== + + * coverage: add coveralls badge + * test: [coveralls] add coveralls api integration. testing travis-ci integration + * Merge branch 'master' of github.com:chaijs/chai + * Merge branch 'feature/bower' + * Merge pull request #180 from tricknotes/modify-method-title + * Merge pull request #179 from tricknotes/highlight-code-example + * Modify method title to include argument name + * Fix to highlight code example + * bower: granular ignores + +1.7.1 / 2013-06-24 +================== + + * Merge branch 'feature/bower'. #175 + * bower: add json file + * build: browser + +1.7.0 / 2013-06-17 +================== + + * error: remove internal assertion error constructor + * core: [assertion-error] replace internal assertion error with dep + * deps: add chaijs/assertion-error@1.0.0 + * docs: fix typo in source file. #174 + * Merge pull request #174 from piecioshka/master + * typo + * Merge branch 'master' of github.com:chaijs/chai + * pkg: lock mocha/mocha-phantomjs versions (for now) + * Merge pull request #173 from chaijs/inspect-fix + * Fix `utils.inspect` with custom object-returning inspect()s. + * Merge pull request #171 from Bartvds/master + * replaced tabs with 2 spaces + * added assert.notOk() + * Merge pull request #169 from katsgeorgeek/topics/master + * Fix comparison objects. + +1.6.1 / 2013-06-05 +================== + + * Merge pull request #168 from katsgeorgeek/topics/master + * Add test for different RegExp flags. + * Add test for regexp comparison. + * Downgrade mocha version for fix running Phantom tests. + * Fix comparison equality of two regexps. + * Merge pull request #161 from brandonpayton/master + * Fix documented name for assert interfaces isDefined method + +1.6.0 / 2013-04-29 +================== + + * build: browser + * assert: [(not)include] throw on incompatible haystack. Closes #142 + * assert: [notInclude] add assert.notInclude. Closes #158 + * browser build + * makefile: force browser build on browser-test + * makefile: use component for browser build + * core: [assertions] remove extraneous comments + * Merge branch 'master' of github.com:chaijs/chai + * test: [assert] deep equal ordering + * Merge pull request #153 from NickHeiner/array-assertions + * giving members a no-flag assertion + * Code review comments - changing syntax + * Code review comments + * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148. + * Merge pull request #140 from RubenVerborgh/function-prototype + * Restore the `call` and `apply` methods of Function when adding a chainable method. + * readme: 2013 + * notes: migration notes for deep equal changes + * test: for ever err() there must be a passing version + +1.5.0 / 2013-02-03 +================== + + * docs: add Release Notes for non-gitlog summary of changes. + * lib: update copyright to 2013 + * Merge branch 'refactor/travis' + * makefile: remove test-component for full test run + * pkg: script test now runs make test so travis will test browser + * browser: build + * tests: refactor some tests to support new objDisplay output + * test: [bootstrap] normalize boostrap across all test scenarios + * assertions: refactor some assertions to use objDisplay instead of inspect + * util: [objDisplay] normalize output of functions + * makefile: refactor for full build scenarios + * component: fix build bug where missing util:type file + * assertions: [throw] code cleanup + * Merge branch 'refactor/typeDetection' + * browser: build + * makefile: chai.js is .PHONY so it builds every time + * test: [expect] add arguments type detection test + * core/assertions: [type] (a/an) refactor to use type detection utility + * util: add cross-browser type detection utility + * Merge branch 'feature/component' + * browser: build + * component: add component.json file + * makefile: refactor for fine grain control of testing scenarios + * test: add mochaPhantomJS support and component test file + * deps: add component and mocha-phantomjs for browser testing + * ignore: update ignore files for component support + * travis: run for all branches + * Merge branch 'feature/showDiff' + * test: [Assertion] configruable showDiff flag. Closes #132 + * lib: [Assertion] add configurable showDiff flag. #132 + * Merge branch 'feature/saucelabs' + * Merge branch 'master' into feature/saucelabs + * browser: build + * support: add mocha cloud runner, client, and html test page + * test: [saucelabs] add auth placeholder + * deps: add mocha-cloud + * Merge pull request #136 from whatthejeff/message_fix + * Merge pull request #138 from timnew/master + * Fix issue #137, test message existence by using message!=null rather than using message + * Fixed backwards negation messages. + * Merge pull request #133 from RubenVerborgh/throw + * Functions throwing strings can reliably be tested. + * Merge pull request #131 from RubenVerborgh/proto + * Cache whether __proto__ is supported. + * Use __proto__ if available. + * Determine the property names to exclude beforehand. + * Merge pull request #126 from RubenVerborgh/eqls + * Add alias eqls for eql. + * Use inherited enumerable properties in deep equality comparison. + * Show inherited properties when inspecting an object. + * Add new getProperties and getEnumerableProperties utils. + * showDiff: force true for equal and eql + +1.4.2 / 2012-12-21 +================== + + * browser build: (object diff support when used with mocha) #106 + * test: [display] array test for mocha object diff + * browser: no longer need different AssertionError constructor + +1.4.1 / 2012-12-21 +================== + + * showDiff: force diff for equal and eql. #106 + * test: [expect] type null. #122 + * Merge pull request #115 from eshao/fix-assert-Throw + * FIX: assert.Throw checks error type/message + * TST: assert.Throw should check error type/message + +1.4.0 / 2012-11-29 +================== + + * pre-release browser build + * clean up index.js to not check for cov, revert package.json to use index.js + * convert tests to use new bootstrap + * refactor testing bootstrap + * use spaces (not tabs). Clean up #114 + * Merge pull request #114 from trantorLiu/master + * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of". + * Change `main` to ./lib/chai. Fixes #28. + * Merge pull request #104 from connec/deep_equals_circular_references_ + * Merge pull request #109 from nnarhinen/patch-1 + * Check for 'actual' type + * Added support for circular references when checking deep (in)equality. + +1.3.0 / 2012-10-01 +================== + + * browser build w/ folio >= 0.3.4. Closes #99 + * add back buffer test for deep equal + * do not write flags to assertion.prototype + * remove buffer test from expect + * browser build + * improve documentation of custom error messages + * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master + * browser build + * improved buffer deep equal checking + * mocha is npm test command + * Cleaning up the js style… + * expect tests now include message pass-through + * packaging up browser-side changes… + * Increasing Throws error message verbosity + * Should syntax: piping message through + * Make globalShould test work in browser too. + * Add a setter for `Object.prototype.should`. Closes #86. + +1.2.0 / 2012-08-07 +================== + + * Merge branch 'feature/errmsg' + * browser build + * comment updates for utilities + * tweak objDislay to only kick in if object inspection is too long + * Merge branch 'master' into feature/errmsg + * add display sample for error message refactor + * first draft of error message refactor. #93 + * add `closeTo` assertion to `assert` interface. Closes #89. + * update folio build for better require.js handling. Closes #85 + * Merge pull request #92 from paulmillr/topics/add-dom-checks + * Add check for DOM objects. + * browser build + * Merge branch 'master' of github.com:chaijs/chai + * bug - getActual not defaulting to assertion subject + * Merge pull request #88 from pwnall/master + * Don't inspect() assertion arguments if the assertion passes. + +1.1.1 / 2012-07-09 +================== + + * improve commonjs support on browser build + * Merge pull request #83 from tkazec/equals + * Document .equals + * Add .equals as an alias of .equal + * remove unused browser prefix/suffix + * Merge branch 'feature/folio-build' + * browser build + * using folio to compile + * clean up makefile + * early folio 0.3.x support + +1.1.0 / 2012-06-26 +================== + + * browser build + * Disable "Assertion.includeStack is false" test in IE. + * Use `utils.getName` for all function inspections. + * Merge pull request #80 from kilianc/closeTo + * fixes #79 + * browser build + * expand docs to indicate change of subject for chaining. Closes #78 + * add `that` chain noop + * Merge branch 'bug/74' + * comments on how to property use `length` as chain. Closes #74 + * tests for length as chainable property. #74 + * add support for `length` as chainable prop/method. + * Merge branch 'bug/77' + * tests for getPathValue when working with nested arrays. Closes #77 + * add getPathValue support for nested arrays + * browser build + * fix bug for missing browser utils + * compile tool aware of new folder layout + * Merge branch 'refactor/1dot1' + * move core assertions to own file and refactor all using utils + * rearrange folder structure + +1.0.4 / 2012-06-03 +================== + + * Merge pull request #68 from fizker/itself + * Added itself chain. + * simplify error inspections for cross browser compatibility + * fix safari `addChainableMethod` errors. Closes #69 + +1.0.3 / 2012-05-27 +================== + + * Point Travis badge to the right place. + * Make error message for eql/deep.equal more clear. + * Fix .not.deep.equal. + * contributors list + +1.0.2 / 2012-05-26 +================== + + * Merge pull request #67 from chaijs/chaining-and-flags + * Browser build. + * Use `addChainableMethod` to get away from `__proto__` manipulation. + * New `addChainableMethod` utility. + * Replace `getAllFlags` with `transferFlags` utility. + * browser build + * test - get all flags + * utility - get all flags + * Add .mailmap to .npmignore. + * Add a .mailmap file to fix my name in shortlogs. + +1.0.1 / 2012-05-18 +================== + + * browser build + * Fixing "an" vs. "a" grammar in type assertions. + * Uniformize `assert` interface inline docs. + * Don't use `instanceof` for `assert.isArray`. + * Add `deep` flag for equality and property value. + * Merge pull request #64 from chaijs/assertion-docs + * Uniformize assertion inline docs. + * Add npm-debug.log to .gitignore. + * no reserved words as actuals. #62 + +1.0.0 / 2012-05-15 +================== + + * readme cleanup + * browser build + * utility comments + * removed docs + * update to package.json + * docs build + * comments / docs updates + * plugins app cleanup + * Merge pull request #61 from joliss/doc + * Fix and improve documentation of assert.equal and friends + * browser build + * doc checkpoint - texture + * Update chai-jquery link + * Use defined return value of Assertion extension functions + * Update utility docs + +1.0.0-rc3 / 2012-05-09 +================== + + * Merge branch 'feature/rc3' + * docs update + * browser build + * assert test conformity for minor refactor api + * assert minor refactor + * update util tests for new add/overwrite prop/method format + * added chai.Assertion.add/overwrite prop/method for plugin toolbox + * add/overwrite prop/method don't make assumptions about context + * doc test suite + * docs don't need coverage + * refactor all simple chains into one forEach loop, for clean documentation + * updated npm ignore + * remove old docs + * docs checkpoint - guide styled + * Merge pull request #59 from joliss/doc + * Document how to run the test suite + * don't need to rebuild docs to view + * dep update + * docs checkpoint - api section + * comment updates for docs + * new doc site checkpoint - plugin directory! + * Merge pull request #57 from kossnocorp/patch-1 + * Fix typo: devDependancies → devDependencies + * Using message flag in `getMessage` util instead of old `msg` property. + * Adding self to package.json contributors. + * `getMessage` shouldn't choke on null/omitted messages. + * `return this` not necessary in example. + * `return this` not necessary in example. + * Sinon–Chai has a dash + * updated plugins list for docs + +1.0.0-rc2 / 2012-05-06 +================== + + * Merge branch 'feature/test-cov' + * browser build + * missing assert tests for ownProperty + * appropriate assert equivalent for expect.to.have.property(key, val) + * reset AssertionError to include full stack + * test for plugin utilities + * overwrite Property and Method now ensure chain + * version notes in readme + +1.0.0-rc1 / 2012-05-04 +================== + + * browser build (rc1) + * assert match/notMatch tests + * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal + * cleaner should interface export. + * added chai.Assertion.prototype._obj (getter) for quick access to object flag + * moved almostEqual / almostDeepEqual to stats plugin + * added mocha.opts + * Add test for `utils.addMethod` + * Fix a typo + * Add test for `utils.overwriteMethod` + * Fix a typo + * Browser build + * Add undefined assertion + * Add null assertion + * Fix an issue with `mocha --watch` + * travis no longer tests on node 0.4.x + * removing unnecissary carbon dep + * Merge branch 'feature/plugins-app' + * docs build + * templates for docs express app for plugin directory + * express app for plugin and static serving + * added web server deps + * Merge pull request #54 from josher19/master + * Remove old test.assert code + * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual + * browser build + * Added almostEqual and deepAlmostEqual to assert test suite. + * bug - context determinants for utils + * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true + * wrong travis link + * readme updates for version information + * travis tests 0.5.x branch as well + * [bug] util `addProperty` not correctly exporting + * read me version notes + * browser build 1.0.0alpha1 + * not using reserved words in internal assertions. #52 + * version tick + * clean up redundant tests + * Merge branch 'refs/heads/0.6.x' + * update version tag in package 1.0.0alpha1 + * browser build + * added utility tests to browser specs + * beginning utility testing + * updated utility comments + * utility - overwriteMethod + * utility - overwriteProperty + * utility - addMethod + * utility - addProperty + * missing ; + * contributors list update + * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x + * Added guide link to docs. WIP + * Include/contain are now both properties and methods + * Add an alias annotation + * Remove usless function wrapper + * Fix a typo + * A/an are now both properties and methods + * [docs] new site homepage layout / color checkpoint + * Ignore IE-specific error properties. + * Fixing order of error message test. + * New cross-browser `getName` util. + * Fixing up `AssertionError` inheritance. + * backup docs + * Add doctypes + * [bug] was still using `constructor.name` in `throw` assertion + * [bug] flag Object.create(null) instead of new Object + * [test] browser build + * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags + * [refactor] remove Assertion.prototype.inspect for testable object inspection + * [refactor] object to test is now stored in flag, with ssfi and custom message + * [bug] flag util - don't return on `set` + * [docs] comments for getMessage utility + * [feature] getMessage + * [feature] testing utilities + * [refactor] flag doesn't require `call` + * Make order of source files well-defined + * Added support for throw(errorInstance). + * Use a foolproof method of grabbing an error's name. + * Removed constructor.name check from throw. + * disabled stackTrack configuration tests until api is stable again + * first version of line displayed error for node js (unstable) + * refactor core Assertion to use flag utility for negation + * added flag utility + * tests for assert interface negatives. Closed #42 + * added assertion negatives that were missing. #42 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + * Added assert.fail. Closes #40 + * better error message for assert.operator. Closes #39 + * [refactor] Assertion#property to use getPathValue property + * added getPathValue utility helper + * removed todo about browser build + * version notes + * version bumb 0.6.0 + * browser build + * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')' + * [feature] browser uses different error.js + * [refactor] error without chai.fail + * Assertion & interfaces use new utils helper export + * [refactor] primary export for new plugin util usage + * added util index.js helper + * added 2012 to copyright headers + * Added DeepEqual assertions + +0.5.3 / 2012-04-21 +================== + + * Merge branch 'refs/heads/jgonera-oldbrowsers' + * browser build + * fixed reserved names for old browsers in interface/assert + * fixed reserved names for old browsers in interface/should + * fixed: chai.js no longer contains fail() + * fixed reserved names for old browsers in Assertion + * Merge pull request #49 from joliss/build-order + * Make order of source files well-defined + * Merge pull request #43 from zzen/patch-1 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + +0.5.2 / 2012-03-21 +================== + + * browser build + * Merge branch 'feature/assert-fail' + * Added assert.fail. Closes #40 + * Merge branch 'bug/operator-msg' + * better error message for assert.operator. Closes #39 + * version notes + +0.5.1 / 2012-03-14 +================== + + * chai.fail no longer exists + * Merge branch 'feature/assertdefined' + * Added asset#isDefined. Closes #37. + * dev docs update for Assertion#assert + +0.5.0 / 2012-03-07 +================== + + * [bug] on inspect of reg on n 0.4.12 + * Merge branch 'bug/33-throws' + * Merge pull request #35 from logicalparadox/empty-object + * browser build + * updated #throw docs + * Assertion#throw `should` tests updated + * Assertion#throw `expect` tests + * Should interface supports multiple throw parameters + * Update Assertion#throw to support strings and type checks. + * Add more tests for `empty` in `should`. + * Add more tests for `empty` in `expect`. + * Merge branch 'master' into empty-object + * don't switch act/exp + * Merge pull request #34 from logicalparadox/assert-operator + * Update the compiled verison. + * Add `assert.operator`. + * Notes on messages. #22 + * browser build + * have been test + * below tests + * Merge branch 'feature/actexp' + * browser build + * remove unnecessary fail export + * full support for actual/expected where relevant + * Assertion.assert support expected value + * clean up error + * Update the compiled version. + * Add object & sane arguments support to `Assertion#empty`. + +0.4.2 / 2012-02-28 +================== + + * fix for `process` not available in browser when used via browserify. Closes #28 + * Merge pull request #31 from joliss/doc + * Document that "should" works in browsers other than IE + * Merge pull request #30 from logicalparadox/assert-tests + * Update the browser version of chai. + * Update `assert.doesNotThrow` test in order to check the use case when type is a string. + * Add test for `assert.ifError`. + * Falsey -> falsy. + * Full coverage for `assert.throws` and `assert.doesNotThrow`. + * Add test for `assert.doesNotThrow`. + * Add test for `assert.throws`. + * Add test for `assert.length`. + * Add test for `assert.include`. + * Add test for `assert.isBoolean`. + * Fix the implementation of `assert.isNumber`. + * Add test for `assert.isNumber`. + * Add test for `assert.isString`. + * Add test for `assert.isArray`. + * Add test for `assert.isUndefined`. + * Add test for `assert.isNotNull`. + * Fix `assert.isNotNull` implementation. + * Fix `assert.isNull` implementation. + * Add test for `assert.isNull`. + * Add test for `assert.notDeepEqual`. + * Add test for `assert.deepEqual`. + * Add test for `assert.notStrictEqual`. + * Add test for `assert.strictEqual`. + * Add test for `assert.notEqual`. + +0.4.1 / 2012-02-26 +================== + + * Merge pull request #27 from logicalparadox/type-fix + * Update the browser version. + * Add should tests for type checks. + * Add function type check test. + * Add more type checks tests. + * Add test for `new Number` type check. + * Fix type of actual checks. + +0.4.0 / 2012-02-25 +================== + + * docs and readme for upcoming 0.4.0 + * docs generated + * putting coverage and tests for docs in docs/out/support + * make docs + * makefile copy necessary resources for tests in docs + * rename configuration test + * Merge pull request #21 from logicalparadox/close-to + * Update the browser version. + * Update `closeTo()` docs. + * Add `Assertion.closeTo()` method. + * Add `.closeTo()` should test. + * Add `.closeTo()` expect test. + * Merge pull request #20 from logicalparadox/satisfy + * Update the browser version. + * `..` -> `()` in `.satisfy()` should test. + * Update example for `.satisfy()`. + * Update the compiled browser version. + * Add `Assertion.satisfy()` method. + * Add `.satisfy()` should test. + * Add `.satisfy()` expect test. + * Merge pull request #19 from logicalparadox/respond-to + * Update the compiled browser version. + * Add `respondTo` Assertion. + * Add `respondTo` should test. + * Add `respondTo` expect test. + * Merge branch 'feature/coverage' + * mocha coverage support + * doc contributors + * README contributors + +0.3.4 / 2012-02-23 +================== + + * inline comment typos for #15 + * Merge branch 'refs/heads/jeffbski-configErrorStackCompat' + * includeStack documentation for all interfaces + * suite name more generic + * Update test to be compatible with browsers that do not support err.stack + * udpated compiled chai.js and added to browser tests + * Allow inclusion of stack trace for Assert error messages to be configurable + * docs sharing buttons + * sinon-chai link + * doc updates + * read me updates include plugins + +0.3.3 / 2012-02-12 +================== + + * Merge pull request #14 from jfirebaugh/configurable_properties + * Make Assertion.prototype properties configurable + +0.3.2 / 2012-02-10 +================== + + * codex version + * docs + * docs cleanup + +0.3.1 / 2012-02-07 +================== + + * node 0.4.x compat + +0.3.0 / 2012-02-07 +================== + + * Merge branch 'feature/03x' + * browser build + * remove html/json/headers testign + * regex error.message testing + * tests for using plugins + * Merge pull request #11 from domenic/master + * Make `chai.use` a no-op if the function has already been used. + +0.2.4 / 2012-02-02 +================== + + * added in past tense switch for `been` + +0.2.3 / 2012-02-01 +================== + + * try that again + +0.2.2 / 2012-02-01 +================== + + * added `been` (past of `be`) alias + +0.2.1 / 2012-01-29 +================== + + * added Throw, with a capital T, as an alias to `throw` (#7) + +0.2.0 / 2012-01-26 +================== + + * update gitignore for vim *.swp + * Merge branch 'feature/plugins' + * browser build + * interfaces now work with use + * simple .use function. See #9. + * readme notice on browser compat + +0.1.7 / 2012-01-25 +================== + + * added assert tests to browser test runner + * browser update + * `should` interface patch for primitives support in FF + * fix isObject() Thanks @milewise + * travis only on branch `master` + * add instanceof alias `instanceOf`. #6 + * some tests for assert module + +0.1.6 / 2012-01-02 +================== + + * commenting for assert interface + * updated codex dep + +0.1.5 / 2012-01-02 +================== + + * browser tests pass + * type in should.not.equal + * test for should (not) exist + * added should.exist and should.not.exist + * browser uses tdd + * convert tests to tdd + +0.1.4 / 2011-12-26 +================== + + * browser lib update for new assert interface compatiblitiy + * inspect typos + * added strict equal + negatives and ifError + * interface assert had doesNotThrow + * added should tests to browser + * new expect empty tests + * should test browser compat + * Fix typo for instanceof docs. Closes #3 [ci skip] + +0.1.3 / 2011-12-18 +================== + + * much cleaner reporting string on error. + +0.1.2 / 2011-12-18 +================== + + * [docs] for upcoming 0.1.2 + * browser version built with pre/suffix … all tests passing + * make / compile now use prefix/suffix correctly + * code clean + * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods. + * Merge branch 'feature/should4xcompatibility' + * compile for browser tests.. all pass + * added header/status/html/json + * throw tests + * should.throw & should.not.throw shortcuts + * improved `throw` type detection and messaging + * contain is now `include` … keys modifier is now `contain` + * removed object() test + * removed #respondTo + * Merge branch 'bug/2' + * replaced __defineGetter__ with defineProperty for all uses + * [docs] change mp tracking code + * docs site updated with assert (TDD) interface + * updated doc comments for assert interface + +0.1.1 / 2011-12-16 +================== + + * docs ready for upcoming 0.1.1 + * readme image fixed [ci skip] + * more readme tweaks [ci skip] + * réadmet image fixed [ci skip] + * documentation + * codex locked in version 0.0.5 + * more comments to assertions for docs + * assertions fully commented, browser library updated + * adding codex as doc dependancy + * prepping for docs + * assertion component completely commented for documentation + * added exist test + * var expect outside of browser if check + * added keywords to package.json + +0.1.0 / 2011-12-15 +================== + + * failing on purpose successful .. back to normal + * testing travis failure + * assert#arguments getter + * readme typo + * updated README + * added travis and npmignore + * copyright notices … think i got them all + * moved expect interface to own file for consistency + * assert ui deepEqual + * browser tests expect (all working) + * browser version built + * chai.fail (should ui) + * expect tests browser compatible + * tests for should and expect (all pass) + * moved fail to primary export + * should compatibility testing + * within, greaterThan, object, keys, + * Aliases + * Assertion#property now correctly works with negate and undefined values + * error message language matches should + * Assertion#respondTo + * Assertion now uses inspect util + * git ignore node modules + * should is exported + * AssertionError __proto__ from Error.prototype + * add should interface for should.js compatibility + * moved eql to until folder and added inspect from (joyent/node) + * added mocha for testing + * browser build for current api + * multiple .property assertions + * added deep equal from node + +0.0.2 / 2011-12-07 +================== + + * cleaner output on error + * improved exists detection + * package remnant artifact + * empty deep equal + * test browser build + * assertion cleanup + * client compile script + * makefile + * most of the basic assertions + * allow no parameters to assertion error + * name change + * assertion error instance + * main exports: assert() & expect() + * initialize diff --git a/node_modules/chai/LICENSE b/node_modules/chai/LICENSE new file mode 100644 index 0000000..eedbe23 --- /dev/null +++ b/node_modules/chai/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Chai.js Assertion Library + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/chai/README.md b/node_modules/chai/README.md new file mode 100644 index 0000000..78e4d2d --- /dev/null +++ b/node_modules/chai/README.md @@ -0,0 +1,212 @@ +

+ + ChaiJS + +
+ chai +

+ +

+ Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework. +

+ +

+ + license:mit + + + tag:? + + + node:? + +
+ + Selenium Test Status + +
+ + downloads:? + + + build:? + + + coverage:? + + + devDependencies:? + +
+ + Join the Slack chat + + + Join the Gitter chat + + + OpenCollective Backers + +

+ +For more information or to download plugins, view the [documentation](http://chaijs.com). + +## What is Chai? + +Chai is an _assertion library_, similar to Node's built-in `assert`. It makes testing much easier by giving you lots of assertions you can run against your code. + +## Installation + +### Node.js + +`chai` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install --save-dev chai + +### Browsers + +You can also use it within the browser; install via npm and use the `chai.js` file found within the download. For example: + +```html + +``` + +## Usage + +Import the library in your code, and then pick one of the styles you'd like to use - either `assert`, `expect` or `should`: + +```js +var chai = require('chai'); +var assert = chai.assert; // Using Assert style +var expect = chai.expect; // Using Expect style +var should = chai.should(); // Using Should style +``` + +### Pre-Native Modules Usage (_registers the chai testing style globally_) + +```js +require('chai/register-assert'); // Using Assert style +require('chai/register-expect'); // Using Expect style +require('chai/register-should'); // Using Should style +``` + +### Pre-Native Modules Usage (_as local variables_) + +```js +const { assert } = require('chai'); // Using Assert style +const { expect } = require('chai'); // Using Expect style +const { should } = require('chai'); // Using Should style +should(); // Modifies `Object.prototype` + +const { expect, use } = require('chai'); // Creates local variables `expect` and `use`; useful for plugin use +``` + +### Native Modules Usage (_registers the chai testing style globally_) + +```js +import 'chai/register-assert'; // Using Assert style +import 'chai/register-expect'; // Using Expect style +import 'chai/register-should'; // Using Should style +``` + +### Native Modules Usage (_local import only_) + +```js +import { assert } from 'chai'; // Using Assert style +import { expect } from 'chai'; // Using Expect style +import { should } from 'chai'; // Using Should style +should(); // Modifies `Object.prototype` +``` + +### Usage with Mocha + +```bash +mocha spec.js -r chai/register-assert # Using Assert style +mocha spec.js -r chai/register-expect # Using Expect style +mocha spec.js -r chai/register-should # Using Should style +``` + +[Read more about these styles in our docs](http://chaijs.com/guide/styles/). + +## Plugins + +Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces. + +- Need a plugin? View the [official plugin list](http://chaijs.com/plugins). +- Want to build a plugin? Read the [plugin api documentation](http://chaijs.com/guide/plugins/). +- Have a plugin and want it listed? Simply add the following keywords to your package.json: + - `chai-plugin` + - `browser` if your plugin works in the browser as well as Node.js + - `browser-only` if your plugin does not work with Node.js + +### Related Projects + +- [chaijs / chai-docs](https://github.com/chaijs/chai-docs): The chaijs.com website source code. +- [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. +- [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. +- [chaijs / type-detect](https://github.com/chaijs/type-detect): Improved typeof detection for Node.js and the browser. +- [chaijs / check-error](https://github.com/chaijs/check-error): Error comparison and information related utility for Node.js and the browser. +- [chaijs / loupe](https://github.com/chaijs/loupe): Inspect utility for Node.js and browsers. +- [chaijs / pathval](https://github.com/chaijs/pathval): Object value retrieval given a string path. +- [chaijs / get-func-name](https://github.com/chaijs/get-func-name): Utility for getting a function's name for node and the browser. + +### Contributing + +Thank you very much for considering to contribute! + +Please make sure you follow our [Code Of Conduct](https://github.com/chaijs/chai/blob/master/CODE_OF_CONDUCT.md) and we also strongly recommend reading our [Contributing Guide](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md). + +Here are a few issues other contributors frequently ran into when opening pull requests: + +- Please do not commit changes to the `chai.js` build. We do it once per release. +- Before pushing your commits, please make sure you [rebase](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md#pull-requests) them. + +### Contributors + +Please see the full +[Contributors Graph](https://github.com/chaijs/chai/graphs/contributors) for our +list of contributors. + +### Core Contributors + +Feel free to reach out to any of the core contributors with your questions or +concerns. We will do our best to respond in a timely manner. + +[![Jake Luer](https://avatars3.githubusercontent.com/u/58988?v=3&s=50)](https://github.com/logicalparadox) +[![Veselin Todorov](https://avatars3.githubusercontent.com/u/330048?v=3&s=50)](https://github.com/vesln) +[![Keith Cirkel](https://avatars3.githubusercontent.com/u/118266?v=3&s=50)](https://github.com/keithamus) +[![Lucas Fernandes da Costa](https://avatars3.githubusercontent.com/u/6868147?v=3&s=50)](https://github.com/lucasfcosta) +[![Grant Snodgrass](https://avatars3.githubusercontent.com/u/17260989?v=3&s=50)](https://github.com/meeber) diff --git a/node_modules/chai/ReleaseNotes.md b/node_modules/chai/ReleaseNotes.md new file mode 100644 index 0000000..2a80d5c --- /dev/null +++ b/node_modules/chai/ReleaseNotes.md @@ -0,0 +1,737 @@ +# Release Notes + +## Note + +As of 3.0.0, the ReleaseNotes.md file has been deprecated. [Please refer to the release notes available on Github](https://github.com/chaijs/chai/releases). Or +[the release notes on the chaijs.com website](https://chaijs.com/releases). + +--- + +## 2.3.0 / 2015-04-26 + +Added `ownPropertyDescriptor` assertion: + +```js +expect('test').to.have.ownPropertyDescriptor('length'); +expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); +expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); +expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); +expect('test').ownPropertyDescriptor('length').to.have.keys('value'); +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#408](https://github.com/chaijs/chai/pull/408) Add `ownPropertyDescriptor` + assertion. + By [@ljharb](https://github.com/ljharb) + * [#422](https://github.com/chaijs/chai/pull/422) Improve ownPropertyDescriptor + tests. + By [@ljharb](https://github.com/ljharb) + +#### Documentation fixes + + * [#417](https://github.com/chaijs/chai/pull/417) Fix documentation typo + By [@astorije](https://github.com/astorije) + * [#423](https://github.com/chaijs/chai/pull/423) Fix inconsistency in docs. + By [@ehntoo](https://github.com/ehntoo) + + +## 2.2.0 / 2015-03-26 + +Deep property strings can now be escaped using `\\` - for example: + +```js +var deepCss = { '.link': { '[target]': 42 }}; +expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42) +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#402](https://github.com/chaijs/chai/pull/402) Allow escaping of deep + property keys. + By [@umireon](https://github.com/umireon) + +#### Documentation fixes + + * [#405](https://github.com/chaijs/chai/pull/405) Tweak documentation around + deep property escaping. + By [@keithamus](https://github.com/keithamus) + + +## 2.1.2 / 2015-03-15 + +A minor bug fix. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#395](https://github.com/chaijs/chai/pull/395) Fix eval-related bugs with + assert.operator ([#386](https://github.com/chaijs/chai/pull/386)). + By [@cjqed](https://github.com/cjqed) + +## 2.1.1 / 2015-03-04 + +Two minor bugfixes. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#385](https://github.com/chaijs/chai/pull/385) Fix a bug (also described in + [#387](https://github.com/chaijs/chai/pull/385)) where `deep.property` would not work with single + key names. By [@eldritch-fossicker](https://github.com/eldritch-fossicker) + * [#379](https://github.com/chaijs/chai/pull/379) Fix bug where tools which overwrite + primitive prototypes, such as Babel or core-js would fail. + By [@dcneiner](https://github.com/dcneiner) + +#### Documentation fixes + + * [#382](https://github.com/chaijs/chai/pull/382) Add doc for showDiff argument in assert. + By [@astorije](https://github.com/astorije) + * [#383](https://github.com/chaijs/chai/pull/383) Improve wording for truncateTreshold docs + By [@gurdiga](https://github.com/gurdiga) + * [#381](https://github.com/chaijs/chai/pull/381) Improve wording for assert.empty docs + By [@astorije](https://github.com/astorije) + +## 2.1.0 / 2015-02-23 + +Small release; fixes an issue where the Chai lib was incorrectly reporting the +version number. + +Adds new `should.fail()` and `expect.fail()` methods, which are convinience +methods to throw Assertion Errors. + +### Community Contributions + +#### Code Features & Fixes + + * [#356](https://github.com/chaijs/chai/pull/356) Add should.fail(), expect.fail(). By [@Soviut](https://github.com/Soviut) + * [#374](https://github.com/chaijs/chai/pull/374) Increment version. By [@jmm](https://github.com/jmm) + +## 2.0.0 / 2015-02-09 + +Unfortunately with 1.10.0 - compatibility broke with older versions because of +the `addChainableNoop`. This change has been reverted. + +Any plugins using `addChainableNoop` should cease to do so. + +Any developers wishing for this behaviour can use [dirty-chai](https://www.npmjs.com/package/dirty-chai) +by [@joshperry](https://github.com/joshperry) + +### Community Contributions + +#### Code Features & Fixes + + * [#361](https://github.com/chaijs/chai/pull/361) `.keys()` now accepts Objects, extracting keys from them. By [@gregglind](https://github.com/gregglind) + * [#359](https://github.com/chaijs/chai/pull/359) `.keys()` no longer mutates passed arrays. By [@gregglind](https://github.com/gregglind) + * [#349](https://github.com/chaijs/chai/pull/349) Add a new chainable keyword - `.which`. By [@toastynerd](https://github.com/toastynerd) + * [#333](https://github.com/chaijs/chai/pull/333) Add `.change`, `.increase` and `.decrease` assertions. By [@cmpolis](https://github.com/cmpolis) + * [#335](https://github.com/chaijs/chai/pull/335) `chai.util` is now exposed [@DingoEatingFuzz](https://github.com/DingoEatingFuzz) + * [#328](https://github.com/chaijs/chai/pull/328) Add `.includes` and `.contains` aliases (for `.include` and `.contain`). By [@lo1tuma](https://github.com/lo1tuma) + * [#313](https://github.com/chaijs/chai/pull/313) Add `.any.keys()` and `.all.keys()` qualifiers. By [@cjqed](https://github.com/cjqed) + * [#312](https://github.com/chaijs/chai/pull/312) Add `assert.sameDeepMembers()`. By [@cjqed](https://github.com/cjqed) + * [#311](https://github.com/chaijs/chai/pull/311) Add `assert.isAbove()` and `assert.isBelow()`. By [@cjqed](https://github.com/cjqed) + * [#308](https://github.com/chaijs/chai/pull/308) `property` and `deep.property` now pass if a value is set to `undefined`. By [@prodatakey](https://github.com/prodatakey) + * [#309](https://github.com/chaijs/chai/pull/309) optimize deep equal in Arrays. By [@ericdouglas](https://github.com/ericdouglas) + * [#306](https://github.com/chaijs/chai/pull/306) revert #297 - allowing lint-friendly tests. By [@keithamus](https://github.com/keithamus) + +#### Documentation fixes + + * [#357](https://github.com/chaijs/chai/pull/357) Copyright year updated in docs. By [@danilovaz](https://github.com/danilovaz) + * [#325](https://github.com/chaijs/chai/pull/325) Fix documentation for overwriteChainableMethod. By [@chasenlehara](https://github.com/chasenlehara) + * [#334](https://github.com/chaijs/chai/pull/334) Typo fix. By [@hurrymaplelad](https://github.com/hurrymaplelad) + * [#317](https://github.com/chaijs/chai/pull/317) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#318](https://github.com/chaijs/chai/pull/318) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#316](https://github.com/chaijs/chai/pull/316) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + + +## 1.10.0 / 2014-11-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review `addChainableNoop` notes below. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Noop Function for Terminating Assertion Properties + +The following assertions can now also be used in the function-call form: + +* ok +* true +* false +* null +* undefined +* exist +* empty +* arguments +* Arguments + +The above list of assertions are property getters that assert immediately on +access. Because of that, they were written to be used by terminating the assertion +chain with a property access. + +```js +expect(true).to.be.true; +foo.should.be.ok; +``` + +This syntax is definitely aesthetically pleasing but, if you are linting your +test code, your linter will complain with an error something like "Expected an +assignment or function call and instead saw an expression." Since the linter +doesn't know about the property getter it assumes this line has no side-effects, +and throws a warning in case you made a mistake. + +Squelching these errors is not a good solution as test code is getting to be +just as important as, if not more than, production code. Catching syntactical +errors in tests using static analysis is a great tool to help make sure that your +tests are well-defined and free of typos. + +A better option was to provide a function-call form for these assertions so that +the code's intent is more clear and the linters stop complaining about something +looking off. This form is added in addition to the existing property access form +and does not impact existing test code. + +```js +expect(true).to.be.true(); +foo.should.be.ok(); +``` + +These forms can also be mixed in any way, these are all functionally identical: + +```js +expect(true).to.be.true.and.not.false(); +expect(true).to.be.true().and.not.false; +expect(true).to.be.true.and.not.false; +``` + +#### Plugin Authors + +If you would like to provide this function-call form for your terminating assertion +properties, there is a new function to register these types of asserts. Instead +of using `addProperty` to register terminating assertions, simply use `addChainableNoop` +instead; the arguments to both are identical. The latter will make the assertion +available in both the attribute and function-call forms and should have no impact +on existing users of your plugin. + +### Community Contributions + +- [#297](https://github.com/chaijs/chai/pull/297) Allow writing lint-friendly tests. [@joshperry](https://github.com/joshperry) +- [#298](https://github.com/chaijs/chai/pull/298) Add check for logging `-0`. [@dasilvacontin](https://github.com/dasilvacontin) +- [#300](https://github.com/chaijs/chai/pull/300) Fix #299: the test is defining global variables [@julienw](https://github.com/julienw) + +Thank you to all who took time to contribute! + +## 1.9.2 / 2014-09-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#264](https://github.com/chaijs/chai/pull/264) Show diff for keys assertions [@cjthompson](https://github.com/cjthompson) +- [#267](https://github.com/chaijs/chai/pull/267) Use SVG badges [@shinnn](https://github.com/shinnn) +- [#268](https://github.com/chaijs/chai/pull/268) Allow messages to be functions (sinon-compat) [@charlierudolph](https://github.com/charlierudolph) +- [#269](https://github.com/chaijs/chai/pull/269) Remove unused argument for #lengthOf [@charlierudolph](https://github.com/charlierudolph) +- [#275](https://github.com/chaijs/chai/pull/275) Rewrite pretty-printing HTML elements to prevent throwing internal errors [@DrRataplan](https://github.com/DrRataplan) +- [#277](https://github.com/chaijs/chai/pull/277) Fix assert documentation for #sameMembers [@charlierudolph](https://github.com/charlierudolph) +- [#279](https://github.com/chaijs/chai/pull/279) closeTo should check value's type before assertion [@mohayonao](https://github.com/mohayonao) +- [#289](https://github.com/chaijs/chai/pull/289) satisfy is called twice [@charlierudolph](https://github.com/charlierudolph) +- [#292](https://github.com/chaijs/chai/pull/292) resolve conflicts with node-webkit and global usage [@boneskull](https://github.com/boneskull) + +Thank you to all who took time to contribute! + +## 1.9.1 / 2014-03-19 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Migrate configuration options to new interface. (see notes) +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Configuration + +There have been requests for changes and additions to the configuration mechanisms +and their impact in the Chai architecture. As such, we have decoupled the +configuration from the `Assertion` constructor. This not only allows for centralized +configuration, but will allow us to shift the responsibility from the `Assertion` +constructor to the `assert` interface in future releases. + +These changes have been implemented in a non-breaking way, but a depretiation +warning will be presented to users until they migrate. The old config method will +be removed in either `v1.11.0` or `v2.0.0`, whichever comes first. + +#### Quick Migration + +```js +// change this: +chai.Assertion.includeStack = true; +chai.Assertion.showDiff = false; + +// ... to this: +chai.config.includeStack = true; +chai.config.showDiff = false; +``` + +#### All Config Options + +##### config.includeStack + +- **@param** _{Boolean}_ +- **@default** `false` + +User configurable property, influences whether stack trace is included in +Assertion error message. Default of `false` suppresses stack trace in the error +message. + +##### config.showDiff + +- **@param** _{Boolean}_ +- **@default** `true` + +User configurable property, influences whether or not the `showDiff` flag +should be included in the thrown AssertionErrors. `false` will always be `false`; +`true` will be true when the assertion has requested a diff be shown. + +##### config.truncateThreshold **(NEW)** + +- **@param** _{Number}_ +- **@default** `40` + +User configurable property, sets length threshold for actual and expected values +in assertion errors. If this threshold is exceeded, the value is truncated. + +Set it to zero if you want to disable truncating altogether. + +```js +chai.config.truncateThreshold = 0; // disable truncating +``` + +### Community Contributions + +- [#228](https://github.com/chaijs/chai/pull/228) Deep equality check for memebers. [@duncanbeevers](https://github.com/duncanbeevers) +- [#247](https://github.com/chaijs/chai/pull/247) Proofreading. [@didorellano](https://github.com/didoarellano) +- [#244](https://github.com/chaijs/chai/pull/244) Fix `contain`/`include` 1.9.0 regression. [@leider](https://github.com/leider) +- [#233](https://github.com/chaijs/chai/pull/233) Improvements to `ssfi` for `assert` interface. [@refack](https://github.com/refack) +- [#251](https://github.com/chaijs/chai/pull/251) New config option: object display threshold. [@romario333](https://github.com/romario333) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#183](https://github.com/chaijs/chai/issues/183) Allow `undefined` for actual. (internal api) +- Update Karam(+plugins)/Istanbul to most recent versions. + +## 1.9.0 / 2014-01-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review [#219](https://github.com/chaijs/chai/pull/219). +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#202](https://github.com/chaijs/chai/pull/201) Improve error message for .throw(). [@andreineculau](https://github.com/andreineculau) +- [#217](https://github.com/chaijs/chai/pull/217) Chai tests can be run with `--watch`. [@demands](https://github.com/demands) +- [#219](https://github.com/chaijs/chai/pull/219) Add overwriteChainableMethod utility. [@demands](https://github.com/demands) +- [#224](https://github.com/chaijs/chai/pull/224) Return error on throw method to chain on error properties. [@vbardales](https://github.com/vbardales) +- [#226](https://github.com/chaijs/chai/pull/226) Add `has` to language chains. [@duncanbeevers](https://github.com/duncanbeevers) +- [#230](https://github.com/chaijs/chai/pull/230) Support `{a:1,b:2}.should.include({a:1})` [@jkroso](https://github.com/jkroso) +- [#231](https://github.com/chaijs/chai/pull/231) Update Copyright notices to 2014 [@duncanbeevers](https://github.com/duncanbeevers) +- [#232](https://github.com/chaijs/chai/pull/232) Avoid error instantiation if possible on assert.throws. [@laconbass](https://github.com/laconbass) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#225](https://github.com/chaijs/chai/pull/225) Improved AMD wrapper provided by upstream `component(1)`. +- [#185](https://github.com/chaijs/chai/issues/185) `assert.throws()` returns thrown error for further assertions. +- [#237](https://github.com/chaijs/chai/pull/237) Remove coveralls/jscoverage, include istanbul coverage report in travis test. +- Update Karma and Sauce runner versions for consistent CI results. No more karma@canary. + +## 1.8.1 / 2013-10-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Refresh `node_modules` folder for updated dependencies. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Browserify + +This is a small patch that updates the dependency tree so browserify users can install +chai. (Remove conditional requires) + +## 1.8.0 / 2013-09-18 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - See `deep.equal` notes. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Deep Equals + +This version of Chai focused on a overhaul to the deep equal utility. The code for this +tool has been removed from the core lib and can now be found at: +[chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases, +this is part of a larger initiative to provide transparency, independent testing, and coverage for +some of the more complicated internal tools. + +For the most part `.deep.equal` will behave the same as it has. However, in order to provide a +consistent ruleset across all types being tested, the following changes have been made and _might_ +require changes to your tests. + +**1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + +_Previously:_ Non-traversable equal via `===`. + +```js +expect(NaN).to.deep.equal(NaN); +expect(-0).to.not.deep.equal(+0); +``` + +**2.** Arguments are not Arrays (and all types must be equal): + +_Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates. + +```js +expect(arguments).to.not.deep.equal([]); +expect(Array.prototype.slice.call(arguments)).to.deep.equal([]); +``` + +- [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array +- [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object +- [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility + +### CI and Browser Testing + +Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at +[SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands... +and we get a cool badge: + +[![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox) + +Look for the list of browsers/versions to expand over the coming releases. + +- [#195](https://github.com/chaijs/chai/issues/195) karma test framework + +## 1.7.2 / 2013-06-27 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Coverage Reporting + +Coverage reporting has always been available for core-developers but the data has never been published +for our end users. In our ongoing effort to improve accountability this data will now be published via +the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report +can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs +will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI. + +### Other Fixes + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all) + +## 1.7.1 / 2013-06-24 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Official Bower Support + +Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though +Chai could be installed via Bower in the past, this update adds official support via the `bower.json` +specification file. + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. + +## 1.7.0 / 2013-06-17 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - Review AssertionError update notice. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### AssertionError Update Notice + +Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal +constructor. This will allow for further iteration/experimentation of the AssertionError constructor +independant of Chai. Future plans include stack parsing for callsite support. + +This update constructor has a different constructor param signature that conforms more with the standard +`Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin +with the new signature. + +```js +var AssertionError = require('chai').AssertionError; + +/** + * previous + * + * @param {Object} options + */ + +throw new AssertionError({ + message: 'An assertion error occurred' + , actual: actual + , expect: expect + , startStackFunction: arguments.callee + , showStack: true +}); + +/** + * new + * + * @param {String} message + * @param {Object} options + * @param {Function} start stack function + */ + +throw new AssertionError('An assertion error occurred', { + actual: actual + , expect: expect + , showStack: true +}, arguments.callee); + +// other signatures +throw new AssertionError('An assertion error occurred'); +throw new AssertionError('An assertion error occurred', null, arguments.callee); +``` + +#### External Dependencies + +This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding +more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing +there is an higher need for accountability and documentation. External dependencies will allow us to iterate and +test on features independent from our interfaces. + +Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai. + +### Community Contributions + +- [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek) +- [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds) +- [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic) + +Thank you to all who took the time to contribute! + +## 1.6.1 / 2013-06-05 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Deep Equality + +Regular Expressions are now tested as part of all deep equality assertions. In previous versions +they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution. + +### Community Contributions + +- [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton) +- [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek) + +Thank you to all who took the time to contribute! + +### Additional Notes + +- Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility. + +## 1.6.0 / 2013-04-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### New Assertions + +#### Array Members Inclusion + +Asserts that the target is a superset of `set`, or that the target and `set` have the same members. +Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution. + +```js +// (expect/should) full set +expect([4, 2]).to.have.members([2, 4]); +expect([5, 2]).to.not.have.members([5, 2, 1]); + +// (expect/should) inclusion +expect([1, 2, 3]).to.include.members([3, 2]); +expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + +// (assert) full set +assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + +// (assert) inclusion +assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + +``` + +#### Non-inclusion for Assert Interface + +Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`. +However `include()` did not have a corresponding `notInclude()`. This has been added. + +```js +assert.notInclude([ 1, 2, 3 ], 8); +assert.notInclude('foobar', 'baz'); +``` + +### Community Contributions + +- [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack. +- [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added. +- Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before. + +## 1.5.0 / 2013-02-03 + +### Migration Requirements + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of + [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions + to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139). +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Community Contributions + +- [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew) +- [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios. +- [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers. +- [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers. + + +### Usage Updates + +#### For Users + +**1. Component Support:** Chai now included the proper configuration to be installed as a +[component](https://github.com/component/component). Component users are encouraged to consult +[chaijs.com](http://chaijs.com) for the latest version number as using the master branch +does not gaurantee stability. + +```js +// relevant component.json + devDependencies: { + "chaijs/chai": "1.5.0" + } +``` + +Alternatively, bleeding-edge is available: + + $ component install chaijs/chai + +**2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/)) +include support for showing the diff of strings and objects when an equality error occurs. Chai has +already included support for this, however some users may not prefer this display behavior. To revert to +no diff display, the following configuration is available: + +```js +chai.Assertion.showDiff = false; // diff output disabled +chai.Assertion.showDiff = true; // default, diff output enabled +``` + +#### For Plugin Developers + +**1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof` +that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection. + +- **@param** _{Mixed}_ object to detect type of +- **@return** _{String}_ object type + +```js +chai.use(function (c, utils) { + // some examples + utils.type({}); // 'object' + utils.type(null); // `null' + utils.type(undefined); // `undefined` + utils.type([]); // `array` +}); +``` + +#### For Core Contributors + +**1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line +via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all +pull requests will now be browser tested in this way. + +_Note: Contributors opening pull requests should still NOT include the browser build._ + +**2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`. +Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account +and include their credentials in `./test/auth/sauce.json`. diff --git a/node_modules/chai/bower.json b/node_modules/chai/bower.json new file mode 100644 index 0000000..af2ee02 --- /dev/null +++ b/node_modules/chai/bower.json @@ -0,0 +1,26 @@ +{ + "name": "chai", + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "license": "MIT", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "main": "chai.js", + "ignore": [ + "build", + "components", + "lib", + "node_modules", + "support", + "test", + "index.js", + "Makefile", + ".*" + ], + "dependencies": {}, + "devDependencies": {} +} diff --git a/node_modules/chai/chai.js b/node_modules/chai/chai.js new file mode 100644 index 0000000..3763e16 --- /dev/null +++ b/node_modules/chai/chai.js @@ -0,0 +1,11300 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + * MIT Licensed + */ + +var used = []; + +/*! + * Chai version + */ + +exports.version = '4.3.8'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +},{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * - `eql`: This flag contains the deepEqual function to be used by the assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + */ + + function Assertion (obj, msg, ssfi, lockSsfi) { + flag(this, 'ssfi', ssfi || Assertion); + flag(this, 'lockSsfi', lockSsfi); + flag(this, 'object', obj); + flag(this, 'message', msg); + flag(this, 'eql', config.deepEqual || util.eql); + + return util.proxify(this); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + var assertionErrorObjectProperties = { + actual: actual + , expected: expected + , showDiff: showDiff + }; + + var operator = util.getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + + throw new AssertionError( + msg, + assertionErrorObjectProperties, + (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; + +},{"./config":4}],4:[function(require,module,exports){ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + + proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'], + + /** + * ### config.deepEqual + * + * User configurable property, defines which a custom function to use for deepEqual + * comparisons. + * By default, the function used is the one from the `deep-eql` package without custom comparator. + * + * // use a custom comparator + * chai.config.deepEqual = (expected, actual) => { + * return chai.util.eql(expected, actual, { + * comparator: (expected, actual) => { + * // for non number comparison, use the default behavior + * if(typeof expected !== 'number') return null; + * // allow a difference of 10 between compared numbers + * return typeof actual === 'number' && Math.abs(actual - expected) < 10 + * } + * }) + * }; + * + * @param {Function} + * @api public + */ + + deepEqual: null + +}; + +},{}],5:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , AssertionError = chai.AssertionError + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * - still + * - also + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been', 'is' + , 'and', 'has', 'have', 'with' + , 'that', 'which', 'at', 'of' + , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) { + Assertion.addProperty(chain); + }); + + /** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @api public + */ + + Assertion.addProperty('nested', function () { + flag(this, 'nested', true); + }); + + /** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @api public + */ + + Assertion.addProperty('own', function () { + flag(this, 'own', true); + }); + + /** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); + }); + + /** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); + }); + + /** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the `type-detect` project page for info on the + * type detection algorithm: https://github.com/chaijs/type-detect. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {String} type + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj).toLowerCase() + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; + } + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + if (msg) flag(this, 'message', msg); + + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : '' + , isEql = isDeep ? flag(this, 'eql') : SameValueZero; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + var included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return isEql(item, val); + }) + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'the given combination of arguments (' + + objType + ' and ' + + _.type(val).toLowerCase() + ')' + + ' is invalid for this assertion. ' + + 'You can use an array, a map, an object, a set, a string, ' + + 'or a weakset instead of a ' + + _.type(val).toLowerCase(), + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included + , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) + , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is a truthy value (considered `true` in boolean context). + * However, it's often best to assert that the target is strictly (`===`) or + * deeply equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , flag(this, 'negate') ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , flag(this, 'negate') ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * The alias `.exists` can be used interchangeably with `.exist`. + * + * @name exist + * @alias exists + * @namespace BDD + * @api public + */ + + function assertExist () { + var val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + } + + Assertion.addProperty('exist', assertExist); + Assertion.addProperty('exists', assertExist); + + /** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var val = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': + var msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that it’s not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = _.type(obj); + this.assert( + 'Arguments' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + var prevLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + this.eql(val); + flag(this, 'lockSsfi', prevLockSsfi); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {Mixed} obj + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + var eql = flag(this, 'eql'); + this.assert( + eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to above must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to above must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n + , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above #{exp}' + , 'expected #{this} to be at most #{exp}' + , n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with + * `.least`. + * + * @name least + * @alias gte + * @alias greaterThanOrEqual + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n + , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least #{exp}' + , 'expected #{this} to be below #{exp}' + , n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + Assertion.addMethod('greaterThanOrEqual', assertLeast); + + /** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n + , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below #{exp}' + , 'expected #{this} to be at least #{exp}' + , n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with + * `.most`. + * + * @name most + * @alias lte + * @alias lessThanOrEqual + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n + , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most #{exp}' + , 'expected #{this} to be above #{exp}' + , n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + Assertion.addMethod('lessThanOrEqual', assertMost); + + /** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `start`, and less + * than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {Number} start lower bound inclusive + * @param {Number} finish upper bound inclusive + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , startType = _.type(start).toLowerCase() + , finishType = _.type(finish).toLowerCase() + , errorMessage + , shouldThrow = true + , range = (startType === 'date' && finishType === 'date') + ? start.toISOString() + '..' + finish.toISOString() + : start + '..' + finish; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish + , 'expected #{this} to have a ' + descriptor + ' within ' + range + , 'expected #{this} to not have a ' + descriptor + ' within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + + var target = flag(this, 'object') + var ssfi = flag(this, 'ssfi'); + var flagMsg = flag(this, 'message'); + + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + var name = _.getName(constructor); + if (name === null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {String} name + * @param {Mixed} val (optional) + * @param {String} msg _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + function assertProperty (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isNested = flag(this, 'nested') + , isOwn = flag(this, 'own') + , flagMsg = flag(this, 'message') + , obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , nameType = typeof name; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + if (isNested) { + if (nameType !== 'string') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string when using nested syntax', + undefined, + ssfi + ); + } + } else { + if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string, number, or symbol', + undefined, + ssfi + ); + } + } + + if (isNested && isOwn) { + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + var isDeep = flag(this, 'deep') + , negate = flag(this, 'negate') + , pathInfo = isNested ? _.getPathInfo(obj, name) : null + , value = isNested ? pathInfo.value : obj[name] + , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;; + + var descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + var hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty + , 'expected #{this} to have ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && isEql(val, value) + , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + } + + Assertion.addMethod('property', assertProperty); + + function assertOwnProperty (name, value, msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but it’s not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + var eql = flag(this, 'eql'); + if (actualDescriptor && descriptor) { + this.assert( + eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` or `size` is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * expect(new Set([1, 2, 3])).to.have.lengthOf(3); + * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi') + , descriptor = 'length' + , itemsCount; + + switch (objType) { + case 'map': + case 'set': + descriptor = 'size'; + itemsCount = obj.size; + break; + default: + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + itemsCount = obj.length; + } + + this.assert( + itemsCount == n + , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' of #{act}' + , n + , itemsCount + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + + /** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string('taco', 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string('taco'); + * + * @name string + * @param {String} str + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + /** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , objType = _.type(obj) + , keysType = _.type(keys) + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , str + , deepStr = '' + , actual + , ok = true + , flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { actual.push(key) }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + var len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all') + , expected = keys + , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + deepStr + str + , 'expected #{this} to not ' + deepStr + str + , expected.slice(0).sort(_.compareByInspect) + , actual.sort(_.compareByInspect) + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error|ErrorConstructor} errorLike + * @param {String|RegExp} errMsgMatcher error message + * @param {String} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (errorLike instanceof RegExp || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + // We need this to display results correctly according to their types + var errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + this.assert( + caughtErr + , 'expected #{this} to throw ' + errorLikeString + , 'expected #{this} to not throw an error but #{act} was thrown' + , errorLike && errorLike.toString() + , (caughtErr instanceof Error ? + caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && + _.checkError.getConstructorName(caughtErr))) + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') + , errorLike.toString() + , caughtErr.toString() + ); + } + } + } + + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + var placeholder = 'including'; + if (errMsgMatcher instanceof RegExp) { + placeholder = 'matching' + } + + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' + , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' + , errMsgMatcher + , _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + + flag(this, 'object', caughtErr); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , flag(this, 'negate') ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.a('number'); + if (typeof expected !== 'number' || typeof delta !== 'number') { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var deltaMessage = delta === undefined ? ", and a delta is required" : ""; + throw new AssertionError( + flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage, + undefined, + ssfi + ); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + // Note: Duplicates are ignored if testing for inclusion instead of sameness. + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); + } + + /** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); + new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); + + var contains = flag(this, 'contains'); + var ordered = flag(this, 'ordered'); + + var subject, failMsg, failNegateMsg; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + var cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered) + , failMsg + , failNegateMsg + , subset + , obj + , true + ); + }); + + /** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * It can also be chained with `.contain` or `.include`, which will work with + * both arrays and strings: + * + * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) + * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) + * expect([1,2,3]).to.contain.oneOf([3,4,5]) + * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi') + , contains = flag(this, 'contains') + , isDeep = flag(this, 'deep') + , eql = flag(this, 'eql'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + if (contains) { + this.assert( + list.some(function(possibility) { return expected.indexOf(possibility) > -1 }) + , 'expected #{this} to contain one of #{exp}' + , 'expected #{this} to not contain one of #{exp}' + , list + , expected + ); + } else { + if (isDeep) { + this.assert( + list.some(function(possibility) { return eql(expected, possibility) }) + , 'expected #{this} to deeply equal one of #{exp}' + , 'expected #{this} to deeply equal one of #{exp}' + , list + , expected + ); + } else { + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + } + } + + Assertion.addMethod('oneOf', oneOf); + + /** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {String} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final + , 'expected ' + msgObj + ' to change' + , 'expected ' + msgObj + ' to not change' + ); + } + + Assertion.addMethod('change', assertChanges); + Assertion.addMethod('changes', assertChanges); + + /** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0 + , 'expected ' + msgObj + ' to increase' + , 'expected ' + msgObj + ' to not increase' + ); + } + + Assertion.addMethod('increase', assertIncreases); + Assertion.addMethod('increases', assertIncreases); + + /** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0 + , 'expected ' + msgObj + ' to decrease' + , 'expected ' + msgObj + ' to not decrease' + ); + } + + Assertion.addMethod('decrease', assertDecreases); + Assertion.addMethod('decreases', assertDecreases); + + /** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + var msgObj = flag(this, 'deltaMsgObj'); + var initial = flag(this, 'initialDeltaValue'); + var final = flag(this, 'finalDeltaValue'); + var behavior = flag(this, 'deltaBehavior'); + var realDelta = flag(this, 'realDelta'); + + var expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression + , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta + , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); + } + + Assertion.addMethod('by', assertDelta); + + /** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); + + /** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @api public + */ + + Assertion.addProperty('finite', function(msg) { + var obj = flag(this, 'object'); + + this.assert( + typeof obj === 'number' && isFinite(obj) + , 'expected #{this} to be a finite number' + , 'expected #{this} to not be a finite number' + ); + }); +}; + +},{}],6:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert, true); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * assert.fail(); + * assert.fail("custom error message"); + * assert.fail(1, 2); + * assert.fail(1, 2, "custom error message"); + * assert.fail(1, 2, "custom error message", ">"); + * assert.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + // Comply with Node's fail([message]) interface + + message = actual; + actual = undefined; + } + + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @alias deepStrictEqual + * @namespace Assert + * @api public + */ + + assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); + }; + + /** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; + }; + + /** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; + }; + + /** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; + }; + + /** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); + }; + + /** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true) + .to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and strictly equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, "array doesn't contain value"); + * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); + }; + + /** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); + }; + + /** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); + }; + + /** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); + }; + + /** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true) + .not.nested.include(inc); + }; + + /** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true) + .deep.nested.include(inc); + }; + + /** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepNestedInclude, true) + .not.deep.nested.include(inc); + }; + + /** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); + }; + + /** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); + }; + + /** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true) + .deep.own.include(inc); + }; + + /** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true) + .not.deep.own.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true) + .to.not.have.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true) + .to.have.property(prop, val); + }; + + /** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true) + .to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true) + .to.have.deep.property(prop, val); + }; + + /** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepPropertyVal, true) + .to.not.have.deep.property(prop, val); + }; + + /** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true) + .to.have.own.property(prop); + }; + + /** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true) + .to.not.have.own.property(prop); + }; + + /** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true) + .to.have.own.property(prop, value); + }; + + /** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notOwnPropertyVal, true) + .to.not.have.own.property(prop, value); + }; + + /** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.deepOwnPropertyVal, true) + .to.have.deep.own.property(prop, value); + }; + + /** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) + .to.not.have.deep.own.property(prop, value); + }; + + /** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true) + .to.have.nested.property(prop); + }; + + /** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notNestedProperty, true) + .to.not.have.nested.property(prop); + }; + + /** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.nestedPropertyVal, true) + .to.have.nested.property(prop, val); + }; + + /** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notNestedPropertyVal, true) + .to.not.have.nested.property(prop, val); + }; + + /** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepNestedPropertyVal, true) + .to.have.deep.nested.property(prop, val); + }; + + /** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) + .to.not.have.deep.nested.property(prop, val); + } + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` or `size` with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); + * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); + }; + + /** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); + } + + /** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); + } + + /** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true) + .to.contain.all.keys(keys); + } + + /** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) + .to.not.have.any.keys(keys); + } + + /** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) + .to.not.have.all.keys(keys); + } + + /** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true) + .to.have.any.deep.keys(keys); + } + + /** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true) + .to.have.all.deep.keys(keys); + } + + /** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllDeepKeys, true) + .to.contain.all.deep.keys(keys); + } + + /** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) + .to.not.have.any.deep.keys(keys); + } + + /** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) + .to.not.have.all.deep.keys(keys); + } + + /** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'Error thrown must have this msg'); + * assert.throws(fn, /Error thrown must have a msg that matches this/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {ErrorConstructor|Error} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + var assertErr = new Assertion(fn, msg, assert.throws, true) + .to.throw(errorLike, errMsgMatcher); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {ErrorConstructor} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, msg, assert.doesNotThrow, true) + .to.not.throw(errorLike, errMsgMatcher); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new chai.AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + var test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true) + .to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true) + .to.have.same.members(set2); + } + + /** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameMembers, true) + .to.not.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepMembers, true) + .to.have.same.deep.members(set2); + } + + /** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepMembers, true) + .to.not.have.same.deep.members(set2); + } + + /** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameOrderedMembers, true) + .to.have.same.ordered.members(set2); + } + + /** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameOrderedMembers, true) + .to.not.have.same.ordered.members(set2); + } + + /** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) + .to.have.same.deep.ordered.members(set2); + } + + /** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) + .to.not.have.same.deep.ordered.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true) + .to.include.members(subset); + } + + /** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeMembers, true) + .to.not.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepMembers, true) + .to.include.deep.members(subset); + } + + /** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepMembers, true) + .to.not.include.deep.members(subset); + } + + /** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeOrderedMembers, true) + .to.include.ordered.members(subset); + } + + /** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) + .to.not.include.ordered.members(subset); + } + + /** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) + .to.include.deep.ordered.members(subset); + } + + /** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) + .to.not.include.deep.ordered.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); + } + + /** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true) + .to.change(obj, prop).by(delta); + } + + /** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true) + .to.not.change(obj, prop); + } + + /** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true) + .to.change(obj, prop).but.not.by(delta); + } + + /** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true) + .to.increase(obj, prop); + } + + /** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @name increasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true) + .to.increase(obj, prop).by(delta); + } + + /** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true) + .to.not.increase(obj, prop); + } + + /** + * ### .increasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true) + .to.increase(obj, prop).but.not.by(delta); + } + + /** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true) + .to.decrease(obj, prop); + } + + /** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true) + .to.decrease(obj, prop).by(delta); + } + + /** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true) + .to.not.decrease(obj, prop); + } + + /** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecreaseBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) + .to.not.decrease(obj, prop).by(delta); + } + + /** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true) + .to.decrease(obj, prop).but.not.by(delta); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; + }; + + /** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; + }; + + /** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen') + ('isEmpty', 'empty') + ('isNotEmpty', 'notEmpty'); +}; + +},{}],7:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * expect.fail(); + * expect.fail("custom error message"); + * expect.fail(1, 2); + * expect.fail(1, 2, "custom error message"); + * expect.fail(1, 2, "custom error message", ">"); + * expect.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; + +},{}],8:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String + || this instanceof Number + || this instanceof Boolean + || typeof Symbol === 'function' && this instanceof Symbol + || typeof BigInt === 'function' && this instanceof BigInt) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * should.fail(); + * should.fail("custom error message"); + * should.fail(1, 2); + * should.fail(1, 2, "custom error message"); + * should.fail(1, 2, "custom error message", ">"); + * should.fail(1, 2, undefined, ">"); + * + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; + +},{}],9:[function(require,module,exports){ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/*! + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +var canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +var testFn = function() {}; +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') + return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + var chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + var result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + } + , configurable: true + }); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){ +var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {String} assertionName + * @param {Boolean} isChainable + * @namespace Utils + * @name addLengthGuard + */ + +module.exports = function addLengthGuard (fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + + throw Error('Invalid Chai property: ' + assertionName + '.length. See' + + ' docs for proper usage of "' + assertionName + '".'); + } + }); + + return fn; +}; + +},{}],11:[function(require,module,exports){ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ + +module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + var result = method.apply(this, arguments); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, + { get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + var result = getter.call(this); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {Mixed} first element to compare + * @param {Mixed} second element to compare + * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @api public + */ + +module.exports = function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +}; + +},{"./inspect":23}],14:[function(require,module,exports){ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, 'message'); + var ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + var objType = type(obj).toLowerCase(); + + if (!types.some(function (expected) { return objType === expected; })) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +}; + +},{"./flag":15,"assertion-error":33,"type-detect":39}],15:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; + +},{}],16:[function(require,module,exports){ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; + +},{}],17:[function(require,module,exports){ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function getMessage(obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; + +},{"./flag":15,"./getActual":16,"./objDisplay":26}],18:[function(require,module,exports){ +var type = require('type-detect'); + +var flag = require('./flag'); + +function isObjectType(obj) { + var objectType = type(obj); + var objectTypes = ['Array', 'Object', 'function']; + + return objectTypes.indexOf(objectType) !== -1; +} + +/** + * ### .getOperator(message) + * + * Extract the operator from error message. + * Operator defined is based on below link + * https://nodejs.org/api/assert.html#assert_assert. + * + * Returns the `operator` or `undefined` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getOperator + * @api public + */ + +module.exports = function getOperator(obj, args) { + var operator = flag(obj, 'operator'); + var negate = flag(obj, 'negate'); + var expected = args[3]; + var msg = negate ? args[2] : args[1]; + + if (operator) { + return operator; + } + + if (typeof msg === 'function') msg = msg(); + + msg = msg || ''; + if (!msg) { + return undefined; + } + + if (/\shave\s/.test(msg)) { + return undefined; + } + + var isObject = isObjectType(expected); + if (/\snot\s/.test(msg)) { + return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; + } + + return isObject ? 'deepStrictEqual' : 'strictEqual'; +}; + +},{"./flag":15,"type-detect":39}],19:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @api public + */ + +module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +}; + +},{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @api public + */ + +module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +}; + +},{}],21:[function(require,module,exports){ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; + +},{}],22:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Dependencies that are used for multiple exports are required here only once + */ + +var pathval = require('pathval'); + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path info + */ + +exports.getPathInfo = pathval.getPathInfo; + +/*! + * Check if a property exists + */ + +exports.hasProperty = pathval.hasProperty; + +/*! + * Function name + */ + +exports.getName = require('get-func-name'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +/*! + * Compare by inspect method + */ + +exports.compareByInspect = require('./compareByInspect'); + +/*! + * Get own enumerable property symbols method + */ + +exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/*! + * Get own enumerable properties method + */ + +exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); + +/*! + * Checks error against a given set of criteria + */ + +exports.checkError = require('check-error'); + +/*! + * Proxify util + */ + +exports.proxify = require('./proxify'); + +/*! + * addLengthGuard util + */ + +exports.addLengthGuard = require('./addLengthGuard'); + +/*! + * isProxyEnabled helper + */ + +exports.isProxyEnabled = require('./isProxyEnabled'); + +/*! + * isNaN method + */ + +exports.isNaN = require('./isNaN'); + +/*! + * getOperator method + */ + +exports.getOperator = require('./getOperator'); +},{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":17,"./getOperator":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":36,"pathval":38,"type-detect":39}],23:[function(require,module,exports){ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('get-func-name'); +var loupe = require('loupe'); +var config = require('../config'); + +module.exports = inspect; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var options = { + colors: colors, + depth: (typeof depth === 'undefined' ? 2 : depth), + showHidden: showHidden, + truncate: config.truncateThreshold ? config.truncateThreshold : Infinity, + }; + return loupe.inspect(obj, options); +} + +},{"../config":4,"get-func-name":36,"loupe":37}],24:[function(require,module,exports){ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +/** + * ### .isNaN(value) + * + * Checks if the given value is NaN or not. + * + * utils.isNaN(NaN); // true + * + * @param {Value} The value which has to be checked if it is NaN + * @name isNaN + * @api private + */ + +function isNaN(value) { + // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number + // section's NOTE. + return value !== value; +} + +// If ECMAScript 6's Number.isNaN is present, prefer that. +module.exports = Number.isNaN || isNaN; + +},{}],25:[function(require,module,exports){ +var config = require('../config'); + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + */ + +module.exports = function isProxyEnabled() { + return config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined'; +}; + +},{"../config":4}],26:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @returns {string} stringified object + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function objDisplay(obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; + +},{"../config":4,"./inspect":23}],27:[function(require,module,exports){ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwrites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +}; + +},{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwrites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name] + , _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) + _super = _method; + + var overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwrites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){ +var config = require('../config'); +var flag = require('./flag'); +var getProperties = require('./getProperties'); +var isProxyEnabled = require('./isProxyEnabled'); + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @param {Object} obj + * @param {String} nonChainableMethodName + * @namespace Utils + * @name proxify + */ + +var builtins = ['__flags', '__methods', '_obj', 'assert']; + +module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if (typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property)) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + + property + '. See docs for proper usage of "' + + nonChainableMethodName + '".'); + } + + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. Only suggest properties with a + // distance less than 4. + var suggestion = null; + var suggestionDistance = 4; + getProperties(target).forEach(function(prop) { + if ( + !Object.prototype.hasOwnProperty(prop) && + builtins.indexOf(prop) === -1 + ) { + var dist = stringDistanceCapped( + property, + prop, + suggestionDistance + ); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + + if (suggestion !== null) { + throw Error('Invalid Chai property: ' + property + + '. Did you mean "' + suggestion + '"?'); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +}; + +/** + * # stringDistanceCapped(strA, strB, cap) + * Return the Levenshtein distance between two strings, but no more than cap. + * @param {string} strA + * @param {string} strB + * @param {number} number + * @return {number} min(string distance between strA and strB, cap) + * @api private + */ + +function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + + var memo = []; + // `memo` is a two-dimensional array containing distances. + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + for (var i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (var j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + + for (var i = 1; i <= strA.length; i++) { + var ch = strA.charCodeAt(i - 1); + for (var j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} + +},{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag'); + +/** + * ### .test(object, expression) + * + * Test an object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function test(obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; + +},{"./flag":15}],32:[function(require,module,exports){ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAssertion = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; + +},{}],33:[function(require,module,exports){ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || AssertionError; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch(e) { + this.stack = e.stack; + } + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; + +},{}],34:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - checkError utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +var getFunctionName = require('get-func-name'); +/** + * ### .checkError + * + * Checks that an error conforms to a given set of criteria and/or retrieves information about it. + * + * @api public + */ + +/** + * ### .compatibleInstance(thrown, errorLike) + * + * Checks if two instances are compatible (strict equal). + * Returns false if errorLike is not an instance of Error, because instances + * can only be compatible if they're both error instances. + * + * @name compatibleInstance + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleInstance(thrown, errorLike) { + return errorLike instanceof Error && thrown === errorLike; +} + +/** + * ### .compatibleConstructor(thrown, errorLike) + * + * Checks if two constructors are compatible. + * This function can receive either an error constructor or + * an error instance as the `errorLike` argument. + * Constructors are compatible if they're the same or if one is + * an instance of another. + * + * @name compatibleConstructor + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleConstructor(thrown, errorLike) { + if (errorLike instanceof Error) { + // If `errorLike` is an instance of any error we compare their constructors + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if (errorLike.prototype instanceof Error || errorLike === Error) { + // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + + return false; +} + +/** + * ### .compatibleMessage(thrown, errMatcher) + * + * Checks if an error's message is compatible with a matcher (String or RegExp). + * If the message contains the String or passes the RegExp test, + * it is considered compatible. + * + * @name compatibleMessage + * @param {Error} thrown error + * @param {String|RegExp} errMatcher to look for into the message + * @namespace Utils + * @api public + */ + +function compatibleMessage(thrown, errMatcher) { + var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; + if (errMatcher instanceof RegExp) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === 'string') { + return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers + } + + return false; +} + +/** + * ### .getConstructorName(errorLike) + * + * Gets the constructor name for an Error instance or constructor itself. + * + * @name getConstructorName + * @param {Error|ErrorConstructor} errorLike + * @namespace Utils + * @api public + */ + +function getConstructorName(errorLike) { + var constructorName = errorLike; + if (errorLike instanceof Error) { + constructorName = getFunctionName(errorLike.constructor); + } else if (typeof errorLike === 'function') { + // If `err` is not an instance of Error it is an error constructor itself or another function. + // If we've got a common function we get its name, otherwise we may need to create a new instance + // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. + constructorName = getFunctionName(errorLike); + if (constructorName === '') { + var newConstructorName = getFunctionName(new errorLike()); // eslint-disable-line new-cap + constructorName = newConstructorName || constructorName; + } + } + + return constructorName; +} + +/** + * ### .getMessage(errorLike) + * + * Gets the error message from an error. + * If `err` is a String itself, we return it. + * If the error has no message, we return an empty string. + * + * @name getMessage + * @param {Error|String} errorLike + * @namespace Utils + * @api public + */ + +function getMessage(errorLike) { + var msg = ''; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === 'string') { + msg = errorLike; + } + + return msg; +} + +module.exports = { + compatibleInstance: compatibleInstance, + compatibleConstructor: compatibleConstructor, + compatibleMessage: compatibleMessage, + getMessage: getMessage, + getConstructorName: getConstructorName, +}; + +},{"get-func-name":36}],35:[function(require,module,exports){ +'use strict'; +/* globals Symbol: false, Uint8Array: false, WeakMap: false */ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); +function FakeMap() { + this._key = 'chai/deep-eql__' + Math.random() + Date.now(); +} + +FakeMap.prototype = { + get: function get(key) { + return key[this._key]; + }, + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value: value, + configurable: true, + }); + } + }, +}; + +var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; +/*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result +*/ +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === 'boolean') { + return result; + } + } + return null; +} + +/*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result +*/ +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; +module.exports.MemoizeMap = MemoizeMap; + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + */ +function deepEqual(leftHandOperand, rightHandOperand, options) { + // If we have a comparator, we can't assume anything; so bail to its check first. + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + + // Deeper comparisons are pushed through to a larger function + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} + +/** + * Many comparisons can be canceled out early via simple equality or primitive checks. + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @return {Boolean|null} equal match + */ +function simpleEqual(leftHandOperand, rightHandOperand) { + // Equal references (except for Numbers) can be returned early + if (leftHandOperand === rightHandOperand) { + // Handle +-0 cases + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + + // handle NaN cases + if ( + leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare + ) { + return true; + } + + // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, + // strings, and undefined, can be compared by reference. + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + // Easy out b/c it would have passed the first equality check + return false; + } + return null; +} + +/*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match +*/ +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + + // Check if a memoized result exists. + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + + // If a comparator is present, use it. + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + // Comparators may return null, in which case we want to go back to default behavior. + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide + // what to do, we need to make sure to return the basic tests first before we move on. + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + // Don't memoize this, it takes longer to set/retrieve than to just compare. + return simpleResult; + } + } + + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + + // Temporarily set the operands in the memoize object to prevent blowing the stack + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} + +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case 'String': + case 'Number': + case 'Boolean': + case 'Date': + // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case 'Promise': + case 'Symbol': + case 'function': + case 'WeakMap': + case 'WeakSet': + return leftHandOperand === rightHandOperand; + case 'Error': + return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options); + case 'Arguments': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'Array': + return iterableEqual(leftHandOperand, rightHandOperand, options); + case 'RegExp': + return regexpEqual(leftHandOperand, rightHandOperand); + case 'Generator': + return generatorEqual(leftHandOperand, rightHandOperand, options); + case 'DataView': + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case 'ArrayBuffer': + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case 'Set': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Map': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Temporal.PlainDate': + case 'Temporal.PlainTime': + case 'Temporal.PlainDateTime': + case 'Temporal.Instant': + case 'Temporal.ZonedDateTime': + case 'Temporal.PlainYearMonth': + case 'Temporal.PlainMonthDay': + return leftHandOperand.equals(rightHandOperand); + case 'Temporal.Duration': + return leftHandOperand.total('nanoseconds') === rightHandOperand.total('nanoseconds'); + case 'Temporal.TimeZone': + case 'Temporal.Calendar': + return leftHandOperand.toString() === rightHandOperand.toString(); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} + +/*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + */ + +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} + +/*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function entriesEqual(leftHandOperand, rightHandOperand, options) { + // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([ key, value ]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([ key, value ]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} + +/*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} + +/*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} + +/*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + */ +function hasIteratorFunction(target) { + return typeof Symbol !== 'undefined' && + typeof target === 'object' && + typeof Symbol.iterator !== 'undefined' && + typeof target[Symbol.iterator] === 'function'; +} + +/*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + */ +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} + +/*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + */ +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [ generatorResult.value ]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} + +/*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + */ +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} + +function getEnumerableSymbols(target) { + var keys = []; + var allKeys = Object.getOwnPropertySymbols(target); + for (var i = 0; i < allKeys.length; i += 1) { + var key = allKeys[i]; + if (Object.getOwnPropertyDescriptor(target, key).enumerable) { + keys.push(key); + } + } + return keys; +} + +/*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} + +/*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + var leftHandSymbols = getEnumerableSymbols(leftHandOperand); + var rightHandSymbols = getEnumerableSymbols(rightHandOperand); + leftHandKeys = leftHandKeys.concat(leftHandSymbols); + rightHandKeys = rightHandKeys.concat(rightHandSymbols); + + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + + if (leftHandKeys.length === 0 && + leftHandEntries.length === 0 && + rightHandKeys.length === 0 && + rightHandEntries.length === 0) { + return true; + } + + return false; +} + +/*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + */ +function isPrimitive(value) { + return value === null || typeof value !== 'object'; +} + +function mapSymbols(arr) { + return arr.map(function mapSymbol(entry) { + if (typeof entry === 'symbol') { + return entry.toString(); + } + + return entry; + }); +} + +},{"type-detect":39}],36:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - getFuncName utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + +var toString = Function.prototype.toString; +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; +var maxFunctionSourceLength = 512; +function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // eslint-disable-next-line prefer-reflect + var functionSource = toString.call(aFunc); + // To avoid unconstrained resource consumption due to pathalogically large function names, + // we limit the available return value to be less than 512 characters. + if (functionSource.indexOf('(') > maxFunctionSourceLength) { + return name; + } + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = functionSource.match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; +} + +module.exports = getFuncName; + +},{}],37:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.loupe = {})); +}(this, (function (exports) { 'use strict'; + + function _typeof(obj) { + "@babel/helpers - typeof"; + + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArrayLimit(arr, i) { + if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var ansiColors = { + bold: ['1', '22'], + dim: ['2', '22'], + italic: ['3', '23'], + underline: ['4', '24'], + // 5 & 6 are blinking + inverse: ['7', '27'], + hidden: ['8', '28'], + strike: ['9', '29'], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ['30', '39'], + red: ['31', '39'], + green: ['32', '39'], + yellow: ['33', '39'], + blue: ['34', '39'], + magenta: ['35', '39'], + cyan: ['36', '39'], + white: ['37', '39'], + brightblack: ['30;1', '39'], + brightred: ['31;1', '39'], + brightgreen: ['32;1', '39'], + brightyellow: ['33;1', '39'], + brightblue: ['34;1', '39'], + brightmagenta: ['35;1', '39'], + brightcyan: ['36;1', '39'], + brightwhite: ['37;1', '39'], + grey: ['90', '39'] + }; + var styles = { + special: 'cyan', + number: 'yellow', + bigint: 'yellow', + boolean: 'yellow', + undefined: 'grey', + null: 'bold', + string: 'green', + symbol: 'green', + date: 'magenta', + regexp: 'red' + }; + var truncator = '…'; + + function colorise(value, styleType) { + var color = ansiColors[styles[styleType]] || ansiColors[styleType]; + + if (!color) { + return String(value); + } + + return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m"); + } + + function normaliseOptions() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref$showHidden = _ref.showHidden, + showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden, + _ref$depth = _ref.depth, + depth = _ref$depth === void 0 ? 2 : _ref$depth, + _ref$colors = _ref.colors, + colors = _ref$colors === void 0 ? false : _ref$colors, + _ref$customInspect = _ref.customInspect, + customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect, + _ref$showProxy = _ref.showProxy, + showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy, + _ref$maxArrayLength = _ref.maxArrayLength, + maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength, + _ref$breakLength = _ref.breakLength, + breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength, + _ref$seen = _ref.seen, + seen = _ref$seen === void 0 ? [] : _ref$seen, + _ref$truncate = _ref.truncate, + truncate = _ref$truncate === void 0 ? Infinity : _ref$truncate, + _ref$stylize = _ref.stylize, + stylize = _ref$stylize === void 0 ? String : _ref$stylize; + + var options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate), + seen: seen, + stylize: stylize + }; + + if (options.colors) { + options.stylize = colorise; + } + + return options; + } + function truncate(string, length) { + var tail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : truncator; + string = String(string); + var tailLength = tail.length; + var stringLength = string.length; + + if (tailLength > length && stringLength > tailLength) { + return tail; + } + + if (stringLength > length && stringLength > tailLength) { + return "".concat(string.slice(0, length - tailLength)).concat(tail); + } + + return string; + } // eslint-disable-next-line complexity + + function inspectList(list, options, inspectItem) { + var separator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ', '; + inspectItem = inspectItem || options.inspect; + var size = list.length; + if (size === 0) return ''; + var originalLength = options.truncate; + var output = ''; + var peek = ''; + var truncated = ''; + + for (var i = 0; i < size; i += 1) { + var last = i + 1 === list.length; + var secondToLast = i + 2 === list.length; + truncated = "".concat(truncator, "(").concat(list.length - i, ")"); + var value = list[i]; // If there is more than one remaining we need to account for a separator of `, ` + + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + var string = peek || inspectItem(value, options) + (last ? '' : separator); + var nextLength = output.length + string.length; + var truncatedLength = nextLength + truncated.length; // If this is the last element, and adding it would + // take us over length, but adding the truncator wouldn't - then break now + + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } // If this isn't the last or second to last element to scan, + // but the string is already over length then break here + + + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } // Peek at the next string to determine if we should + // break early before adding this item to the output + + + peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator); // If we have one element left, but this element and + // the next takes over length, the break early + + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + + output += string; // If the next element takes us to length - + // but there are more after that, then we should truncate now + + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")"); + break; + } + + truncated = ''; + } + + return "".concat(output).concat(truncated); + } + + function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + + return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); + } + + function inspectProperty(_ref2, options) { + var _ref3 = _slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; + + options.truncate -= 2; + + if (typeof key === 'string') { + key = quoteComplexKey(key); + } else if (typeof key !== 'number') { + key = "[".concat(options.inspect(key, options), "]"); + } + + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, ": ").concat(value); + } + + function inspectArray(array, options) { + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return '[]'; + options.truncate -= 4; + var listContents = inspectList(array, options); + options.truncate -= listContents.length; + var propertyContents = ''; + + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function (key) { + return [key, array[key]]; + }), options, inspectProperty); + } + + return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); + } + + /* ! + * Chai - getFuncName utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + + /** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + + var toString = Function.prototype.toString; + var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; + function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = toString.call(aFunc).match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; + } + + var getFuncName_1 = getFuncName; + + var getArrayName = function getArrayName(array) { + // We need to special case Node.js' Buffers, which report to be Uint8Array + if (typeof Buffer === 'function' && array instanceof Buffer) { + return 'Buffer'; + } + + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + + return getFuncName_1(array.constructor); + }; + + function inspectTypedArray(array, options) { + var name = getArrayName(array); + options.truncate -= name.length + 4; // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return "".concat(name, "[]"); // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply + // stylise the toString() value of them + + var output = ''; + + for (var i = 0; i < array.length; i++) { + var string = "".concat(options.stylize(truncate(array[i], options.truncate), 'number')).concat(i === array.length - 1 ? '' : ', '); + options.truncate -= string.length; + + if (array[i] !== array.length && options.truncate <= 3) { + output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")"); + break; + } + + output += string; + } + + var propertyContents = ''; + + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function (key) { + return [key, array[key]]; + }), options, inspectProperty); + } + + return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); + } + + function inspectDate(dateObject, options) { + var stringRepresentation = dateObject.toJSON(); + + if (stringRepresentation === null) { + return 'Invalid Date'; + } + + var split = stringRepresentation.split('T'); + var date = split[0]; // If we need to - truncate the time portion, but never the date + + return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), 'date'); + } + + function inspectFunction(func, options) { + var name = getFuncName_1(func); + + if (!name) { + return options.stylize('[Function]', 'special'); + } + + return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), 'special'); + } + + function inspectMapEntry(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, " => ").concat(value); + } // IE11 doesn't support `map.entries()` + + + function mapToEntries(map) { + var entries = []; + map.forEach(function (value, key) { + entries.push([key, value]); + }); + return entries; + } + + function inspectMap(map, options) { + var size = map.size - 1; + + if (size <= 0) { + return 'Map{}'; + } + + options.truncate -= 7; + return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }"); + } + + var isNaN = Number.isNaN || function (i) { + return i !== i; + }; // eslint-disable-line no-self-compare + + + function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize('NaN', 'number'); + } + + if (number === Infinity) { + return options.stylize('Infinity', 'number'); + } + + if (number === -Infinity) { + return options.stylize('-Infinity', 'number'); + } + + if (number === 0) { + return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number'); + } + + return options.stylize(truncate(number, options.truncate), 'number'); + } + + function inspectBigInt(number, options) { + var nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) nums += 'n'; + return options.stylize(nums, 'bigint'); + } + + function inspectRegExp(value, options) { + var flags = value.toString().split('/')[2]; + var sourceLength = options.truncate - (2 + flags.length); + var source = value.source; + return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), 'regexp'); + } + + function arrayFromSet(set) { + var values = []; + set.forEach(function (value) { + values.push(value); + }); + return values; + } + + function inspectSet(set, options) { + if (set.size === 0) return 'Set{}'; + options.truncate -= 7; + return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }"); + } + + var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + "\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", 'g'); + var escapeCharacters = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + "'": "\\'", + '\\': '\\\\' + }; + var hex = 16; + var unicodeLength = 4; + + function escape(char) { + return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength)); + } + + function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape); + } + + return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), 'string'); + } + + function inspectSymbol(value) { + if ('description' in Symbol.prototype) { + return value.description ? "Symbol(".concat(value.description, ")") : 'Symbol()'; + } + + return value.toString(); + } + + var getPromiseValue = function getPromiseValue() { + return 'Promise{…}'; + }; + + try { + var _process$binding = process.binding('util'), + getPromiseDetails = _process$binding.getPromiseDetails, + kPending = _process$binding.kPending, + kRejected = _process$binding.kRejected; + + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = function getPromiseValue(value, options) { + var _getPromiseDetails = getPromiseDetails(value), + _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2), + state = _getPromiseDetails2[0], + innerValue = _getPromiseDetails2[1]; + + if (state === kPending) { + return 'Promise{}'; + } + + return "Promise".concat(state === kRejected ? '!' : '', "{").concat(options.inspect(innerValue, options), "}"); + }; + } + } catch (notNode) { + /* ignore */ + } + + var inspectPromise = getPromiseValue; + + function inspectObject(object, options) { + var properties = Object.getOwnPropertyNames(object); + var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + + if (properties.length === 0 && symbols.length === 0) { + return '{}'; + } + + options.truncate -= 4; + options.seen = options.seen || []; + + if (options.seen.indexOf(object) >= 0) { + return '[Circular]'; + } + + options.seen.push(object); + var propertyContents = inspectList(properties.map(function (key) { + return [key, object[key]]; + }), options, inspectProperty); + var symbolContents = inspectList(symbols.map(function (key) { + return [key, object[key]]; + }), options, inspectProperty); + options.seen.pop(); + var sep = ''; + + if (propertyContents && symbolContents) { + sep = ', '; + } + + return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }"); + } + + var toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false; + function inspectClass(value, options) { + var name = ''; + + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + + name = name || getFuncName_1(value.constructor); // Babel transforms anonymous classes to the name `_class` + + if (!name || name === '_class') { + name = ''; + } + + options.truncate -= name.length; + return "".concat(name).concat(inspectObject(value, options)); + } + + function inspectArguments(args, options) { + if (args.length === 0) return 'Arguments[]'; + options.truncate -= 13; + return "Arguments[ ".concat(inspectList(args, options), " ]"); + } + + var errorKeys = ['stack', 'line', 'column', 'name', 'message', 'fileName', 'lineNumber', 'columnNumber', 'number', 'description']; + function inspectObject$1(error, options) { + var properties = Object.getOwnPropertyNames(error).filter(function (key) { + return errorKeys.indexOf(key) === -1; + }); + var name = error.name; + options.truncate -= name.length; + var message = ''; + + if (typeof error.message === 'string') { + message = truncate(error.message, options.truncate); + } else { + properties.unshift('message'); + } + + message = message ? ": ".concat(message) : ''; + options.truncate -= message.length + 5; + var propertyContents = inspectList(properties.map(function (key) { + return [key, error[key]]; + }), options, inspectProperty); + return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : ''); + } + + function inspectAttribute(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + options.truncate -= 3; + + if (!value) { + return "".concat(options.stylize(key, 'yellow')); + } + + return "".concat(options.stylize(key, 'yellow'), "=").concat(options.stylize("\"".concat(value, "\""), 'string')); + } + function inspectHTMLCollection(collection, options) { + // eslint-disable-next-line no-use-before-define + return inspectList(collection, options, inspectHTML, '\n'); + } + function inspectHTML(element, options) { + var properties = element.getAttributeNames(); + var name = element.tagName.toLowerCase(); + var head = options.stylize("<".concat(name), 'special'); + var headClose = options.stylize(">", 'special'); + var tail = options.stylize(""), 'special'); + options.truncate -= name.length * 2 + 5; + var propertyContents = ''; + + if (properties.length > 0) { + propertyContents += ' '; + propertyContents += inspectList(properties.map(function (key) { + return [key, element.getAttribute(key)]; + }), options, inspectAttribute, ' '); + } + + options.truncate -= propertyContents.length; + var truncate = options.truncate; + var children = inspectHTMLCollection(element.children, options); + + if (children && children.length > truncate) { + children = "".concat(truncator, "(").concat(element.children.length, ")"); + } + + return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail); + } + + var symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function'; + var chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect'; + var nodeInspect = false; + + try { + // eslint-disable-next-line global-require + var nodeUtil = require('util'); + + nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; + } catch (noNodeInspect) { + nodeInspect = false; + } + + function FakeMap() { + // eslint-disable-next-line prefer-template + this.key = 'chai/loupe__' + Math.random() + Date.now(); + } + + FakeMap.prototype = { + // eslint-disable-next-line object-shorthand + get: function get(key) { + return key[this.key]; + }, + // eslint-disable-next-line object-shorthand + has: function has(key) { + return this.key in key; + }, + // eslint-disable-next-line object-shorthand + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this.key, { + // eslint-disable-next-line object-shorthand + value: value, + configurable: true + }); + } + } + }; + var constructorMap = new (typeof WeakMap === 'function' ? WeakMap : FakeMap)(); + var stringTagMap = {}; + var baseTypesMap = { + undefined: function undefined$1(value, options) { + return options.stylize('undefined', 'undefined'); + }, + null: function _null(value, options) { + return options.stylize(null, 'null'); + }, + boolean: function boolean(value, options) { + return options.stylize(value, 'boolean'); + }, + Boolean: function Boolean(value, options) { + return options.stylize(value, 'boolean'); + }, + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: inspectPromise, + // WeakSet, WeakMap are totally opaque to us + WeakSet: function WeakSet(value, options) { + return options.stylize('WeakSet{…}', 'special'); + }, + WeakMap: function WeakMap(value, options) { + return options.stylize('WeakMap{…}', 'special'); + }, + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: function Generator() { + return ''; + }, + DataView: function DataView() { + return ''; + }, + ArrayBuffer: function ArrayBuffer() { + return ''; + }, + Error: inspectObject$1, + HTMLCollection: inspectHTMLCollection, + NodeList: inspectHTMLCollection + }; // eslint-disable-next-line complexity + + var inspectCustom = function inspectCustom(value, options, type) { + if (chaiInspect in value && typeof value[chaiInspect] === 'function') { + return value[chaiInspect](options); + } + + if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') { + return value[nodeInspect](options.depth, options); + } + + if ('inspect' in value && typeof value.inspect === 'function') { + return value.inspect(options.depth, options); + } + + if ('constructor' in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + + if (stringTagMap[type]) { + return stringTagMap[type](value, options); + } + + return ''; + }; + + var toString$1 = Object.prototype.toString; // eslint-disable-next-line complexity + + function inspect(value, options) { + options = normaliseOptions(options); + options.inspect = inspect; + var _options = options, + customInspect = _options.customInspect; + var type = value === null ? 'null' : _typeof(value); + + if (type === 'object') { + type = toString$1.call(value).slice(8, -1); + } // If it is a base value that we already support, then use Loupe's inspector + + + if (baseTypesMap[type]) { + return baseTypesMap[type](value, options); + } // If `options.customInspect` is set to true then try to use the custom inspector + + + if (customInspect && value) { + var output = inspectCustom(value, options, type); + + if (output) { + if (typeof output === 'string') return output; + return inspect(output, options); + } + } + + var proto = value ? Object.getPrototypeOf(value) : false; // If it's a plain Object then use Loupe's inspector + + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } // Specifically account for HTMLElements + // eslint-disable-next-line no-undef + + + if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) { + return inspectHTML(value, options); + } + + if ('constructor' in value) { + // If it is a class, inspect it like an object but add the constructor name + if (value.constructor !== Object) { + return inspectClass(value, options); + } // If it is an object with an anonymous prototype, display it as an object. + + + return inspectObject(value, options); + } // last chance to check if it's an object + + + if (value === Object(value)) { + return inspectObject(value, options); + } // We have run out of options! Just stringify the value + + + return options.stylize(String(value), type); + } + function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false; + } + + constructorMap.set(constructor, inspector); + return true; + } + function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false; + } + + stringTagMap[stringTag] = inspector; + return true; + } + var custom = chaiInspect; + + exports.custom = custom; + exports.default = inspect; + exports.inspect = inspect; + exports.registerConstructor = registerConstructor; + exports.registerStringTag = registerStringTag; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + +},{"util":undefined}],38:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - pathval utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has own + * or inherited from prototype chain named property. + * + * Basically does the same thing as the `in` + * operator but works properly with null/undefined values + * and other primitives. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty(obj, 'str'); // true + * hasProperty(obj, 'constructor'); // true + * hasProperty(obj, 'bar'); // false + * + * hasProperty(obj.str, 'length'); // true + * hasProperty(obj.str, 1); // true + * hasProperty(obj.str, 5); // false + * + * hasProperty(obj.arr, 'length'); // true + * hasProperty(obj.arr, 2); // true + * hasProperty(obj.arr, 3); // false + * + * @param {Object} object + * @param {String|Symbol} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name hasProperty + * @api public + */ + +function hasProperty(obj, name) { + if (typeof obj === 'undefined' || obj === null) { + return false; + } + + // The `in` operator does not work with primitives. + return name in Object(obj); +} + +/* ! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `internalGetPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be infinitely deep and nested. + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath(path) { + var str = path.replace(/([^\\])\[/g, '$1.['); + var parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function mapMatches(value) { + if ( + value === 'constructor' || + value === '__proto__' || + value === 'prototype' + ) { + return {}; + } + var regexp = /^\[(\d+)\]$/; + var mArr = regexp.exec(value); + var parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.[\]])/g, '$1') }; + } + + return parsed; + }); +} + +/* ! + * ## internalGetPathValue(obj, parsed[, pathDepth]) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(obj, parsed); + * + * @param {Object} object to search against + * @param {Object} parsed definition from `parsePath`. + * @param {Number} depth (nesting level) of the property we want to retrieve + * @returns {Object|Undefined} value + * @api private + */ + +function internalGetPathValue(obj, parsed, pathDepth) { + var temporaryValue = obj; + var res = null; + pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth; + + for (var i = 0; i < pathDepth; i++) { + var part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === 'undefined') { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + + if (i === pathDepth - 1) { + res = temporaryValue; + } + } + } + + return res; +} + +/* ! + * ## internalSetPathValue(obj, value, parsed) + * + * Companion function for `parsePath` that sets + * the value located at a parsed address. + * + * internalSetPathValue(obj, 'value', parsed); + * + * @param {Object} object to search and define on + * @param {*} value to use upon set + * @param {Object} parsed definition from `parsePath` + * @api private + */ + +function internalSetPathValue(obj, val, parsed) { + var tempObj = obj; + var pathDepth = parsed.length; + var part = null; + // Here we iterate through every part of the path + for (var i = 0; i < pathDepth; i++) { + var propName = null; + var propVal = null; + part = parsed[i]; + + // If it's the last part of the path, we set the 'propName' value with the property name + if (i === pathDepth - 1) { + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Now we set the property with the name held by 'propName' on object with the desired val + tempObj[propName] = val; + } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { + tempObj = tempObj[part.p]; + } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { + tempObj = tempObj[part.i]; + } else { + // If the obj doesn't have the property we create one with that name to define it + var next = parsed[i + 1]; + // Here we set the name of the property which will be defined + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Here we decide if this property will be an array or a new object + propVal = typeof next.p === 'undefined' ? [] : {}; + tempObj[propName] = propVal; + tempObj = tempObj[propName]; + } + } +} + +/** + * ### .getPathInfo(object, path) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {Object} object + * @param {String} path + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +function getPathInfo(obj, path) { + var parsed = parsePath(path); + var last = parsed[parsed.length - 1]; + var info = { + parent: + parsed.length > 1 ? + internalGetPathValue(obj, parsed, parsed.length - 1) : + obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed), + }; + info.exists = hasProperty(info.parent, info.name); + + return info; +} + +/** + * ### .getPathValue(object, path) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue(obj, 'prop1.str'); // Hello + * getPathValue(obj, 'prop1.att[2]'); // b + * getPathValue(obj, 'prop2.arr[0].nested'); // Universe + * + * @param {Object} object + * @param {String} path + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ + +function getPathValue(obj, path) { + var info = getPathInfo(obj, path); + return info.value; +} + +/** + * ### .setPathValue(object, path, value) + * + * Define the value in an object at a given string path. + * + * ```js + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * }; + * ``` + * + * The following would be acceptable. + * + * ```js + * var properties = require('tea-properties'); + * properties.set(obj, 'prop1.str', 'Hello Universe!'); + * properties.set(obj, 'prop1.arr[2]', 'B'); + * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); + * ``` + * + * @param {Object} object + * @param {String} path + * @param {Mixed} value + * @api private + */ + +function setPathValue(obj, path, val) { + var parsed = parsePath(path); + internalSetPathValue(obj, val, parsed); + return obj; +} + +module.exports = { + hasProperty: hasProperty, + getPathInfo: getPathInfo, + getPathValue: getPathValue, + setPathValue: setPathValue, +}; + +},{}],39:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.typeDetect = factory()); +})(this, (function () { 'use strict'; + + var promiseExists = typeof Promise === 'function'; + var globalObject = (function (Obj) { + if (typeof globalThis === 'object') { + return globalThis; + } + Object.defineProperty(Obj, 'typeDetectGlobalObject', { + get: function get() { + return this; + }, + configurable: true, + }); + var global = typeDetectGlobalObject; + delete Obj.typeDetectGlobalObject; + return global; + })(Object.prototype); + var symbolExists = typeof Symbol !== 'undefined'; + var mapExists = typeof Map !== 'undefined'; + var setExists = typeof Set !== 'undefined'; + var weakMapExists = typeof WeakMap !== 'undefined'; + var weakSetExists = typeof WeakSet !== 'undefined'; + var dataViewExists = typeof DataView !== 'undefined'; + var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; + var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; + var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; + var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; + var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); + var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); + var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; + var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); + var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; + var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); + var toStringLeftSliceLength = 8; + var toStringRightSliceLength = -1; + function typeDetect(obj) { + var typeofObj = typeof obj; + if (typeofObj !== 'object') { + return typeofObj; + } + if (obj === null) { + return 'null'; + } + if (obj === globalObject) { + return 'global'; + } + if (Array.isArray(obj) && + (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) { + return 'Array'; + } + if (typeof window === 'object' && window !== null) { + if (typeof window.location === 'object' && obj === window.location) { + return 'Location'; + } + if (typeof window.document === 'object' && obj === window.document) { + return 'Document'; + } + if (typeof window.navigator === 'object') { + if (typeof window.navigator.mimeTypes === 'object' && + obj === window.navigator.mimeTypes) { + return 'MimeTypeArray'; + } + if (typeof window.navigator.plugins === 'object' && + obj === window.navigator.plugins) { + return 'PluginArray'; + } + } + if ((typeof window.HTMLElement === 'function' || + typeof window.HTMLElement === 'object') && + obj instanceof window.HTMLElement) { + if (obj.tagName === 'BLOCKQUOTE') { + return 'HTMLQuoteElement'; + } + if (obj.tagName === 'TD') { + return 'HTMLTableDataCellElement'; + } + if (obj.tagName === 'TH') { + return 'HTMLTableHeaderCellElement'; + } + } + } + var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); + if (typeof stringTag === 'string') { + return stringTag; + } + var objPrototype = Object.getPrototypeOf(obj); + if (objPrototype === RegExp.prototype) { + return 'RegExp'; + } + if (objPrototype === Date.prototype) { + return 'Date'; + } + if (promiseExists && objPrototype === Promise.prototype) { + return 'Promise'; + } + if (setExists && objPrototype === Set.prototype) { + return 'Set'; + } + if (mapExists && objPrototype === Map.prototype) { + return 'Map'; + } + if (weakSetExists && objPrototype === WeakSet.prototype) { + return 'WeakSet'; + } + if (weakMapExists && objPrototype === WeakMap.prototype) { + return 'WeakMap'; + } + if (dataViewExists && objPrototype === DataView.prototype) { + return 'DataView'; + } + if (mapExists && objPrototype === mapIteratorPrototype) { + return 'Map Iterator'; + } + if (setExists && objPrototype === setIteratorPrototype) { + return 'Set Iterator'; + } + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return 'Array Iterator'; + } + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return 'String Iterator'; + } + if (objPrototype === null) { + return 'Object'; + } + return Object + .prototype + .toString + .call(obj) + .slice(toStringLeftSliceLength, toStringRightSliceLength); + } + + return typeDetect; + +})); + +},{}]},{},[1])(1) +}); diff --git a/node_modules/chai/index.js b/node_modules/chai/index.js new file mode 100644 index 0000000..634483b --- /dev/null +++ b/node_modules/chai/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/chai'); diff --git a/node_modules/chai/index.mjs b/node_modules/chai/index.mjs new file mode 100644 index 0000000..65b726a --- /dev/null +++ b/node_modules/chai/index.mjs @@ -0,0 +1,14 @@ +import chai from './index.js'; + +export const expect = chai.expect; +export const version = chai.version; +export const Assertion = chai.Assertion; +export const AssertionError = chai.AssertionError; +export const util = chai.util; +export const config = chai.config; +export const use = chai.use; +export const should = chai.should; +export const assert = chai.assert; +export const core = chai.core; + +export default chai; diff --git a/node_modules/chai/karma.conf.js b/node_modules/chai/karma.conf.js new file mode 100644 index 0000000..e22923f --- /dev/null +++ b/node_modules/chai/karma.conf.js @@ -0,0 +1,34 @@ +module.exports = function(config) { + config.set({ + frameworks: [ 'mocha' ] + , files: [ + 'chai.js' + , 'test/bootstrap/index.js' + , 'test/*.js' + ] + , reporters: [ 'progress' ] + , colors: true + , logLevel: config.LOG_INFO + , autoWatch: false + , browsers: [ 'HeadlessChrome' ] + , customLaunchers: { + HeadlessChrome: { + base: 'ChromeHeadless' + , flags: [ '--no-sandbox',] + , } + , } + , browserDisconnectTimeout: 10000 + , browserDisconnectTolerance: 2 + , browserNoActivityTimeout: 20000 + , singleRun: true + }); + + switch (process.env.CHAI_TEST_ENV) { + case 'sauce': + require('./karma.sauce')(config); + break; + default: + // ... + break; + }; +}; diff --git a/node_modules/chai/karma.sauce.js b/node_modules/chai/karma.sauce.js new file mode 100644 index 0000000..b4f22fe --- /dev/null +++ b/node_modules/chai/karma.sauce.js @@ -0,0 +1,41 @@ +var version = require('./package.json').version; +var ts = new Date().getTime(); + +module.exports = function(config) { + var auth; + + try { + auth = require('./test/auth/index'); + } catch(ex) { + auth = {}; + auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null; + auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null; + } + + if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return; + if (process.env.SKIP_SAUCE) return; + + var branch = process.env.TRAVIS_BRANCH || 'local' + var browserConfig = require('./sauce.browsers'); + var browsers = Object.keys(browserConfig); + var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ]; + var tunnel = process.env.TRAVIS_JOB_NUMBER || ts; + + if (process.env.TRAVIS_JOB_NUMBER) { + tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER); + } + + config.browsers = config.browsers.concat(browsers); + Object.assign(config.customLaunchers, browserConfig); + config.reporters.push('saucelabs'); + config.captureTimeout = 300000; + + config.sauceLabs = { + username: auth.SAUCE_USERNAME + , accessKey: auth.SAUCE_ACCESS_KEY + , startConnect: ('TRAVIS' in process.env) === false + , tags: tags + , testName: 'ChaiJS' + , tunnelIdentifier: tunnel + }; +}; diff --git a/node_modules/chai/lib/chai.js b/node_modules/chai/lib/chai.js new file mode 100644 index 0000000..960d83c --- /dev/null +++ b/node_modules/chai/lib/chai.js @@ -0,0 +1,92 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var used = []; + +/*! + * Chai version + */ + +exports.version = '4.3.8'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); diff --git a/node_modules/chai/lib/chai/assertion.js b/node_modules/chai/lib/chai/assertion.js new file mode 100644 index 0000000..32e7ee2 --- /dev/null +++ b/node_modules/chai/lib/chai/assertion.js @@ -0,0 +1,178 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * - `eql`: This flag contains the deepEqual function to be used by the assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + */ + + function Assertion (obj, msg, ssfi, lockSsfi) { + flag(this, 'ssfi', ssfi || Assertion); + flag(this, 'lockSsfi', lockSsfi); + flag(this, 'object', obj); + flag(this, 'message', msg); + flag(this, 'eql', config.deepEqual || util.eql); + + return util.proxify(this); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + var assertionErrorObjectProperties = { + actual: actual + , expected: expected + , showDiff: showDiff + }; + + var operator = util.getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + + throw new AssertionError( + msg, + assertionErrorObjectProperties, + (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; diff --git a/node_modules/chai/lib/chai/config.js b/node_modules/chai/lib/chai/config.js new file mode 100644 index 0000000..d7cbdb9 --- /dev/null +++ b/node_modules/chai/lib/chai/config.js @@ -0,0 +1,120 @@ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + + proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'], + + /** + * ### config.deepEqual + * + * User configurable property, defines which a custom function to use for deepEqual + * comparisons. + * By default, the function used is the one from the `deep-eql` package without custom comparator. + * + * // use a custom comparator + * chai.config.deepEqual = (expected, actual) => { + * return chai.util.eql(expected, actual, { + * comparator: (expected, actual) => { + * // for non number comparison, use the default behavior + * if(typeof expected !== 'number') return null; + * // allow a difference of 10 between compared numbers + * return typeof actual === 'number' && Math.abs(actual - expected) < 10 + * } + * }) + * }; + * + * @param {Function} + * @api public + */ + + deepEqual: null + +}; diff --git a/node_modules/chai/lib/chai/core/assertions.js b/node_modules/chai/lib/chai/core/assertions.js new file mode 100644 index 0000000..19bdbbc --- /dev/null +++ b/node_modules/chai/lib/chai/core/assertions.js @@ -0,0 +1,3850 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , AssertionError = chai.AssertionError + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * - still + * - also + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been', 'is' + , 'and', 'has', 'have', 'with' + , 'that', 'which', 'at', 'of' + , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) { + Assertion.addProperty(chain); + }); + + /** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @api public + */ + + Assertion.addProperty('nested', function () { + flag(this, 'nested', true); + }); + + /** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @api public + */ + + Assertion.addProperty('own', function () { + flag(this, 'own', true); + }); + + /** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); + }); + + /** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); + }); + + /** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the `type-detect` project page for info on the + * type detection algorithm: https://github.com/chaijs/type-detect. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {String} type + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj).toLowerCase() + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; + } + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + if (msg) flag(this, 'message', msg); + + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : '' + , isEql = isDeep ? flag(this, 'eql') : SameValueZero; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + var included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return isEql(item, val); + }) + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'the given combination of arguments (' + + objType + ' and ' + + _.type(val).toLowerCase() + ')' + + ' is invalid for this assertion. ' + + 'You can use an array, a map, an object, a set, a string, ' + + 'or a weakset instead of a ' + + _.type(val).toLowerCase(), + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included + , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) + , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is a truthy value (considered `true` in boolean context). + * However, it's often best to assert that the target is strictly (`===`) or + * deeply equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , flag(this, 'negate') ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , flag(this, 'negate') ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * The alias `.exists` can be used interchangeably with `.exist`. + * + * @name exist + * @alias exists + * @namespace BDD + * @api public + */ + + function assertExist () { + var val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + } + + Assertion.addProperty('exist', assertExist); + Assertion.addProperty('exists', assertExist); + + /** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var val = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': + var msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that it’s not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = _.type(obj); + this.assert( + 'Arguments' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + var prevLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + this.eql(val); + flag(this, 'lockSsfi', prevLockSsfi); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {Mixed} obj + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + var eql = flag(this, 'eql'); + this.assert( + eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to above must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to above must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n + , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above #{exp}' + , 'expected #{this} to be at most #{exp}' + , n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with + * `.least`. + * + * @name least + * @alias gte + * @alias greaterThanOrEqual + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n + , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least #{exp}' + , 'expected #{this} to be below #{exp}' + , n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + Assertion.addMethod('greaterThanOrEqual', assertLeast); + + /** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n + , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below #{exp}' + , 'expected #{this} to be at least #{exp}' + , n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with + * `.most`. + * + * @name most + * @alias lte + * @alias lessThanOrEqual + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n + , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most #{exp}' + , 'expected #{this} to be above #{exp}' + , n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + Assertion.addMethod('lessThanOrEqual', assertMost); + + /** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `start`, and less + * than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {Number} start lower bound inclusive + * @param {Number} finish upper bound inclusive + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , startType = _.type(start).toLowerCase() + , finishType = _.type(finish).toLowerCase() + , errorMessage + , shouldThrow = true + , range = (startType === 'date' && finishType === 'date') + ? start.toISOString() + '..' + finish.toISOString() + : start + '..' + finish; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish + , 'expected #{this} to have a ' + descriptor + ' within ' + range + , 'expected #{this} to not have a ' + descriptor + ' within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + + var target = flag(this, 'object') + var ssfi = flag(this, 'ssfi'); + var flagMsg = flag(this, 'message'); + + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + var name = _.getName(constructor); + if (name === null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {String} name + * @param {Mixed} val (optional) + * @param {String} msg _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + function assertProperty (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isNested = flag(this, 'nested') + , isOwn = flag(this, 'own') + , flagMsg = flag(this, 'message') + , obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , nameType = typeof name; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + if (isNested) { + if (nameType !== 'string') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string when using nested syntax', + undefined, + ssfi + ); + } + } else { + if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string, number, or symbol', + undefined, + ssfi + ); + } + } + + if (isNested && isOwn) { + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + var isDeep = flag(this, 'deep') + , negate = flag(this, 'negate') + , pathInfo = isNested ? _.getPathInfo(obj, name) : null + , value = isNested ? pathInfo.value : obj[name] + , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;; + + var descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + var hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty + , 'expected #{this} to have ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && isEql(val, value) + , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + } + + Assertion.addMethod('property', assertProperty); + + function assertOwnProperty (name, value, msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but it’s not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + var eql = flag(this, 'eql'); + if (actualDescriptor && descriptor) { + this.assert( + eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` or `size` is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * expect(new Set([1, 2, 3])).to.have.lengthOf(3); + * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi') + , descriptor = 'length' + , itemsCount; + + switch (objType) { + case 'map': + case 'set': + descriptor = 'size'; + itemsCount = obj.size; + break; + default: + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + itemsCount = obj.length; + } + + this.assert( + itemsCount == n + , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' of #{act}' + , n + , itemsCount + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + + /** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string('taco', 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string('taco'); + * + * @name string + * @param {String} str + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + /** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , objType = _.type(obj) + , keysType = _.type(keys) + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , str + , deepStr = '' + , actual + , ok = true + , flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { actual.push(key) }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + var len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all') + , expected = keys + , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + return isEql(expectedKey, actualKey); + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + deepStr + str + , 'expected #{this} to not ' + deepStr + str + , expected.slice(0).sort(_.compareByInspect) + , actual.sort(_.compareByInspect) + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error|ErrorConstructor} errorLike + * @param {String|RegExp} errMsgMatcher error message + * @param {String} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (errorLike instanceof RegExp || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + // We need this to display results correctly according to their types + var errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + this.assert( + caughtErr + , 'expected #{this} to throw ' + errorLikeString + , 'expected #{this} to not throw an error but #{act} was thrown' + , errorLike && errorLike.toString() + , (caughtErr instanceof Error ? + caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && + _.checkError.getConstructorName(caughtErr))) + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') + , errorLike.toString() + , caughtErr.toString() + ); + } + } + } + + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + var placeholder = 'including'; + if (errMsgMatcher instanceof RegExp) { + placeholder = 'matching' + } + + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' + , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' + , errMsgMatcher + , _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + + flag(this, 'object', caughtErr); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , flag(this, 'negate') ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.a('number'); + if (typeof expected !== 'number' || typeof delta !== 'number') { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var deltaMessage = delta === undefined ? ", and a delta is required" : ""; + throw new AssertionError( + flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage, + undefined, + ssfi + ); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + // Note: Duplicates are ignored if testing for inclusion instead of sameness. + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); + } + + /** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); + new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); + + var contains = flag(this, 'contains'); + var ordered = flag(this, 'ordered'); + + var subject, failMsg, failNegateMsg; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + var cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered) + , failMsg + , failNegateMsg + , subset + , obj + , true + ); + }); + + /** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * It can also be chained with `.contain` or `.include`, which will work with + * both arrays and strings: + * + * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) + * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) + * expect([1,2,3]).to.contain.oneOf([3,4,5]) + * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi') + , contains = flag(this, 'contains') + , isDeep = flag(this, 'deep') + , eql = flag(this, 'eql'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + if (contains) { + this.assert( + list.some(function(possibility) { return expected.indexOf(possibility) > -1 }) + , 'expected #{this} to contain one of #{exp}' + , 'expected #{this} to not contain one of #{exp}' + , list + , expected + ); + } else { + if (isDeep) { + this.assert( + list.some(function(possibility) { return eql(expected, possibility) }) + , 'expected #{this} to deeply equal one of #{exp}' + , 'expected #{this} to deeply equal one of #{exp}' + , list + , expected + ); + } else { + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + } + } + + Assertion.addMethod('oneOf', oneOf); + + /** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {String} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final + , 'expected ' + msgObj + ' to change' + , 'expected ' + msgObj + ' to not change' + ); + } + + Assertion.addMethod('change', assertChanges); + Assertion.addMethod('changes', assertChanges); + + /** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0 + , 'expected ' + msgObj + ' to increase' + , 'expected ' + msgObj + ' to not increase' + ); + } + + Assertion.addMethod('increase', assertIncreases); + Assertion.addMethod('increases', assertIncreases); + + /** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0 + , 'expected ' + msgObj + ' to decrease' + , 'expected ' + msgObj + ' to not decrease' + ); + } + + Assertion.addMethod('decrease', assertDecreases); + Assertion.addMethod('decreases', assertDecreases); + + /** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + var msgObj = flag(this, 'deltaMsgObj'); + var initial = flag(this, 'initialDeltaValue'); + var final = flag(this, 'finalDeltaValue'); + var behavior = flag(this, 'deltaBehavior'); + var realDelta = flag(this, 'realDelta'); + + var expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression + , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta + , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); + } + + Assertion.addMethod('by', assertDelta); + + /** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); + + /** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @api public + */ + + Assertion.addProperty('finite', function(msg) { + var obj = flag(this, 'object'); + + this.assert( + typeof obj === 'number' && isFinite(obj) + , 'expected #{this} to be a finite number' + , 'expected #{this} to not be a finite number' + ); + }); +}; diff --git a/node_modules/chai/lib/chai/interface/assert.js b/node_modules/chai/lib/chai/interface/assert.js new file mode 100644 index 0000000..11b3c25 --- /dev/null +++ b/node_modules/chai/lib/chai/interface/assert.js @@ -0,0 +1,3113 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert, true); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * assert.fail(); + * assert.fail("custom error message"); + * assert.fail(1, 2); + * assert.fail(1, 2, "custom error message"); + * assert.fail(1, 2, "custom error message", ">"); + * assert.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + // Comply with Node's fail([message]) interface + + message = actual; + actual = undefined; + } + + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @alias deepStrictEqual + * @namespace Assert + * @api public + */ + + assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); + }; + + /** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; + }; + + /** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; + }; + + /** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; + }; + + /** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); + }; + + /** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true) + .to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and strictly equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, "array doesn't contain value"); + * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); + }; + + /** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); + }; + + /** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); + }; + + /** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); + }; + + /** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true) + .not.nested.include(inc); + }; + + /** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true) + .deep.nested.include(inc); + }; + + /** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepNestedInclude, true) + .not.deep.nested.include(inc); + }; + + /** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); + }; + + /** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); + }; + + /** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true) + .deep.own.include(inc); + }; + + /** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true) + .not.deep.own.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true) + .to.not.have.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true) + .to.have.property(prop, val); + }; + + /** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true) + .to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true) + .to.have.deep.property(prop, val); + }; + + /** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepPropertyVal, true) + .to.not.have.deep.property(prop, val); + }; + + /** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true) + .to.have.own.property(prop); + }; + + /** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true) + .to.not.have.own.property(prop); + }; + + /** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true) + .to.have.own.property(prop, value); + }; + + /** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notOwnPropertyVal, true) + .to.not.have.own.property(prop, value); + }; + + /** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.deepOwnPropertyVal, true) + .to.have.deep.own.property(prop, value); + }; + + /** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) + .to.not.have.deep.own.property(prop, value); + }; + + /** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true) + .to.have.nested.property(prop); + }; + + /** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notNestedProperty, true) + .to.not.have.nested.property(prop); + }; + + /** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.nestedPropertyVal, true) + .to.have.nested.property(prop, val); + }; + + /** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notNestedPropertyVal, true) + .to.not.have.nested.property(prop, val); + }; + + /** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepNestedPropertyVal, true) + .to.have.deep.nested.property(prop, val); + }; + + /** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) + .to.not.have.deep.nested.property(prop, val); + } + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` or `size` with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); + * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); + }; + + /** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); + } + + /** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); + } + + /** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true) + .to.contain.all.keys(keys); + } + + /** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) + .to.not.have.any.keys(keys); + } + + /** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) + .to.not.have.all.keys(keys); + } + + /** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true) + .to.have.any.deep.keys(keys); + } + + /** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true) + .to.have.all.deep.keys(keys); + } + + /** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllDeepKeys, true) + .to.contain.all.deep.keys(keys); + } + + /** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) + .to.not.have.any.deep.keys(keys); + } + + /** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) + .to.not.have.all.deep.keys(keys); + } + + /** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'Error thrown must have this msg'); + * assert.throws(fn, /Error thrown must have a msg that matches this/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {ErrorConstructor|Error} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + var assertErr = new Assertion(fn, msg, assert.throws, true) + .to.throw(errorLike, errMsgMatcher); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {ErrorConstructor} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, msg, assert.doesNotThrow, true) + .to.not.throw(errorLike, errMsgMatcher); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new chai.AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + var test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true) + .to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true) + .to.have.same.members(set2); + } + + /** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameMembers, true) + .to.not.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepMembers, true) + .to.have.same.deep.members(set2); + } + + /** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepMembers, true) + .to.not.have.same.deep.members(set2); + } + + /** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameOrderedMembers, true) + .to.have.same.ordered.members(set2); + } + + /** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameOrderedMembers, true) + .to.not.have.same.ordered.members(set2); + } + + /** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) + .to.have.same.deep.ordered.members(set2); + } + + /** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) + .to.not.have.same.deep.ordered.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true) + .to.include.members(subset); + } + + /** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeMembers, true) + .to.not.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepMembers, true) + .to.include.deep.members(subset); + } + + /** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepMembers, true) + .to.not.include.deep.members(subset); + } + + /** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeOrderedMembers, true) + .to.include.ordered.members(subset); + } + + /** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) + .to.not.include.ordered.members(subset); + } + + /** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) + .to.include.deep.ordered.members(subset); + } + + /** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) + .to.not.include.deep.ordered.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); + } + + /** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true) + .to.change(obj, prop).by(delta); + } + + /** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true) + .to.not.change(obj, prop); + } + + /** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true) + .to.change(obj, prop).but.not.by(delta); + } + + /** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true) + .to.increase(obj, prop); + } + + /** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @name increasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true) + .to.increase(obj, prop).by(delta); + } + + /** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true) + .to.not.increase(obj, prop); + } + + /** + * ### .increasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true) + .to.increase(obj, prop).but.not.by(delta); + } + + /** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true) + .to.decrease(obj, prop); + } + + /** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true) + .to.decrease(obj, prop).by(delta); + } + + /** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true) + .to.not.decrease(obj, prop); + } + + /** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecreaseBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) + .to.not.decrease(obj, prop).by(delta); + } + + /** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true) + .to.decrease(obj, prop).but.not.by(delta); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; + }; + + /** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; + }; + + /** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen') + ('isEmpty', 'empty') + ('isNotEmpty', 'notEmpty'); +}; diff --git a/node_modules/chai/lib/chai/interface/expect.js b/node_modules/chai/lib/chai/interface/expect.js new file mode 100644 index 0000000..6867e2a --- /dev/null +++ b/node_modules/chai/lib/chai/interface/expect.js @@ -0,0 +1,47 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * expect.fail(); + * expect.fail("custom error message"); + * expect.fail(1, 2); + * expect.fail(1, 2, "custom error message"); + * expect.fail(1, 2, "custom error message", ">"); + * expect.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; diff --git a/node_modules/chai/lib/chai/interface/should.js b/node_modules/chai/lib/chai/interface/should.js new file mode 100644 index 0000000..17902af --- /dev/null +++ b/node_modules/chai/lib/chai/interface/should.js @@ -0,0 +1,219 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String + || this instanceof Number + || this instanceof Boolean + || typeof Symbol === 'function' && this instanceof Symbol + || typeof BigInt === 'function' && this instanceof BigInt) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * should.fail(); + * should.fail("custom error message"); + * should.fail(1, 2); + * should.fail(1, 2, "custom error message"); + * should.fail(1, 2, "custom error message", ">"); + * should.fail(1, 2, undefined, ">"); + * + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; diff --git a/node_modules/chai/lib/chai/utils/addChainableMethod.js b/node_modules/chai/lib/chai/utils/addChainableMethod.js new file mode 100644 index 0000000..a713f6a --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addChainableMethod.js @@ -0,0 +1,152 @@ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/*! + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +var canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +var testFn = function() {}; +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') + return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + var chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + var result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/addLengthGuard.js b/node_modules/chai/lib/chai/utils/addLengthGuard.js new file mode 100644 index 0000000..e51ce80 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addLengthGuard.js @@ -0,0 +1,60 @@ +var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {String} assertionName + * @param {Boolean} isChainable + * @namespace Utils + * @name addLengthGuard + */ + +module.exports = function addLengthGuard (fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + + throw Error('Invalid Chai property: ' + assertionName + '.length. See' + + ' docs for proper usage of "' + assertionName + '".'); + } + }); + + return fn; +}; diff --git a/node_modules/chai/lib/chai/utils/addMethod.js b/node_modules/chai/lib/chai/utils/addMethod.js new file mode 100644 index 0000000..021f080 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addMethod.js @@ -0,0 +1,68 @@ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ + +module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + var result = method.apply(this, arguments); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +}; diff --git a/node_modules/chai/lib/chai/utils/addProperty.js b/node_modules/chai/lib/chai/utils/addProperty.js new file mode 100644 index 0000000..872a8cd --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addProperty.js @@ -0,0 +1,72 @@ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, + { get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + var result = getter.call(this); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/compareByInspect.js b/node_modules/chai/lib/chai/utils/compareByInspect.js new file mode 100644 index 0000000..c8cd5e1 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/compareByInspect.js @@ -0,0 +1,31 @@ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {Mixed} first element to compare + * @param {Mixed} second element to compare + * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @api public + */ + +module.exports = function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +}; diff --git a/node_modules/chai/lib/chai/utils/expectTypes.js b/node_modules/chai/lib/chai/utils/expectTypes.js new file mode 100644 index 0000000..6293db7 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/expectTypes.js @@ -0,0 +1,51 @@ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, 'message'); + var ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + var objType = type(obj).toLowerCase(); + + if (!types.some(function (expected) { return objType === expected; })) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +}; diff --git a/node_modules/chai/lib/chai/utils/flag.js b/node_modules/chai/lib/chai/utils/flag.js new file mode 100644 index 0000000..dd53bfb --- /dev/null +++ b/node_modules/chai/lib/chai/utils/flag.js @@ -0,0 +1,33 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; diff --git a/node_modules/chai/lib/chai/utils/getActual.js b/node_modules/chai/lib/chai/utils/getActual.js new file mode 100644 index 0000000..976e112 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getActual.js @@ -0,0 +1,20 @@ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; diff --git a/node_modules/chai/lib/chai/utils/getEnumerableProperties.js b/node_modules/chai/lib/chai/utils/getEnumerableProperties.js new file mode 100644 index 0000000..a84252c --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getEnumerableProperties.js @@ -0,0 +1,26 @@ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; diff --git a/node_modules/chai/lib/chai/utils/getMessage.js b/node_modules/chai/lib/chai/utils/getMessage.js new file mode 100644 index 0000000..bb83716 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getMessage.js @@ -0,0 +1,50 @@ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function getMessage(obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; diff --git a/node_modules/chai/lib/chai/utils/getOperator.js b/node_modules/chai/lib/chai/utils/getOperator.js new file mode 100644 index 0000000..f7d10ef --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOperator.js @@ -0,0 +1,55 @@ +var type = require('type-detect'); + +var flag = require('./flag'); + +function isObjectType(obj) { + var objectType = type(obj); + var objectTypes = ['Array', 'Object', 'function']; + + return objectTypes.indexOf(objectType) !== -1; +} + +/** + * ### .getOperator(message) + * + * Extract the operator from error message. + * Operator defined is based on below link + * https://nodejs.org/api/assert.html#assert_assert. + * + * Returns the `operator` or `undefined` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getOperator + * @api public + */ + +module.exports = function getOperator(obj, args) { + var operator = flag(obj, 'operator'); + var negate = flag(obj, 'negate'); + var expected = args[3]; + var msg = negate ? args[2] : args[1]; + + if (operator) { + return operator; + } + + if (typeof msg === 'function') msg = msg(); + + msg = msg || ''; + if (!msg) { + return undefined; + } + + if (/\shave\s/.test(msg)) { + return undefined; + } + + var isObject = isObjectType(expected); + if (/\snot\s/.test(msg)) { + return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; + } + + return isObject ? 'deepStrictEqual' : 'strictEqual'; +}; diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js new file mode 100644 index 0000000..a4aa83a --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js @@ -0,0 +1,29 @@ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @api public + */ + +module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +}; diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js new file mode 100644 index 0000000..823c6b7 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js @@ -0,0 +1,27 @@ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @api public + */ + +module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +}; diff --git a/node_modules/chai/lib/chai/utils/getProperties.js b/node_modules/chai/lib/chai/utils/getProperties.js new file mode 100644 index 0000000..ccf9631 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getProperties.js @@ -0,0 +1,36 @@ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; diff --git a/node_modules/chai/lib/chai/utils/index.js b/node_modules/chai/lib/chai/utils/index.js new file mode 100644 index 0000000..c12a38e --- /dev/null +++ b/node_modules/chai/lib/chai/utils/index.js @@ -0,0 +1,178 @@ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Dependencies that are used for multiple exports are required here only once + */ + +var pathval = require('pathval'); + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path info + */ + +exports.getPathInfo = pathval.getPathInfo; + +/*! + * Check if a property exists + */ + +exports.hasProperty = pathval.hasProperty; + +/*! + * Function name + */ + +exports.getName = require('get-func-name'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +/*! + * Compare by inspect method + */ + +exports.compareByInspect = require('./compareByInspect'); + +/*! + * Get own enumerable property symbols method + */ + +exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/*! + * Get own enumerable properties method + */ + +exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); + +/*! + * Checks error against a given set of criteria + */ + +exports.checkError = require('check-error'); + +/*! + * Proxify util + */ + +exports.proxify = require('./proxify'); + +/*! + * addLengthGuard util + */ + +exports.addLengthGuard = require('./addLengthGuard'); + +/*! + * isProxyEnabled helper + */ + +exports.isProxyEnabled = require('./isProxyEnabled'); + +/*! + * isNaN method + */ + +exports.isNaN = require('./isNaN'); + +/*! + * getOperator method + */ + +exports.getOperator = require('./getOperator'); \ No newline at end of file diff --git a/node_modules/chai/lib/chai/utils/inspect.js b/node_modules/chai/lib/chai/utils/inspect.js new file mode 100644 index 0000000..3c83057 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/inspect.js @@ -0,0 +1,33 @@ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('get-func-name'); +var loupe = require('loupe'); +var config = require('../config'); + +module.exports = inspect; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var options = { + colors: colors, + depth: (typeof depth === 'undefined' ? 2 : depth), + showHidden: showHidden, + truncate: config.truncateThreshold ? config.truncateThreshold : Infinity, + }; + return loupe.inspect(obj, options); +} diff --git a/node_modules/chai/lib/chai/utils/isNaN.js b/node_modules/chai/lib/chai/utils/isNaN.js new file mode 100644 index 0000000..d64f7f4 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isNaN.js @@ -0,0 +1,26 @@ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +/** + * ### .isNaN(value) + * + * Checks if the given value is NaN or not. + * + * utils.isNaN(NaN); // true + * + * @param {Value} The value which has to be checked if it is NaN + * @name isNaN + * @api private + */ + +function isNaN(value) { + // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number + // section's NOTE. + return value !== value; +} + +// If ECMAScript 6's Number.isNaN is present, prefer that. +module.exports = Number.isNaN || isNaN; diff --git a/node_modules/chai/lib/chai/utils/isProxyEnabled.js b/node_modules/chai/lib/chai/utils/isProxyEnabled.js new file mode 100644 index 0000000..11e58ed --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isProxyEnabled.js @@ -0,0 +1,24 @@ +var config = require('../config'); + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + */ + +module.exports = function isProxyEnabled() { + return config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined'; +}; diff --git a/node_modules/chai/lib/chai/utils/objDisplay.js b/node_modules/chai/lib/chai/utils/objDisplay.js new file mode 100644 index 0000000..2891c2d --- /dev/null +++ b/node_modules/chai/lib/chai/utils/objDisplay.js @@ -0,0 +1,51 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @returns {string} stringified object + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function objDisplay(obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js new file mode 100644 index 0000000..4b38569 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js @@ -0,0 +1,69 @@ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwrites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteMethod.js b/node_modules/chai/lib/chai/utils/overwriteMethod.js new file mode 100644 index 0000000..7925e05 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteMethod.js @@ -0,0 +1,92 @@ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwrites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name] + , _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) + _super = _method; + + var overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteProperty.js b/node_modules/chai/lib/chai/utils/overwriteProperty.js new file mode 100644 index 0000000..5f870b0 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteProperty.js @@ -0,0 +1,92 @@ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwrites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/proxify.js b/node_modules/chai/lib/chai/utils/proxify.js new file mode 100644 index 0000000..4bbbee3 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/proxify.js @@ -0,0 +1,147 @@ +var config = require('../config'); +var flag = require('./flag'); +var getProperties = require('./getProperties'); +var isProxyEnabled = require('./isProxyEnabled'); + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @param {Object} obj + * @param {String} nonChainableMethodName + * @namespace Utils + * @name proxify + */ + +var builtins = ['__flags', '__methods', '_obj', 'assert']; + +module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if (typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property)) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + + property + '. See docs for proper usage of "' + + nonChainableMethodName + '".'); + } + + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. Only suggest properties with a + // distance less than 4. + var suggestion = null; + var suggestionDistance = 4; + getProperties(target).forEach(function(prop) { + if ( + !Object.prototype.hasOwnProperty(prop) && + builtins.indexOf(prop) === -1 + ) { + var dist = stringDistanceCapped( + property, + prop, + suggestionDistance + ); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + + if (suggestion !== null) { + throw Error('Invalid Chai property: ' + property + + '. Did you mean "' + suggestion + '"?'); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +}; + +/** + * # stringDistanceCapped(strA, strB, cap) + * Return the Levenshtein distance between two strings, but no more than cap. + * @param {string} strA + * @param {string} strB + * @param {number} number + * @return {number} min(string distance between strA and strB, cap) + * @api private + */ + +function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + + var memo = []; + // `memo` is a two-dimensional array containing distances. + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + for (var i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (var j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + + for (var i = 1; i <= strA.length; i++) { + var ch = strA.charCodeAt(i - 1); + for (var j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} diff --git a/node_modules/chai/lib/chai/utils/test.js b/node_modules/chai/lib/chai/utils/test.js new file mode 100644 index 0000000..277a2a5 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/test.js @@ -0,0 +1,28 @@ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag'); + +/** + * ### .test(object, expression) + * + * Test an object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function test(obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; diff --git a/node_modules/chai/lib/chai/utils/transferFlags.js b/node_modules/chai/lib/chai/utils/transferFlags.js new file mode 100644 index 0000000..7b50190 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/transferFlags.js @@ -0,0 +1,45 @@ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAssertion = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; diff --git a/node_modules/chai/package.json b/node_modules/chai/package.json new file mode 100644 index 0000000..342c9a0 --- /dev/null +++ b/node_modules/chai/package.json @@ -0,0 +1,63 @@ +{ + "author": "Jake Luer ", + "name": "chai", + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "homepage": "http://chaijs.com", + "license": "MIT", + "contributors": [ + "Jake Luer ", + "Domenic Denicola (http://domenicdenicola.com)", + "Veselin Todorov ", + "John Firebaugh " + ], + "version": "4.5.0", + "repository": { + "type": "git", + "url": "https://github.com/chaijs/chai" + }, + "bugs": { + "url": "https://github.com/chaijs/chai/issues" + }, + "main": "./index", + "exports": { + ".": { + "require": "./index.js", + "import": "./index.mjs" + }, + "./*": "./*" + }, + "scripts": { + "test": "make test" + }, + "engines": { + "node": ">=4" + }, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "devDependencies": { + "browserify": "^16.5.2", + "bump-cli": "^2.7.1", + "codecov": "^3.8.3", + "istanbul": "^0.4.5", + "karma": "^6.4.2", + "karma-chrome-launcher": "^2.2.0", + "karma-firefox-launcher": "^1.3.0", + "karma-mocha": "^2.0.1", + "karma-sauce-launcher": "^4.1.4", + "mocha": "^10.2.0" + } +} diff --git a/node_modules/chai/register-assert.js b/node_modules/chai/register-assert.js new file mode 100644 index 0000000..f80cb4d --- /dev/null +++ b/node_modules/chai/register-assert.js @@ -0,0 +1 @@ +global.assert = require('./').assert; diff --git a/node_modules/chai/register-expect.js b/node_modules/chai/register-expect.js new file mode 100644 index 0000000..f905c3a --- /dev/null +++ b/node_modules/chai/register-expect.js @@ -0,0 +1 @@ +global.expect = require('./').expect; diff --git a/node_modules/chai/register-should.js b/node_modules/chai/register-should.js new file mode 100644 index 0000000..5dab96f --- /dev/null +++ b/node_modules/chai/register-should.js @@ -0,0 +1 @@ +global.should = require('./').should(); diff --git a/node_modules/chai/sauce.browsers.js b/node_modules/chai/sauce.browsers.js new file mode 100644 index 0000000..328f0c7 --- /dev/null +++ b/node_modules/chai/sauce.browsers.js @@ -0,0 +1,106 @@ + +/*! + * Chrome + */ + +exports['SL_Chrome'] = { + base: 'SauceLabs' + , browserName: 'chrome' +}; + +/*! + * Firefox + */ + + exports['SL_Firefox'] = { + base: 'SauceLabs' + , browserName: 'firefox' + }; + + exports['SL_Firefox_ESR'] = { + base: 'SauceLabs' + , browserName: 'firefox' + , version: 38 + }; + +/*! + * Internet Explorer + */ + +exports['SL_IE'] = { + base: 'SauceLabs' + , browserName: 'internet explorer' +}; + +/*! + * TODO: fails because of Uint8Array support + * +exports['SL_IE_Old'] = { + base: 'SauceLabs' + , browserName: 'internet explorer' + , version: 10 +}; +*/ + +exports['SL_Edge'] = { + base: 'SauceLabs' + , browserName: 'microsoftedge' +}; + +/*! + * Safari + */ + +exports['SL_Safari'] = { + base: 'SauceLabs' + , browserName: 'safari' + , platform: 'Mac 10.11' +}; + +/*! + * iPhone + */ + +/*! + * TODO: These take forever to boot or shut down. Causes timeout. + * + +exports['SL_iPhone_6'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '6' +}; + +exports['SL_iPhone_5-1'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '5.1' +}; + +exports['SL_iPhone_5'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.6' + , version: '5' +}; + +*/ + +/*! + * Android + */ + +/*! + * TODO: fails because of error serialization + * + +exports['SL_Android_4'] = { + base: 'SauceLabs' + , browserName: 'android' + , platform: 'Linux' + , version: '4' +}; + +*/ diff --git a/node_modules/check-error/LICENSE b/node_modules/check-error/LICENSE new file mode 100644 index 0000000..7ea799f --- /dev/null +++ b/node_modules/check-error/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/check-error/README.md b/node_modules/check-error/README.md new file mode 100644 index 0000000..1fa64c3 --- /dev/null +++ b/node_modules/check-error/README.md @@ -0,0 +1,207 @@ +

+ + ChaiJS check-error + +

+ +

+ Error comparison and information related utility for node and the browser. +

+ +

+ + license:mit + + + tag:? + + + build:? + + + coverage:? + + + npm:? + + + dependencies:? + + + devDependencies:? + +
+ + Selenium Test Status + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is Check-Error? + +Check-Error is a module which you can use to retrieve an Error's information such as its `message` or `constructor` name and also to check whether two Errors are compatible based on their messages, constructors or even instances. + +## Installation + +### Node.js + +`check-error` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install check-error + +### Browsers + +You can also use it within the browser; install via npm and use the `check-error.js` file found within the download. For example: + +```html + +``` + +## Usage + +The primary export of `check-error` is an object which has the following methods: + +* `compatibleInstance(err, errorLike)` - Checks if an error is compatible with another `errorLike` object. If `errorLike` is an error instance we do a strict comparison, otherwise we return `false` by default, because instances of objects can only be compatible if they're both error instances. +* `compatibleConstructor(err, errorLike)` - Checks if an error's constructor is compatible with another `errorLike` object. If `err` has the same constructor as `errorLike` or if `err` is an instance of `errorLike`. +* `compatibleMessage(err, errMatcher)` - Checks if an error message is compatible with an `errMatcher` RegExp or String (we check if the message contains the String). +* `getConstructorName(errorLike)` - Retrieves the name of a constructor, an error's constructor or `errorLike` itself if it's not an error instance or constructor. +* `getMessage(err)` - Retrieves the message of an error or `err` itself if it's a String. If `err` or `err.message` is undefined we return an empty String. + +```js +var checkError = require('check-error'); +``` + +#### .compatibleInstance(err, errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.compatibleInstance(caughtErr, sameInstance); // true +checkError.compatibleInstance(caughtErr, new TypeError('Another error')); // false +``` + +#### .compatibleConstructor(err, errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +checkError.compatibleConstructor(caughtErr, Error); // true +checkError.compatibleConstructor(caughtErr, TypeError); // true +checkError.compatibleConstructor(caughtErr, RangeError); // false +``` + +#### .compatibleMessage(err, errMatcher) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.compatibleMessage(caughtErr, /TypeError$/); // true +checkError.compatibleMessage(caughtErr, 'I am a'); // true +checkError.compatibleMessage(caughtErr, /unicorn/); // false +checkError.compatibleMessage(caughtErr, 'I do not exist'); // false +``` + +#### .getConstructorName(errorLike) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.getConstructorName(caughtErr) // 'TypeError' +``` + +#### .getMessage(err) + +```js +var checkError = require('check-error'); + +var funcThatThrows = function() { throw new TypeError('I am a TypeError') }; +var caughtErr; + +try { + funcThatThrows(); +} catch(e) { + caughtErr = e; +} + +var sameInstance = caughtErr; + +checkError.getMessage(caughtErr) // 'I am a TypeError' +``` diff --git a/node_modules/check-error/check-error.js b/node_modules/check-error/check-error.js new file mode 100644 index 0000000..0070ed4 --- /dev/null +++ b/node_modules/check-error/check-error.js @@ -0,0 +1 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + * MIT Licensed + */ + +var getFunctionName = require('get-func-name'); +/** + * ### .checkError + * + * Checks that an error conforms to a given set of criteria and/or retrieves information about it. + * + * @api public + */ + +/** + * ### .compatibleInstance(thrown, errorLike) + * + * Checks if two instances are compatible (strict equal). + * Returns false if errorLike is not an instance of Error, because instances + * can only be compatible if they're both error instances. + * + * @name compatibleInstance + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleInstance(thrown, errorLike) { + return errorLike instanceof Error && thrown === errorLike; +} + +/** + * ### .compatibleConstructor(thrown, errorLike) + * + * Checks if two constructors are compatible. + * This function can receive either an error constructor or + * an error instance as the `errorLike` argument. + * Constructors are compatible if they're the same or if one is + * an instance of another. + * + * @name compatibleConstructor + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleConstructor(thrown, errorLike) { + if (errorLike instanceof Error) { + // If `errorLike` is an instance of any error we compare their constructors + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if (errorLike.prototype instanceof Error || errorLike === Error) { + // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + + return false; +} + +/** + * ### .compatibleMessage(thrown, errMatcher) + * + * Checks if an error's message is compatible with a matcher (String or RegExp). + * If the message contains the String or passes the RegExp test, + * it is considered compatible. + * + * @name compatibleMessage + * @param {Error} thrown error + * @param {String|RegExp} errMatcher to look for into the message + * @namespace Utils + * @api public + */ + +function compatibleMessage(thrown, errMatcher) { + var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; + if (errMatcher instanceof RegExp) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === 'string') { + return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers + } + + return false; +} + +/** + * ### .getConstructorName(errorLike) + * + * Gets the constructor name for an Error instance or constructor itself. + * + * @name getConstructorName + * @param {Error|ErrorConstructor} errorLike + * @namespace Utils + * @api public + */ + +function getConstructorName(errorLike) { + var constructorName = errorLike; + if (errorLike instanceof Error) { + constructorName = getFunctionName(errorLike.constructor); + } else if (typeof errorLike === 'function') { + // If `err` is not an instance of Error it is an error constructor itself or another function. + // If we've got a common function we get its name, otherwise we may need to create a new instance + // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. + constructorName = getFunctionName(errorLike); + if (constructorName === '') { + var newConstructorName = getFunctionName(new errorLike()); // eslint-disable-line new-cap + constructorName = newConstructorName || constructorName; + } + } + + return constructorName; +} + +/** + * ### .getMessage(errorLike) + * + * Gets the error message from an error. + * If `err` is a String itself, we return it. + * If the error has no message, we return an empty string. + * + * @name getMessage + * @param {Error|String} errorLike + * @namespace Utils + * @api public + */ + +function getMessage(errorLike) { + var msg = ''; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === 'string') { + msg = errorLike; + } + + return msg; +} + +module.exports = { + compatibleInstance: compatibleInstance, + compatibleConstructor: compatibleConstructor, + compatibleMessage: compatibleMessage, + getMessage: getMessage, + getConstructorName: getConstructorName, +}; diff --git a/node_modules/check-error/package.json b/node_modules/check-error/package.json new file mode 100644 index 0000000..4084f78 --- /dev/null +++ b/node_modules/check-error/package.json @@ -0,0 +1,87 @@ +{ + "name": "check-error", + "description": "Error comparison and information related utility for node and the browser", + "keywords": [ + "check-error", + "error", + "chai util" + ], + "license": "MIT", + "author": "Jake Luer (http://alogicalparadox.com)", + "contributors": [ + "David Losert (https://github.com/davelosert)", + "Keith Cirkel (https://github.com/keithamus)", + "Miroslav Bajtoš (https://github.com/bajtos)", + "Lucas Fernandes da Costa (https://github.com/lucasfcosta)" + ], + "files": [ + "index.js", + "check-error.js" + ], + "main": "./index.js", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/check-error.git" + }, + "scripts": { + "build": "browserify --bare $npm_package_main --standalone checkError -o check-error.js", + "lint": "eslint --ignore-path .gitignore .", + "prepublish": "npm run build", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser && npm run upload-coverage", + "test:browser": "karma start --singleRun=true", + "test:node": "istanbul cover _mocha", + "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0" + }, + "config": { + "ghooks": { + "commit-msg": "validate-commit-msg" + } + }, + "eslintConfig": { + "extends": [ + "strict/es5" + ], + "env": { + "es6": true + }, + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": 0, + "max-statements": 0 + } + }, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "devDependencies": { + "browserify": "^13.0.0", + "browserify-istanbul": "^1.0.0", + "coveralls": "2.11.9", + "eslint": "^2.4.0", + "eslint-config-strict": "^8.5.0", + "eslint-plugin-filenames": "^0.2.0", + "ghooks": "^1.0.1", + "istanbul": "^0.4.2", + "karma": "^0.13.22", + "karma-browserify": "^5.0.2", + "karma-coverage": "^0.5.5", + "karma-mocha": "^0.2.2", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sauce-launcher": "^0.3.1", + "lcov-result-merger": "^1.0.2", + "mocha": "^2.4.5", + "phantomjs-prebuilt": "^2.1.5", + "semantic-release": "^4.3.5", + "simple-assert": "^1.0.0", + "travis-after-all": "^1.4.4", + "validate-commit-msg": "^2.3.1" + }, + "engines": { + "node": "*" + }, + "version": "1.0.3" +} diff --git a/node_modules/confbox/LICENSE b/node_modules/confbox/LICENSE new file mode 100644 index 0000000..71e6fac --- /dev/null +++ b/node_modules/confbox/LICENSE @@ -0,0 +1,118 @@ +MIT License + +Copyright (c) Pooya Parsa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +js-yaml: https://github.com/nodeca/js-yaml/tree/master + +(The MIT License) + +Copyright (C) 2011-2015 by Vitaly Puzrin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--- + +smol-toml: https://github.com/squirrelchat/smol-toml/blob/mistress/LICENSE + +Copyright (c) Squirrel Chat et al., All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +jsonc-parser: https://github.com/microsoft/node-jsonc-parser/blob/main/LICENSE.md + +The MIT License (MIT) + +Copyright (c) Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +json5: https://github.com/json5/json5/blob/main/LICENSE.md + +MIT License + +Copyright (c) 2012-2018 Aseem Kishore, and others (https://github.com/json5/json5/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +detect-indent: https://github.com/sindresorhus/detect-indent/blob/main/license + +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/confbox/README.md b/node_modules/confbox/README.md new file mode 100644 index 0000000..eb05005 --- /dev/null +++ b/node_modules/confbox/README.md @@ -0,0 +1,191 @@ +# confbox + + + +[![npm version](https://img.shields.io/npm/v/confbox?color=yellow)](https://npmjs.com/package/confbox) +[![npm downloads](https://img.shields.io/npm/dm/confbox?color=yellow)](https://npm.chart.dev/confbox) +[![bundle size](https://img.shields.io/bundlephobia/minzip/confbox?color=yellow)](https://bundlephobia.com/package/confbox) + + + +Parsing and serialization utils for [YAML](https://yaml.org/) ([js-yaml](https://github.com/nodeca/js-yaml)), [TOML](https://toml.io/) ([smol-toml](https://github.com/squirrelchat/smol-toml)), [JSONC](https://github.com/microsoft/node-jsonc-parser) ([jsonc-parser](https://github.com/microsoft/node-jsonc-parser)), [JSON5](https://json5.org/) ([json5](https://github.com/json5/json5)), and [JSON](https://www.json.org/json-en.html). + +✨ Zero dependency and tree-shakable + +✨ Types exported out of the box + +✨ Presrves code style (indentation and whitespace) + +> [!TIP] +> Use [unjs/c12](https://github.com/unjs/c12) for a full featured configuration loader! + +## Usage + +Install package: + + + +```sh +# ✨ Auto-detect +npx nypm install confbox + +# npm +npm install confbox + +# yarn +yarn add confbox + +# pnpm +pnpm install confbox + +# bun +bun install confbox + +# deno +deno install confbox +``` + + + +Import: + + + +**ESM** (Node.js, Bun, Deno) + +```js +import { + parseJSON5, + stringifyJSON5, + parseJSONC, + stringifyJSONC, + parseYAML, + stringifyYAML, + parseJSON, + stringifyJSON, + parseTOML, + stringifyTOML, +} from "confbox"; +``` + +**CommonJS** (Legacy Node.js) + +```js +const { + parseJSON5, + stringifyJSON5, + parseJSONC, + stringifyJSONC, + parseYAML, + stringifyYAML, + parseJSON, + stringifyJSON, + parseTOML, + stringifyTOML, +} = require("confbox"); +``` + +**CDN** (Deno, Bun and Browsers) + +```js +import { + parseJSON5, + stringifyJSON5, + parseJSONC, + stringifyJSONC, + parseYAML, + stringifyYAML, + parseJSON, + stringifyJSON, + parseTOML, + stringifyTOML, +} from "https://esm.sh/confbox"; +``` + + + + + +### `parseJSON(text, options?)` + +Converts a [JSON](https://www.json.org/json-en.html) string into an object. + +Indentation status is auto-detected and preserved when stringifying back using `stringifyJSON` + +### `parseJSON5(text, options?)` + +Converts a [JSON5](https://json5.org/) string into an object. + +### `parseJSONC(text, options?)` + +Converts a [JSONC](https://github.com/microsoft/node-jsonc-parser) string into an object. + +### `parseTOML(text)` + +Converts a [TOML](https://toml.io/) string into an object. + +### `parseYAML(text, options?)` + +Converts a [YAML](https://yaml.org/) string into an object. + +### `stringifyJSON(value, options?)` + +Converts a JavaScript value to a [JSON](https://www.json.org/json-en.html) string. + +Indentation status is auto detected and preserved when using value from parseJSON. + +### `stringifyJSON5(value, options?)` + +Converts a JavaScript value to a [JSON5](https://json5.org/) string. + +### `stringifyJSONC(value, options?)` + +Converts a JavaScript value to a [JSONC](https://github.com/microsoft/node-jsonc-parser) string. + +### `stringifyTOML(value)` + +Converts a JavaScript value to a [TOML](https://toml.io/) string. + +### `stringifyYAML(value, options?)` + +Converts a JavaScript value to a [YAML](https://yaml.org/) string. + + + + + +## Contribution + +
+ Local development + +- Clone this repository +- Install the latest LTS version of [Node.js](https://nodejs.org/en/) +- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` +- Install dependencies using `pnpm install` +- Run tests using `pnpm dev` or `pnpm test` + +
+ + + +## License + + + +Published under the [MIT](https://github.com/unjs/confbox/blob/main/LICENSE) license. +Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/confbox/graphs/contributors) 💛 +

+ + + + + + + + +--- + +_🤖 auto updated with [automd](https://automd.unjs.io)_ + + diff --git a/node_modules/confbox/dist/index.cjs b/node_modules/confbox/dist/index.cjs new file mode 100644 index 0000000..47efa88 --- /dev/null +++ b/node_modules/confbox/dist/index.cjs @@ -0,0 +1 @@ +"use strict";const json5=require("./json5.cjs"),jsonc=require("./shared/confbox.6b479c78.cjs"),yaml=require("./yaml.cjs"),toml=require("./toml.cjs");require("./shared/confbox.3768c7e9.cjs"),exports.parseJSON5=json5.parseJSON5,exports.stringifyJSON5=json5.stringifyJSON5,exports.parseJSON=jsonc.parseJSON,exports.parseJSONC=jsonc.parseJSONC,exports.stringifyJSON=jsonc.stringifyJSON,exports.stringifyJSONC=jsonc.stringifyJSONC,exports.parseYAML=yaml.parseYAML,exports.stringifyYAML=yaml.stringifyYAML,exports.parseTOML=toml.parseTOML,exports.stringifyTOML=toml.stringifyTOML; diff --git a/node_modules/confbox/dist/index.d.cts b/node_modules/confbox/dist/index.d.cts new file mode 100644 index 0000000..9ae613e --- /dev/null +++ b/node_modules/confbox/dist/index.d.cts @@ -0,0 +1,32 @@ +export { JSON5ParseOptions, JSON5StringifyOptions, parseJSON5, stringifyJSON5 } from './json5.cjs'; +export { JSONCParseError, JSONCParseOptions, parseJSONC, stringifyJSONC } from './jsonc.cjs'; +export { YAMLParseOptions, YAMLStringifyOptions, parseYAML, stringifyYAML } from './yaml.cjs'; +import { F as FormatOptions } from './shared/confbox.9745c98f.cjs'; +export { parseTOML, stringifyTOML } from './toml.cjs'; + +/** + * Converts a [JSON](https://www.json.org/json-en.html) string into an object. + * + * Indentation status is auto-detected and preserved when stringifying back using `stringifyJSON` + */ +declare function parseJSON(text: string, options?: JSONParseOptions): T; +/** + * Converts a JavaScript value to a [JSON](https://www.json.org/json-en.html) string. + * + * Indentation status is auto detected and preserved when using value from parseJSON. + */ +declare function stringifyJSON(value: any, options?: JSONStringifyOptions): string; +interface JSONParseOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSONStringifyOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + replacer?: (this: any, key: string, value: any) => any; +} + +export { type JSONParseOptions, type JSONStringifyOptions, parseJSON, stringifyJSON }; diff --git a/node_modules/confbox/dist/index.d.mts b/node_modules/confbox/dist/index.d.mts new file mode 100644 index 0000000..6e33c1d --- /dev/null +++ b/node_modules/confbox/dist/index.d.mts @@ -0,0 +1,32 @@ +export { JSON5ParseOptions, JSON5StringifyOptions, parseJSON5, stringifyJSON5 } from './json5.mjs'; +export { JSONCParseError, JSONCParseOptions, parseJSONC, stringifyJSONC } from './jsonc.mjs'; +export { YAMLParseOptions, YAMLStringifyOptions, parseYAML, stringifyYAML } from './yaml.mjs'; +import { F as FormatOptions } from './shared/confbox.9745c98f.mjs'; +export { parseTOML, stringifyTOML } from './toml.mjs'; + +/** + * Converts a [JSON](https://www.json.org/json-en.html) string into an object. + * + * Indentation status is auto-detected and preserved when stringifying back using `stringifyJSON` + */ +declare function parseJSON(text: string, options?: JSONParseOptions): T; +/** + * Converts a JavaScript value to a [JSON](https://www.json.org/json-en.html) string. + * + * Indentation status is auto detected and preserved when using value from parseJSON. + */ +declare function stringifyJSON(value: any, options?: JSONStringifyOptions): string; +interface JSONParseOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSONStringifyOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + replacer?: (this: any, key: string, value: any) => any; +} + +export { type JSONParseOptions, type JSONStringifyOptions, parseJSON, stringifyJSON }; diff --git a/node_modules/confbox/dist/index.d.ts b/node_modules/confbox/dist/index.d.ts new file mode 100644 index 0000000..5c383e6 --- /dev/null +++ b/node_modules/confbox/dist/index.d.ts @@ -0,0 +1,32 @@ +export { JSON5ParseOptions, JSON5StringifyOptions, parseJSON5, stringifyJSON5 } from './json5.js'; +export { JSONCParseError, JSONCParseOptions, parseJSONC, stringifyJSONC } from './jsonc.js'; +export { YAMLParseOptions, YAMLStringifyOptions, parseYAML, stringifyYAML } from './yaml.js'; +import { F as FormatOptions } from './shared/confbox.9745c98f.js'; +export { parseTOML, stringifyTOML } from './toml.js'; + +/** + * Converts a [JSON](https://www.json.org/json-en.html) string into an object. + * + * Indentation status is auto-detected and preserved when stringifying back using `stringifyJSON` + */ +declare function parseJSON(text: string, options?: JSONParseOptions): T; +/** + * Converts a JavaScript value to a [JSON](https://www.json.org/json-en.html) string. + * + * Indentation status is auto detected and preserved when using value from parseJSON. + */ +declare function stringifyJSON(value: any, options?: JSONStringifyOptions): string; +interface JSONParseOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSONStringifyOptions extends FormatOptions { + /** + * A function that transforms the results. This function is called for each member of the object. + */ + replacer?: (this: any, key: string, value: any) => any; +} + +export { type JSONParseOptions, type JSONStringifyOptions, parseJSON, stringifyJSON }; diff --git a/node_modules/confbox/dist/index.mjs b/node_modules/confbox/dist/index.mjs new file mode 100644 index 0000000..76ca7dc --- /dev/null +++ b/node_modules/confbox/dist/index.mjs @@ -0,0 +1 @@ +export{parseJSON5,stringifyJSON5}from"./json5.mjs";export{a as parseJSON,p as parseJSONC,b as stringifyJSON,s as stringifyJSONC}from"./shared/confbox.f9f03f05.mjs";export{parseYAML,stringifyYAML}from"./yaml.mjs";export{parseTOML,stringifyTOML}from"./toml.mjs";import"./shared/confbox.9388d834.mjs"; diff --git a/node_modules/confbox/dist/json5.cjs b/node_modules/confbox/dist/json5.cjs new file mode 100644 index 0000000..a3fae76 --- /dev/null +++ b/node_modules/confbox/dist/json5.cjs @@ -0,0 +1,14 @@ +"use strict";const _format=require("./shared/confbox.3768c7e9.cjs");function getDefaultExportFromCjs(u){return u&&u.__esModule&&Object.prototype.hasOwnProperty.call(u,"default")?u.default:u}var unicode$1={};unicode$1.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,unicode$1.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,unicode$1.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/;const unicode=unicode$1;var util$2={isSpaceSeparator(u){return typeof u=="string"&&unicode.Space_Separator.test(u)},isIdStartChar(u){return typeof u=="string"&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u==="$"||u==="_"||unicode.ID_Start.test(u))},isIdContinueChar(u){return typeof u=="string"&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||u==="$"||u==="_"||u==="\u200C"||u==="\u200D"||unicode.ID_Continue.test(u))},isDigit(u){return typeof u=="string"&&/[0-9]/.test(u)},isHexDigit(u){return typeof u=="string"&&/[0-9A-Fa-f]/.test(u)}};const util$1=util$2;let source,parseState,stack,pos,line,column,token,key,root;var parse=function(e,t){source=String(e),parseState="start",stack=[],pos=0,line=1,column=0,token=void 0,key=void 0,root=void 0;do token=lex(),parseStates[parseState]();while(token.type!=="eof");return typeof t=="function"?internalize({"":root},"",t):root};function internalize(u,e,t){const C=u[e];if(C!=null&&typeof C=="object")if(Array.isArray(C))for(let s=0;s0;){const t=peek();if(!util$1.isHexDigit(t))throw invalidChar(read());u+=read()}return String.fromCodePoint(parseInt(u,16))}const parseStates={start(){if(token.type==="eof")throw invalidEOF();push()},beforePropertyName(){switch(token.type){case"identifier":case"string":key=token.value,parseState="afterPropertyName";return;case"punctuator":pop();return;case"eof":throw invalidEOF()}},afterPropertyName(){if(token.type==="eof")throw invalidEOF();parseState="beforePropertyValue"},beforePropertyValue(){if(token.type==="eof")throw invalidEOF();push()},beforeArrayValue(){if(token.type==="eof")throw invalidEOF();if(token.type==="punctuator"&&token.value==="]"){pop();return}push()},afterPropertyValue(){if(token.type==="eof")throw invalidEOF();switch(token.value){case",":parseState="beforePropertyName";return;case"}":pop()}},afterArrayValue(){if(token.type==="eof")throw invalidEOF();switch(token.value){case",":parseState="beforeArrayValue";return;case"]":pop()}},end(){}};function push(){let u;switch(token.type){case"punctuator":switch(token.value){case"{":u={};break;case"[":u=[];break}break;case"null":case"boolean":case"numeric":case"string":u=token.value;break}if(root===void 0)root=u;else{const e=stack[stack.length-1];Array.isArray(e)?e.push(u):Object.defineProperty(e,key,{value:u,writable:!0,enumerable:!0,configurable:!0})}if(u!==null&&typeof u=="object")stack.push(u),Array.isArray(u)?parseState="beforeArrayValue":parseState="beforePropertyName";else{const e=stack[stack.length-1];e==null?parseState="end":Array.isArray(e)?parseState="afterArrayValue":parseState="afterPropertyValue"}}function pop(){stack.pop();const u=stack[stack.length-1];u==null?parseState="end":Array.isArray(u)?parseState="afterArrayValue":parseState="afterPropertyValue"}function invalidChar(u){return syntaxError(u===void 0?`JSON5: invalid end of input at ${line}:${column}`:`JSON5: invalid character '${formatChar(u)}' at ${line}:${column}`)}function invalidEOF(){return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)}function invalidIdentifier(){return column-=5,syntaxError(`JSON5: invalid identifier character at ${line}:${column}`)}function separatorChar(u){console.warn(`JSON5: '${formatChar(u)}' in strings is not valid ECMAScript; consider escaping`)}function formatChar(u){const e={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r"," ":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(e[u])return e[u];if(u<" "){const t=u.charCodeAt(0).toString(16);return"\\x"+("00"+t).substring(t.length)}return u}function syntaxError(u){const e=new SyntaxError(u);return e.lineNumber=line,e.columnNumber=column,e}const o=getDefaultExportFromCjs(parse),util=util$2;var stringify=function(e,t,C){const s=[];let E="",f,h,l="",g;if(t!=null&&typeof t=="object"&&!Array.isArray(t)&&(C=t.space,g=t.quote,t=t.replacer),typeof t=="function")h=t;else if(Array.isArray(t)){f=[];for(const F of t){let r;typeof F=="string"?r=F:(typeof F=="number"||F instanceof String||F instanceof Number)&&(r=String(F)),r!==void 0&&f.indexOf(r)<0&&f.push(r)}}return C instanceof Number?C=Number(C):C instanceof String&&(C=String(C)),typeof C=="number"?C>0&&(C=Math.min(10,Math.floor(C)),l=" ".substr(0,C)):typeof C=="string"&&(l=C.substr(0,10)),m("",{"":e});function m(F,r){let D=r[F];switch(D!=null&&(typeof D.toJSON5=="function"?D=D.toJSON5(F):typeof D.toJSON=="function"&&(D=D.toJSON(F))),h&&(D=h.call(r,F,D)),D instanceof Number?D=Number(D):D instanceof String?D=String(D):D instanceof Boolean&&(D=D.valueOf()),D){case null:return"null";case!0:return"true";case!1:return"false"}if(typeof D=="string")return p(D);if(typeof D=="number")return String(D);if(typeof D=="object")return Array.isArray(D)?b(D):y(D)}function p(F){const r={"'":.1,'"':.2},D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r"," ":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};let n="";for(let A=0;Ar[A]=0)throw TypeError("Converting circular structure to JSON5");s.push(F);let r=E;E=E+l;let D=f||Object.keys(F),n=[];for(const A of D){const B=m(A,F);if(B!==void 0){let d=w(A)+":";l!==""&&(d+=" "),d+=B,n.push(d)}}let i;if(n.length===0)i="{}";else{let A;if(l==="")A=n.join(","),i="{"+A+"}";else{let B=`, +`+E;A=n.join(B),i=`{ +`+E+A+`, +`+r+"}"}}return s.pop(),E=r,i}function w(F){if(F.length===0)return p(F);const r=String.fromCodePoint(F.codePointAt(0));if(!util.isIdStartChar(r))return p(F);for(let D=r.length;D=0)throw TypeError("Converting circular structure to JSON5");s.push(F);let r=E;E=E+l;let D=[];for(let i=0;i(text: string, options?: JSON5ParseOptions): T; +/** + * Converts a JavaScript value to a [JSON5](https://json5.org/) string. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSON5(value: any, options?: JSON5StringifyOptions): string; +interface JSON5ParseOptions extends FormatOptions { + /** + * A function that alters the behavior of the parsing process, or an array of + * String and Number objects that serve as a allowlist for selecting/filtering + * the properties of the value object to be included in the resulting + * JavaScript object. If this value is null or not provided, all properties of + * the object are included in the resulting JavaScript object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSON5StringifyOptions extends FormatOptions { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: ((this: any, key: string, value: any) => any) | null; + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null; + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null; +} + +export { type JSON5ParseOptions, type JSON5StringifyOptions, parseJSON5, stringifyJSON5 }; diff --git a/node_modules/confbox/dist/json5.d.mts b/node_modules/confbox/dist/json5.d.mts new file mode 100644 index 0000000..9709875 --- /dev/null +++ b/node_modules/confbox/dist/json5.d.mts @@ -0,0 +1,58 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.mjs'; + +/** + * Converts a [JSON5](https://json5.org/) string into an object. + * + * @template T The type of the return value. + * @param text The string to parse as JSON5. + * @param options Parsing options. + * @returns The JavaScript value converted from the JSON5 string. + */ +declare function parseJSON5(text: string, options?: JSON5ParseOptions): T; +/** + * Converts a JavaScript value to a [JSON5](https://json5.org/) string. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSON5(value: any, options?: JSON5StringifyOptions): string; +interface JSON5ParseOptions extends FormatOptions { + /** + * A function that alters the behavior of the parsing process, or an array of + * String and Number objects that serve as a allowlist for selecting/filtering + * the properties of the value object to be included in the resulting + * JavaScript object. If this value is null or not provided, all properties of + * the object are included in the resulting JavaScript object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSON5StringifyOptions extends FormatOptions { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: ((this: any, key: string, value: any) => any) | null; + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null; + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null; +} + +export { type JSON5ParseOptions, type JSON5StringifyOptions, parseJSON5, stringifyJSON5 }; diff --git a/node_modules/confbox/dist/json5.d.ts b/node_modules/confbox/dist/json5.d.ts new file mode 100644 index 0000000..8f4ee36 --- /dev/null +++ b/node_modules/confbox/dist/json5.d.ts @@ -0,0 +1,58 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.js'; + +/** + * Converts a [JSON5](https://json5.org/) string into an object. + * + * @template T The type of the return value. + * @param text The string to parse as JSON5. + * @param options Parsing options. + * @returns The JavaScript value converted from the JSON5 string. + */ +declare function parseJSON5(text: string, options?: JSON5ParseOptions): T; +/** + * Converts a JavaScript value to a [JSON5](https://json5.org/) string. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSON5(value: any, options?: JSON5StringifyOptions): string; +interface JSON5ParseOptions extends FormatOptions { + /** + * A function that alters the behavior of the parsing process, or an array of + * String and Number objects that serve as a allowlist for selecting/filtering + * the properties of the value object to be included in the resulting + * JavaScript object. If this value is null or not provided, all properties of + * the object are included in the resulting JavaScript object. + */ + reviver?: (this: any, key: string, value: any) => any; +} +interface JSON5StringifyOptions extends FormatOptions { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: ((this: any, key: string, value: any) => any) | null; + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null; + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null; +} + +export { type JSON5ParseOptions, type JSON5StringifyOptions, parseJSON5, stringifyJSON5 }; diff --git a/node_modules/confbox/dist/json5.mjs b/node_modules/confbox/dist/json5.mjs new file mode 100644 index 0000000..c7f9919 --- /dev/null +++ b/node_modules/confbox/dist/json5.mjs @@ -0,0 +1,14 @@ +import{s as Fu,g as tu}from"./shared/confbox.9388d834.mjs";function X(D){return D&&D.__esModule&&Object.prototype.hasOwnProperty.call(D,"default")?D.default:D}var k={};k.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,k.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,k.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/;const H=k;var G={isSpaceSeparator(D){return typeof D=="string"&&H.Space_Separator.test(D)},isIdStartChar(D){return typeof D=="string"&&(D>="a"&&D<="z"||D>="A"&&D<="Z"||D==="$"||D==="_"||H.ID_Start.test(D))},isIdContinueChar(D){return typeof D=="string"&&(D>="a"&&D<="z"||D>="A"&&D<="Z"||D>="0"&&D<="9"||D==="$"||D==="_"||D==="\u200C"||D==="\u200D"||H.ID_Continue.test(D))},isDigit(D){return typeof D=="string"&&/[0-9]/.test(D)},isHexDigit(D){return typeof D=="string"&&/[0-9A-Fa-f]/.test(D)}};const f=G;let q,h,y,V,S,g,l,M,O;var Cu=function(C,E){q=String(C),h="start",y=[],V=0,S=1,g=0,l=void 0,M=void 0,O=void 0;do l=ru(),nu[h]();while(l.type!=="eof");return typeof E=="function"?T({"":O},"",E):O};function T(D,C,E){const n=D[C];if(n!=null&&typeof n=="object")if(Array.isArray(n))for(let m=0;m0;){const E=b();if(!f.isHexDigit(E))throw a(u());D+=u()}return String.fromCodePoint(parseInt(D,16))}const nu={start(){if(l.type==="eof")throw I();K()},beforePropertyName(){switch(l.type){case"identifier":case"string":M=l.value,h="afterPropertyName";return;case"punctuator":_();return;case"eof":throw I()}},afterPropertyName(){if(l.type==="eof")throw I();h="beforePropertyValue"},beforePropertyValue(){if(l.type==="eof")throw I();K()},beforeArrayValue(){if(l.type==="eof")throw I();if(l.type==="punctuator"&&l.value==="]"){_();return}K()},afterPropertyValue(){if(l.type==="eof")throw I();switch(l.value){case",":h="beforePropertyName";return;case"}":_()}},afterArrayValue(){if(l.type==="eof")throw I();switch(l.value){case",":h="beforeArrayValue";return;case"]":_()}},end(){}};function K(){let D;switch(l.type){case"punctuator":switch(l.value){case"{":D={};break;case"[":D=[];break}break;case"null":case"boolean":case"numeric":case"string":D=l.value;break}if(O===void 0)O=D;else{const C=y[y.length-1];Array.isArray(C)?C.push(D):Object.defineProperty(C,M,{value:D,writable:!0,enumerable:!0,configurable:!0})}if(D!==null&&typeof D=="object")y.push(D),Array.isArray(D)?h="beforeArrayValue":h="beforePropertyName";else{const C=y[y.length-1];C==null?h="end":Array.isArray(C)?h="afterArrayValue":h="afterPropertyValue"}}function _(){y.pop();const D=y[y.length-1];D==null?h="end":Array.isArray(D)?h="afterArrayValue":h="afterPropertyValue"}function a(D){return J(D===void 0?`JSON5: invalid end of input at ${S}:${g}`:`JSON5: invalid character '${Y(D)}' at ${S}:${g}`)}function I(){return J(`JSON5: invalid end of input at ${S}:${g}`)}function W(){return g-=5,J(`JSON5: invalid identifier character at ${S}:${g}`)}function iu(D){console.warn(`JSON5: '${Y(D)}' in strings is not valid ECMAScript; consider escaping`)}function Y(D){const C={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r"," ":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(C[D])return C[D];if(D<" "){const E=D.charCodeAt(0).toString(16);return"\\x"+("00"+E).substring(E.length)}return D}function J(D){const C=new SyntaxError(D);return C.lineNumber=S,C.columnNumber=g,C}const au=X(Cu),Q=G;var Bu=function(C,E,n){const m=[];let o="",x,L,N="",R;if(E!=null&&typeof E=="object"&&!Array.isArray(E)&&(n=E.space,R=E.quote,E=E.replacer),typeof E=="function")L=E;else if(Array.isArray(E)){x=[];for(const A of E){let B;typeof A=="string"?B=A:(typeof A=="number"||A instanceof String||A instanceof Number)&&(B=String(A)),B!==void 0&&x.indexOf(B)<0&&x.push(B)}}return n instanceof Number?n=Number(n):n instanceof String&&(n=String(n)),typeof n=="number"?n>0&&(n=Math.min(10,Math.floor(n)),N=" ".substr(0,n)):typeof n=="string"&&(N=n.substr(0,10)),z("",{"":C});function z(A,B){let F=B[A];switch(F!=null&&(typeof F.toJSON5=="function"?F=F.toJSON5(A):typeof F.toJSON=="function"&&(F=F.toJSON(A))),L&&(F=L.call(B,A,F)),F instanceof Number?F=Number(F):F instanceof String?F=String(F):F instanceof Boolean&&(F=F.valueOf()),F){case null:return"null";case!0:return"true";case!1:return"false"}if(typeof F=="string")return j(F);if(typeof F=="number")return String(F);if(typeof F=="object")return Array.isArray(F)?eu(F):uu(F)}function j(A){const B={"'":.1,'"':.2},F={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r"," ":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};let c="";for(let s=0;sB[s]=0)throw TypeError("Converting circular structure to JSON5");m.push(A);let B=o;o=o+N;let F=x||Object.keys(A),c=[];for(const s of F){const p=z(s,A);if(p!==void 0){let v=Du(s)+":";N!==""&&(v+=" "),v+=p,c.push(v)}}let d;if(c.length===0)d="{}";else{let s;if(N==="")s=c.join(","),d="{"+s+"}";else{let p=`, +`+o;s=c.join(p),d=`{ +`+o+s+`, +`+B+"}"}}return m.pop(),o=B,d}function Du(A){if(A.length===0)return j(A);const B=String.fromCodePoint(A.codePointAt(0));if(!Q.isIdStartChar(B))return j(A);for(let F=B.length;F=0)throw TypeError("Converting circular structure to JSON5");m.push(A);let B=o;o=o+N;let F=[];for(let d=0;d(text: string, options?: JSONCParseOptions): T; +/** + * Converts a JavaScript value to a [JSONC](https://github.com/microsoft/node-jsonc-parser) string. + * + * @NOTE Comments and trailing commas are not preserved in the output. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSONC(value: any, options?: JSONCStringifyOptions): string; +interface JSONCParseOptions extends FormatOptions { + disallowComments?: boolean; + allowTrailingComma?: boolean; + allowEmptyContent?: boolean; + errors?: JSONCParseError[]; +} +interface JSONCStringifyOptions extends FormatOptions { +} +interface JSONCParseError { + error: number; + offset: number; + length: number; +} + +export { type JSONCParseError, type JSONCParseOptions, type JSONCStringifyOptions, parseJSONC, stringifyJSONC }; diff --git a/node_modules/confbox/dist/jsonc.d.mts b/node_modules/confbox/dist/jsonc.d.mts new file mode 100644 index 0000000..b3d35fa --- /dev/null +++ b/node_modules/confbox/dist/jsonc.d.mts @@ -0,0 +1,41 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.mjs'; + +/** + * + * Converts a [JSONC](https://github.com/microsoft/node-jsonc-parser) string into an object. + * + * @NOTE On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + * + * @NOTE Comments and trailing commas are not preserved after parsing. + * + * @template T The type of the return value. + * @param text The string to parse as JSONC. + * @param options Parsing options. + * @returns The JavaScript value converted from the JSONC string. + */ +declare function parseJSONC(text: string, options?: JSONCParseOptions): T; +/** + * Converts a JavaScript value to a [JSONC](https://github.com/microsoft/node-jsonc-parser) string. + * + * @NOTE Comments and trailing commas are not preserved in the output. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSONC(value: any, options?: JSONCStringifyOptions): string; +interface JSONCParseOptions extends FormatOptions { + disallowComments?: boolean; + allowTrailingComma?: boolean; + allowEmptyContent?: boolean; + errors?: JSONCParseError[]; +} +interface JSONCStringifyOptions extends FormatOptions { +} +interface JSONCParseError { + error: number; + offset: number; + length: number; +} + +export { type JSONCParseError, type JSONCParseOptions, type JSONCStringifyOptions, parseJSONC, stringifyJSONC }; diff --git a/node_modules/confbox/dist/jsonc.d.ts b/node_modules/confbox/dist/jsonc.d.ts new file mode 100644 index 0000000..edc19ad --- /dev/null +++ b/node_modules/confbox/dist/jsonc.d.ts @@ -0,0 +1,41 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.js'; + +/** + * + * Converts a [JSONC](https://github.com/microsoft/node-jsonc-parser) string into an object. + * + * @NOTE On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + * + * @NOTE Comments and trailing commas are not preserved after parsing. + * + * @template T The type of the return value. + * @param text The string to parse as JSONC. + * @param options Parsing options. + * @returns The JavaScript value converted from the JSONC string. + */ +declare function parseJSONC(text: string, options?: JSONCParseOptions): T; +/** + * Converts a JavaScript value to a [JSONC](https://github.com/microsoft/node-jsonc-parser) string. + * + * @NOTE Comments and trailing commas are not preserved in the output. + * + * @param value + * @param options + * @returns The JSON string converted from the JavaScript value. + */ +declare function stringifyJSONC(value: any, options?: JSONCStringifyOptions): string; +interface JSONCParseOptions extends FormatOptions { + disallowComments?: boolean; + allowTrailingComma?: boolean; + allowEmptyContent?: boolean; + errors?: JSONCParseError[]; +} +interface JSONCStringifyOptions extends FormatOptions { +} +interface JSONCParseError { + error: number; + offset: number; + length: number; +} + +export { type JSONCParseError, type JSONCParseOptions, type JSONCStringifyOptions, parseJSONC, stringifyJSONC }; diff --git a/node_modules/confbox/dist/jsonc.mjs b/node_modules/confbox/dist/jsonc.mjs new file mode 100644 index 0000000..0c97409 --- /dev/null +++ b/node_modules/confbox/dist/jsonc.mjs @@ -0,0 +1 @@ +import"./shared/confbox.9388d834.mjs";export{p as parseJSONC,s as stringifyJSONC}from"./shared/confbox.f9f03f05.mjs"; diff --git a/node_modules/confbox/dist/shared/confbox.3768c7e9.cjs b/node_modules/confbox/dist/shared/confbox.3768c7e9.cjs new file mode 100644 index 0000000..8b47219 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.3768c7e9.cjs @@ -0,0 +1 @@ +"use strict";const INDENT_REGEX=/^(?:( )+|\t+)/,INDENT_TYPE_SPACE="space",INDENT_TYPE_TAB="tab";function makeIndentsMap(e,t){const n=new Map;let i=0,a,c;for(const f of e.split(/\n/g)){if(!f)continue;let l,u,y,m,d;const h=f.match(INDENT_REGEX);if(h===null)i=0,a="";else{if(l=h[0].length,u=h[1]?INDENT_TYPE_SPACE:INDENT_TYPE_TAB,t&&u===INDENT_TYPE_SPACE&&l===1)continue;u!==a&&(i=0),a=u,y=1,m=0;const p=l-i;if(i=l,p===0)y=0,m=1;else{const g=p>0?p:-p;c=encodeIndentsKey(u,g)}d=n.get(c),d=d===void 0?[1,0]:[d[0]+y,d[1]+m],n.set(c,d)}}return n}function encodeIndentsKey(e,t){return(e===INDENT_TYPE_SPACE?"s":"t")+String(t)}function decodeIndentsKey(e){const n=e[0]==="s"?INDENT_TYPE_SPACE:INDENT_TYPE_TAB,i=Number(e.slice(1));return{type:n,amount:i}}function getMostUsedKey(e){let t,n=0,i=0;for(const[a,[c,f]]of e)(c>n||c===n&&f>i)&&(n=c,i=f,t=a);return t}function makeIndentString(e,t){return(e===INDENT_TYPE_SPACE?" ":" ").repeat(t)}function detectIndent(e){if(typeof e!="string")throw new TypeError("Expected a string");let t=makeIndentsMap(e,!0);t.size===0&&(t=makeIndentsMap(e,!1));const n=getMostUsedKey(t);let i,a=0,c="";return n!==void 0&&({type:i,amount:a}=decodeIndentsKey(n),c=makeIndentString(i,a)),{amount:a,type:i,indent:c}}const r=Symbol.for("__confbox_fmt__"),o=/^(\s+)/,s=/(\s+)$/;function detectFormat(e,t={}){const n=t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),i=t.preserveWhitespace===!1?void 0:{start:o.exec(e)?.[0]||"",end:s.exec(e)?.[0]||""};return{sample:n,whiteSpace:i}}function storeFormat(e,t,n){!t||typeof t!="object"||Object.defineProperty(t,r,{enumerable:!1,configurable:!0,writable:!0,value:detectFormat(e,n)})}function getFormat(e,t){if(!e||typeof e!="object"||!(r in e))return{indent:t?.indent,whitespace:{start:"",end:""}};const n=e[r];return{indent:t?.indent||detectIndent(n.sample||"").indent,whitespace:n.whiteSpace||{start:"",end:""}}}exports.getFormat=getFormat,exports.storeFormat=storeFormat; diff --git a/node_modules/confbox/dist/shared/confbox.6b479c78.cjs b/node_modules/confbox/dist/shared/confbox.6b479c78.cjs new file mode 100644 index 0000000..f96c519 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.6b479c78.cjs @@ -0,0 +1,7 @@ +"use strict";const _format=require("./confbox.3768c7e9.cjs");function createScanner(n,l=!1){const g=n.length;let e=0,u="",p=0,k=16,A=0,o=0,O=0,r=0,T=0;function L(t,s){let b=0,c=0;for(;b=48&&i<=57)c=c*16+i-48;else if(i>=65&&i<=70)c=c*16+i-65+10;else if(i>=97&&i<=102)c=c*16+i-97+10;else break;e++,b++}return b=g){t+=n.substring(s,e),T=2;break}const b=n.charCodeAt(e);if(b===34){t+=n.substring(s,e),e++;break}if(b===92){if(t+=n.substring(s,e),e++,e>=g){T=2;break}switch(n.charCodeAt(e++)){case 34:t+='"';break;case 92:t+="\\";break;case 47:t+="/";break;case 98:t+="\b";break;case 102:t+="\f";break;case 110:t+=` +`;break;case 114:t+="\r";break;case 116:t+=" ";break;case 117:const i=L(4,!0);i>=0?t+=String.fromCharCode(i):T=4;break;default:T=5}s=e;continue}if(b>=0&&b<=31)if(isLineBreak(b)){t+=n.substring(s,e),T=2;break}else T=6;e++}return t}function w(){if(u="",T=0,p=e,o=A,r=O,e>=g)return p=g,k=17;let t=n.charCodeAt(e);if(isWhiteSpace(t)){do e++,u+=String.fromCharCode(t),t=n.charCodeAt(e);while(isWhiteSpace(t));return k=15}if(isLineBreak(t))return e++,u+=String.fromCharCode(t),t===13&&n.charCodeAt(e)===10&&(e++,u+=` +`),A++,O=e,k=14;switch(t){case 123:return e++,k=1;case 125:return e++,k=2;case 91:return e++,k=3;case 93:return e++,k=4;case 58:return e++,k=6;case 44:return e++,k=5;case 34:return e++,u=U(),k=10;case 47:const s=e-1;if(n.charCodeAt(e+1)===47){for(e+=2;e=12&&t<=15);return t}return{setPosition:v,getPosition:()=>e,scan:l?I:w,getToken:()=>k,getTokenValue:()=>u,getTokenOffset:()=>p,getTokenLength:()=>e-p,getTokenStartLine:()=>o,getTokenStartCharacter:()=>p-r,getTokenError:()=>T}}function isWhiteSpace(n){return n===32||n===9}function isLineBreak(n){return n===10||n===13}function isDigit(n){return n>=48&&n<=57}var CharacterCodes;(function(n){n[n.lineFeed=10]="lineFeed",n[n.carriageReturn=13]="carriageReturn",n[n.space=32]="space",n[n._0=48]="_0",n[n._1=49]="_1",n[n._2=50]="_2",n[n._3=51]="_3",n[n._4=52]="_4",n[n._5=53]="_5",n[n._6=54]="_6",n[n._7=55]="_7",n[n._8=56]="_8",n[n._9=57]="_9",n[n.a=97]="a",n[n.b=98]="b",n[n.c=99]="c",n[n.d=100]="d",n[n.e=101]="e",n[n.f=102]="f",n[n.g=103]="g",n[n.h=104]="h",n[n.i=105]="i",n[n.j=106]="j",n[n.k=107]="k",n[n.l=108]="l",n[n.m=109]="m",n[n.n=110]="n",n[n.o=111]="o",n[n.p=112]="p",n[n.q=113]="q",n[n.r=114]="r",n[n.s=115]="s",n[n.t=116]="t",n[n.u=117]="u",n[n.v=118]="v",n[n.w=119]="w",n[n.x=120]="x",n[n.y=121]="y",n[n.z=122]="z",n[n.A=65]="A",n[n.B=66]="B",n[n.C=67]="C",n[n.D=68]="D",n[n.E=69]="E",n[n.F=70]="F",n[n.G=71]="G",n[n.H=72]="H",n[n.I=73]="I",n[n.J=74]="J",n[n.K=75]="K",n[n.L=76]="L",n[n.M=77]="M",n[n.N=78]="N",n[n.O=79]="O",n[n.P=80]="P",n[n.Q=81]="Q",n[n.R=82]="R",n[n.S=83]="S",n[n.T=84]="T",n[n.U=85]="U",n[n.V=86]="V",n[n.W=87]="W",n[n.X=88]="X",n[n.Y=89]="Y",n[n.Z=90]="Z",n[n.asterisk=42]="asterisk",n[n.backslash=92]="backslash",n[n.closeBrace=125]="closeBrace",n[n.closeBracket=93]="closeBracket",n[n.colon=58]="colon",n[n.comma=44]="comma",n[n.dot=46]="dot",n[n.doubleQuote=34]="doubleQuote",n[n.minus=45]="minus",n[n.openBrace=123]="openBrace",n[n.openBracket=91]="openBracket",n[n.plus=43]="plus",n[n.slash=47]="slash",n[n.formFeed=12]="formFeed",n[n.tab=9]="tab"})(CharacterCodes||(CharacterCodes={})),new Array(20).fill(0).map((n,l)=>" ".repeat(l));const maxCachedValues=200;new Array(maxCachedValues).fill(0).map((n,l)=>` +`+" ".repeat(l)),new Array(maxCachedValues).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(maxCachedValues).fill(0).map((n,l)=>`\r +`+" ".repeat(l)),new Array(maxCachedValues).fill(0).map((n,l)=>` +`+" ".repeat(l)),new Array(maxCachedValues).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(maxCachedValues).fill(0).map((n,l)=>`\r +`+" ".repeat(l));var ParseOptions;(function(n){n.DEFAULT={allowTrailingComma:!1}})(ParseOptions||(ParseOptions={}));function parse$1(n,l=[],g=ParseOptions.DEFAULT){let e=null,u=[];const p=[];function k(o){Array.isArray(u)?u.push(o):e!==null&&(u[e]=o)}return visit(n,{onObjectBegin:()=>{const o={};k(o),p.push(u),u=o,e=null},onObjectProperty:o=>{e=o},onObjectEnd:()=>{u=p.pop()},onArrayBegin:()=>{const o=[];k(o),p.push(u),u=o,e=null},onArrayEnd:()=>{u=p.pop()},onLiteralValue:k,onError:(o,O,r)=>{l.push({error:o,offset:O,length:r})}},g),u[0]}function visit(n,l,g=ParseOptions.DEFAULT){const e=createScanner(n,!1),u=[];let p=0;function k(f){return f?()=>p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function A(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function o(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice()):()=>!0}function O(f){return f?()=>{p>0?p++:f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice())===!1&&(p=1)}:()=>!0}function r(f){return f?()=>{p>0&&p--,p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter())}:()=>!0}const T=O(l.onObjectBegin),L=o(l.onObjectProperty),v=r(l.onObjectEnd),_=O(l.onArrayBegin),U=r(l.onArrayEnd),w=o(l.onLiteralValue),N=A(l.onSeparator),I=k(l.onComment),t=A(l.onError),s=g&&g.disallowComments,b=g&&g.allowTrailingComma;function c(){for(;;){const f=e.scan();switch(e.getTokenError()){case 4:i(14);break;case 5:i(15);break;case 3:i(13);break;case 1:s||i(11);break;case 2:i(12);break;case 6:i(16);break}switch(f){case 12:case 13:s?i(10):I();break;case 16:i(1);break;case 15:case 14:break;default:return f}}}function i(f,m=[],j=[]){if(t(f),m.length+j.length>0){let B=e.getToken();for(;B!==17;){if(m.indexOf(B)!==-1){c();break}else if(j.indexOf(B)!==-1)break;B=c()}}}function F(f){const m=e.getTokenValue();return f?w(m):(L(m),u.push(m)),c(),!0}function E(){switch(e.getToken()){case 11:const f=e.getTokenValue();let m=Number(f);isNaN(m)&&(i(2),m=0),w(m);break;case 7:w(null);break;case 8:w(!0);break;case 9:w(!1);break;default:return!1}return c(),!0}function J(){return e.getToken()!==10?(i(3,[],[2,5]),!1):(F(!1),e.getToken()===6?(N(":"),c(),V()||i(4,[],[2,5])):i(5,[],[2,5]),u.pop(),!0)}function a(){T(),c();let f=!1;for(;e.getToken()!==2&&e.getToken()!==17;){if(e.getToken()===5){if(f||i(4,[],[]),N(","),c(),e.getToken()===2&&b)break}else f&&i(6,[],[]);J()||i(4,[],[2,5]),f=!0}return v(),e.getToken()!==2?i(7,[2],[]):c(),!0}function y(){_(),c();let f=!0,m=!1;for(;e.getToken()!==4&&e.getToken()!==17;){if(e.getToken()===5){if(m||i(4,[],[]),N(","),c(),e.getToken()===4&&b)break}else m&&i(6,[],[]);f?(u.push(0),f=!1):u[u.length-1]++,V()||i(4,[],[4,5]),m=!0}return U(),f||u.pop(),e.getToken()!==4?i(8,[4],[]):c(),!0}function V(){switch(e.getToken()){case 3:return y();case 1:return a();case 10:return F(!0);default:return E()}}return c(),e.getToken()===17?g.allowEmptyContent?!0:(i(4,[],[]),!1):V()?(e.getToken()!==17&&i(9,[],[]),!0):(i(4,[],[]),!1)}var ScanError;(function(n){n[n.None=0]="None",n[n.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=2]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",n[n.InvalidUnicode=4]="InvalidUnicode",n[n.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",n[n.InvalidCharacter=6]="InvalidCharacter"})(ScanError||(ScanError={}));var SyntaxKind;(function(n){n[n.OpenBraceToken=1]="OpenBraceToken",n[n.CloseBraceToken=2]="CloseBraceToken",n[n.OpenBracketToken=3]="OpenBracketToken",n[n.CloseBracketToken=4]="CloseBracketToken",n[n.CommaToken=5]="CommaToken",n[n.ColonToken=6]="ColonToken",n[n.NullKeyword=7]="NullKeyword",n[n.TrueKeyword=8]="TrueKeyword",n[n.FalseKeyword=9]="FalseKeyword",n[n.StringLiteral=10]="StringLiteral",n[n.NumericLiteral=11]="NumericLiteral",n[n.LineCommentTrivia=12]="LineCommentTrivia",n[n.BlockCommentTrivia=13]="BlockCommentTrivia",n[n.LineBreakTrivia=14]="LineBreakTrivia",n[n.Trivia=15]="Trivia",n[n.Unknown=16]="Unknown",n[n.EOF=17]="EOF"})(SyntaxKind||(SyntaxKind={}));const parse=parse$1;var ParseErrorCode;(function(n){n[n.InvalidSymbol=1]="InvalidSymbol",n[n.InvalidNumberFormat=2]="InvalidNumberFormat",n[n.PropertyNameExpected=3]="PropertyNameExpected",n[n.ValueExpected=4]="ValueExpected",n[n.ColonExpected=5]="ColonExpected",n[n.CommaExpected=6]="CommaExpected",n[n.CloseBraceExpected=7]="CloseBraceExpected",n[n.CloseBracketExpected=8]="CloseBracketExpected",n[n.EndOfFileExpected=9]="EndOfFileExpected",n[n.InvalidCommentToken=10]="InvalidCommentToken",n[n.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=12]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",n[n.InvalidUnicode=14]="InvalidUnicode",n[n.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",n[n.InvalidCharacter=16]="InvalidCharacter"})(ParseErrorCode||(ParseErrorCode={}));function parseJSON(n,l){const g=JSON.parse(n,l?.reviver);return _format.storeFormat(n,g,l),g}function stringifyJSON(n,l){const g=_format.getFormat(n,l),e=JSON.stringify(n,l?.replacer,g.indent);return g.whitespace.start+e+g.whitespace.end}function parseJSONC(n,l){const g=parse(n,l?.errors,l);return _format.storeFormat(n,g,l),g}function stringifyJSONC(n,l){return stringifyJSON(n,l)}exports.parseJSON=parseJSON,exports.parseJSONC=parseJSONC,exports.stringifyJSON=stringifyJSON,exports.stringifyJSONC=stringifyJSONC; diff --git a/node_modules/confbox/dist/shared/confbox.9388d834.mjs b/node_modules/confbox/dist/shared/confbox.9388d834.mjs new file mode 100644 index 0000000..e51ca70 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.9388d834.mjs @@ -0,0 +1 @@ +const b=/^(?:( )+|\t+)/,d="space",h="tab";function g(e,t){const n=new Map;let i=0,s,o;for(const c of e.split(/\n/g)){if(!c)continue;let f,a,l,p,r;const y=c.match(b);if(y===null)i=0,s="";else{if(f=y[0].length,a=y[1]?d:h,t&&a===d&&f===1)continue;a!==s&&(i=0),s=a,l=1,p=0;const u=f-i;if(i=f,u===0)l=0,p=1;else{const I=u>0?u:-u;o=T(a,I)}r=n.get(o),r=r===void 0?[1,0]:[r[0]+l,r[1]+p],n.set(o,r)}}return n}function T(e,t){return(e===d?"s":"t")+String(t)}function w(e){const n=e[0]==="s"?d:h,i=Number(e.slice(1));return{type:n,amount:i}}function E(e){let t,n=0,i=0;for(const[s,[o,c]]of e)(o>n||o===n&&c>i)&&(n=o,i=c,t=s);return t}function S(e,t){return(e===d?" ":" ").repeat(t)}function _(e){if(typeof e!="string")throw new TypeError("Expected a string");let t=g(e,!0);t.size===0&&(t=g(e,!1));const n=E(t);let i,s=0,o="";return n!==void 0&&({type:i,amount:s}=w(n),o=S(i,s)),{amount:s,type:i,indent:o}}const m=Symbol.for("__confbox_fmt__"),k=/^(\s+)/,v=/(\s+)$/;function x(e,t={}){const n=t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),i=t.preserveWhitespace===!1?void 0:{start:k.exec(e)?.[0]||"",end:v.exec(e)?.[0]||""};return{sample:n,whiteSpace:i}}function N(e,t,n){!t||typeof t!="object"||Object.defineProperty(t,m,{enumerable:!1,configurable:!0,writable:!0,value:x(e,n)})}function C(e,t){if(!e||typeof e!="object"||!(m in e))return{indent:t?.indent,whitespace:{start:"",end:""}};const n=e[m];return{indent:t?.indent||_(n.sample||"").indent,whitespace:n.whiteSpace||{start:"",end:""}}}export{C as g,N as s}; diff --git a/node_modules/confbox/dist/shared/confbox.9745c98f.d.cts b/node_modules/confbox/dist/shared/confbox.9745c98f.d.cts new file mode 100644 index 0000000..2e14655 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.9745c98f.d.cts @@ -0,0 +1,24 @@ +interface FormatOptions { + /** + * A String or Number object that's used to insert white space into the output JSON string for readability purposes. + * + * When provided, identation won't be auto detected anymore. + */ + indent?: string | number; + /** + * Set to `false` to skip indentation preservation. + */ + preserveIndentation?: boolean; + /** + * Set to `false` to skip whitespace preservation. + */ + preserveWhitespace?: boolean; + /** + * The number of characters to sample from the start of the text. + * + * Default: 1024 + */ + sampleSize?: number; +} + +export type { FormatOptions as F }; diff --git a/node_modules/confbox/dist/shared/confbox.9745c98f.d.mts b/node_modules/confbox/dist/shared/confbox.9745c98f.d.mts new file mode 100644 index 0000000..2e14655 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.9745c98f.d.mts @@ -0,0 +1,24 @@ +interface FormatOptions { + /** + * A String or Number object that's used to insert white space into the output JSON string for readability purposes. + * + * When provided, identation won't be auto detected anymore. + */ + indent?: string | number; + /** + * Set to `false` to skip indentation preservation. + */ + preserveIndentation?: boolean; + /** + * Set to `false` to skip whitespace preservation. + */ + preserveWhitespace?: boolean; + /** + * The number of characters to sample from the start of the text. + * + * Default: 1024 + */ + sampleSize?: number; +} + +export type { FormatOptions as F }; diff --git a/node_modules/confbox/dist/shared/confbox.9745c98f.d.ts b/node_modules/confbox/dist/shared/confbox.9745c98f.d.ts new file mode 100644 index 0000000..2e14655 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.9745c98f.d.ts @@ -0,0 +1,24 @@ +interface FormatOptions { + /** + * A String or Number object that's used to insert white space into the output JSON string for readability purposes. + * + * When provided, identation won't be auto detected anymore. + */ + indent?: string | number; + /** + * Set to `false` to skip indentation preservation. + */ + preserveIndentation?: boolean; + /** + * Set to `false` to skip whitespace preservation. + */ + preserveWhitespace?: boolean; + /** + * The number of characters to sample from the start of the text. + * + * Default: 1024 + */ + sampleSize?: number; +} + +export type { FormatOptions as F }; diff --git a/node_modules/confbox/dist/shared/confbox.f9f03f05.mjs b/node_modules/confbox/dist/shared/confbox.f9f03f05.mjs new file mode 100644 index 0000000..326cd26 --- /dev/null +++ b/node_modules/confbox/dist/shared/confbox.f9f03f05.mjs @@ -0,0 +1,7 @@ +import{s as R,g as Z}from"./confbox.9388d834.mjs";function $(n,l=!1){const g=n.length;let e=0,u="",p=0,k=16,A=0,o=0,O=0,B=0,b=0;function I(i,T){let s=0,c=0;for(;s=48&&t<=57)c=c*16+t-48;else if(t>=65&&t<=70)c=c*16+t-65+10;else if(t>=97&&t<=102)c=c*16+t-97+10;else break;e++,s++}return s=g){i+=n.substring(T,e),b=2;break}const s=n.charCodeAt(e);if(s===34){i+=n.substring(T,e),e++;break}if(s===92){if(i+=n.substring(T,e),e++,e>=g){b=2;break}switch(n.charCodeAt(e++)){case 34:i+='"';break;case 92:i+="\\";break;case 47:i+="/";break;case 98:i+="\b";break;case 102:i+="\f";break;case 110:i+=` +`;break;case 114:i+="\r";break;case 116:i+=" ";break;case 117:const t=I(4,!0);t>=0?i+=String.fromCharCode(t):b=4;break;default:b=5}T=e;continue}if(s>=0&&s<=31)if(r(s)){i+=n.substring(T,e),b=2;break}else b=6;e++}return i}function w(){if(u="",b=0,p=e,o=A,B=O,e>=g)return p=g,k=17;let i=n.charCodeAt(e);if(J(i)){do e++,u+=String.fromCharCode(i),i=n.charCodeAt(e);while(J(i));return k=15}if(r(i))return e++,u+=String.fromCharCode(i),i===13&&n.charCodeAt(e)===10&&(e++,u+=` +`),A++,O=e,k=14;switch(i){case 123:return e++,k=1;case 125:return e++,k=2;case 91:return e++,k=3;case 93:return e++,k=4;case 58:return e++,k=6;case 44:return e++,k=5;case 34:return e++,u=j(),k=10;case 47:const T=e-1;if(n.charCodeAt(e+1)===47){for(e+=2;e=12&&i<=15);return i}return{setPosition:V,getPosition:()=>e,scan:l?E:w,getToken:()=>k,getTokenValue:()=>u,getTokenOffset:()=>p,getTokenLength:()=>e-p,getTokenStartLine:()=>o,getTokenStartCharacter:()=>p-B,getTokenError:()=>b}}function J(n){return n===32||n===9}function r(n){return n===10||n===13}function L(n){return n>=48&&n<=57}var Q;(function(n){n[n.lineFeed=10]="lineFeed",n[n.carriageReturn=13]="carriageReturn",n[n.space=32]="space",n[n._0=48]="_0",n[n._1=49]="_1",n[n._2=50]="_2",n[n._3=51]="_3",n[n._4=52]="_4",n[n._5=53]="_5",n[n._6=54]="_6",n[n._7=55]="_7",n[n._8=56]="_8",n[n._9=57]="_9",n[n.a=97]="a",n[n.b=98]="b",n[n.c=99]="c",n[n.d=100]="d",n[n.e=101]="e",n[n.f=102]="f",n[n.g=103]="g",n[n.h=104]="h",n[n.i=105]="i",n[n.j=106]="j",n[n.k=107]="k",n[n.l=108]="l",n[n.m=109]="m",n[n.n=110]="n",n[n.o=111]="o",n[n.p=112]="p",n[n.q=113]="q",n[n.r=114]="r",n[n.s=115]="s",n[n.t=116]="t",n[n.u=117]="u",n[n.v=118]="v",n[n.w=119]="w",n[n.x=120]="x",n[n.y=121]="y",n[n.z=122]="z",n[n.A=65]="A",n[n.B=66]="B",n[n.C=67]="C",n[n.D=68]="D",n[n.E=69]="E",n[n.F=70]="F",n[n.G=71]="G",n[n.H=72]="H",n[n.I=73]="I",n[n.J=74]="J",n[n.K=75]="K",n[n.L=76]="L",n[n.M=77]="M",n[n.N=78]="N",n[n.O=79]="O",n[n.P=80]="P",n[n.Q=81]="Q",n[n.R=82]="R",n[n.S=83]="S",n[n.T=84]="T",n[n.U=85]="U",n[n.V=86]="V",n[n.W=87]="W",n[n.X=88]="X",n[n.Y=89]="Y",n[n.Z=90]="Z",n[n.asterisk=42]="asterisk",n[n.backslash=92]="backslash",n[n.closeBrace=125]="closeBrace",n[n.closeBracket=93]="closeBracket",n[n.colon=58]="colon",n[n.comma=44]="comma",n[n.dot=46]="dot",n[n.doubleQuote=34]="doubleQuote",n[n.minus=45]="minus",n[n.openBrace=123]="openBrace",n[n.openBracket=91]="openBracket",n[n.plus=43]="plus",n[n.slash=47]="slash",n[n.formFeed=12]="formFeed",n[n.tab=9]="tab"})(Q||(Q={})),new Array(20).fill(0).map((n,l)=>" ".repeat(l));const N=200;new Array(N).fill(0).map((n,l)=>` +`+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>`\r +`+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>` +`+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>`\r +`+" ".repeat(l));var U;(function(n){n.DEFAULT={allowTrailingComma:!1}})(U||(U={}));function S(n,l=[],g=U.DEFAULT){let e=null,u=[];const p=[];function k(o){Array.isArray(u)?u.push(o):e!==null&&(u[e]=o)}return P(n,{onObjectBegin:()=>{const o={};k(o),p.push(u),u=o,e=null},onObjectProperty:o=>{e=o},onObjectEnd:()=>{u=p.pop()},onArrayBegin:()=>{const o=[];k(o),p.push(u),u=o,e=null},onArrayEnd:()=>{u=p.pop()},onLiteralValue:k,onError:(o,O,B)=>{l.push({error:o,offset:O,length:B})}},g),u[0]}function P(n,l,g=U.DEFAULT){const e=$(n,!1),u=[];let p=0;function k(f){return f?()=>p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function A(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function o(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice()):()=>!0}function O(f){return f?()=>{p>0?p++:f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice())===!1&&(p=1)}:()=>!0}function B(f){return f?()=>{p>0&&p--,p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter())}:()=>!0}const b=O(l.onObjectBegin),I=o(l.onObjectProperty),V=B(l.onObjectEnd),F=O(l.onArrayBegin),j=B(l.onArrayEnd),w=o(l.onLiteralValue),v=A(l.onSeparator),E=k(l.onComment),i=A(l.onError),T=g&&g.disallowComments,s=g&&g.allowTrailingComma;function c(){for(;;){const f=e.scan();switch(e.getTokenError()){case 4:t(14);break;case 5:t(15);break;case 3:t(13);break;case 1:T||t(11);break;case 2:t(12);break;case 6:t(16);break}switch(f){case 12:case 13:T?t(10):E();break;case 16:t(1);break;case 15:case 14:break;default:return f}}}function t(f,m=[],y=[]){if(i(f),m.length+y.length>0){let _=e.getToken();for(;_!==17;){if(m.indexOf(_)!==-1){c();break}else if(y.indexOf(_)!==-1)break;_=c()}}}function D(f){const m=e.getTokenValue();return f?w(m):(I(m),u.push(m)),c(),!0}function G(){switch(e.getToken()){case 11:const f=e.getTokenValue();let m=Number(f);isNaN(m)&&(t(2),m=0),w(m);break;case 7:w(null);break;case 8:w(!0);break;case 9:w(!1);break;default:return!1}return c(),!0}function M(){return e.getToken()!==10?(t(3,[],[2,5]),!1):(D(!1),e.getToken()===6?(v(":"),c(),a()||t(4,[],[2,5])):t(5,[],[2,5]),u.pop(),!0)}function X(){b(),c();let f=!1;for(;e.getToken()!==2&&e.getToken()!==17;){if(e.getToken()===5){if(f||t(4,[],[]),v(","),c(),e.getToken()===2&&s)break}else f&&t(6,[],[]);M()||t(4,[],[2,5]),f=!0}return V(),e.getToken()!==2?t(7,[2],[]):c(),!0}function Y(){F(),c();let f=!0,m=!1;for(;e.getToken()!==4&&e.getToken()!==17;){if(e.getToken()===5){if(m||t(4,[],[]),v(","),c(),e.getToken()===4&&s)break}else m&&t(6,[],[]);f?(u.push(0),f=!1):u[u.length-1]++,a()||t(4,[],[4,5]),m=!0}return j(),f||u.pop(),e.getToken()!==4?t(8,[4],[]):c(),!0}function a(){switch(e.getToken()){case 3:return Y();case 1:return X();case 10:return D(!0);default:return G()}}return c(),e.getToken()===17?g.allowEmptyContent?!0:(t(4,[],[]),!1):a()?(e.getToken()!==17&&t(9,[],[]),!0):(t(4,[],[]),!1)}var W;(function(n){n[n.None=0]="None",n[n.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=2]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",n[n.InvalidUnicode=4]="InvalidUnicode",n[n.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",n[n.InvalidCharacter=6]="InvalidCharacter"})(W||(W={}));var H;(function(n){n[n.OpenBraceToken=1]="OpenBraceToken",n[n.CloseBraceToken=2]="CloseBraceToken",n[n.OpenBracketToken=3]="OpenBracketToken",n[n.CloseBracketToken=4]="CloseBracketToken",n[n.CommaToken=5]="CommaToken",n[n.ColonToken=6]="ColonToken",n[n.NullKeyword=7]="NullKeyword",n[n.TrueKeyword=8]="TrueKeyword",n[n.FalseKeyword=9]="FalseKeyword",n[n.StringLiteral=10]="StringLiteral",n[n.NumericLiteral=11]="NumericLiteral",n[n.LineCommentTrivia=12]="LineCommentTrivia",n[n.BlockCommentTrivia=13]="BlockCommentTrivia",n[n.LineBreakTrivia=14]="LineBreakTrivia",n[n.Trivia=15]="Trivia",n[n.Unknown=16]="Unknown",n[n.EOF=17]="EOF"})(H||(H={}));const K=S;var q;(function(n){n[n.InvalidSymbol=1]="InvalidSymbol",n[n.InvalidNumberFormat=2]="InvalidNumberFormat",n[n.PropertyNameExpected=3]="PropertyNameExpected",n[n.ValueExpected=4]="ValueExpected",n[n.ColonExpected=5]="ColonExpected",n[n.CommaExpected=6]="CommaExpected",n[n.CloseBraceExpected=7]="CloseBraceExpected",n[n.CloseBracketExpected=8]="CloseBracketExpected",n[n.EndOfFileExpected=9]="EndOfFileExpected",n[n.InvalidCommentToken=10]="InvalidCommentToken",n[n.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=12]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",n[n.InvalidUnicode=14]="InvalidUnicode",n[n.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",n[n.InvalidCharacter=16]="InvalidCharacter"})(q||(q={}));function x(n,l){const g=JSON.parse(n,l?.reviver);return R(n,g,l),g}function z(n,l){const g=Z(n,l),e=JSON.stringify(n,l?.replacer,g.indent);return g.whitespace.start+e+g.whitespace.end}function h(n,l){const g=K(n,l?.errors,l);return R(n,g,l),g}function d(n,l){return z(n,l)}export{x as a,z as b,h as p,d as s}; diff --git a/node_modules/confbox/dist/toml.cjs b/node_modules/confbox/dist/toml.cjs new file mode 100644 index 0000000..10746a7 --- /dev/null +++ b/node_modules/confbox/dist/toml.cjs @@ -0,0 +1,239 @@ +"use strict";var _=Object.defineProperty;var A=(e,n,t)=>n in e?_(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t;var b=(e,n,t)=>(A(e,typeof n!="symbol"?n+"":n,t),t),E=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)};var c=(e,n,t)=>(E(e,n,"read from private field"),t?t.call(e):n.get(e)),O=(e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)},d=(e,n,t,i)=>(E(e,n,"write to private field"),i?i.call(e,t):n.set(e,t),t);var h,w,s;const _format=require("./shared/confbox.3768c7e9.cjs");/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */function getLineColFromPtr(e,n){let t=e.slice(0,n).split(/\r\n|\n|\r/g);return[t.length,t.pop().length+1]}function makeCodeBlock(e,n,t){let i=e.split(/\r\n|\n|\r/g),l="",r=(Math.log10(n+1)|0)+1;for(let f=n-1;f<=n+1;f++){let o=i[f-1];o&&(l+=f.toString().padEnd(r," "),l+=": ",l+=o,l+=` +`,f===n&&(l+=" ".repeat(r+t+2),l+=`^ +`))}return l}class TomlError extends Error{constructor(t,i){const[l,r]=getLineColFromPtr(i.toml,i.ptr),f=makeCodeBlock(i.toml,l,r);super(`Invalid TOML document: ${t} + +${f}`,i);b(this,"line");b(this,"column");b(this,"codeblock");this.line=l,this.column=r,this.codeblock=f}}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */function indexOfNewline(e,n=0,t=e.length){let i=e.indexOf(` +`,n);return e[i-1]==="\r"&&i--,i<=t?i:-1}function skipComment(e,n){for(let t=n;t-1&&t!=="'"&&e[n-1]==="\\"&&e[n-2]!=="\\");return n>-1&&(n+=i.length,i.length>1&&(e[n]===t&&n++,e[n]===t&&n++)),n}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let DATE_TIME_RE=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}:\d{2}(?:\.\d+)?)?(Z|[-+]\d{2}:\d{2})?$/i;const g=class g extends Date{constructor(t){let i=!0,l=!0,r="Z";if(typeof t=="string"){let f=t.match(DATE_TIME_RE);f?(f[1]||(i=!1,t=`0000-01-01T${t}`),l=!!f[2],f[2]&&+f[2]>23?t="":(r=f[3]||null,t=t.toUpperCase(),!r&&l&&(t+="Z"))):t=""}super(t);O(this,h,!1);O(this,w,!1);O(this,s,null);isNaN(this.getTime())||(d(this,h,i),d(this,w,l),d(this,s,r))}isDateTime(){return c(this,h)&&c(this,w)}isLocal(){return!c(this,h)||!c(this,w)||!c(this,s)}isDate(){return c(this,h)&&!c(this,w)}isTime(){return c(this,w)&&!c(this,h)}isValid(){return c(this,h)||c(this,w)}toISOString(){let t=super.toISOString();if(this.isDate())return t.slice(0,10);if(this.isTime())return t.slice(11,23);if(c(this,s)===null)return t.slice(0,-1);if(c(this,s)==="Z")return t;let i=+c(this,s).slice(1,3)*60+ +c(this,s).slice(4,6);return i=c(this,s)[0]==="-"?i:-i,new Date(this.getTime()-i*6e4).toISOString().slice(0,-1)+c(this,s)}static wrapAsOffsetDateTime(t,i="Z"){let l=new g(t);return d(l,s,i),l}static wrapAsLocalDateTime(t){let i=new g(t);return d(i,s,null),i}static wrapAsLocalDate(t){let i=new g(t);return d(i,w,!1),d(i,s,null),i}static wrapAsLocalTime(t){let i=new g(t);return d(i,h,!1),d(i,s,null),i}};h=new WeakMap,w=new WeakMap,s=new WeakMap;let TomlDate=g;/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let INT_REGEX=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,FLOAT_REGEX=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,LEADING_ZERO=/^[+-]?0[0-9_]/,ESCAPE_REGEX=/^[0-9a-f]{4,8}$/i,ESC_MAP={b:"\b",t:" ",n:` +`,f:"\f",r:"\r",'"':'"',"\\":"\\"};function parseString(e,n=0,t=e.length){let i=e[n]==="'",l=e[n++]===e[n]&&e[n]===e[n+1];l&&(t-=2,e[n+=2]==="\r"&&n++,e[n]===` +`&&n++);let r=0,f,o="",a=n;for(;n-1&&(skipComment(e,r),l=l.slice(0,r));let f=l.trimEnd();if(!i){let o=l.indexOf(` +`,f.length);if(o>-1)throw new TomlError("newlines are not allowed in inline tables",{toml:e,ptr:n+o})}return[f,r]}function extractValue(e,n,t){let i=e[n];if(i==="["||i==="{"){let[f,o]=i==="["?parseArray(e,n):parseInlineTable(e,n),a=skipUntil(e,o,",",t);if(t==="}"){let u=indexOfNewline(e,o,a);if(u>-1)throw new TomlError("newlines are not allowed in inline tables",{toml:e,ptr:u})}return[f,a]}let l;if(i==='"'||i==="'"){l=getStringEnd(e,n);let f=parseString(e,n,l);if(t){if(l=skipVoid(e,l,t!=="]"),e[l]&&e[l]!==","&&e[l]!==t&&e[l]!==` +`&&e[l]!=="\r")throw new TomlError("unexpected character encountered",{toml:e,ptr:l});l+=+(e[l]===",")}return[f,l]}l=skipUntil(e,n,",",t);let r=sliceAndTrimEndOf(e,n,l-+(e[l-1]===","),t==="]");if(!r[0])throw new TomlError("incomplete key-value declaration: no value specified",{toml:e,ptr:n});return t&&r[1]>-1&&(l=skipVoid(e,n+r[1]),l+=+(e[l]===",")),[parseValue(r[0],e,n),l]}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let KEY_PART_RE=/^[a-zA-Z0-9-_]+[ \t]*$/;function parseKey(e,n,t="="){let i=n-1,l=[],r=e.indexOf(t,n);if(r<0)throw new TomlError("incomplete key-value: cannot find end of key",{toml:e,ptr:n});do{let f=e[n=++i];if(f!==" "&&f!==" ")if(f==='"'||f==="'"){if(f===e[n+1]&&f===e[n+2])throw new TomlError("multiline strings are not allowed in keys",{toml:e,ptr:n});let o=getStringEnd(e,n);if(o<0)throw new TomlError("unfinished string encountered",{toml:e,ptr:n});i=e.indexOf(".",o);let a=e.slice(o,i<0||i>r?r:i),u=indexOfNewline(a);if(u>-1)throw new TomlError("newlines are not allowed in keys",{toml:e,ptr:n+i+u});if(a.trimStart())throw new TomlError("found extra tokens after the string part",{toml:e,ptr:o});if(rr?r:i);if(!KEY_PART_RE.test(o))throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys",{toml:e,ptr:n});l.push(o.trimEnd())}}while(i+1&&i(text: string): T; +/** + * Converts a JavaScript value to a [TOML](https://toml.io/) string. + * + * @NOTE Comments and indentation is not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyTOML(value: any): string; + +export { parseTOML, stringifyTOML }; diff --git a/node_modules/confbox/dist/toml.d.mts b/node_modules/confbox/dist/toml.d.mts new file mode 100644 index 0000000..2d210d8 --- /dev/null +++ b/node_modules/confbox/dist/toml.d.mts @@ -0,0 +1,22 @@ +/** + * Converts a [TOML](https://toml.io/) string into an object. + * + * @NOTE Comments and indentation is not preserved after parsing. + * + * @template T The type of the return value. + * @param text The TOML string to parse. + * @returns The JavaScript value converted from the TOML string. + */ +declare function parseTOML(text: string): T; +/** + * Converts a JavaScript value to a [TOML](https://toml.io/) string. + * + * @NOTE Comments and indentation is not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyTOML(value: any): string; + +export { parseTOML, stringifyTOML }; diff --git a/node_modules/confbox/dist/toml.d.ts b/node_modules/confbox/dist/toml.d.ts new file mode 100644 index 0000000..2d210d8 --- /dev/null +++ b/node_modules/confbox/dist/toml.d.ts @@ -0,0 +1,22 @@ +/** + * Converts a [TOML](https://toml.io/) string into an object. + * + * @NOTE Comments and indentation is not preserved after parsing. + * + * @template T The type of the return value. + * @param text The TOML string to parse. + * @returns The JavaScript value converted from the TOML string. + */ +declare function parseTOML(text: string): T; +/** + * Converts a JavaScript value to a [TOML](https://toml.io/) string. + * + * @NOTE Comments and indentation is not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyTOML(value: any): string; + +export { parseTOML, stringifyTOML }; diff --git a/node_modules/confbox/dist/toml.mjs b/node_modules/confbox/dist/toml.mjs new file mode 100644 index 0000000..4ecc58f --- /dev/null +++ b/node_modules/confbox/dist/toml.mjs @@ -0,0 +1,239 @@ +var F=Object.defineProperty;var V=(e,n,t)=>n in e?F(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t;var O=(e,n,t)=>(V(e,typeof n!="symbol"?n+"":n,t),t),L=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)};var d=(e,n,t)=>(L(e,n,"read from private field"),t?t.call(e):n.get(e)),T=(e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)},w=(e,n,t,i)=>(L(e,n,"write to private field"),i?i.call(e,t):n.set(e,t),t);var h,m,s;import{s as G,g as K}from"./shared/confbox.9388d834.mjs";/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */function U(e,n){let t=e.slice(0,n).split(/\r\n|\n|\r/g);return[t.length,t.pop().length+1]}function X(e,n,t){let i=e.split(/\r\n|\n|\r/g),l="",r=(Math.log10(n+1)|0)+1;for(let f=n-1;f<=n+1;f++){let o=i[f-1];o&&(l+=f.toString().padEnd(r," "),l+=": ",l+=o,l+=` +`,f===n&&(l+=" ".repeat(r+t+2),l+=`^ +`))}return l}class u extends Error{constructor(t,i){const[l,r]=U(i.toml,i.ptr),f=X(i.toml,l,r);super(`Invalid TOML document: ${t} + +${f}`,i);O(this,"line");O(this,"column");O(this,"codeblock");this.line=l,this.column=r,this.codeblock=f}}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */function x(e,n=0,t=e.length){let i=e.indexOf(` +`,n);return e[i-1]==="\r"&&i--,i<=t?i:-1}function A(e,n){for(let t=n;t-1&&t!=="'"&&e[n-1]==="\\"&&e[n-2]!=="\\");return n>-1&&(n+=i.length,i.length>1&&(e[n]===t&&n++,e[n]===t&&n++)),n}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let B=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}:\d{2}(?:\.\d+)?)?(Z|[-+]\d{2}:\d{2})?$/i;const b=class b extends Date{constructor(t){let i=!0,l=!0,r="Z";if(typeof t=="string"){let f=t.match(B);f?(f[1]||(i=!1,t=`0000-01-01T${t}`),l=!!f[2],f[2]&&+f[2]>23?t="":(r=f[3]||null,t=t.toUpperCase(),!r&&l&&(t+="Z"))):t=""}super(t);T(this,h,!1);T(this,m,!1);T(this,s,null);isNaN(this.getTime())||(w(this,h,i),w(this,m,l),w(this,s,r))}isDateTime(){return d(this,h)&&d(this,m)}isLocal(){return!d(this,h)||!d(this,m)||!d(this,s)}isDate(){return d(this,h)&&!d(this,m)}isTime(){return d(this,m)&&!d(this,h)}isValid(){return d(this,h)||d(this,m)}toISOString(){let t=super.toISOString();if(this.isDate())return t.slice(0,10);if(this.isTime())return t.slice(11,23);if(d(this,s)===null)return t.slice(0,-1);if(d(this,s)==="Z")return t;let i=+d(this,s).slice(1,3)*60+ +d(this,s).slice(4,6);return i=d(this,s)[0]==="-"?i:-i,new Date(this.getTime()-i*6e4).toISOString().slice(0,-1)+d(this,s)}static wrapAsOffsetDateTime(t,i="Z"){let l=new b(t);return w(l,s,i),l}static wrapAsLocalDateTime(t){let i=new b(t);return w(i,s,null),i}static wrapAsLocalDate(t){let i=new b(t);return w(i,m,!1),w(i,s,null),i}static wrapAsLocalTime(t){let i=new b(t);return w(i,h,!1),w(i,s,null),i}};h=new WeakMap,m=new WeakMap,s=new WeakMap;let S=b;/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let Y=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,j=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,q=/^[+-]?0[0-9_]/,J=/^[0-9a-f]{4,8}$/i,R={b:"\b",t:" ",n:` +`,f:"\f",r:"\r",'"':'"',"\\":"\\"};function C(e,n=0,t=e.length){let i=e[n]==="'",l=e[n++]===e[n]&&e[n]===e[n+1];l&&(t-=2,e[n+=2]==="\r"&&n++,e[n]===` +`&&n++);let r=0,f,o="",a=n;for(;n-1&&(A(e,r),l=l.slice(0,r));let f=l.trimEnd();if(!i){let o=l.indexOf(` +`,f.length);if(o>-1)throw new u("newlines are not allowed in inline tables",{toml:e,ptr:n+o})}return[f,r]}function I(e,n,t){let i=e[n];if(i==="["||i==="{"){let[f,o]=i==="["?ne(e,n):ee(e,n),a=P(e,o,",",t);if(t==="}"){let c=x(e,o,a);if(c>-1)throw new u("newlines are not allowed in inline tables",{toml:e,ptr:c})}return[f,a]}let l;if(i==='"'||i==="'"){l=v(e,n);let f=C(e,n,l);if(t){if(l=g(e,l,t!=="]"),e[l]&&e[l]!==","&&e[l]!==t&&e[l]!==` +`&&e[l]!=="\r")throw new u("unexpected character encountered",{toml:e,ptr:l});l+=+(e[l]===",")}return[f,l]}l=P(e,n,",",t);let r=Q(e,n,l-+(e[l-1]===","),t==="]");if(!r[0])throw new u("incomplete key-value declaration: no value specified",{toml:e,ptr:n});return t&&r[1]>-1&&(l=g(e,n+r[1]),l+=+(e[l]===",")),[H(r[0],e,n),l]}/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */let W=/^[a-zA-Z0-9-_]+[ \t]*$/;function p(e,n,t="="){let i=n-1,l=[],r=e.indexOf(t,n);if(r<0)throw new u("incomplete key-value: cannot find end of key",{toml:e,ptr:n});do{let f=e[n=++i];if(f!==" "&&f!==" ")if(f==='"'||f==="'"){if(f===e[n+1]&&f===e[n+2])throw new u("multiline strings are not allowed in keys",{toml:e,ptr:n});let o=v(e,n);if(o<0)throw new u("unfinished string encountered",{toml:e,ptr:n});i=e.indexOf(".",o);let a=e.slice(o,i<0||i>r?r:i),c=x(a);if(c>-1)throw new u("newlines are not allowed in keys",{toml:e,ptr:n+i+c});if(a.trimStart())throw new u("found extra tokens after the string part",{toml:e,ptr:o});if(rr?r:i);if(!W.test(o))throw new u("only letter, numbers, dashes and underscores are allowed in keys",{toml:e,ptr:n});l.push(o.trimEnd())}}while(i+1&&i"u"||e===null}function isObject(e){return typeof e=="object"&&e!==null}function toArray(e){return Array.isArray(e)?e:isNothing(e)?[]:[e]}function extend(e,n){var r,o,l,f;if(n)for(f=Object.keys(n),r=0,o=f.length;rc&&(f=" ... ",n=o-c+f.length),r-o>c&&(u=" ...",r=o+c-u.length),{str:f+e.slice(n,r).replace(/\t/g,"\u2192")+u,pos:o-n+f.length}}function padStart(e,n){return common.repeat(" ",n-e.length)+e}function makeSnippet(e,n){if(n=Object.create(n||null),!e.buffer)return null;n.maxLength||(n.maxLength=79),typeof n.indent!="number"&&(n.indent=1),typeof n.linesBefore!="number"&&(n.linesBefore=3),typeof n.linesAfter!="number"&&(n.linesAfter=2);for(var r=/\r?\n|\r|\0/g,o=[0],l=[],f,u=-1;f=r.exec(e.buffer);)l.push(f.index),o.push(f.index+f[0].length),e.position<=f.index&&u<0&&(u=o.length-2);u<0&&(u=o.length-1);var c="",a,p,h=Math.min(e.line+n.linesAfter,l.length).toString().length,t=n.maxLength-(n.indent+h+3);for(a=1;a<=n.linesBefore&&!(u-a<0);a++)p=getLine(e.buffer,o[u-a],l[u-a],e.position-(o[u]-o[u-a]),t),c=common.repeat(" ",n.indent)+padStart((e.line-a+1).toString(),h)+" | "+p.str+` +`+c;for(p=getLine(e.buffer,o[u],l[u],e.position,t),c+=common.repeat(" ",n.indent)+padStart((e.line+1).toString(),h)+" | "+p.str+` +`,c+=common.repeat("-",n.indent+h+3+p.pos)+`^ +`,a=1;a<=n.linesAfter&&!(u+a>=l.length);a++)p=getLine(e.buffer,o[u+a],l[u+a],e.position-(o[u]-o[u+a]),t),c+=common.repeat(" ",n.indent)+padStart((e.line+a+1).toString(),h)+" | "+p.str+` +`;return c.replace(/\n$/,"")}var snippet=makeSnippet,TYPE_CONSTRUCTOR_OPTIONS=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],YAML_NODE_KINDS=["scalar","sequence","mapping"];function compileStyleAliases(e){var n={};return e!==null&&Object.keys(e).forEach(function(r){e[r].forEach(function(o){n[String(o)]=r})}),n}function Type$1(e,n){if(n=n||{},Object.keys(n).forEach(function(r){if(TYPE_CONSTRUCTOR_OPTIONS.indexOf(r)===-1)throw new exception('Unknown option "'+r+'" is met in definition of "'+e+'" YAML type.')}),this.options=n,this.tag=e,this.kind=n.kind||null,this.resolve=n.resolve||function(){return!0},this.construct=n.construct||function(r){return r},this.instanceOf=n.instanceOf||null,this.predicate=n.predicate||null,this.represent=n.represent||null,this.representName=n.representName||null,this.defaultStyle=n.defaultStyle||null,this.multi=n.multi||!1,this.styleAliases=compileStyleAliases(n.styleAliases||null),YAML_NODE_KINDS.indexOf(this.kind)===-1)throw new exception('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var type=Type$1;function compileList(e,n){var r=[];return e[n].forEach(function(o){var l=r.length;r.forEach(function(f,u){f.tag===o.tag&&f.kind===o.kind&&f.multi===o.multi&&(l=u)}),r[l]=o}),r}function compileMap(){var e={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},n,r;function o(l){l.multi?(e.multi[l.kind].push(l),e.multi.fallback.push(l)):e[l.kind][l.tag]=e.fallback[l.tag]=l}for(n=0,r=arguments.length;n=0?"0b"+e.toString(2):"-0b"+e.toString(2).slice(1)},octal:function(e){return e>=0?"0o"+e.toString(8):"-0o"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?"0x"+e.toString(16).toUpperCase():"-0x"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),YAML_FLOAT_PATTERN=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function resolveYamlFloat(e){return!(e===null||!YAML_FLOAT_PATTERN.test(e)||e[e.length-1]==="_")}function constructYamlFloat(e){var n,r;return n=e.replace(/_/g,"").toLowerCase(),r=n[0]==="-"?-1:1,"+-".indexOf(n[0])>=0&&(n=n.slice(1)),n===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:n===".nan"?NaN:r*parseFloat(n,10)}var SCIENTIFIC_WITHOUT_DOT=/^[-+]?[0-9]+e/;function representYamlFloat(e,n){var r;if(isNaN(e))switch(n){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(n){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(n){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(common.isNegativeZero(e))return"-0.0";return r=e.toString(10),SCIENTIFIC_WITHOUT_DOT.test(r)?r.replace("e",".e"):r}function isFloat(e){return Object.prototype.toString.call(e)==="[object Number]"&&(e%1!==0||common.isNegativeZero(e))}var float=new type("tag:yaml.org,2002:float",{kind:"scalar",resolve:resolveYamlFloat,construct:constructYamlFloat,predicate:isFloat,represent:representYamlFloat,defaultStyle:"lowercase"}),json=failsafe.extend({implicit:[_null,bool,int,float]}),core=json,YAML_DATE_REGEXP=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),YAML_TIMESTAMP_REGEXP=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function resolveYamlTimestamp(e){return e===null?!1:YAML_DATE_REGEXP.exec(e)!==null||YAML_TIMESTAMP_REGEXP.exec(e)!==null}function constructYamlTimestamp(e){var n,r,o,l,f,u,c,a=0,p=null,h,t,d;if(n=YAML_DATE_REGEXP.exec(e),n===null&&(n=YAML_TIMESTAMP_REGEXP.exec(e)),n===null)throw new Error("Date resolve error");if(r=+n[1],o=+n[2]-1,l=+n[3],!n[4])return new Date(Date.UTC(r,o,l));if(f=+n[4],u=+n[5],c=+n[6],n[7]){for(a=n[7].slice(0,3);a.length<3;)a+="0";a=+a}return n[9]&&(h=+n[10],t=+(n[11]||0),p=(h*60+t)*6e4,n[9]==="-"&&(p=-p)),d=new Date(Date.UTC(r,o,l,f,u,c,a)),p&&d.setTime(d.getTime()-p),d}function representYamlTimestamp(e){return e.toISOString()}var timestamp=new type("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:resolveYamlTimestamp,construct:constructYamlTimestamp,instanceOf:Date,represent:representYamlTimestamp});function resolveYamlMerge(e){return e==="<<"||e===null}var merge=new type("tag:yaml.org,2002:merge",{kind:"scalar",resolve:resolveYamlMerge}),BASE64_MAP=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function resolveYamlBinary(e){if(e===null)return!1;var n,r,o=0,l=e.length,f=BASE64_MAP;for(r=0;r64)){if(n<0)return!1;o+=6}return o%8===0}function constructYamlBinary(e){var n,r,o=e.replace(/[\r\n=]/g,""),l=o.length,f=BASE64_MAP,u=0,c=[];for(n=0;n>16&255),c.push(u>>8&255),c.push(u&255)),u=u<<6|f.indexOf(o.charAt(n));return r=l%4*6,r===0?(c.push(u>>16&255),c.push(u>>8&255),c.push(u&255)):r===18?(c.push(u>>10&255),c.push(u>>2&255)):r===12&&c.push(u>>4&255),new Uint8Array(c)}function representYamlBinary(e){var n="",r=0,o,l,f=e.length,u=BASE64_MAP;for(o=0;o>18&63],n+=u[r>>12&63],n+=u[r>>6&63],n+=u[r&63]),r=(r<<8)+e[o];return l=f%3,l===0?(n+=u[r>>18&63],n+=u[r>>12&63],n+=u[r>>6&63],n+=u[r&63]):l===2?(n+=u[r>>10&63],n+=u[r>>4&63],n+=u[r<<2&63],n+=u[64]):l===1&&(n+=u[r>>2&63],n+=u[r<<4&63],n+=u[64],n+=u[64]),n}function isBinary(e){return Object.prototype.toString.call(e)==="[object Uint8Array]"}var binary=new type("tag:yaml.org,2002:binary",{kind:"scalar",resolve:resolveYamlBinary,construct:constructYamlBinary,predicate:isBinary,represent:representYamlBinary}),_hasOwnProperty$3=Object.prototype.hasOwnProperty,_toString$2=Object.prototype.toString;function resolveYamlOmap(e){if(e===null)return!0;var n=[],r,o,l,f,u,c=e;for(r=0,o=c.length;r>10)+55296,(e-65536&1023)+56320)}for(var simpleEscapeCheck=new Array(256),simpleEscapeMap=new Array(256),i=0;i<256;i++)simpleEscapeCheck[i]=simpleEscapeSequence(i)?1:0,simpleEscapeMap[i]=simpleEscapeSequence(i);function State$1(e,n){this.input=e,this.filename=n.filename||null,this.schema=n.schema||_default,this.onWarning=n.onWarning||null,this.legacy=n.legacy||!1,this.json=n.json||!1,this.listener=n.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function generateError(e,n){var r={name:e.filename,buffer:e.input.slice(0,-1),position:e.position,line:e.line,column:e.position-e.lineStart};return r.snippet=snippet(r),new exception(n,r)}function throwError(e,n){throw generateError(e,n)}function throwWarning(e,n){e.onWarning&&e.onWarning.call(null,generateError(e,n))}var directiveHandlers={YAML:function(n,r,o){var l,f,u;n.version!==null&&throwError(n,"duplication of %YAML directive"),o.length!==1&&throwError(n,"YAML directive accepts exactly one argument"),l=/^([0-9]+)\.([0-9]+)$/.exec(o[0]),l===null&&throwError(n,"ill-formed argument of the YAML directive"),f=parseInt(l[1],10),u=parseInt(l[2],10),f!==1&&throwError(n,"unacceptable YAML version of the document"),n.version=o[0],n.checkLineBreaks=u<2,u!==1&&u!==2&&throwWarning(n,"unsupported YAML version of the document")},TAG:function(n,r,o){var l,f;o.length!==2&&throwError(n,"TAG directive accepts exactly two arguments"),l=o[0],f=o[1],PATTERN_TAG_HANDLE.test(l)||throwError(n,"ill-formed tag handle (first argument) of the TAG directive"),_hasOwnProperty$1.call(n.tagMap,l)&&throwError(n,'there is a previously declared suffix for "'+l+'" tag handle'),PATTERN_TAG_URI.test(f)||throwError(n,"ill-formed tag prefix (second argument) of the TAG directive");try{f=decodeURIComponent(f)}catch{throwError(n,"tag prefix is malformed: "+f)}n.tagMap[l]=f}};function captureSegment(e,n,r,o){var l,f,u,c;if(n1&&(e.result+=common.repeat(` +`,n-1))}function readPlainScalar(e,n,r){var o,l,f,u,c,a,p,h,t=e.kind,d=e.result,s;if(s=e.input.charCodeAt(e.position),is_WS_OR_EOL(s)||is_FLOW_INDICATOR(s)||s===35||s===38||s===42||s===33||s===124||s===62||s===39||s===34||s===37||s===64||s===96||(s===63||s===45)&&(l=e.input.charCodeAt(e.position+1),is_WS_OR_EOL(l)||r&&is_FLOW_INDICATOR(l)))return!1;for(e.kind="scalar",e.result="",f=u=e.position,c=!1;s!==0;){if(s===58){if(l=e.input.charCodeAt(e.position+1),is_WS_OR_EOL(l)||r&&is_FLOW_INDICATOR(l))break}else if(s===35){if(o=e.input.charCodeAt(e.position-1),is_WS_OR_EOL(o))break}else{if(e.position===e.lineStart&&testDocumentSeparator(e)||r&&is_FLOW_INDICATOR(s))break;if(is_EOL(s))if(a=e.line,p=e.lineStart,h=e.lineIndent,skipSeparationSpace(e,!1,-1),e.lineIndent>=n){c=!0,s=e.input.charCodeAt(e.position);continue}else{e.position=u,e.line=a,e.lineStart=p,e.lineIndent=h;break}}c&&(captureSegment(e,f,u,!1),writeFoldedLines(e,e.line-a),f=u=e.position,c=!1),is_WHITE_SPACE(s)||(u=e.position+1),s=e.input.charCodeAt(++e.position)}return captureSegment(e,f,u,!1),e.result?!0:(e.kind=t,e.result=d,!1)}function readSingleQuotedScalar(e,n){var r,o,l;if(r=e.input.charCodeAt(e.position),r!==39)return!1;for(e.kind="scalar",e.result="",e.position++,o=l=e.position;(r=e.input.charCodeAt(e.position))!==0;)if(r===39)if(captureSegment(e,o,e.position,!0),r=e.input.charCodeAt(++e.position),r===39)o=e.position,e.position++,l=e.position;else return!0;else is_EOL(r)?(captureSegment(e,o,l,!0),writeFoldedLines(e,skipSeparationSpace(e,!1,n)),o=l=e.position):e.position===e.lineStart&&testDocumentSeparator(e)?throwError(e,"unexpected end of the document within a single quoted scalar"):(e.position++,l=e.position);throwError(e,"unexpected end of the stream within a single quoted scalar")}function readDoubleQuotedScalar(e,n){var r,o,l,f,u,c;if(c=e.input.charCodeAt(e.position),c!==34)return!1;for(e.kind="scalar",e.result="",e.position++,r=o=e.position;(c=e.input.charCodeAt(e.position))!==0;){if(c===34)return captureSegment(e,r,e.position,!0),e.position++,!0;if(c===92){if(captureSegment(e,r,e.position,!0),c=e.input.charCodeAt(++e.position),is_EOL(c))skipSeparationSpace(e,!1,n);else if(c<256&&simpleEscapeCheck[c])e.result+=simpleEscapeMap[c],e.position++;else if((u=escapedHexLen(c))>0){for(l=u,f=0;l>0;l--)c=e.input.charCodeAt(++e.position),(u=fromHexCode(c))>=0?f=(f<<4)+u:throwError(e,"expected hexadecimal character");e.result+=charFromCodepoint(f),e.position++}else throwError(e,"unknown escape sequence");r=o=e.position}else is_EOL(c)?(captureSegment(e,r,o,!0),writeFoldedLines(e,skipSeparationSpace(e,!1,n)),r=o=e.position):e.position===e.lineStart&&testDocumentSeparator(e)?throwError(e,"unexpected end of the document within a double quoted scalar"):(e.position++,o=e.position)}throwError(e,"unexpected end of the stream within a double quoted scalar")}function readFlowCollection(e,n){var r=!0,o,l,f,u=e.tag,c,a=e.anchor,p,h,t,d,s,x=Object.create(null),g,A,v,m;if(m=e.input.charCodeAt(e.position),m===91)h=93,s=!1,c=[];else if(m===123)h=125,s=!0,c={};else return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=c),m=e.input.charCodeAt(++e.position);m!==0;){if(skipSeparationSpace(e,!0,n),m=e.input.charCodeAt(e.position),m===h)return e.position++,e.tag=u,e.anchor=a,e.kind=s?"mapping":"sequence",e.result=c,!0;r?m===44&&throwError(e,"expected the node content, but found ','"):throwError(e,"missed comma between flow collection entries"),A=g=v=null,t=d=!1,m===63&&(p=e.input.charCodeAt(e.position+1),is_WS_OR_EOL(p)&&(t=d=!0,e.position++,skipSeparationSpace(e,!0,n))),o=e.line,l=e.lineStart,f=e.position,composeNode(e,n,CONTEXT_FLOW_IN,!1,!0),A=e.tag,g=e.result,skipSeparationSpace(e,!0,n),m=e.input.charCodeAt(e.position),(d||e.line===o)&&m===58&&(t=!0,m=e.input.charCodeAt(++e.position),skipSeparationSpace(e,!0,n),composeNode(e,n,CONTEXT_FLOW_IN,!1,!0),v=e.result),s?storeMappingPair(e,c,x,A,g,v,o,l,f):t?c.push(storeMappingPair(e,null,x,A,g,v,o,l,f)):c.push(g),skipSeparationSpace(e,!0,n),m=e.input.charCodeAt(e.position),m===44?(r=!0,m=e.input.charCodeAt(++e.position)):r=!1}throwError(e,"unexpected end of the stream within a flow collection")}function readBlockScalar(e,n){var r,o,l=CHOMPING_CLIP,f=!1,u=!1,c=n,a=0,p=!1,h,t;if(t=e.input.charCodeAt(e.position),t===124)o=!1;else if(t===62)o=!0;else return!1;for(e.kind="scalar",e.result="";t!==0;)if(t=e.input.charCodeAt(++e.position),t===43||t===45)CHOMPING_CLIP===l?l=t===43?CHOMPING_KEEP:CHOMPING_STRIP:throwError(e,"repeat of a chomping mode identifier");else if((h=fromDecimalCode(t))>=0)h===0?throwError(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):u?throwError(e,"repeat of an indentation width identifier"):(c=n+h-1,u=!0);else break;if(is_WHITE_SPACE(t)){do t=e.input.charCodeAt(++e.position);while(is_WHITE_SPACE(t));if(t===35)do t=e.input.charCodeAt(++e.position);while(!is_EOL(t)&&t!==0)}for(;t!==0;){for(readLineBreak(e),e.lineIndent=0,t=e.input.charCodeAt(e.position);(!u||e.lineIndentc&&(c=e.lineIndent),is_EOL(t)){a++;continue}if(e.lineIndentn)&&a!==0)throwError(e,"bad indentation of a sequence entry");else if(e.lineIndentn)&&(A&&(u=e.line,c=e.lineStart,a=e.position),composeNode(e,n,CONTEXT_BLOCK_OUT,!0,l)&&(A?x=e.result:g=e.result),A||(storeMappingPair(e,t,d,s,x,g,u,c,a),s=x=g=null),skipSeparationSpace(e,!0,-1),m=e.input.charCodeAt(e.position)),(e.line===f||e.lineIndent>n)&&m!==0)throwError(e,"bad indentation of a mapping entry");else if(e.lineIndentn?a=1:e.lineIndent===n?a=0:e.lineIndentn?a=1:e.lineIndent===n?a=0:e.lineIndent tag; it should be "scalar", not "'+e.kind+'"'),t=0,d=e.implicitTypes.length;t"),e.result!==null&&x.kind!==e.kind&&throwError(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+x.kind+'", not "'+e.kind+'"'),x.resolve(e.result,e.tag)?(e.result=x.construct(e.result,e.tag),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):throwError(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return e.listener!==null&&e.listener("close",e),e.tag!==null||e.anchor!==null||h}function readDocument(e){var n=e.position,r,o,l,f=!1,u;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);(u=e.input.charCodeAt(e.position))!==0&&(skipSeparationSpace(e,!0,-1),u=e.input.charCodeAt(e.position),!(e.lineIndent>0||u!==37));){for(f=!0,u=e.input.charCodeAt(++e.position),r=e.position;u!==0&&!is_WS_OR_EOL(u);)u=e.input.charCodeAt(++e.position);for(o=e.input.slice(r,e.position),l=[],o.length<1&&throwError(e,"directive name must not be less than one character in length");u!==0;){for(;is_WHITE_SPACE(u);)u=e.input.charCodeAt(++e.position);if(u===35){do u=e.input.charCodeAt(++e.position);while(u!==0&&!is_EOL(u));break}if(is_EOL(u))break;for(r=e.position;u!==0&&!is_WS_OR_EOL(u);)u=e.input.charCodeAt(++e.position);l.push(e.input.slice(r,e.position))}u!==0&&readLineBreak(e),_hasOwnProperty$1.call(directiveHandlers,o)?directiveHandlers[o](e,o,l):throwWarning(e,'unknown document directive "'+o+'"')}if(skipSeparationSpace(e,!0,-1),e.lineIndent===0&&e.input.charCodeAt(e.position)===45&&e.input.charCodeAt(e.position+1)===45&&e.input.charCodeAt(e.position+2)===45?(e.position+=3,skipSeparationSpace(e,!0,-1)):f&&throwError(e,"directives end mark is expected"),composeNode(e,e.lineIndent-1,CONTEXT_BLOCK_OUT,!1,!0),skipSeparationSpace(e,!0,-1),e.checkLineBreaks&&PATTERN_NON_ASCII_LINE_BREAKS.test(e.input.slice(n,e.position))&&throwWarning(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&testDocumentSeparator(e)){e.input.charCodeAt(e.position)===46&&(e.position+=3,skipSeparationSpace(e,!0,-1));return}if(e.position"u"&&(r=n,n=null);var o=loadDocuments(e,r);if(typeof n!="function")return o;for(var l=0,f=o.length;l=55296&&r<=56319&&n+1=56320&&o<=57343)?(r-55296)*1024+o-56320+65536:r}function needIndentIndicator(e){var n=/^\n* /;return n.test(e)}var STYLE_PLAIN=1,STYLE_SINGLE=2,STYLE_LITERAL=3,STYLE_FOLDED=4,STYLE_DOUBLE=5;function chooseScalarStyle(e,n,r,o,l,f,u,c){var a,p=0,h=null,t=!1,d=!1,s=o!==-1,x=-1,g=isPlainSafeFirst(codePointAt(e,0))&&isPlainSafeLast(codePointAt(e,e.length-1));if(n||u)for(a=0;a=65536?a+=2:a++){if(p=codePointAt(e,a),!isPrintable(p))return STYLE_DOUBLE;g=g&&isPlainSafe(p,h,c),h=p}else{for(a=0;a=65536?a+=2:a++){if(p=codePointAt(e,a),p===CHAR_LINE_FEED)t=!0,s&&(d=d||a-x-1>o&&e[x+1]!==" ",x=a);else if(!isPrintable(p))return STYLE_DOUBLE;g=g&&isPlainSafe(p,h,c),h=p}d=d||s&&a-x-1>o&&e[x+1]!==" "}return!t&&!d?g&&!u&&!l(e)?STYLE_PLAIN:f===QUOTING_TYPE_DOUBLE?STYLE_DOUBLE:STYLE_SINGLE:r>9&&needIndentIndicator(e)?STYLE_DOUBLE:u?f===QUOTING_TYPE_DOUBLE?STYLE_DOUBLE:STYLE_SINGLE:d?STYLE_FOLDED:STYLE_LITERAL}function writeScalar(e,n,r,o,l){e.dump=function(){if(n.length===0)return e.quotingType===QUOTING_TYPE_DOUBLE?'""':"''";if(!e.noCompatMode&&(DEPRECATED_BOOLEANS_SYNTAX.indexOf(n)!==-1||DEPRECATED_BASE60_SYNTAX.test(n)))return e.quotingType===QUOTING_TYPE_DOUBLE?'"'+n+'"':"'"+n+"'";var f=e.indent*Math.max(1,r),u=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-f),c=o||e.flowLevel>-1&&r>=e.flowLevel;function a(p){return testImplicitResolving(e,p)}switch(chooseScalarStyle(n,c,e.indent,u,a,e.quotingType,e.forceQuotes&&!o,l)){case STYLE_PLAIN:return n;case STYLE_SINGLE:return"'"+n.replace(/'/g,"''")+"'";case STYLE_LITERAL:return"|"+blockHeader(n,e.indent)+dropEndingNewline(indentString(n,f));case STYLE_FOLDED:return">"+blockHeader(n,e.indent)+dropEndingNewline(indentString(foldString(n,u),f));case STYLE_DOUBLE:return'"'+escapeString(n)+'"';default:throw new exception("impossible error: invalid scalar style")}}()}function blockHeader(e,n){var r=needIndentIndicator(e)?String(n):"",o=e[e.length-1]===` +`,l=o&&(e[e.length-2]===` +`||e===` +`),f=l?"+":o?"":"-";return r+f+` +`}function dropEndingNewline(e){return e[e.length-1]===` +`?e.slice(0,-1):e}function foldString(e,n){for(var r=/(\n+)([^\n]*)/g,o=function(){var p=e.indexOf(` +`);return p=p!==-1?p:e.length,r.lastIndex=p,foldLine(e.slice(0,p),n)}(),l=e[0]===` +`||e[0]===" ",f,u;u=r.exec(e);){var c=u[1],a=u[2];f=a[0]===" ",o+=c+(!l&&!f&&a!==""?` +`:"")+foldLine(a,n),l=f}return o}function foldLine(e,n){if(e===""||e[0]===" ")return e;for(var r=/ [^ ]/g,o,l=0,f,u=0,c=0,a="";o=r.exec(e);)c=o.index,c-l>n&&(f=u>l?u:c,a+=` +`+e.slice(l,f),l=f+1),u=c;return a+=` +`,e.length-l>n&&u>l?a+=e.slice(l,u)+` +`+e.slice(u+1):a+=e.slice(l),a.slice(1)}function escapeString(e){for(var n="",r=0,o,l=0;l=65536?l+=2:l++)r=codePointAt(e,l),o=ESCAPE_SEQUENCES[r],!o&&isPrintable(r)?(n+=e[l],r>=65536&&(n+=e[l+1])):n+=o||encodeHex(r);return n}function writeFlowSequence(e,n,r){var o="",l=e.tag,f,u,c;for(f=0,u=r.length;f"u"&&writeNode(e,n,null,!1,!1))&&(o!==""&&(o+=","+(e.condenseFlow?"":" ")),o+=e.dump);e.tag=l,e.dump="["+o+"]"}function writeBlockSequence(e,n,r,o){var l="",f=e.tag,u,c,a;for(u=0,c=r.length;u"u"&&writeNode(e,n+1,null,!0,!0,!1,!0))&&((!o||l!=="")&&(l+=generateNextLine(e,n)),e.dump&&CHAR_LINE_FEED===e.dump.charCodeAt(0)?l+="-":l+="- ",l+=e.dump);e.tag=f,e.dump=l||"[]"}function writeFlowMapping(e,n,r){var o="",l=e.tag,f=Object.keys(r),u,c,a,p,h;for(u=0,c=f.length;u1024&&(h+="? "),h+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),writeNode(e,n,p,!1,!1)&&(h+=e.dump,o+=h));e.tag=l,e.dump="{"+o+"}"}function writeBlockMapping(e,n,r,o){var l="",f=e.tag,u=Object.keys(r),c,a,p,h,t,d;if(e.sortKeys===!0)u.sort();else if(typeof e.sortKeys=="function")u.sort(e.sortKeys);else if(e.sortKeys)throw new exception("sortKeys must be a boolean or a function");for(c=0,a=u.length;c1024,t&&(e.dump&&CHAR_LINE_FEED===e.dump.charCodeAt(0)?d+="?":d+="? "),d+=e.dump,t&&(d+=generateNextLine(e,n)),writeNode(e,n+1,h,!0,t)&&(e.dump&&CHAR_LINE_FEED===e.dump.charCodeAt(0)?d+=":":d+=": ",d+=e.dump,l+=d));e.tag=f,e.dump=l||"{}"}function detectType(e,n,r){var o,l,f,u,c,a;for(l=r?e.explicitTypes:e.implicitTypes,f=0,u=l.length;f tag resolver accepts not "'+a+'" style');e.dump=o}return!0}return!1}function writeNode(e,n,r,o,l,f,u){e.tag=null,e.dump=r,detectType(e,r,!1)||detectType(e,r,!0);var c=_toString.call(e.dump),a=o,p;o&&(o=e.flowLevel<0||e.flowLevel>n);var h=c==="[object Object]"||c==="[object Array]",t,d;if(h&&(t=e.duplicates.indexOf(r),d=t!==-1),(e.tag!==null&&e.tag!=="?"||d||e.indent!==2&&n>0)&&(l=!1),d&&e.usedDuplicates[t])e.dump="*ref_"+t;else{if(h&&d&&!e.usedDuplicates[t]&&(e.usedDuplicates[t]=!0),c==="[object Object]")o&&Object.keys(e.dump).length!==0?(writeBlockMapping(e,n,e.dump,l),d&&(e.dump="&ref_"+t+e.dump)):(writeFlowMapping(e,n,e.dump),d&&(e.dump="&ref_"+t+" "+e.dump));else if(c==="[object Array]")o&&e.dump.length!==0?(e.noArrayIndent&&!u&&n>0?writeBlockSequence(e,n-1,e.dump,l):writeBlockSequence(e,n,e.dump,l),d&&(e.dump="&ref_"+t+e.dump)):(writeFlowSequence(e,n,e.dump),d&&(e.dump="&ref_"+t+" "+e.dump));else if(c==="[object String]")e.tag!=="?"&&writeScalar(e,e.dump,n,f,a);else{if(c==="[object Undefined]")return!1;if(e.skipInvalid)return!1;throw new exception("unacceptable kind of an object to dump "+c)}e.tag!==null&&e.tag!=="?"&&(p=encodeURI(e.tag[0]==="!"?e.tag.slice(1):e.tag).replace(/!/g,"%21"),e.tag[0]==="!"?p="!"+p:p.slice(0,18)==="tag:yaml.org,2002:"?p="!!"+p.slice(18):p="!<"+p+">",e.dump=p+" "+e.dump)}return!0}function getDuplicateReferences(e,n){var r=[],o=[],l,f;for(inspectNode(e,r,o),l=0,f=o.length;l(text: string, options?: YAMLParseOptions): T; +/** + * Converts a JavaScript value to a [YAML](https://yaml.org/) string. + * + * @NOTE Comments are not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyYAML(value: any, options?: YAMLStringifyOptions): string; +interface YAMLParseOptions extends FormatOptions { + /** string to be used as a file path in error/warning messages. */ + filename?: string | undefined; + /** function to call on warning messages. */ + onWarning?(this: null, e: YAMLException): void; + /** specifies a schema to use. */ + schema?: any | undefined; + /** compatibility with JSON.parse behaviour. */ + json?: boolean | undefined; + /** listener for parse events */ + listener?(this: any, eventType: any, state: any): void; +} +interface YAMLStringifyOptions extends FormatOptions { + /** indentation width to use (in spaces). */ + indent?: number | undefined; + /** when true, will not add an indentation level to array elements */ + noArrayIndent?: boolean | undefined; + /** do not throw on invalid types (like function in the safe schema) and skip pairs and single values with such types. */ + skipInvalid?: boolean | undefined; + /** specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everwhere */ + flowLevel?: number | undefined; + /** Each tag may have own set of styles. - "tag" => "style" map. */ + styles?: { + [x: string]: any; + } | undefined; + /** specifies a schema to use. */ + schema?: any | undefined; + /** if true, sort keys when dumping YAML. If a function, use the function to sort the keys. (default: false) */ + sortKeys?: boolean | ((a: any, b: any) => number) | undefined; + /** set max line width. (default: 80) */ + lineWidth?: number | undefined; + /** if true, don't convert duplicate objects into references (default: false) */ + noRefs?: boolean | undefined; + /** if true don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 (default: false) */ + noCompatMode?: boolean | undefined; + /** + * if true flow sequences will be condensed, omitting the space between `key: value` or `a, b`. Eg. `'[a,b]'` or `{a:{b:c}}`. + * Can be useful when using yaml for pretty URL query params as spaces are %-encoded. (default: false). + */ + condenseFlow?: boolean | undefined; + /** strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. (default: `'`) */ + quotingType?: "'" | '"' | undefined; + /** if true, all non-key strings will be quoted even if they normally don't need to. (default: false) */ + forceQuotes?: boolean | undefined; + /** callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`). */ + replacer?: ((key: string, value: any) => any) | undefined; +} +interface Mark { + buffer: string; + column: number; + line: number; + name: string; + position: number; + snippet: string; +} +declare class YAMLException extends Error { + constructor(reason?: string, mark?: Mark); + toString(compact?: boolean): string; + name: string; + reason: string; + message: string; + mark: Mark; +} + +export { type YAMLParseOptions, type YAMLStringifyOptions, parseYAML, stringifyYAML }; diff --git a/node_modules/confbox/dist/yaml.d.mts b/node_modules/confbox/dist/yaml.d.mts new file mode 100644 index 0000000..6e716d7 --- /dev/null +++ b/node_modules/confbox/dist/yaml.d.mts @@ -0,0 +1,95 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.mjs'; + +/** + * Converts a [YAML](https://yaml.org/) string into an object. + * + * @NOTE This function does **not** understand multi-document sources, it throws exception on those. + * + * @NOTE Comments are not preserved after parsing. + * + * @NOTE This function does **not** support schema-specific tag resolution restrictions. + * So, the JSON schema is not as strictly defined in the YAML specification. + * It allows numbers in any notation, use `Null` and `NULL` as `null`, etc. + * The core schema also has no such restrictions. It allows binary notation for integers. + * + * @template T The type of the return value. + * @param text The YAML string to parse. + * @param options Parsing options. + * @returns The JavaScript value converted from the YAML string. + */ +declare function parseYAML(text: string, options?: YAMLParseOptions): T; +/** + * Converts a JavaScript value to a [YAML](https://yaml.org/) string. + * + * @NOTE Comments are not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyYAML(value: any, options?: YAMLStringifyOptions): string; +interface YAMLParseOptions extends FormatOptions { + /** string to be used as a file path in error/warning messages. */ + filename?: string | undefined; + /** function to call on warning messages. */ + onWarning?(this: null, e: YAMLException): void; + /** specifies a schema to use. */ + schema?: any | undefined; + /** compatibility with JSON.parse behaviour. */ + json?: boolean | undefined; + /** listener for parse events */ + listener?(this: any, eventType: any, state: any): void; +} +interface YAMLStringifyOptions extends FormatOptions { + /** indentation width to use (in spaces). */ + indent?: number | undefined; + /** when true, will not add an indentation level to array elements */ + noArrayIndent?: boolean | undefined; + /** do not throw on invalid types (like function in the safe schema) and skip pairs and single values with such types. */ + skipInvalid?: boolean | undefined; + /** specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everwhere */ + flowLevel?: number | undefined; + /** Each tag may have own set of styles. - "tag" => "style" map. */ + styles?: { + [x: string]: any; + } | undefined; + /** specifies a schema to use. */ + schema?: any | undefined; + /** if true, sort keys when dumping YAML. If a function, use the function to sort the keys. (default: false) */ + sortKeys?: boolean | ((a: any, b: any) => number) | undefined; + /** set max line width. (default: 80) */ + lineWidth?: number | undefined; + /** if true, don't convert duplicate objects into references (default: false) */ + noRefs?: boolean | undefined; + /** if true don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 (default: false) */ + noCompatMode?: boolean | undefined; + /** + * if true flow sequences will be condensed, omitting the space between `key: value` or `a, b`. Eg. `'[a,b]'` or `{a:{b:c}}`. + * Can be useful when using yaml for pretty URL query params as spaces are %-encoded. (default: false). + */ + condenseFlow?: boolean | undefined; + /** strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. (default: `'`) */ + quotingType?: "'" | '"' | undefined; + /** if true, all non-key strings will be quoted even if they normally don't need to. (default: false) */ + forceQuotes?: boolean | undefined; + /** callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`). */ + replacer?: ((key: string, value: any) => any) | undefined; +} +interface Mark { + buffer: string; + column: number; + line: number; + name: string; + position: number; + snippet: string; +} +declare class YAMLException extends Error { + constructor(reason?: string, mark?: Mark); + toString(compact?: boolean): string; + name: string; + reason: string; + message: string; + mark: Mark; +} + +export { type YAMLParseOptions, type YAMLStringifyOptions, parseYAML, stringifyYAML }; diff --git a/node_modules/confbox/dist/yaml.d.ts b/node_modules/confbox/dist/yaml.d.ts new file mode 100644 index 0000000..fa4977f --- /dev/null +++ b/node_modules/confbox/dist/yaml.d.ts @@ -0,0 +1,95 @@ +import { F as FormatOptions } from './shared/confbox.9745c98f.js'; + +/** + * Converts a [YAML](https://yaml.org/) string into an object. + * + * @NOTE This function does **not** understand multi-document sources, it throws exception on those. + * + * @NOTE Comments are not preserved after parsing. + * + * @NOTE This function does **not** support schema-specific tag resolution restrictions. + * So, the JSON schema is not as strictly defined in the YAML specification. + * It allows numbers in any notation, use `Null` and `NULL` as `null`, etc. + * The core schema also has no such restrictions. It allows binary notation for integers. + * + * @template T The type of the return value. + * @param text The YAML string to parse. + * @param options Parsing options. + * @returns The JavaScript value converted from the YAML string. + */ +declare function parseYAML(text: string, options?: YAMLParseOptions): T; +/** + * Converts a JavaScript value to a [YAML](https://yaml.org/) string. + * + * @NOTE Comments are not preserved in the output. + * + * @param value + * @param options + * @returns The YAML string converted from the JavaScript value. + */ +declare function stringifyYAML(value: any, options?: YAMLStringifyOptions): string; +interface YAMLParseOptions extends FormatOptions { + /** string to be used as a file path in error/warning messages. */ + filename?: string | undefined; + /** function to call on warning messages. */ + onWarning?(this: null, e: YAMLException): void; + /** specifies a schema to use. */ + schema?: any | undefined; + /** compatibility with JSON.parse behaviour. */ + json?: boolean | undefined; + /** listener for parse events */ + listener?(this: any, eventType: any, state: any): void; +} +interface YAMLStringifyOptions extends FormatOptions { + /** indentation width to use (in spaces). */ + indent?: number | undefined; + /** when true, will not add an indentation level to array elements */ + noArrayIndent?: boolean | undefined; + /** do not throw on invalid types (like function in the safe schema) and skip pairs and single values with such types. */ + skipInvalid?: boolean | undefined; + /** specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everwhere */ + flowLevel?: number | undefined; + /** Each tag may have own set of styles. - "tag" => "style" map. */ + styles?: { + [x: string]: any; + } | undefined; + /** specifies a schema to use. */ + schema?: any | undefined; + /** if true, sort keys when dumping YAML. If a function, use the function to sort the keys. (default: false) */ + sortKeys?: boolean | ((a: any, b: any) => number) | undefined; + /** set max line width. (default: 80) */ + lineWidth?: number | undefined; + /** if true, don't convert duplicate objects into references (default: false) */ + noRefs?: boolean | undefined; + /** if true don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 (default: false) */ + noCompatMode?: boolean | undefined; + /** + * if true flow sequences will be condensed, omitting the space between `key: value` or `a, b`. Eg. `'[a,b]'` or `{a:{b:c}}`. + * Can be useful when using yaml for pretty URL query params as spaces are %-encoded. (default: false). + */ + condenseFlow?: boolean | undefined; + /** strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. (default: `'`) */ + quotingType?: "'" | '"' | undefined; + /** if true, all non-key strings will be quoted even if they normally don't need to. (default: false) */ + forceQuotes?: boolean | undefined; + /** callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`). */ + replacer?: ((key: string, value: any) => any) | undefined; +} +interface Mark { + buffer: string; + column: number; + line: number; + name: string; + position: number; + snippet: string; +} +declare class YAMLException extends Error { + constructor(reason?: string, mark?: Mark); + toString(compact?: boolean): string; + name: string; + reason: string; + message: string; + mark: Mark; +} + +export { type YAMLParseOptions, type YAMLStringifyOptions, parseYAML, stringifyYAML }; diff --git a/node_modules/confbox/dist/yaml.mjs b/node_modules/confbox/dist/yaml.mjs new file mode 100644 index 0000000..b6e91bf --- /dev/null +++ b/node_modules/confbox/dist/yaml.mjs @@ -0,0 +1,32 @@ +import{s as qe,g as Ge}from"./shared/confbox.9388d834.mjs";/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */function oe(e){return typeof e>"u"||e===null}function We(e){return typeof e=="object"&&e!==null}function $e(e){return Array.isArray(e)?e:oe(e)?[]:[e]}function Qe(e,n){var i,l,r,u;if(n)for(u=Object.keys(n),i=0,l=u.length;if&&(u=" ... ",n=l-f+u.length),i-l>f&&(o=" ...",i=l+f-o.length),{str:u+e.slice(n,i).replace(/\t/g,"\u2192")+o,pos:l-n+u.length}}function Q(e,n){return y.repeat(" ",n-e.length)+e}function ln(e,n){if(n=Object.create(n||null),!e.buffer)return null;n.maxLength||(n.maxLength=79),typeof n.indent!="number"&&(n.indent=1),typeof n.linesBefore!="number"&&(n.linesBefore=3),typeof n.linesAfter!="number"&&(n.linesAfter=2);for(var i=/\r?\n|\r|\0/g,l=[0],r=[],u,o=-1;u=i.exec(e.buffer);)r.push(u.index),l.push(u.index+u[0].length),e.position<=u.index&&o<0&&(o=l.length-2);o<0&&(o=l.length-1);var f="",c,a,t=Math.min(e.line+n.linesAfter,r.length).toString().length,p=n.maxLength-(n.indent+t+3);for(c=1;c<=n.linesBefore&&!(o-c<0);c++)a=$(e.buffer,l[o-c],r[o-c],e.position-(l[o]-l[o-c]),p),f=y.repeat(" ",n.indent)+Q((e.line-c+1).toString(),t)+" | "+a.str+` +`+f;for(a=$(e.buffer,l[o],r[o],e.position,p),f+=y.repeat(" ",n.indent)+Q((e.line+1).toString(),t)+" | "+a.str+` +`,f+=y.repeat("-",n.indent+t+3+a.pos)+`^ +`,c=1;c<=n.linesAfter&&!(o+c>=r.length);c++)a=$(e.buffer,l[o+c],r[o+c],e.position-(l[o]-l[o+c]),p),f+=y.repeat(" ",n.indent)+Q((e.line+c+1).toString(),t)+" | "+a.str+` +`;return f.replace(/\n$/,"")}var on=ln,un=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],fn=["scalar","sequence","mapping"];function cn(e){var n={};return e!==null&&Object.keys(e).forEach(function(i){e[i].forEach(function(l){n[String(l)]=i})}),n}function an(e,n){if(n=n||{},Object.keys(n).forEach(function(i){if(un.indexOf(i)===-1)throw new w('Unknown option "'+i+'" is met in definition of "'+e+'" YAML type.')}),this.options=n,this.tag=e,this.kind=n.kind||null,this.resolve=n.resolve||function(){return!0},this.construct=n.construct||function(i){return i},this.instanceOf=n.instanceOf||null,this.predicate=n.predicate||null,this.represent=n.represent||null,this.representName=n.representName||null,this.defaultStyle=n.defaultStyle||null,this.multi=n.multi||!1,this.styleAliases=cn(n.styleAliases||null),fn.indexOf(this.kind)===-1)throw new w('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var C=an;function fe(e,n){var i=[];return e[n].forEach(function(l){var r=i.length;i.forEach(function(u,o){u.tag===l.tag&&u.kind===l.kind&&u.multi===l.multi&&(r=o)}),i[r]=l}),i}function pn(){var e={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},n,i;function l(r){r.multi?(e.multi[r.kind].push(r),e.multi.fallback.push(r)):e[r.kind][r.tag]=e.fallback[r.tag]=r}for(n=0,i=arguments.length;n=0?"0b"+e.toString(2):"-0b"+e.toString(2).slice(1)},octal:function(e){return e>=0?"0o"+e.toString(8):"-0o"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?"0x"+e.toString(16).toUpperCase():"-0x"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),kn=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function Ln(e){return!(e===null||!kn.test(e)||e[e.length-1]==="_")}function Nn(e){var n,i;return n=e.replace(/_/g,"").toLowerCase(),i=n[0]==="-"?-1:1,"+-".indexOf(n[0])>=0&&(n=n.slice(1)),n===".inf"?i===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:n===".nan"?NaN:i*parseFloat(n,10)}var Rn=/^[-+]?[0-9]+e/;function Dn(e,n){var i;if(isNaN(e))switch(n){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(n){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(n){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(y.isNegativeZero(e))return"-0.0";return i=e.toString(10),Rn.test(i)?i.replace("e",".e"):i}function Mn(e){return Object.prototype.toString.call(e)==="[object Number]"&&(e%1!==0||y.isNegativeZero(e))}var Yn=new C("tag:yaml.org,2002:float",{kind:"scalar",resolve:Ln,construct:Nn,predicate:Mn,represent:Dn,defaultStyle:"lowercase"}),Bn=xn.extend({implicit:[vn,wn,In,Yn]}),Pn=Bn,ce=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),ae=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function jn(e){return e===null?!1:ce.exec(e)!==null||ae.exec(e)!==null}function Hn(e){var n,i,l,r,u,o,f,c=0,a=null,t,p,d;if(n=ce.exec(e),n===null&&(n=ae.exec(e)),n===null)throw new Error("Date resolve error");if(i=+n[1],l=+n[2]-1,r=+n[3],!n[4])return new Date(Date.UTC(i,l,r));if(u=+n[4],o=+n[5],f=+n[6],n[7]){for(c=n[7].slice(0,3);c.length<3;)c+="0";c=+c}return n[9]&&(t=+n[10],p=+(n[11]||0),a=(t*60+p)*6e4,n[9]==="-"&&(a=-a)),d=new Date(Date.UTC(i,l,r,u,o,f,c)),a&&d.setTime(d.getTime()-a),d}function Un(e){return e.toISOString()}var Kn=new C("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:jn,construct:Hn,instanceOf:Date,represent:Un});function qn(e){return e==="<<"||e===null}var Gn=new C("tag:yaml.org,2002:merge",{kind:"scalar",resolve:qn}),X=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function Wn(e){if(e===null)return!1;var n,i,l=0,r=e.length,u=X;for(i=0;i64)){if(n<0)return!1;l+=6}return l%8===0}function $n(e){var n,i,l=e.replace(/[\r\n=]/g,""),r=l.length,u=X,o=0,f=[];for(n=0;n>16&255),f.push(o>>8&255),f.push(o&255)),o=o<<6|u.indexOf(l.charAt(n));return i=r%4*6,i===0?(f.push(o>>16&255),f.push(o>>8&255),f.push(o&255)):i===18?(f.push(o>>10&255),f.push(o>>2&255)):i===12&&f.push(o>>4&255),new Uint8Array(f)}function Qn(e){var n="",i=0,l,r,u=e.length,o=X;for(l=0;l>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[i&63]),i=(i<<8)+e[l];return r=u%3,r===0?(n+=o[i>>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[i&63]):r===2?(n+=o[i>>10&63],n+=o[i>>4&63],n+=o[i<<2&63],n+=o[64]):r===1&&(n+=o[i>>2&63],n+=o[i<<4&63],n+=o[64],n+=o[64]),n}function Vn(e){return Object.prototype.toString.call(e)==="[object Uint8Array]"}var Xn=new C("tag:yaml.org,2002:binary",{kind:"scalar",resolve:Wn,construct:$n,predicate:Vn,represent:Qn}),Zn=Object.prototype.hasOwnProperty,zn=Object.prototype.toString;function Jn(e){if(e===null)return!0;var n=[],i,l,r,u,o,f=e;for(i=0,l=f.length;i>10)+55296,(e-65536&1023)+56320)}for(var Ae=new Array(256),ve=new Array(256),L=0;L<256;L++)Ae[L]=ge(L)?1:0,ve[L]=ge(L);function Ai(e,n){this.input=e,this.filename=n.filename||null,this.schema=n.schema||pe,this.onWarning=n.onWarning||null,this.legacy=n.legacy||!1,this.json=n.json||!1,this.listener=n.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function ye(e,n){var i={name:e.filename,buffer:e.input.slice(0,-1),position:e.position,line:e.line,column:e.position-e.lineStart};return i.snippet=on(i),new w(n,i)}function h(e,n){throw ye(e,n)}function K(e,n){e.onWarning&&e.onWarning.call(null,ye(e,n))}var Ce={YAML:function(n,i,l){var r,u,o;n.version!==null&&h(n,"duplication of %YAML directive"),l.length!==1&&h(n,"YAML directive accepts exactly one argument"),r=/^([0-9]+)\.([0-9]+)$/.exec(l[0]),r===null&&h(n,"ill-formed argument of the YAML directive"),u=parseInt(r[1],10),o=parseInt(r[2],10),u!==1&&h(n,"unacceptable YAML version of the document"),n.version=l[0],n.checkLineBreaks=o<2,o!==1&&o!==2&&K(n,"unsupported YAML version of the document")},TAG:function(n,i,l){var r,u;l.length!==2&&h(n,"TAG directive accepts exactly two arguments"),r=l[0],u=l[1],se.test(r)||h(n,"ill-formed tag handle (first argument) of the TAG directive"),T.call(n.tagMap,r)&&h(n,'there is a previously declared suffix for "'+r+'" tag handle'),xe.test(u)||h(n,"ill-formed tag prefix (second argument) of the TAG directive");try{u=decodeURIComponent(u)}catch{h(n,"tag prefix is malformed: "+u)}n.tagMap[r]=u}};function O(e,n,i,l){var r,u,o,f;if(n1&&(e.result+=y.repeat(` +`,n-1))}function vi(e,n,i){var l,r,u,o,f,c,a,t,p=e.kind,d=e.result,s;if(s=e.input.charCodeAt(e.position),b(s)||k(s)||s===35||s===38||s===42||s===33||s===124||s===62||s===39||s===34||s===37||s===64||s===96||(s===63||s===45)&&(r=e.input.charCodeAt(e.position+1),b(r)||i&&k(r)))return!1;for(e.kind="scalar",e.result="",u=o=e.position,f=!1;s!==0;){if(s===58){if(r=e.input.charCodeAt(e.position+1),b(r)||i&&k(r))break}else if(s===35){if(l=e.input.charCodeAt(e.position-1),b(l))break}else{if(e.position===e.lineStart&&q(e)||i&&k(s))break;if(S(s))if(c=e.line,a=e.lineStart,t=e.lineIndent,v(e,!1,-1),e.lineIndent>=n){f=!0,s=e.input.charCodeAt(e.position);continue}else{e.position=o,e.line=c,e.lineStart=a,e.lineIndent=t;break}}f&&(O(e,u,o,!1),J(e,e.line-c),u=o=e.position,f=!1),I(s)||(o=e.position+1),s=e.input.charCodeAt(++e.position)}return O(e,u,o,!1),e.result?!0:(e.kind=p,e.result=d,!1)}function yi(e,n){var i,l,r;if(i=e.input.charCodeAt(e.position),i!==39)return!1;for(e.kind="scalar",e.result="",e.position++,l=r=e.position;(i=e.input.charCodeAt(e.position))!==0;)if(i===39)if(O(e,l,e.position,!0),i=e.input.charCodeAt(++e.position),i===39)l=e.position,e.position++,r=e.position;else return!0;else S(i)?(O(e,l,r,!0),J(e,v(e,!1,n)),l=r=e.position):e.position===e.lineStart&&q(e)?h(e,"unexpected end of the document within a single quoted scalar"):(e.position++,r=e.position);h(e,"unexpected end of the stream within a single quoted scalar")}function Ci(e,n){var i,l,r,u,o,f;if(f=e.input.charCodeAt(e.position),f!==34)return!1;for(e.kind="scalar",e.result="",e.position++,i=l=e.position;(f=e.input.charCodeAt(e.position))!==0;){if(f===34)return O(e,i,e.position,!0),e.position++,!0;if(f===92){if(O(e,i,e.position,!0),f=e.input.charCodeAt(++e.position),S(f))v(e,!1,n);else if(f<256&&Ae[f])e.result+=ve[f],e.position++;else if((o=xi(f))>0){for(r=o,u=0;r>0;r--)f=e.input.charCodeAt(++e.position),(o=si(f))>=0?u=(u<<4)+o:h(e,"expected hexadecimal character");e.result+=gi(u),e.position++}else h(e,"unknown escape sequence");i=l=e.position}else S(f)?(O(e,i,l,!0),J(e,v(e,!1,n)),i=l=e.position):e.position===e.lineStart&&q(e)?h(e,"unexpected end of the document within a double quoted scalar"):(e.position++,l=e.position)}h(e,"unexpected end of the stream within a double quoted scalar")}function _i(e,n){var i=!0,l,r,u,o=e.tag,f,c=e.anchor,a,t,p,d,s,x=Object.create(null),g,A,F,m;if(m=e.input.charCodeAt(e.position),m===91)t=93,s=!1,f=[];else if(m===123)t=125,s=!0,f={};else return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=f),m=e.input.charCodeAt(++e.position);m!==0;){if(v(e,!0,n),m=e.input.charCodeAt(e.position),m===t)return e.position++,e.tag=o,e.anchor=c,e.kind=s?"mapping":"sequence",e.result=f,!0;i?m===44&&h(e,"expected the node content, but found ','"):h(e,"missed comma between flow collection entries"),A=g=F=null,p=d=!1,m===63&&(a=e.input.charCodeAt(e.position+1),b(a)&&(p=d=!0,e.position++,v(e,!0,n))),l=e.line,r=e.lineStart,u=e.position,R(e,n,H,!1,!0),A=e.tag,g=e.result,v(e,!0,n),m=e.input.charCodeAt(e.position),(d||e.line===l)&&m===58&&(p=!0,m=e.input.charCodeAt(++e.position),v(e,!0,n),R(e,n,H,!1,!0),F=e.result),s?N(e,f,x,A,g,F,l,r,u):p?f.push(N(e,null,x,A,g,F,l,r,u)):f.push(g),v(e,!0,n),m=e.input.charCodeAt(e.position),m===44?(i=!0,m=e.input.charCodeAt(++e.position)):i=!1}h(e,"unexpected end of the stream within a flow collection")}function wi(e,n){var i,l,r=Z,u=!1,o=!1,f=n,c=0,a=!1,t,p;if(p=e.input.charCodeAt(e.position),p===124)l=!1;else if(p===62)l=!0;else return!1;for(e.kind="scalar",e.result="";p!==0;)if(p=e.input.charCodeAt(++e.position),p===43||p===45)Z===r?r=p===43?de:pi:h(e,"repeat of a chomping mode identifier");else if((t=mi(p))>=0)t===0?h(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?h(e,"repeat of an indentation width identifier"):(f=n+t-1,o=!0);else break;if(I(p)){do p=e.input.charCodeAt(++e.position);while(I(p));if(p===35)do p=e.input.charCodeAt(++e.position);while(!S(p)&&p!==0)}for(;p!==0;){for(z(e),e.lineIndent=0,p=e.input.charCodeAt(e.position);(!o||e.lineIndentf&&(f=e.lineIndent),S(p)){c++;continue}if(e.lineIndentn)&&c!==0)h(e,"bad indentation of a sequence entry");else if(e.lineIndentn)&&(A&&(o=e.line,f=e.lineStart,c=e.position),R(e,n,U,!0,r)&&(A?x=e.result:g=e.result),A||(N(e,p,d,s,x,g,o,f,c),s=x=g=null),v(e,!0,-1),m=e.input.charCodeAt(e.position)),(e.line===u||e.lineIndent>n)&&m!==0)h(e,"bad indentation of a mapping entry");else if(e.lineIndentn?c=1:e.lineIndent===n?c=0:e.lineIndentn?c=1:e.lineIndent===n?c=0:e.lineIndent tag; it should be "scalar", not "'+e.kind+'"'),p=0,d=e.implicitTypes.length;p"),e.result!==null&&x.kind!==e.kind&&h(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+x.kind+'", not "'+e.kind+'"'),x.resolve(e.result,e.tag)?(e.result=x.construct(e.result,e.tag),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):h(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return e.listener!==null&&e.listener("close",e),e.tag!==null||e.anchor!==null||t}function Ti(e){var n=e.position,i,l,r,u=!1,o;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);(o=e.input.charCodeAt(e.position))!==0&&(v(e,!0,-1),o=e.input.charCodeAt(e.position),!(e.lineIndent>0||o!==37));){for(u=!0,o=e.input.charCodeAt(++e.position),i=e.position;o!==0&&!b(o);)o=e.input.charCodeAt(++e.position);for(l=e.input.slice(i,e.position),r=[],l.length<1&&h(e,"directive name must not be less than one character in length");o!==0;){for(;I(o);)o=e.input.charCodeAt(++e.position);if(o===35){do o=e.input.charCodeAt(++e.position);while(o!==0&&!S(o));break}if(S(o))break;for(i=e.position;o!==0&&!b(o);)o=e.input.charCodeAt(++e.position);r.push(e.input.slice(i,e.position))}o!==0&&z(e),T.call(Ce,l)?Ce[l](e,l,r):K(e,'unknown document directive "'+l+'"')}if(v(e,!0,-1),e.lineIndent===0&&e.input.charCodeAt(e.position)===45&&e.input.charCodeAt(e.position+1)===45&&e.input.charCodeAt(e.position+2)===45?(e.position+=3,v(e,!0,-1)):u&&h(e,"directives end mark is expected"),R(e,e.lineIndent-1,U,!1,!0),v(e,!0,-1),e.checkLineBreaks&&hi.test(e.input.slice(n,e.position))&&K(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&q(e)){e.input.charCodeAt(e.position)===46&&(e.position+=3,v(e,!0,-1));return}if(e.position"u"&&(i=n,n=null);var l=be(e,i);if(typeof n!="function")return l;for(var r=0,u=l.length;r=55296&&i<=56319&&n+1=56320&&l<=57343)?(i-55296)*1024+l-56320+65536:i}function De(e){var n=/^\n* /;return n.test(e)}var Me=1,re=2,Ye=3,Be=4,D=5;function or(e,n,i,l,r,u,o,f){var c,a=0,t=null,p=!1,d=!1,s=l!==-1,x=-1,g=rr(j(e,0))&&lr(j(e,e.length-1));if(n||o)for(c=0;c=65536?c+=2:c++){if(a=j(e,c),!P(a))return D;g=g&&Re(a,t,f),t=a}else{for(c=0;c=65536?c+=2:c++){if(a=j(e,c),a===Y)p=!0,s&&(d=d||c-x-1>l&&e[x+1]!==" ",x=c);else if(!P(a))return D;g=g&&Re(a,t,f),t=a}d=d||s&&c-x-1>l&&e[x+1]!==" "}return!p&&!d?g&&!o&&!r(e)?Me:u===B?D:re:i>9&&De(e)?D:o?u===B?D:re:d?Be:Ye}function ur(e,n,i,l,r){e.dump=function(){if(n.length===0)return e.quotingType===B?'""':"''";if(!e.noCompatMode&&(Xi.indexOf(n)!==-1||Zi.test(n)))return e.quotingType===B?'"'+n+'"':"'"+n+"'";var u=e.indent*Math.max(1,i),o=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-u),f=l||e.flowLevel>-1&&i>=e.flowLevel;function c(a){return ir(e,a)}switch(or(n,f,e.indent,o,c,e.quotingType,e.forceQuotes&&!l,r)){case Me:return n;case re:return"'"+n.replace(/'/g,"''")+"'";case Ye:return"|"+Pe(n,e.indent)+je(Le(n,u));case Be:return">"+Pe(n,e.indent)+je(Le(fr(n,o),u));case D:return'"'+cr(n)+'"';default:throw new w("impossible error: invalid scalar style")}}()}function Pe(e,n){var i=De(e)?String(n):"",l=e[e.length-1]===` +`,r=l&&(e[e.length-2]===` +`||e===` +`),u=r?"+":l?"":"-";return i+u+` +`}function je(e){return e[e.length-1]===` +`?e.slice(0,-1):e}function fr(e,n){for(var i=/(\n+)([^\n]*)/g,l=function(){var a=e.indexOf(` +`);return a=a!==-1?a:e.length,i.lastIndex=a,He(e.slice(0,a),n)}(),r=e[0]===` +`||e[0]===" ",u,o;o=i.exec(e);){var f=o[1],c=o[2];u=c[0]===" ",l+=f+(!r&&!u&&c!==""?` +`:"")+He(c,n),r=u}return l}function He(e,n){if(e===""||e[0]===" ")return e;for(var i=/ [^ ]/g,l,r=0,u,o=0,f=0,c="";l=i.exec(e);)f=l.index,f-r>n&&(u=o>r?o:f,c+=` +`+e.slice(r,u),r=u+1),o=f;return c+=` +`,e.length-r>n&&o>r?c+=e.slice(r,o)+` +`+e.slice(o+1):c+=e.slice(r),c.slice(1)}function cr(e){for(var n="",i=0,l,r=0;r=65536?r+=2:r++)i=j(e,r),l=_[i],!l&&P(i)?(n+=e[r],i>=65536&&(n+=e[r+1])):n+=l||Ji(i);return n}function ar(e,n,i){var l="",r=e.tag,u,o,f;for(u=0,o=i.length;u"u"&&E(e,n,null,!1,!1))&&(l!==""&&(l+=","+(e.condenseFlow?"":" ")),l+=e.dump);e.tag=r,e.dump="["+l+"]"}function Ue(e,n,i,l){var r="",u=e.tag,o,f,c;for(o=0,f=i.length;o"u"&&E(e,n+1,null,!0,!0,!1,!0))&&((!l||r!=="")&&(r+=ie(e,n)),e.dump&&Y===e.dump.charCodeAt(0)?r+="-":r+="- ",r+=e.dump);e.tag=u,e.dump=r||"[]"}function pr(e,n,i){var l="",r=e.tag,u=Object.keys(i),o,f,c,a,t;for(o=0,f=u.length;o1024&&(t+="? "),t+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),E(e,n,a,!1,!1)&&(t+=e.dump,l+=t));e.tag=r,e.dump="{"+l+"}"}function tr(e,n,i,l){var r="",u=e.tag,o=Object.keys(i),f,c,a,t,p,d;if(e.sortKeys===!0)o.sort();else if(typeof e.sortKeys=="function")o.sort(e.sortKeys);else if(e.sortKeys)throw new w("sortKeys must be a boolean or a function");for(f=0,c=o.length;f1024,p&&(e.dump&&Y===e.dump.charCodeAt(0)?d+="?":d+="? "),d+=e.dump,p&&(d+=ie(e,n)),E(e,n+1,t,!0,p)&&(e.dump&&Y===e.dump.charCodeAt(0)?d+=":":d+=": ",d+=e.dump,r+=d));e.tag=u,e.dump=r||"{}"}function Ke(e,n,i){var l,r,u,o,f,c;for(r=i?e.explicitTypes:e.implicitTypes,u=0,o=r.length;u tag resolver accepts not "'+c+'" style');e.dump=l}return!0}return!1}function E(e,n,i,l,r,u,o){e.tag=null,e.dump=i,Ke(e,i,!1)||Ke(e,i,!0);var f=Fe.call(e.dump),c=l,a;l&&(l=e.flowLevel<0||e.flowLevel>n);var t=f==="[object Object]"||f==="[object Array]",p,d;if(t&&(p=e.duplicates.indexOf(i),d=p!==-1),(e.tag!==null&&e.tag!=="?"||d||e.indent!==2&&n>0)&&(r=!1),d&&e.usedDuplicates[p])e.dump="*ref_"+p;else{if(t&&d&&!e.usedDuplicates[p]&&(e.usedDuplicates[p]=!0),f==="[object Object]")l&&Object.keys(e.dump).length!==0?(tr(e,n,e.dump,r),d&&(e.dump="&ref_"+p+e.dump)):(pr(e,n,e.dump),d&&(e.dump="&ref_"+p+" "+e.dump));else if(f==="[object Array]")l&&e.dump.length!==0?(e.noArrayIndent&&!o&&n>0?Ue(e,n-1,e.dump,r):Ue(e,n,e.dump,r),d&&(e.dump="&ref_"+p+e.dump)):(ar(e,n,e.dump),d&&(e.dump="&ref_"+p+" "+e.dump));else if(f==="[object String]")e.tag!=="?"&&ur(e,e.dump,n,u,c);else{if(f==="[object Undefined]")return!1;if(e.skipInvalid)return!1;throw new w("unacceptable kind of an object to dump "+f)}e.tag!==null&&e.tag!=="?"&&(a=encodeURI(e.tag[0]==="!"?e.tag.slice(1):e.tag).replace(/!/g,"%21"),e.tag[0]==="!"?a="!"+a:a.slice(0,18)==="tag:yaml.org,2002:"?a="!!"+a.slice(18):a="!<"+a+">",e.dump=a+" "+e.dump)}return!0}function hr(e,n){var i=[],l=[],r,u;for(le(e,i,l),r=0,u=l.length;r + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/cross-spawn/README.md b/node_modules/cross-spawn/README.md new file mode 100644 index 0000000..1ed9252 --- /dev/null +++ b/node_modules/cross-spawn/README.md @@ -0,0 +1,89 @@ +# cross-spawn + +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Build status][appveyor-image]][appveyor-url] + +[npm-url]:https://npmjs.org/package/cross-spawn +[downloads-image]:https://img.shields.io/npm/dm/cross-spawn.svg +[npm-image]:https://img.shields.io/npm/v/cross-spawn.svg +[ci-url]:https://github.com/moxystudio/node-cross-spawn/actions/workflows/ci.yaml +[ci-image]:https://github.com/moxystudio/node-cross-spawn/actions/workflows/ci.yaml/badge.svg +[appveyor-url]:https://ci.appveyor.com/project/satazor/node-cross-spawn +[appveyor-image]:https://img.shields.io/appveyor/ci/satazor/node-cross-spawn/master.svg + +A cross platform solution to node's spawn and spawnSync. + +## Installation + +Node.js version 8 and up: +`$ npm install cross-spawn` + +Node.js version 7 and under: +`$ npm install cross-spawn@6` + +## Why + +Node has issues when using spawn on Windows: + +- It ignores [PATHEXT](https://github.com/joyent/node/issues/2318) +- It does not support [shebangs](https://en.wikipedia.org/wiki/Shebang_(Unix)) +- Has problems running commands with [spaces](https://github.com/nodejs/node/issues/7367) +- Has problems running commands with posix relative paths (e.g.: `./my-folder/my-executable`) +- Has an [issue](https://github.com/moxystudio/node-cross-spawn/issues/82) with command shims (files in `node_modules/.bin/`), where arguments with quotes and parenthesis would result in [invalid syntax error](https://github.com/moxystudio/node-cross-spawn/blob/e77b8f22a416db46b6196767bcd35601d7e11d54/test/index.test.js#L149) +- No `options.shell` support on node `` where `` must not contain any arguments. +If you would like to have the shebang support improved, feel free to contribute via a pull-request. + +Remember to always test your code on Windows! + + +## Tests + +`$ npm test` +`$ npm test -- --watch` during development + + +## License + +Released under the [MIT License](https://www.opensource.org/licenses/mit-license.php). diff --git a/node_modules/cross-spawn/index.js b/node_modules/cross-spawn/index.js new file mode 100644 index 0000000..5509742 --- /dev/null +++ b/node_modules/cross-spawn/index.js @@ -0,0 +1,39 @@ +'use strict'; + +const cp = require('child_process'); +const parse = require('./lib/parse'); +const enoent = require('./lib/enoent'); + +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; +} + +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; +} + +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; + +module.exports._parse = parse; +module.exports._enoent = enoent; diff --git a/node_modules/cross-spawn/lib/enoent.js b/node_modules/cross-spawn/lib/enoent.js new file mode 100644 index 0000000..da33471 --- /dev/null +++ b/node_modules/cross-spawn/lib/enoent.js @@ -0,0 +1,59 @@ +'use strict'; + +const isWin = process.platform === 'win32'; + +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); +} + +function hookChildProcess(cp, parsed) { + if (!isWin) { + return; + } + + const originalEmit = cp.emit; + + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} + +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + return null; +} + +module.exports = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; diff --git a/node_modules/cross-spawn/lib/parse.js b/node_modules/cross-spawn/lib/parse.js new file mode 100644 index 0000000..0129d74 --- /dev/null +++ b/node_modules/cross-spawn/lib/parse.js @@ -0,0 +1,91 @@ +'use strict'; + +const path = require('path'); +const resolveCommand = require('./util/resolveCommand'); +const escape = require('./util/escape'); +const readShebang = require('./util/readShebang'); + +const isWin = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); + + const shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + + return resolveCommand(parsed); + } + + return parsed.file; +} + +function parseNonShell(parsed) { + if (!isWin) { + return parsed; + } + + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); + + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); + + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); + + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); + + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); + + const shellCommand = [parsed.command].concat(parsed.args).join(' '); + + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } + + return parsed; +} + +function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); +} + +module.exports = parse; diff --git a/node_modules/cross-spawn/lib/util/escape.js b/node_modules/cross-spawn/lib/util/escape.js new file mode 100644 index 0000000..7bf2905 --- /dev/null +++ b/node_modules/cross-spawn/lib/util/escape.js @@ -0,0 +1,47 @@ +'use strict'; + +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; +} + +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd + // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input + // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(?=(\\+?)?)\1$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; +} + +module.exports.command = escapeCommand; +module.exports.argument = escapeArgument; diff --git a/node_modules/cross-spawn/lib/util/readShebang.js b/node_modules/cross-spawn/lib/util/readShebang.js new file mode 100644 index 0000000..5e83733 --- /dev/null +++ b/node_modules/cross-spawn/lib/util/readShebang.js @@ -0,0 +1,23 @@ +'use strict'; + +const fs = require('fs'); +const shebangCommand = require('shebang-command'); + +function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); + + let fd; + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } + + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); +} + +module.exports = readShebang; diff --git a/node_modules/cross-spawn/lib/util/resolveCommand.js b/node_modules/cross-spawn/lib/util/resolveCommand.js new file mode 100644 index 0000000..7972455 --- /dev/null +++ b/node_modules/cross-spawn/lib/util/resolveCommand.js @@ -0,0 +1,52 @@ +'use strict'; + +const path = require('path'); +const which = require('which'); +const getPathKey = require('path-key'); + +function resolveCommandAttempt(parsed, withoutPathExt) { + const env = parsed.options.env || process.env; + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled; + + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } + + let resolved; + + try { + resolved = which.sync(parsed.command, { + path: env[getPathKey({ env })], + pathExt: withoutPathExt ? path.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } + + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } + + return resolved; +} + +function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} + +module.exports = resolveCommand; diff --git a/node_modules/cross-spawn/package.json b/node_modules/cross-spawn/package.json new file mode 100644 index 0000000..24b2eb4 --- /dev/null +++ b/node_modules/cross-spawn/package.json @@ -0,0 +1,73 @@ +{ + "name": "cross-spawn", + "version": "7.0.6", + "description": "Cross platform child_process#spawn and child_process#spawnSync", + "keywords": [ + "spawn", + "spawnSync", + "windows", + "cross-platform", + "path-ext", + "shebang", + "cmd", + "execute" + ], + "author": "André Cruz ", + "homepage": "https://github.com/moxystudio/node-cross-spawn", + "repository": { + "type": "git", + "url": "git@github.com:moxystudio/node-cross-spawn.git" + }, + "license": "MIT", + "main": "index.js", + "files": [ + "lib" + ], + "scripts": { + "lint": "eslint .", + "test": "jest --env node --coverage", + "prerelease": "npm t && npm run lint", + "release": "standard-version", + "postrelease": "git push --follow-tags origin HEAD && npm publish" + }, + "husky": { + "hooks": { + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.js": [ + "eslint --fix", + "git add" + ] + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "devDependencies": { + "@commitlint/cli": "^8.1.0", + "@commitlint/config-conventional": "^8.1.0", + "babel-core": "^6.26.3", + "babel-jest": "^24.9.0", + "babel-preset-moxy": "^3.1.0", + "eslint": "^5.16.0", + "eslint-config-moxy": "^7.1.0", + "husky": "^3.0.5", + "jest": "^24.9.0", + "lint-staged": "^9.2.5", + "mkdirp": "^0.5.1", + "rimraf": "^3.0.0", + "standard-version": "^9.5.0" + }, + "engines": { + "node": ">= 8" + } +} diff --git a/node_modules/debug/LICENSE b/node_modules/debug/LICENSE new file mode 100644 index 0000000..1a9820e --- /dev/null +++ b/node_modules/debug/LICENSE @@ -0,0 +1,20 @@ +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/node_modules/debug/README.md b/node_modules/debug/README.md new file mode 100644 index 0000000..9ebdfbf --- /dev/null +++ b/node_modules/debug/README.md @@ -0,0 +1,481 @@ +# debug +[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors) + + + +A tiny JavaScript debugging utility modelled after Node.js core's debugging +technique. Works in Node.js and web browsers. + +## Installation + +```bash +$ npm install debug +``` + +## Usage + +`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. + +Example [_app.js_](./examples/node/app.js): + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %o', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example [_worker.js_](./examples/node/worker.js): + +```js +var a = require('debug')('worker:a') + , b = require('debug')('worker:b'); + +function work() { + a('doing lots of uninteresting work'); + setTimeout(work, Math.random() * 1000); +} + +work(); + +function workb() { + b('doing some work'); + setTimeout(workb, Math.random() * 2000); +} + +workb(); +``` + +The `DEBUG` environment variable is then used to enable these based on space or +comma-delimited names. + +Here are some examples: + +screen shot 2017-08-08 at 12 53 04 pm +screen shot 2017-08-08 at 12 53 38 pm +screen shot 2017-08-08 at 12 53 25 pm + +#### Windows command prompt notes + +##### CMD + +On Windows the environment variable is set using the `set` command. + +```cmd +set DEBUG=*,-not_this +``` + +Example: + +```cmd +set DEBUG=* & node app.js +``` + +##### PowerShell (VS Code default) + +PowerShell uses different syntax to set environment variables. + +```cmd +$env:DEBUG = "*,-not_this" +``` + +Example: + +```cmd +$env:DEBUG='app';node app.js +``` + +Then, run the program to be debugged as usual. + +npm script example: +```js + "windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js", +``` + +## Namespace Colors + +Every debug instance has a color generated for it based on its namespace name. +This helps when visually parsing the debug output to identify which debug instance +a debug line belongs to. + +#### Node.js + +In Node.js, colors are enabled when stderr is a TTY. You also _should_ install +the [`supports-color`](https://npmjs.org/supports-color) module alongside debug, +otherwise debug will only use a small handful of basic colors. + + + +#### Web Browser + +Colors are also enabled on "Web Inspectors" that understand the `%c` formatting +option. These are WebKit web inspectors, Firefox ([since version +31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) +and the Firebug plugin for Firefox (any version). + + + + +## Millisecond diff + +When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + + +When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below: + + + + +## Conventions + +If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output. + +## Wildcards + +The `*` character may be used as a wildcard. Suppose for example your library has +debuggers named "connect:bodyParser", "connect:compress", "connect:session", +instead of listing all three with +`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do +`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + +You can also exclude specific debuggers by prefixing them with a "-" character. +For example, `DEBUG=*,-connect:*` would include all debuggers except those +starting with "connect:". + +## Environment Variables + +When running through Node.js, you can set a few environment variables that will +change the behavior of the debug logging: + +| Name | Purpose | +|-----------|-------------------------------------------------| +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). | +| `DEBUG_COLORS`| Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + + +__Note:__ The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +## Formatters + +Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. +Below are the officially supported formatters: + +| Formatter | Representation | +|-----------|----------------| +| `%O` | Pretty-print an Object on multiple lines. | +| `%o` | Pretty-print an Object all on a single line. | +| `%s` | String. | +| `%d` | Number (both integer and float). | +| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | +| `%%` | Single percent sign ('%'). This does not consume an argument. | + + +### Custom formatters + +You can add custom formatters by extending the `debug.formatters` object. +For example, if you wanted to add support for rendering a Buffer as hex with +`%h`, you could do something like: + +```js +const createDebug = require('debug') +createDebug.formatters.h = (v) => { + return v.toString('hex') +} + +// …elsewhere +const debug = createDebug('foo') +debug('this is hex: %h', new Buffer('hello world')) +// foo this is hex: 68656c6c6f20776f726c6421 +0ms +``` + + +## Browser Support + +You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), +or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), +if you don't want to build it yourself. + +Debug's enable state is currently persisted by `localStorage`. +Consider the situation shown below where you have `worker:a` and `worker:b`, +and wish to debug both. You can enable this using `localStorage.debug`: + +```js +localStorage.debug = 'worker:*' +``` + +And then refresh the page. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + b('doing some work'); +}, 1200); +``` + +In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_. + + + +## Output streams + + By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: + +Example [_stdout.js_](./examples/node/stdout.js): + +```js +var debug = require('debug'); +var error = debug('app:error'); + +// by default stderr is used +error('goes to stderr!'); + +var log = debug('app:log'); +// set this namespace to log via console.log +log.log = console.log.bind(console); // don't forget to bind to console! +log('goes to stdout'); +error('still goes to stderr!'); + +// set all output to go via console.info +// overrides all per-namespace log settings +debug.log = console.info.bind(console); +error('now goes to stdout via console.info'); +log('still goes to stdout, but via console.info now'); +``` + +## Extend +You can simply extend debugger +```js +const log = require('debug')('auth'); + +//creates new debug instance with extended namespace +const logSign = log.extend('sign'); +const logLogin = log.extend('login'); + +log('hello'); // auth hello +logSign('hello'); //auth:sign hello +logLogin('hello'); //auth:login hello +``` + +## Set dynamically + +You can also enable debug dynamically by calling the `enable()` method : + +```js +let debug = require('debug'); + +console.log(1, debug.enabled('test')); + +debug.enable('test'); +console.log(2, debug.enabled('test')); + +debug.disable(); +console.log(3, debug.enabled('test')); + +``` + +print : +``` +1 false +2 true +3 false +``` + +Usage : +`enable(namespaces)` +`namespaces` can include modes separated by a colon and wildcards. + +Note that calling `enable()` completely overrides previously set DEBUG variable : + +``` +$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))' +=> false +``` + +`disable()` + +Will disable all namespaces. The functions returns the namespaces currently +enabled (and skipped). This can be useful if you want to disable debugging +temporarily without knowing what was enabled to begin with. + +For example: + +```js +let debug = require('debug'); +debug.enable('foo:*,-foo:bar'); +let namespaces = debug.disable(); +debug.enable(namespaces); +``` + +Note: There is no guarantee that the string will be identical to the initial +enable string, but semantically they will be identical. + +## Checking whether a debug target is enabled + +After you've created a debug instance, you can determine whether or not it is +enabled by checking the `enabled` property: + +```javascript +const debug = require('debug')('http'); + +if (debug.enabled) { + // do stuff... +} +``` + +You can also manually toggle this property to force the debug instance to be +enabled or disabled. + +## Usage in child processes + +Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process. +For example: + +```javascript +worker = fork(WORKER_WRAP_PATH, [workerPath], { + stdio: [ + /* stdin: */ 0, + /* stdout: */ 'pipe', + /* stderr: */ 'pipe', + 'ipc', + ], + env: Object.assign({}, process.env, { + DEBUG_COLORS: 1 // without this settings, colors won't be shown + }), +}); + +worker.stderr.pipe(process.stderr, { end: false }); +``` + + +## Authors + + - TJ Holowaychuk + - Nathan Rajlich + - Andrew Rhyne + - Josh Junon + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## License + +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/debug/package.json b/node_modules/debug/package.json new file mode 100644 index 0000000..ee8abb5 --- /dev/null +++ b/node_modules/debug/package.json @@ -0,0 +1,64 @@ +{ + "name": "debug", + "version": "4.4.3", + "repository": { + "type": "git", + "url": "git://github.com/debug-js/debug.git" + }, + "description": "Lightweight debugging utility for Node.js and the browser", + "keywords": [ + "debug", + "log", + "debugger" + ], + "files": [ + "src", + "LICENSE", + "README.md" + ], + "author": "Josh Junon (https://github.com/qix-)", + "contributors": [ + "TJ Holowaychuk ", + "Nathan Rajlich (http://n8.io)", + "Andrew Rhyne " + ], + "license": "MIT", + "scripts": { + "lint": "xo", + "test": "npm run test:node && npm run test:browser && npm run lint", + "test:node": "mocha test.js test.node.js", + "test:browser": "karma start --single-run", + "test:coverage": "cat ./coverage/lcov.info | coveralls" + }, + "dependencies": { + "ms": "^2.1.3" + }, + "devDependencies": { + "brfs": "^2.0.1", + "browserify": "^16.2.3", + "coveralls": "^3.0.2", + "karma": "^3.1.4", + "karma-browserify": "^6.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "mocha": "^5.2.0", + "mocha-lcov-reporter": "^1.2.0", + "sinon": "^14.0.0", + "xo": "^0.23.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + }, + "main": "./src/index.js", + "browser": "./src/browser.js", + "engines": { + "node": ">=6.0" + }, + "xo": { + "rules": { + "import/extensions": "off" + } + } +} diff --git a/node_modules/debug/src/browser.js b/node_modules/debug/src/browser.js new file mode 100644 index 0000000..5993451 --- /dev/null +++ b/node_modules/debug/src/browser.js @@ -0,0 +1,272 @@ +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ + +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); +exports.destroy = (() => { + let warned = false; + + return () => { + if (!warned) { + warned = true; + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + }; +})(); + +/** + * Colors. + */ + +exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +// eslint-disable-next-line complexity +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + + let m; + + // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + // eslint-disable-next-line no-return-assign + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // Is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) || + // Double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + + this.namespace + + (this.useColors ? ' %c' : ' ') + + args[0] + + (this.useColors ? '%c ' : ' ') + + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + + // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); +} + +/** + * Invokes `console.debug()` when available. + * No-op when `console.debug` is not a "function". + * If `console.debug` is not available, falls back + * to `console.log`. + * + * @api public + */ +exports.log = console.debug || console.log || (() => {}); + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + let r; + try { + r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; diff --git a/node_modules/debug/src/common.js b/node_modules/debug/src/common.js new file mode 100644 index 0000000..141cb57 --- /dev/null +++ b/node_modules/debug/src/common.js @@ -0,0 +1,292 @@ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ + +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require('ms'); + createDebug.destroy = destroy; + + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); + + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + createDebug.formatters = {}; + + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + function selectColor(namespace) { + let hash = 0; + + for (let i = 0; i < namespace.length; i++) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + + function debug(...args) { + // Disabled? + if (!debug.enabled) { + return; + } + + const self = debug; + + // Set `diff` timestamp + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } + + // Apply any `formatters` transformations + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return '%'; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); + + // Now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // Apply env-specific formatting (colors, etc.) + createDebug.formatArgs.call(self, args); + + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. + + Object.defineProperty(debug, 'enabled', { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + + return enabledCache; + }, + set: v => { + enableOverride = v; + } + }); + + // Env-specific initialization logic for debug instances + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + return debug; + } + + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + + createDebug.names = []; + createDebug.skips = []; + + const split = (typeof namespaces === 'string' ? namespaces : '') + .trim() + .replace(/\s+/g, ',') + .split(',') + .filter(Boolean); + + for (const ns of split) { + if (ns[0] === '-') { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); + } + } + } + + /** + * Checks if the given string matches a namespace template, honoring + * asterisks as wildcards. + * + * @param {String} search + * @param {String} template + * @return {Boolean} + */ + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { + // Match character or proceed with wildcard + if (template[templateIndex] === '*') { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; // Skip the '*' + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition + // Backtrack to the last '*' and try to match more characters + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; + } else { + return false; // No match + } + } + + // Handle trailing '*' in template + while (templateIndex < template.length && template[templateIndex] === '*') { + templateIndex++; + } + + return templateIndex === template.length; + } + + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + function disable() { + const namespaces = [ + ...createDebug.names, + ...createDebug.skips.map(namespace => '-' + namespace) + ].join(','); + createDebug.enable(''); + return namespaces; + } + + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + function enabled(name) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { + return false; + } + } + + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { + return true; + } + } + + return false; + } + + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + + /** + * XXX DO NOT USE. This is a temporary stub function. + * XXX It WILL be removed in the next major release. + */ + function destroy() { + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + + createDebug.enable(createDebug.load()); + + return createDebug; +} + +module.exports = setup; diff --git a/node_modules/debug/src/index.js b/node_modules/debug/src/index.js new file mode 100644 index 0000000..bf4c57f --- /dev/null +++ b/node_modules/debug/src/index.js @@ -0,0 +1,10 @@ +/** + * Detect Electron renderer / nwjs process, which is node, but we should + * treat as a browser. + */ + +if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { + module.exports = require('./browser.js'); +} else { + module.exports = require('./node.js'); +} diff --git a/node_modules/debug/src/node.js b/node_modules/debug/src/node.js new file mode 100644 index 0000000..715560a --- /dev/null +++ b/node_modules/debug/src/node.js @@ -0,0 +1,263 @@ +/** + * Module dependencies. + */ + +const tty = require('tty'); +const util = require('util'); + +/** + * This is the Node.js implementation of `debug()`. + */ + +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.destroy = util.deprecate( + () => {}, + 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' +); + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +try { + // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) + // eslint-disable-next-line import/no-extraneous-dependencies + const supportsColor = require('supports-color'); + + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } +} catch (error) { + // Swallow - we only care if `supports-color` is available; it doesn't have to be. +} + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + +exports.inspectOpts = Object.keys(process.env).filter(key => { + return /^debug_/i.test(key); +}).reduce((obj, key) => { + // Camel-case + const prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + + // Coerce string value into JS value + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === 'null') { + val = null; + } else { + val = Number(val); + } + + obj[prop] = val; + return obj; +}, {}); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts ? + Boolean(exports.inspectOpts.colors) : + tty.isatty(process.stderr.fd); +} + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs(args) { + const {namespace: name, useColors} = this; + + if (useColors) { + const c = this.color; + const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); + const prefix = ` ${colorCode};1m${name} \u001B[0m`; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} + +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } + return new Date().toISOString() + ' '; +} + +/** + * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. + */ + +function log(...args) { + return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + +function init(debug) { + debug.inspectOpts = {}; + + const keys = Object.keys(exports.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +formatters.o = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n') + .map(str => str.trim()) + .join(' '); +}; + +/** + * Map %O to `util.inspect()`, allowing multiple lines if needed. + */ + +formatters.O = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; diff --git a/node_modules/deep-eql/LICENSE b/node_modules/deep-eql/LICENSE new file mode 100644 index 0000000..7ea799f --- /dev/null +++ b/node_modules/deep-eql/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/deep-eql/README.md b/node_modules/deep-eql/README.md new file mode 100644 index 0000000..f6e1b85 --- /dev/null +++ b/node_modules/deep-eql/README.md @@ -0,0 +1,93 @@ +

+ + deep-eql + +

+ +

+ Improved deep equality testing for node and the browser. +

+ +

+ + build:? + + coverage:? + + dependencies:? + + devDependencies:? + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is Deep-Eql? + +Deep Eql is a module which you can use to determine if two objects are "deeply" equal - that is, rather than having referential equality (`a === b`), this module checks an object's keys recursively, until it finds primitives to check for referential equality. For more on equality in JavaScript, read [the comparison operators article on mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators). + +As an example, take the following: + +```js +1 === 1 // These are primitives, they hold the same reference - they are strictly equal +1 == '1' // These are two different primitives, through type coercion they hold the same value - they are loosely equal +{ a: 1 } !== { a: 1 } // These are two different objects, they hold different references and so are not strictly equal - even though they hold the same values inside +{ a: 1 } != { a: 1 } // They have the same type, meaning loose equality performs the same check as strict equality - they are still not equal. + +var deepEql = require("deep-eql"); +deepEql({ a: 1 }, { a: 1 }) === true // deepEql can determine that they share the same keys and those keys share the same values, therefore they are deeply equal! +``` + +## Installation + +### Node.js + +`deep-eql` is available on [npm](http://npmjs.org). + + $ npm install deep-eql + +## Usage + +The primary export of `deep-eql` is function that can be given two objects to compare. It will always return a boolean which can be used to determine if two objects are deeply equal. + +### Rules + +- Strict equality for non-traversable nodes according to [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is): + - `eql(NaN, NaN).should.be.true;` + - `eql(-0, +0).should.be.false;` +- All own and inherited enumerable properties are considered: + - `eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 1 } })).should.be.true;` + - `eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 2 } })).should.be.false;` +- When comparing `Error` objects, only `name`, `message`, and `code` properties are considered, regardless of enumerability: + - `eql(Error('foo'), Error('foo')).should.be.true;` + - `eql(Error('foo'), Error('bar')).should.be.false;` + - `eql(Error('foo'), TypeError('foo')).should.be.false;` + - `eql(Object.assign(Error('foo'), { code: 42 }), Object.assign(Error('foo'), { code: 42 })).should.be.true;` + - `eql(Object.assign(Error('foo'), { code: 42 }), Object.assign(Error('foo'), { code: 13 })).should.be.false;` + - `eql(Object.assign(Error('foo'), { otherProp: 42 }), Object.assign(Error('foo'), { otherProp: 13 })).should.be.true;` +- Arguments are not Arrays: + - `eql([], arguments).should.be.false;` + - `eql([], Array.prototype.slice.call(arguments)).should.be.true;` diff --git a/node_modules/deep-eql/deep-eql.js b/node_modules/deep-eql/deep-eql.js new file mode 100644 index 0000000..0070ed4 --- /dev/null +++ b/node_modules/deep-eql/deep-eql.js @@ -0,0 +1 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + * MIT Licensed + */ + +var type = require('type-detect'); +function FakeMap() { + this._key = 'chai/deep-eql__' + Math.random() + Date.now(); +} + +FakeMap.prototype = { + get: function get(key) { + return key[this._key]; + }, + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value: value, + configurable: true, + }); + } + }, +}; + +var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; +/*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result +*/ +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === 'boolean') { + return result; + } + } + return null; +} + +/*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result +*/ +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; +module.exports.MemoizeMap = MemoizeMap; + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + */ +function deepEqual(leftHandOperand, rightHandOperand, options) { + // If we have a comparator, we can't assume anything; so bail to its check first. + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + + // Deeper comparisons are pushed through to a larger function + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} + +/** + * Many comparisons can be canceled out early via simple equality or primitive checks. + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @return {Boolean|null} equal match + */ +function simpleEqual(leftHandOperand, rightHandOperand) { + // Equal references (except for Numbers) can be returned early + if (leftHandOperand === rightHandOperand) { + // Handle +-0 cases + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + + // handle NaN cases + if ( + leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare + ) { + return true; + } + + // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, + // strings, and undefined, can be compared by reference. + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + // Easy out b/c it would have passed the first equality check + return false; + } + return null; +} + +/*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match +*/ +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + + // Check if a memoized result exists. + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + + // If a comparator is present, use it. + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + // Comparators may return null, in which case we want to go back to default behavior. + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide + // what to do, we need to make sure to return the basic tests first before we move on. + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + // Don't memoize this, it takes longer to set/retrieve than to just compare. + return simpleResult; + } + } + + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + + // Temporarily set the operands in the memoize object to prevent blowing the stack + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} + +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case 'String': + case 'Number': + case 'Boolean': + case 'Date': + // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case 'Promise': + case 'Symbol': + case 'function': + case 'WeakMap': + case 'WeakSet': + return leftHandOperand === rightHandOperand; + case 'Error': + return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options); + case 'Arguments': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'Array': + return iterableEqual(leftHandOperand, rightHandOperand, options); + case 'RegExp': + return regexpEqual(leftHandOperand, rightHandOperand); + case 'Generator': + return generatorEqual(leftHandOperand, rightHandOperand, options); + case 'DataView': + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case 'ArrayBuffer': + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case 'Set': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Map': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Temporal.PlainDate': + case 'Temporal.PlainTime': + case 'Temporal.PlainDateTime': + case 'Temporal.Instant': + case 'Temporal.ZonedDateTime': + case 'Temporal.PlainYearMonth': + case 'Temporal.PlainMonthDay': + return leftHandOperand.equals(rightHandOperand); + case 'Temporal.Duration': + return leftHandOperand.total('nanoseconds') === rightHandOperand.total('nanoseconds'); + case 'Temporal.TimeZone': + case 'Temporal.Calendar': + return leftHandOperand.toString() === rightHandOperand.toString(); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} + +/*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + */ + +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} + +/*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function entriesEqual(leftHandOperand, rightHandOperand, options) { + try { + // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + } catch (sizeError) { + // things that aren't actual Maps or Sets will throw here + return false; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([ key, value ]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([ key, value ]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} + +/*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} + +/*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} + +/*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + */ +function hasIteratorFunction(target) { + return typeof Symbol !== 'undefined' && + typeof target === 'object' && + typeof Symbol.iterator !== 'undefined' && + typeof target[Symbol.iterator] === 'function'; +} + +/*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + */ +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} + +/*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + */ +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [ generatorResult.value ]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} + +/*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + */ +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} + +function getEnumerableSymbols(target) { + var keys = []; + var allKeys = Object.getOwnPropertySymbols(target); + for (var i = 0; i < allKeys.length; i += 1) { + var key = allKeys[i]; + if (Object.getOwnPropertyDescriptor(target, key).enumerable) { + keys.push(key); + } + } + return keys; +} + +/*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} + +/*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + var leftHandSymbols = getEnumerableSymbols(leftHandOperand); + var rightHandSymbols = getEnumerableSymbols(rightHandOperand); + leftHandKeys = leftHandKeys.concat(leftHandSymbols); + rightHandKeys = rightHandKeys.concat(rightHandSymbols); + + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + + if (leftHandKeys.length === 0 && + leftHandEntries.length === 0 && + rightHandKeys.length === 0 && + rightHandEntries.length === 0) { + return true; + } + + return false; +} + +/*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + */ +function isPrimitive(value) { + return value === null || typeof value !== 'object'; +} + +function mapSymbols(arr) { + return arr.map(function mapSymbol(entry) { + if (typeof entry === 'symbol') { + return entry.toString(); + } + + return entry; + }); +} diff --git a/node_modules/deep-eql/package.json b/node_modules/deep-eql/package.json new file mode 100644 index 0000000..27391d2 --- /dev/null +++ b/node_modules/deep-eql/package.json @@ -0,0 +1,79 @@ +{ + "name": "deep-eql", + "version": "4.1.4", + "description": "Improved deep equality testing for Node.js and the browser.", + "keywords": [ + "chai util", + "deep equal", + "object equal", + "testing" + ], + "repository": { + "type": "git", + "url": "git@github.com:chaijs/deep-eql.git" + }, + "license": "MIT", + "author": "Jake Luer ", + "contributors": [ + "Keith Cirkel (https://github.com/keithamus)", + "dougluce (https://github.com/dougluce)", + "Lorenz Leutgeb (https://github.com/flowlo)" + ], + "main": "./index", + "files": [ + "index.js", + "deep-eql.js" + ], + "scripts": { + "bench": "node bench", + "build": "browserify $npm_package_main --standalone deepEqual -o deep-eql.js", + "lint": "eslint --ignore-path .gitignore .", + "prepublish": "npm run build", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser", + "test:browser": "karma start --singleRun=true", + "test:node": "istanbul cover _mocha", + "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0", + "watch": "karma start --auto-watch --singleRun=false" + }, + "eslintConfig": { + "extends": [ + "strict/es5" + ], + "rules": { + "complexity": 0, + "no-underscore-dangle": 0, + "no-use-before-define": 0, + "spaced-comment": 0 + } + }, + "dependencies": { + "type-detect": "^4.0.0" + }, + "devDependencies": { + "@js-temporal/polyfill": "^0.4.1", + "benchmark": "^2.1.0", + "browserify": "^17.0.0", + "browserify-istanbul": "^3.0.1", + "coveralls": "^3.1.1", + "eslint": "^7.32.0", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "istanbul": "^0.4.2", + "karma": "^6.3.4", + "karma-browserify": "^8.1.0", + "karma-chrome-launcher": "^3.1.0", + "karma-coverage": "^2.0.3", + "karma-mocha": "^2.0.1", + "karma-sauce-launcher": "^4.1.4", + "kewlr": "^0.4.1", + "lcov-result-merger": "^1.0.2", + "lodash.isequal": "^4.4.0", + "mocha": "^9.1.1", + "simple-assert": "^1.0.0" + }, + "engines": { + "node": ">=6" + } +} diff --git a/node_modules/diff-sequences/LICENSE b/node_modules/diff-sequences/LICENSE new file mode 100644 index 0000000..b93be90 --- /dev/null +++ b/node_modules/diff-sequences/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/diff-sequences/README.md b/node_modules/diff-sequences/README.md new file mode 100644 index 0000000..fd5b99b --- /dev/null +++ b/node_modules/diff-sequences/README.md @@ -0,0 +1,404 @@ +# diff-sequences + +Compare items in two sequences to find a **longest common subsequence**. + +The items not in common are the items to delete or insert in a **shortest edit script**. + +To maximize flexibility and minimize memory, you write **callback** functions as configuration: + +**Input** function `isCommon(aIndex, bIndex)` compares items at indexes in the sequences and returns a truthy/falsey value. This package might call your function more than once for some pairs of indexes. + +- Because your function encapsulates **comparison**, this package can compare items according to `===` operator, `Object.is` method, or other criterion. +- Because your function encapsulates **sequences**, this package can find differences in arrays, strings, or other data. + +**Output** function `foundSubsequence(nCommon, aCommon, bCommon)` receives the number of adjacent items and starting indexes of each common subsequence. If sequences do not have common items, then this package does not call your function. + +If N is the sum of lengths of sequences and L is length of a longest common subsequence, then D = N – 2L is the number of **differences** in the corresponding shortest edit script. + +[_An O(ND) Difference Algorithm and Its Variations_](http://xmailserver.org/diff2.pdf) by Eugene W. Myers is fast when sequences have **few** differences. + +This package implements the **linear space** variation with optimizations so it is fast even when sequences have **many** differences. + +## Usage + +To add this package as a dependency of a project, do either of the following: + +- `npm install diff-sequences` +- `yarn add diff-sequences` + +To use `diff` as the name of the default export from this package, do either of the following: + +- `var diff = require('diff-sequences').default; // CommonJS modules` +- `import diff from 'diff-sequences'; // ECMAScript modules` + +Call `diff` with the **lengths** of sequences and your **callback** functions: + +```js +const a = ['a', 'b', 'c', 'a', 'b', 'b', 'a']; +const b = ['c', 'b', 'a', 'b', 'a', 'c']; + +function isCommon(aIndex, bIndex) { + return a[aIndex] === b[bIndex]; +} +function foundSubsequence(nCommon, aCommon, bCommon) { + // see examples +} + +diff(a.length, b.length, isCommon, foundSubsequence); +``` + +## Example of longest common subsequence + +Some sequences (for example, `a` and `b` in the example of usage) have more than one longest common subsequence. + +This package finds the following common items: + +| comparisons of common items | values | output arguments | +| :------------------------------- | :--------- | --------------------------: | +| `a[2] === b[0]` | `'c'` | `foundSubsequence(1, 2, 0)` | +| `a[4] === b[1]` | `'b'` | `foundSubsequence(1, 4, 1)` | +| `a[5] === b[3] && a[6] === b[4]` | `'b', 'a'` | `foundSubsequence(2, 5, 3)` | + +The “edit graph” analogy in the Myers paper shows the following common items: + +| comparisons of common items | values | +| :------------------------------- | :--------- | +| `a[2] === b[0]` | `'c'` | +| `a[3] === b[2] && a[4] === b[3]` | `'a', 'b'` | +| `a[6] === b[4]` | `'a'` | + +Various packages which implement the Myers algorithm will **always agree** on the **length** of a longest common subsequence, but might **sometimes disagree** on which **items** are in it. + +## Example of callback functions to count common items + +```js +// Return length of longest common subsequence according to === operator. +function countCommonItems(a, b) { + let n = 0; + function isCommon(aIndex, bIndex) { + return a[aIndex] === b[bIndex]; + } + function foundSubsequence(nCommon) { + n += nCommon; + } + + diff(a.length, b.length, isCommon, foundSubsequence); + + return n; +} + +const commonLength = countCommonItems( + ['a', 'b', 'c', 'a', 'b', 'b', 'a'], + ['c', 'b', 'a', 'b', 'a', 'c'], +); +``` + +| category of items | expression | value | +| :----------------- | ------------------------: | ----: | +| in common | `commonLength` | `4` | +| to delete from `a` | `a.length - commonLength` | `3` | +| to insert from `b` | `b.length - commonLength` | `2` | + +If the length difference `b.length - a.length` is: + +- negative: its absolute value is the minimum number of items to **delete** from `a` +- positive: it is the minimum number of items to **insert** from `b` +- zero: there is an **equal** number of items to delete from `a` and insert from `b` +- non-zero: there is an equal number of **additional** items to delete from `a` and insert from `b` + +In this example, `6 - 7` is: + +- negative: `1` is the minimum number of items to **delete** from `a` +- non-zero: `2` is the number of **additional** items to delete from `a` and insert from `b` + +## Example of callback functions to find common items + +```js +// Return array of items in longest common subsequence according to Object.is method. +const findCommonItems = (a, b) => { + const array = []; + diff( + a.length, + b.length, + (aIndex, bIndex) => Object.is(a[aIndex], b[bIndex]), + (nCommon, aCommon) => { + for (; nCommon !== 0; nCommon -= 1, aCommon += 1) { + array.push(a[aCommon]); + } + }, + ); + return array; +}; + +const commonItems = findCommonItems( + ['a', 'b', 'c', 'a', 'b', 'b', 'a'], + ['c', 'b', 'a', 'b', 'a', 'c'], +); +``` + +| `i` | `commonItems[i]` | `aIndex` | +| --: | :--------------- | -------: | +| `0` | `'c'` | `2` | +| `1` | `'b'` | `4` | +| `2` | `'b'` | `5` | +| `3` | `'a'` | `6` | + +## Example of callback functions to diff index intervals + +Instead of slicing array-like objects, you can adjust indexes in your callback functions. + +```js +// Diff index intervals that are half open [start, end) like array slice method. +const diffIndexIntervals = (a, aStart, aEnd, b, bStart, bEnd) => { + // Validate: 0 <= aStart and aStart <= aEnd and aEnd <= a.length + // Validate: 0 <= bStart and bStart <= bEnd and bEnd <= b.length + + diff( + aEnd - aStart, + bEnd - bStart, + (aIndex, bIndex) => Object.is(a[aStart + aIndex], b[bStart + bIndex]), + (nCommon, aCommon, bCommon) => { + // aStart + aCommon, bStart + bCommon + }, + ); + + // After the last common subsequence, do any remaining work. +}; +``` + +## Example of callback functions to emulate diff command + +Linux or Unix has a `diff` command to compare files line by line. Its output is a **shortest edit script**: + +- **c**hange adjacent lines from the first file to lines from the second file +- **d**elete lines from the first file +- **a**ppend or insert lines from the second file + +```js +// Given zero-based half-open range [start, end) of array indexes, +// return one-based closed range [start + 1, end] as string. +const getRange = (start, end) => + start + 1 === end ? `${start + 1}` : `${start + 1},${end}`; + +// Given index intervals of lines to delete or insert, or both, or neither, +// push formatted diff lines onto array. +const pushDelIns = (aLines, aIndex, aEnd, bLines, bIndex, bEnd, array) => { + const deleteLines = aIndex !== aEnd; + const insertLines = bIndex !== bEnd; + const changeLines = deleteLines && insertLines; + if (changeLines) { + array.push(`${getRange(aIndex, aEnd)}c${getRange(bIndex, bEnd)}`); + } else if (deleteLines) { + array.push(`${getRange(aIndex, aEnd)}d${String(bIndex)}`); + } else if (insertLines) { + array.push(`${String(aIndex)}a${getRange(bIndex, bEnd)}`); + } else { + return; + } + + for (; aIndex !== aEnd; aIndex += 1) { + array.push(`< ${aLines[aIndex]}`); // delete is less than + } + + if (changeLines) { + array.push('---'); + } + + for (; bIndex !== bEnd; bIndex += 1) { + array.push(`> ${bLines[bIndex]}`); // insert is greater than + } +}; + +// Given content of two files, return emulated output of diff utility. +const findShortestEditScript = (a, b) => { + const aLines = a.split('\n'); + const bLines = b.split('\n'); + const aLength = aLines.length; + const bLength = bLines.length; + + const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex]; + + let aIndex = 0; + let bIndex = 0; + const array = []; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + pushDelIns(aLines, aIndex, aCommon, bLines, bIndex, bCommon, array); + aIndex = aCommon + nCommon; // number of lines compared in a + bIndex = bCommon + nCommon; // number of lines compared in b + }; + + diff(aLength, bLength, isCommon, foundSubsequence); + + // After the last common subsequence, push remaining change lines. + pushDelIns(aLines, aIndex, aLength, bLines, bIndex, bLength, array); + + return array.length === 0 ? '' : `${array.join('\n')}\n`; +}; +``` + +## Example of callback functions to format diff lines + +Here is simplified code to format **changed and unchanged lines** in expected and received values after a test fails in Jest: + +```js +// Format diff with minus or plus for change lines and space for common lines. +const formatDiffLines = (a, b) => { + // Jest depends on pretty-format package to serialize objects as strings. + // Unindented for comparison to avoid distracting differences: + const aLinesUn = format(a, {indent: 0 /*, other options*/}).split('\n'); + const bLinesUn = format(b, {indent: 0 /*, other options*/}).split('\n'); + // Indented to display changed and unchanged lines: + const aLinesIn = format(a, {indent: 2 /*, other options*/}).split('\n'); + const bLinesIn = format(b, {indent: 2 /*, other options*/}).split('\n'); + + const aLength = aLinesIn.length; // Validate: aLinesUn.length === aLength + const bLength = bLinesIn.length; // Validate: bLinesUn.length === bLength + + const isCommon = (aIndex, bIndex) => aLinesUn[aIndex] === bLinesUn[bIndex]; + + // Only because the GitHub Flavored Markdown doc collapses adjacent spaces, + // this example code and the following table represent spaces as middle dots. + let aIndex = 0; + let bIndex = 0; + const array = []; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + for (; aIndex !== aCommon; aIndex += 1) { + array.push(`-·${aLinesIn[aIndex]}`); // delete is minus + } + for (; bIndex !== bCommon; bIndex += 1) { + array.push(`+·${bLinesIn[bIndex]}`); // insert is plus + } + for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) { + // For common lines, received indentation seems more intuitive. + array.push(`··${bLinesIn[bIndex]}`); // common is space + } + }; + + diff(aLength, bLength, isCommon, foundSubsequence); + + // After the last common subsequence, push remaining change lines. + for (; aIndex !== aLength; aIndex += 1) { + array.push(`-·${aLinesIn[aIndex]}`); + } + for (; bIndex !== bLength; bIndex += 1) { + array.push(`+·${bLinesIn[bIndex]}`); + } + + return array; +}; + +const expected = { + searching: '', + sorting: { + ascending: true, + fieldKey: 'what', + }, +}; +const received = { + searching: '', + sorting: [ + { + descending: false, + fieldKey: 'what', + }, + ], +}; + +const diffLines = formatDiffLines(expected, received); +``` + +If N is the sum of lengths of sequences and L is length of a longest common subsequence, then N – L is length of an array of diff lines. In this example, N is 7 + 9, L is 5, and N – L is 11. + +| `i` | `diffLines[i]` | `aIndex` | `bIndex` | +| ---: | :--------------------------------- | -------: | -------: | +| `0` | `'··Object {'` | `0` | `0` | +| `1` | `'····"searching": "",'` | `1` | `1` | +| `2` | `'-···"sorting": Object {'` | `2` | | +| `3` | `'-·····"ascending": true,'` | `3` | | +| `4` | `'+·····"sorting": Array ['` | | `2` | +| `5` | `'+·······Object {'` | | `3` | +| `6` | `'+·········"descending": false,'` | | `4` | +| `7` | `'··········"fieldKey": "what",'` | `4` | `5` | +| `8` | `'········},'` | `5` | `6` | +| `9` | `'+·····],'` | | `7` | +| `10` | `'··}'` | `6` | `8` | + +## Example of callback functions to find diff items + +Here is simplified code to find changed and unchanged substrings **within adjacent changed lines** in expected and received values after a test fails in Jest: + +```js +// Return diff items for strings (compatible with diff-match-patch package). +const findDiffItems = (a, b) => { + const isCommon = (aIndex, bIndex) => a[aIndex] === b[bIndex]; + + let aIndex = 0; + let bIndex = 0; + const array = []; + const foundSubsequence = (nCommon, aCommon, bCommon) => { + if (aIndex !== aCommon) { + array.push([-1, a.slice(aIndex, aCommon)]); // delete is -1 + } + if (bIndex !== bCommon) { + array.push([1, b.slice(bIndex, bCommon)]); // insert is 1 + } + + aIndex = aCommon + nCommon; // number of characters compared in a + bIndex = bCommon + nCommon; // number of characters compared in b + array.push([0, a.slice(aCommon, aIndex)]); // common is 0 + }; + + diff(a.length, b.length, isCommon, foundSubsequence); + + // After the last common subsequence, push remaining change items. + if (aIndex !== a.length) { + array.push([-1, a.slice(aIndex)]); + } + if (bIndex !== b.length) { + array.push([1, b.slice(bIndex)]); + } + + return array; +}; + +const expectedDeleted = ['"sorting": Object {', '"ascending": true,'].join( + '\n', +); +const receivedInserted = [ + '"sorting": Array [', + 'Object {', + '"descending": false,', +].join('\n'); + +const diffItems = findDiffItems(expectedDeleted, receivedInserted); +``` + +| `i` | `diffItems[i][0]` | `diffItems[i][1]` | +| --: | ----------------: | :---------------- | +| `0` | `0` | `'"sorting": '` | +| `1` | `1` | `'Array [\n'` | +| `2` | `0` | `'Object {\n"'` | +| `3` | `-1` | `'a'` | +| `4` | `1` | `'de'` | +| `5` | `0` | `'scending": '` | +| `6` | `-1` | `'tru'` | +| `7` | `1` | `'fals'` | +| `8` | `0` | `'e,'` | + +The length difference `b.length - a.length` is equal to the sum of `diffItems[i][0]` values times `diffItems[i][1]` lengths. In this example, the difference `48 - 38` is equal to the sum `10`. + +| category of diff item | `[0]` | `[1]` lengths | subtotal | +| :-------------------- | ----: | -----------------: | -------: | +| in common | `0` | `11 + 10 + 11 + 2` | `0` | +| to delete from `a` | `–1` | `1 + 3` | `-4` | +| to insert from `b` | `1` | `8 + 2 + 4` | `14` | + +Instead of formatting the changed substrings with escape codes for colors in the `foundSubsequence` function to save memory, this example spends memory to **gain flexibility** before formatting, so a separate heuristic algorithm might modify the generic array of diff items to show changes more clearly: + +| `i` | `diffItems[i][0]` | `diffItems[i][1]` | +| --: | ----------------: | :---------------- | +| `6` | `-1` | `'true'` | +| `7` | `1` | `'false'` | +| `8` | `0` | `','` | + +For expected and received strings of serialized data, the result of finding changed **lines**, and then finding changed **substrings** within adjacent changed lines (as in the preceding two examples) sometimes displays the changes in a more intuitive way than the result of finding changed substrings, and then splitting them into changed and unchanged lines. diff --git a/node_modules/diff-sequences/build/index.d.ts b/node_modules/diff-sequences/build/index.d.ts new file mode 100644 index 0000000..9e9c3db --- /dev/null +++ b/node_modules/diff-sequences/build/index.d.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +export declare type Callbacks = { + foundSubsequence: FoundSubsequence; + isCommon: IsCommon; +}; + +declare function diffSequence( + aLength: number, + bLength: number, + isCommon: IsCommon, + foundSubsequence: FoundSubsequence, +): void; +export default diffSequence; + +declare type FoundSubsequence = ( + nCommon: number, // caller can assume: 0 < nCommon + aCommon: number, // caller can assume: 0 <= aCommon && aCommon < aLength + bCommon: number, +) => void; + +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +declare type IsCommon = ( + aIndex: number, // caller can assume: 0 <= aIndex && aIndex < aLength + bIndex: number, +) => boolean; + +export {}; diff --git a/node_modules/diff-sequences/build/index.js b/node_modules/diff-sequences/build/index.js new file mode 100644 index 0000000..b0a1ff6 --- /dev/null +++ b/node_modules/diff-sequences/build/index.js @@ -0,0 +1,798 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = diffSequence; +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +// This diff-sequences package implements the linear space variation in +// An O(ND) Difference Algorithm and Its Variations by Eugene W. Myers + +// Relationship in notation between Myers paper and this package: +// A is a +// N is aLength, aEnd - aStart, and so on +// x is aIndex, aFirst, aLast, and so on +// B is b +// M is bLength, bEnd - bStart, and so on +// y is bIndex, bFirst, bLast, and so on +// Δ = N - M is negative of baDeltaLength = bLength - aLength +// D is d +// k is kF +// k + Δ is kF = kR - baDeltaLength +// V is aIndexesF or aIndexesR (see comment below about Indexes type) +// index intervals [1, N] and [1, M] are [0, aLength) and [0, bLength) +// starting point in forward direction (0, 0) is (-1, -1) +// starting point in reverse direction (N + 1, M + 1) is (aLength, bLength) + +// The “edit graph” for sequences a and b corresponds to items: +// in a on the horizontal axis +// in b on the vertical axis +// +// Given a-coordinate of a point in a diagonal, you can compute b-coordinate. +// +// Forward diagonals kF: +// zero diagonal intersects top left corner +// positive diagonals intersect top edge +// negative diagonals insersect left edge +// +// Reverse diagonals kR: +// zero diagonal intersects bottom right corner +// positive diagonals intersect right edge +// negative diagonals intersect bottom edge + +// The graph contains a directed acyclic graph of edges: +// horizontal: delete an item from a +// vertical: insert an item from b +// diagonal: common item in a and b +// +// The algorithm solves dual problems in the graph analogy: +// Find longest common subsequence: path with maximum number of diagonal edges +// Find shortest edit script: path with minimum number of non-diagonal edges + +// Input callback function compares items at indexes in the sequences. + +// Output callback function receives the number of adjacent items +// and starting indexes of each common subsequence. +// Either original functions or wrapped to swap indexes if graph is transposed. +// Indexes in sequence a of last point of forward or reverse paths in graph. +// Myers algorithm indexes by diagonal k which for negative is bad deopt in V8. +// This package indexes by iF and iR which are greater than or equal to zero. +// and also updates the index arrays in place to cut memory in half. +// kF = 2 * iF - d +// kR = d - 2 * iR +// Division of index intervals in sequences a and b at the middle change. +// Invariant: intervals do not have common items at the start or end. +const pkg = 'diff-sequences'; // for error messages +const NOT_YET_SET = 0; // small int instead of undefined to avoid deopt in V8 + +// Return the number of common items that follow in forward direction. +// The length of what Myers paper calls a “snake” in a forward path. +const countCommonItemsF = (aIndex, aEnd, bIndex, bEnd, isCommon) => { + let nCommon = 0; + while (aIndex < aEnd && bIndex < bEnd && isCommon(aIndex, bIndex)) { + aIndex += 1; + bIndex += 1; + nCommon += 1; + } + return nCommon; +}; + +// Return the number of common items that precede in reverse direction. +// The length of what Myers paper calls a “snake” in a reverse path. +const countCommonItemsR = (aStart, aIndex, bStart, bIndex, isCommon) => { + let nCommon = 0; + while (aStart <= aIndex && bStart <= bIndex && isCommon(aIndex, bIndex)) { + aIndex -= 1; + bIndex -= 1; + nCommon += 1; + } + return nCommon; +}; + +// A simple function to extend forward paths from (d - 1) to d changes +// when forward and reverse paths cannot yet overlap. +const extendPathsF = ( + d, + aEnd, + bEnd, + bF, + isCommon, + aIndexesF, + iMaxF // return the value because optimization might decrease it +) => { + // Unroll the first iteration. + let iF = 0; + let kF = -d; // kF = 2 * iF - d + let aFirst = aIndexesF[iF]; // in first iteration always insert + let aIndexPrev1 = aFirst; // prev value of [iF - 1] in next iteration + aIndexesF[iF] += countCommonItemsF( + aFirst + 1, + aEnd, + bF + aFirst - kF + 1, + bEnd, + isCommon + ); + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nF = d < iMaxF ? d : iMaxF; + + // The diagonals kF are odd when d is odd and even when d is even. + for (iF += 1, kF += 2; iF <= nF; iF += 1, kF += 2) { + // To get first point of path segment, move one change in forward direction + // from last point of previous path segment in an adjacent diagonal. + // In last possible iteration when iF === d and kF === d always delete. + if (iF !== d && aIndexPrev1 < aIndexesF[iF]) { + aFirst = aIndexesF[iF]; // vertical to insert from b + } else { + aFirst = aIndexPrev1 + 1; // horizontal to delete from a + + if (aEnd <= aFirst) { + // Optimization: delete moved past right of graph. + return iF - 1; + } + } + + // To get last point of path segment, move along diagonal of common items. + aIndexPrev1 = aIndexesF[iF]; + aIndexesF[iF] = + aFirst + + countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon); + } + return iMaxF; +}; + +// A simple function to extend reverse paths from (d - 1) to d changes +// when reverse and forward paths cannot yet overlap. +const extendPathsR = ( + d, + aStart, + bStart, + bR, + isCommon, + aIndexesR, + iMaxR // return the value because optimization might decrease it +) => { + // Unroll the first iteration. + let iR = 0; + let kR = d; // kR = d - 2 * iR + let aFirst = aIndexesR[iR]; // in first iteration always insert + let aIndexPrev1 = aFirst; // prev value of [iR - 1] in next iteration + aIndexesR[iR] -= countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bR + aFirst - kR - 1, + isCommon + ); + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nR = d < iMaxR ? d : iMaxR; + + // The diagonals kR are odd when d is odd and even when d is even. + for (iR += 1, kR -= 2; iR <= nR; iR += 1, kR -= 2) { + // To get first point of path segment, move one change in reverse direction + // from last point of previous path segment in an adjacent diagonal. + // In last possible iteration when iR === d and kR === -d always delete. + if (iR !== d && aIndexesR[iR] < aIndexPrev1) { + aFirst = aIndexesR[iR]; // vertical to insert from b + } else { + aFirst = aIndexPrev1 - 1; // horizontal to delete from a + + if (aFirst < aStart) { + // Optimization: delete moved past left of graph. + return iR - 1; + } + } + + // To get last point of path segment, move along diagonal of common items. + aIndexPrev1 = aIndexesR[iR]; + aIndexesR[iR] = + aFirst - + countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bR + aFirst - kR - 1, + isCommon + ); + } + return iMaxR; +}; + +// A complete function to extend forward paths from (d - 1) to d changes. +// Return true if a path overlaps reverse path of (d - 1) changes in its diagonal. +const extendOverlappablePathsF = ( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division // update prop values if return true +) => { + const bF = bStart - aStart; // bIndex = bF + aIndex - kF + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + const baDeltaLength = bLength - aLength; // kF = kR - baDeltaLength + + // Range of diagonals in which forward and reverse paths might overlap. + const kMinOverlapF = -baDeltaLength - (d - 1); // -(d - 1) <= kR + const kMaxOverlapF = -baDeltaLength + (d - 1); // kR <= (d - 1) + + let aIndexPrev1 = NOT_YET_SET; // prev value of [iF - 1] in next iteration + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nF = d < iMaxF ? d : iMaxF; + + // The diagonals kF = 2 * iF - d are odd when d is odd and even when d is even. + for (let iF = 0, kF = -d; iF <= nF; iF += 1, kF += 2) { + // To get first point of path segment, move one change in forward direction + // from last point of previous path segment in an adjacent diagonal. + // In first iteration when iF === 0 and kF === -d always insert. + // In last possible iteration when iF === d and kF === d always delete. + const insert = iF === 0 || (iF !== d && aIndexPrev1 < aIndexesF[iF]); + const aLastPrev = insert ? aIndexesF[iF] : aIndexPrev1; + const aFirst = insert + ? aLastPrev // vertical to insert from b + : aLastPrev + 1; // horizontal to delete from a + + // To get last point of path segment, move along diagonal of common items. + const bFirst = bF + aFirst - kF; + const nCommonF = countCommonItemsF( + aFirst + 1, + aEnd, + bFirst + 1, + bEnd, + isCommon + ); + const aLast = aFirst + nCommonF; + aIndexPrev1 = aIndexesF[iF]; + aIndexesF[iF] = aLast; + if (kMinOverlapF <= kF && kF <= kMaxOverlapF) { + // Solve for iR of reverse path with (d - 1) changes in diagonal kF: + // kR = kF + baDeltaLength + // kR = (d - 1) - 2 * iR + const iR = (d - 1 - (kF + baDeltaLength)) / 2; + + // If this forward path overlaps the reverse path in this diagonal, + // then this is the middle change of the index intervals. + if (iR <= iMaxR && aIndexesR[iR] - 1 <= aLast) { + // Unlike the Myers algorithm which finds only the middle “snake” + // this package can find two common subsequences per division. + // Last point of previous path segment is on an adjacent diagonal. + const bLastPrev = bF + aLastPrev - (insert ? kF + 1 : kF - 1); + + // Because of invariant that intervals preceding the middle change + // cannot have common items at the end, + // move in reverse direction along a diagonal of common items. + const nCommonR = countCommonItemsR( + aStart, + aLastPrev, + bStart, + bLastPrev, + isCommon + ); + const aIndexPrevFirst = aLastPrev - nCommonR; + const bIndexPrevFirst = bLastPrev - nCommonR; + const aEndPreceding = aIndexPrevFirst + 1; + const bEndPreceding = bIndexPrevFirst + 1; + division.nChangePreceding = d - 1; + if (d - 1 === aEndPreceding + bEndPreceding - aStart - bStart) { + // Optimization: number of preceding changes in forward direction + // is equal to number of items in preceding interval, + // therefore it cannot contain any common items. + division.aEndPreceding = aStart; + division.bEndPreceding = bStart; + } else { + division.aEndPreceding = aEndPreceding; + division.bEndPreceding = bEndPreceding; + } + division.nCommonPreceding = nCommonR; + if (nCommonR !== 0) { + division.aCommonPreceding = aEndPreceding; + division.bCommonPreceding = bEndPreceding; + } + division.nCommonFollowing = nCommonF; + if (nCommonF !== 0) { + division.aCommonFollowing = aFirst + 1; + division.bCommonFollowing = bFirst + 1; + } + const aStartFollowing = aLast + 1; + const bStartFollowing = bFirst + nCommonF + 1; + division.nChangeFollowing = d - 1; + if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) { + // Optimization: number of changes in reverse direction + // is equal to number of items in following interval, + // therefore it cannot contain any common items. + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + division.aStartFollowing = aStartFollowing; + division.bStartFollowing = bStartFollowing; + } + return true; + } + } + } + return false; +}; + +// A complete function to extend reverse paths from (d - 1) to d changes. +// Return true if a path overlaps forward path of d changes in its diagonal. +const extendOverlappablePathsR = ( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division // update prop values if return true +) => { + const bR = bEnd - aEnd; // bIndex = bR + aIndex - kR + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + const baDeltaLength = bLength - aLength; // kR = kF + baDeltaLength + + // Range of diagonals in which forward and reverse paths might overlap. + const kMinOverlapR = baDeltaLength - d; // -d <= kF + const kMaxOverlapR = baDeltaLength + d; // kF <= d + + let aIndexPrev1 = NOT_YET_SET; // prev value of [iR - 1] in next iteration + + // Optimization: skip diagonals in which paths cannot ever overlap. + const nR = d < iMaxR ? d : iMaxR; + + // The diagonals kR = d - 2 * iR are odd when d is odd and even when d is even. + for (let iR = 0, kR = d; iR <= nR; iR += 1, kR -= 2) { + // To get first point of path segment, move one change in reverse direction + // from last point of previous path segment in an adjacent diagonal. + // In first iteration when iR === 0 and kR === d always insert. + // In last possible iteration when iR === d and kR === -d always delete. + const insert = iR === 0 || (iR !== d && aIndexesR[iR] < aIndexPrev1); + const aLastPrev = insert ? aIndexesR[iR] : aIndexPrev1; + const aFirst = insert + ? aLastPrev // vertical to insert from b + : aLastPrev - 1; // horizontal to delete from a + + // To get last point of path segment, move along diagonal of common items. + const bFirst = bR + aFirst - kR; + const nCommonR = countCommonItemsR( + aStart, + aFirst - 1, + bStart, + bFirst - 1, + isCommon + ); + const aLast = aFirst - nCommonR; + aIndexPrev1 = aIndexesR[iR]; + aIndexesR[iR] = aLast; + if (kMinOverlapR <= kR && kR <= kMaxOverlapR) { + // Solve for iF of forward path with d changes in diagonal kR: + // kF = kR - baDeltaLength + // kF = 2 * iF - d + const iF = (d + (kR - baDeltaLength)) / 2; + + // If this reverse path overlaps the forward path in this diagonal, + // then this is a middle change of the index intervals. + if (iF <= iMaxF && aLast - 1 <= aIndexesF[iF]) { + const bLast = bFirst - nCommonR; + division.nChangePreceding = d; + if (d === aLast + bLast - aStart - bStart) { + // Optimization: number of changes in reverse direction + // is equal to number of items in preceding interval, + // therefore it cannot contain any common items. + division.aEndPreceding = aStart; + division.bEndPreceding = bStart; + } else { + division.aEndPreceding = aLast; + division.bEndPreceding = bLast; + } + division.nCommonPreceding = nCommonR; + if (nCommonR !== 0) { + // The last point of reverse path segment is start of common subsequence. + division.aCommonPreceding = aLast; + division.bCommonPreceding = bLast; + } + division.nChangeFollowing = d - 1; + if (d === 1) { + // There is no previous path segment. + division.nCommonFollowing = 0; + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + // Unlike the Myers algorithm which finds only the middle “snake” + // this package can find two common subsequences per division. + // Last point of previous path segment is on an adjacent diagonal. + const bLastPrev = bR + aLastPrev - (insert ? kR - 1 : kR + 1); + + // Because of invariant that intervals following the middle change + // cannot have common items at the start, + // move in forward direction along a diagonal of common items. + const nCommonF = countCommonItemsF( + aLastPrev, + aEnd, + bLastPrev, + bEnd, + isCommon + ); + division.nCommonFollowing = nCommonF; + if (nCommonF !== 0) { + // The last point of reverse path segment is start of common subsequence. + division.aCommonFollowing = aLastPrev; + division.bCommonFollowing = bLastPrev; + } + const aStartFollowing = aLastPrev + nCommonF; // aFirstPrev + const bStartFollowing = bLastPrev + nCommonF; // bFirstPrev + + if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) { + // Optimization: number of changes in forward direction + // is equal to number of items in following interval, + // therefore it cannot contain any common items. + division.aStartFollowing = aEnd; + division.bStartFollowing = bEnd; + } else { + division.aStartFollowing = aStartFollowing; + division.bStartFollowing = bStartFollowing; + } + } + return true; + } + } + } + return false; +}; + +// Given index intervals and input function to compare items at indexes, +// divide at the middle change. +// +// DO NOT CALL if start === end, because interval cannot contain common items +// and because this function will throw the “no overlap” error. +const divide = ( + nChange, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + aIndexesR, + division // output +) => { + const bF = bStart - aStart; // bIndex = bF + aIndex - kF + const bR = bEnd - aEnd; // bIndex = bR + aIndex - kR + const aLength = aEnd - aStart; + const bLength = bEnd - bStart; + + // Because graph has square or portrait orientation, + // length difference is minimum number of items to insert from b. + // Corresponding forward and reverse diagonals in graph + // depend on length difference of the sequences: + // kF = kR - baDeltaLength + // kR = kF + baDeltaLength + const baDeltaLength = bLength - aLength; + + // Optimization: max diagonal in graph intersects corner of shorter side. + let iMaxF = aLength; + let iMaxR = aLength; + + // Initialize no changes yet in forward or reverse direction: + aIndexesF[0] = aStart - 1; // at open start of interval, outside closed start + aIndexesR[0] = aEnd; // at open end of interval + + if (baDeltaLength % 2 === 0) { + // The number of changes in paths is 2 * d if length difference is even. + const dMin = (nChange || baDeltaLength) / 2; + const dMax = (aLength + bLength) / 2; + for (let d = 1; d <= dMax; d += 1) { + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + if (d < dMin) { + iMaxR = extendPathsR(d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR); + } else if ( + // If a reverse path overlaps a forward path in the same diagonal, + // return a division of the index intervals at the middle change. + extendOverlappablePathsR( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division + ) + ) { + return; + } + } + } else { + // The number of changes in paths is 2 * d - 1 if length difference is odd. + const dMin = ((nChange || baDeltaLength) + 1) / 2; + const dMax = (aLength + bLength + 1) / 2; + + // Unroll first half iteration so loop extends the relevant pairs of paths. + // Because of invariant that intervals have no common items at start or end, + // and limitation not to call divide with empty intervals, + // therefore it cannot be called if a forward path with one change + // would overlap a reverse path with no changes, even if dMin === 1. + let d = 1; + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + for (d += 1; d <= dMax; d += 1) { + iMaxR = extendPathsR( + d - 1, + aStart, + bStart, + bR, + isCommon, + aIndexesR, + iMaxR + ); + if (d < dMin) { + iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF); + } else if ( + // If a forward path overlaps a reverse path in the same diagonal, + // return a division of the index intervals at the middle change. + extendOverlappablePathsF( + d, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + iMaxF, + aIndexesR, + iMaxR, + division + ) + ) { + return; + } + } + } + + /* istanbul ignore next */ + throw new Error( + `${pkg}: no overlap aStart=${aStart} aEnd=${aEnd} bStart=${bStart} bEnd=${bEnd}` + ); +}; + +// Given index intervals and input function to compare items at indexes, +// return by output function the number of adjacent items and starting indexes +// of each common subsequence. Divide and conquer with only linear space. +// +// The index intervals are half open [start, end) like array slice method. +// DO NOT CALL if start === end, because interval cannot contain common items +// and because divide function will throw the “no overlap” error. +const findSubsequences = ( + nChange, + aStart, + aEnd, + bStart, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division // temporary memory, not input nor output +) => { + if (bEnd - bStart < aEnd - aStart) { + // Transpose graph so it has portrait instead of landscape orientation. + // Always compare shorter to longer sequence for consistency and optimization. + transposed = !transposed; + if (transposed && callbacks.length === 1) { + // Lazily wrap callback functions to swap args if graph is transposed. + const {foundSubsequence, isCommon} = callbacks[0]; + callbacks[1] = { + foundSubsequence: (nCommon, bCommon, aCommon) => { + foundSubsequence(nCommon, aCommon, bCommon); + }, + isCommon: (bIndex, aIndex) => isCommon(aIndex, bIndex) + }; + } + const tStart = aStart; + const tEnd = aEnd; + aStart = bStart; + aEnd = bEnd; + bStart = tStart; + bEnd = tEnd; + } + const {foundSubsequence, isCommon} = callbacks[transposed ? 1 : 0]; + + // Divide the index intervals at the middle change. + divide( + nChange, + aStart, + aEnd, + bStart, + bEnd, + isCommon, + aIndexesF, + aIndexesR, + division + ); + const { + nChangePreceding, + aEndPreceding, + bEndPreceding, + nCommonPreceding, + aCommonPreceding, + bCommonPreceding, + nCommonFollowing, + aCommonFollowing, + bCommonFollowing, + nChangeFollowing, + aStartFollowing, + bStartFollowing + } = division; + + // Unless either index interval is empty, they might contain common items. + if (aStart < aEndPreceding && bStart < bEndPreceding) { + // Recursely find and return common subsequences preceding the division. + findSubsequences( + nChangePreceding, + aStart, + aEndPreceding, + bStart, + bEndPreceding, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } + + // Return common subsequences that are adjacent to the middle change. + if (nCommonPreceding !== 0) { + foundSubsequence(nCommonPreceding, aCommonPreceding, bCommonPreceding); + } + if (nCommonFollowing !== 0) { + foundSubsequence(nCommonFollowing, aCommonFollowing, bCommonFollowing); + } + + // Unless either index interval is empty, they might contain common items. + if (aStartFollowing < aEnd && bStartFollowing < bEnd) { + // Recursely find and return common subsequences following the division. + findSubsequences( + nChangeFollowing, + aStartFollowing, + aEnd, + bStartFollowing, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } +}; +const validateLength = (name, arg) => { + if (typeof arg !== 'number') { + throw new TypeError(`${pkg}: ${name} typeof ${typeof arg} is not a number`); + } + if (!Number.isSafeInteger(arg)) { + throw new RangeError(`${pkg}: ${name} value ${arg} is not a safe integer`); + } + if (arg < 0) { + throw new RangeError(`${pkg}: ${name} value ${arg} is a negative integer`); + } +}; +const validateCallback = (name, arg) => { + const type = typeof arg; + if (type !== 'function') { + throw new TypeError(`${pkg}: ${name} typeof ${type} is not a function`); + } +}; + +// Compare items in two sequences to find a longest common subsequence. +// Given lengths of sequences and input function to compare items at indexes, +// return by output function the number of adjacent items and starting indexes +// of each common subsequence. +function diffSequence(aLength, bLength, isCommon, foundSubsequence) { + validateLength('aLength', aLength); + validateLength('bLength', bLength); + validateCallback('isCommon', isCommon); + validateCallback('foundSubsequence', foundSubsequence); + + // Count common items from the start in the forward direction. + const nCommonF = countCommonItemsF(0, aLength, 0, bLength, isCommon); + if (nCommonF !== 0) { + foundSubsequence(nCommonF, 0, 0); + } + + // Unless both sequences consist of common items only, + // find common items in the half-trimmed index intervals. + if (aLength !== nCommonF || bLength !== nCommonF) { + // Invariant: intervals do not have common items at the start. + // The start of an index interval is closed like array slice method. + const aStart = nCommonF; + const bStart = nCommonF; + + // Count common items from the end in the reverse direction. + const nCommonR = countCommonItemsR( + aStart, + aLength - 1, + bStart, + bLength - 1, + isCommon + ); + + // Invariant: intervals do not have common items at the end. + // The end of an index interval is open like array slice method. + const aEnd = aLength - nCommonR; + const bEnd = bLength - nCommonR; + + // Unless one sequence consists of common items only, + // therefore the other trimmed index interval consists of changes only, + // find common items in the trimmed index intervals. + const nCommonFR = nCommonF + nCommonR; + if (aLength !== nCommonFR && bLength !== nCommonFR) { + const nChange = 0; // number of change items is not yet known + const transposed = false; // call the original unwrapped functions + const callbacks = [ + { + foundSubsequence, + isCommon + } + ]; + + // Indexes in sequence a of last points in furthest reaching paths + // from outside the start at top left in the forward direction: + const aIndexesF = [NOT_YET_SET]; + // from the end at bottom right in the reverse direction: + const aIndexesR = [NOT_YET_SET]; + + // Initialize one object as output of all calls to divide function. + const division = { + aCommonFollowing: NOT_YET_SET, + aCommonPreceding: NOT_YET_SET, + aEndPreceding: NOT_YET_SET, + aStartFollowing: NOT_YET_SET, + bCommonFollowing: NOT_YET_SET, + bCommonPreceding: NOT_YET_SET, + bEndPreceding: NOT_YET_SET, + bStartFollowing: NOT_YET_SET, + nChangeFollowing: NOT_YET_SET, + nChangePreceding: NOT_YET_SET, + nCommonFollowing: NOT_YET_SET, + nCommonPreceding: NOT_YET_SET + }; + + // Find and return common subsequences in the trimmed index intervals. + findSubsequences( + nChange, + aStart, + aEnd, + bStart, + bEnd, + transposed, + callbacks, + aIndexesF, + aIndexesR, + division + ); + } + if (nCommonR !== 0) { + foundSubsequence(nCommonR, aEnd, bEnd); + } + } +} diff --git a/node_modules/diff-sequences/package.json b/node_modules/diff-sequences/package.json new file mode 100644 index 0000000..0324bab --- /dev/null +++ b/node_modules/diff-sequences/package.json @@ -0,0 +1,39 @@ +{ + "name": "diff-sequences", + "version": "29.6.3", + "repository": { + "type": "git", + "url": "https://github.com/jestjs/jest.git", + "directory": "packages/diff-sequences" + }, + "license": "MIT", + "description": "Compare items in two sequences to find a longest common subsequence", + "keywords": [ + "fast", + "linear", + "space", + "callback", + "diff" + ], + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "main": "./build/index.js", + "types": "./build/index.d.ts", + "exports": { + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "@fast-check/jest": "^1.3.0", + "benchmark": "^2.1.4", + "diff": "^5.0.0" + }, + "publishConfig": { + "access": "public" + }, + "gitHead": "fb7d95c8af6e0d65a8b65348433d8a0ea0725b5b" +} diff --git a/node_modules/esbuild/LICENSE.md b/node_modules/esbuild/LICENSE.md new file mode 100644 index 0000000..2027e8d --- /dev/null +++ b/node_modules/esbuild/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Evan Wallace + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/esbuild/README.md b/node_modules/esbuild/README.md new file mode 100644 index 0000000..93863d1 --- /dev/null +++ b/node_modules/esbuild/README.md @@ -0,0 +1,3 @@ +# esbuild + +This is a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details. diff --git a/node_modules/esbuild/bin/esbuild b/node_modules/esbuild/bin/esbuild new file mode 100755 index 0000000..288f768 Binary files /dev/null and b/node_modules/esbuild/bin/esbuild differ diff --git a/node_modules/esbuild/install.js b/node_modules/esbuild/install.js new file mode 100644 index 0000000..d97764e --- /dev/null +++ b/node_modules/esbuild/install.js @@ -0,0 +1,285 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// lib/npm/node-platform.ts +var fs = require("fs"); +var os = require("os"); +var path = require("path"); +var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH; +var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild"; +var knownWindowsPackages = { + "win32 arm64 LE": "@esbuild/win32-arm64", + "win32 ia32 LE": "@esbuild/win32-ia32", + "win32 x64 LE": "@esbuild/win32-x64" +}; +var knownUnixlikePackages = { + "aix ppc64 BE": "@esbuild/aix-ppc64", + "android arm64 LE": "@esbuild/android-arm64", + "darwin arm64 LE": "@esbuild/darwin-arm64", + "darwin x64 LE": "@esbuild/darwin-x64", + "freebsd arm64 LE": "@esbuild/freebsd-arm64", + "freebsd x64 LE": "@esbuild/freebsd-x64", + "linux arm LE": "@esbuild/linux-arm", + "linux arm64 LE": "@esbuild/linux-arm64", + "linux ia32 LE": "@esbuild/linux-ia32", + "linux mips64el LE": "@esbuild/linux-mips64el", + "linux ppc64 LE": "@esbuild/linux-ppc64", + "linux riscv64 LE": "@esbuild/linux-riscv64", + "linux s390x BE": "@esbuild/linux-s390x", + "linux x64 LE": "@esbuild/linux-x64", + "linux loong64 LE": "@esbuild/linux-loong64", + "netbsd x64 LE": "@esbuild/netbsd-x64", + "openbsd x64 LE": "@esbuild/openbsd-x64", + "sunos x64 LE": "@esbuild/sunos-x64" +}; +var knownWebAssemblyFallbackPackages = { + "android arm LE": "@esbuild/android-arm", + "android x64 LE": "@esbuild/android-x64" +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + let isWASM = false; + let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; + if (platformKey in knownWindowsPackages) { + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + } else if (platformKey in knownUnixlikePackages) { + pkg = knownUnixlikePackages[platformKey]; + subpath = "bin/esbuild"; + } else if (platformKey in knownWebAssemblyFallbackPackages) { + pkg = knownWebAssemblyFallbackPackages[platformKey]; + subpath = "bin/esbuild"; + isWASM = true; + } else { + throw new Error(`Unsupported platform: ${platformKey}`); + } + return { pkg, subpath, isWASM }; +} +function downloadedBinPath(pkg, subpath) { + const esbuildLibDir = path.dirname(require.resolve("esbuild")); + return path.join(esbuildLibDir, `downloaded-${pkg.replace("/", "-")}-${path.basename(subpath)}`); +} + +// lib/npm/node-install.ts +var fs2 = require("fs"); +var os2 = require("os"); +var path2 = require("path"); +var zlib = require("zlib"); +var https = require("https"); +var child_process = require("child_process"); +var versionFromPackageJSON = require(path2.join(__dirname, "package.json")).version; +var toPath = path2.join(__dirname, "bin", "esbuild"); +var isToPathJS = true; +function validateBinaryVersion(...command) { + command.push("--version"); + let stdout; + try { + stdout = child_process.execFileSync(command.shift(), command, { + // Without this, this install script strangely crashes with the error + // "EACCES: permission denied, write" but only on Ubuntu Linux when node is + // installed from the Snap Store. This is not a problem when you download + // the official version of node. The problem appears to be that stderr + // (i.e. file descriptor 2) isn't writable? + // + // More info: + // - https://snapcraft.io/ (what the Snap Store is) + // - https://nodejs.org/dist/ (download the official version of node) + // - https://github.com/evanw/esbuild/issues/1711#issuecomment-1027554035 + // + stdio: "pipe" + }).toString().trim(); + } catch (err) { + if (os2.platform() === "darwin" && /_SecTrustEvaluateWithError/.test(err + "")) { + let os3 = "this version of macOS"; + try { + os3 = "macOS " + child_process.execFileSync("sw_vers", ["-productVersion"]).toString().trim(); + } catch { + } + throw new Error(`The "esbuild" package cannot be installed because ${os3} is too outdated. + +The Go compiler (which esbuild relies on) no longer supports ${os3}, +which means the "esbuild" binary executable can't be run. You can either: + + * Update your version of macOS to one that the Go compiler supports + * Use the "esbuild-wasm" package instead of the "esbuild" package + * Build esbuild yourself using an older version of the Go compiler +`); + } + throw err; + } + if (stdout !== versionFromPackageJSON) { + throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`); + } +} +function isYarn() { + const { npm_config_user_agent } = process.env; + if (npm_config_user_agent) { + return /\byarn\//.test(npm_config_user_agent); + } + return false; +} +function fetch(url) { + return new Promise((resolve, reject) => { + https.get(url, (res) => { + if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location) + return fetch(res.headers.location).then(resolve, reject); + if (res.statusCode !== 200) + return reject(new Error(`Server responded with ${res.statusCode}`)); + let chunks = []; + res.on("data", (chunk) => chunks.push(chunk)); + res.on("end", () => resolve(Buffer.concat(chunks))); + }).on("error", reject); + }); +} +function extractFileFromTarGzip(buffer, subpath) { + try { + buffer = zlib.unzipSync(buffer); + } catch (err) { + throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`); + } + let str = (i, n) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\0.*$/, ""); + let offset = 0; + subpath = `package/${subpath}`; + while (offset < buffer.length) { + let name = str(offset, 100); + let size = parseInt(str(offset + 124, 12), 8); + offset += 512; + if (!isNaN(size)) { + if (name === subpath) return buffer.subarray(offset, offset + size); + offset += size + 511 & ~511; + } + } + throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`); +} +function installUsingNPM(pkg, subpath, binPath) { + const env = { ...process.env, npm_config_global: void 0 }; + const esbuildLibDir = path2.dirname(require.resolve("esbuild")); + const installDir = path2.join(esbuildLibDir, "npm-install"); + fs2.mkdirSync(installDir); + try { + fs2.writeFileSync(path2.join(installDir, "package.json"), "{}"); + child_process.execSync( + `npm install --loglevel=error --prefer-offline --no-audit --progress=false ${pkg}@${versionFromPackageJSON}`, + { cwd: installDir, stdio: "pipe", env } + ); + const installedBinPath = path2.join(installDir, "node_modules", pkg, subpath); + fs2.renameSync(installedBinPath, binPath); + } finally { + try { + removeRecursive(installDir); + } catch { + } + } +} +function removeRecursive(dir) { + for (const entry of fs2.readdirSync(dir)) { + const entryPath = path2.join(dir, entry); + let stats; + try { + stats = fs2.lstatSync(entryPath); + } catch { + continue; + } + if (stats.isDirectory()) removeRecursive(entryPath); + else fs2.unlinkSync(entryPath); + } + fs2.rmdirSync(dir); +} +function applyManualBinaryPathOverride(overridePath) { + const pathString = JSON.stringify(overridePath); + fs2.writeFileSync(toPath, `#!/usr/bin/env node +require('child_process').execFileSync(${pathString}, process.argv.slice(2), { stdio: 'inherit' }); +`); + const libMain = path2.join(__dirname, "lib", "main.js"); + const code = fs2.readFileSync(libMain, "utf8"); + fs2.writeFileSync(libMain, `var ESBUILD_BINARY_PATH = ${pathString}; +${code}`); +} +function maybeOptimizePackage(binPath) { + if (os2.platform() !== "win32" && !isYarn()) { + const tempPath = path2.join(__dirname, "bin-esbuild"); + try { + fs2.linkSync(binPath, tempPath); + fs2.renameSync(tempPath, toPath); + isToPathJS = false; + fs2.unlinkSync(tempPath); + } catch { + } + } +} +async function downloadDirectlyFromNPM(pkg, subpath, binPath) { + const url = `https://registry.npmjs.org/${pkg}/-/${pkg.replace("@esbuild/", "")}-${versionFromPackageJSON}.tgz`; + console.error(`[esbuild] Trying to download ${JSON.stringify(url)}`); + try { + fs2.writeFileSync(binPath, extractFileFromTarGzip(await fetch(url), subpath)); + fs2.chmodSync(binPath, 493); + } catch (e) { + console.error(`[esbuild] Failed to download ${JSON.stringify(url)}: ${e && e.message || e}`); + throw e; + } +} +async function checkAndPreparePackage() { + if (isValidBinaryPath(ESBUILD_BINARY_PATH)) { + if (!fs2.existsSync(ESBUILD_BINARY_PATH)) { + console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`); + } else { + applyManualBinaryPathOverride(ESBUILD_BINARY_PATH); + return; + } + } + const { pkg, subpath } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) { + console.error(`[esbuild] Failed to find package "${pkg}" on the file system + +This can happen if you use the "--no-optional" flag. The "optionalDependencies" +package.json feature is used by esbuild to install the correct binary executable +for your current platform. This install script will now attempt to work around +this. If that fails, you need to remove the "--no-optional" flag to use esbuild. +`); + binPath = downloadedBinPath(pkg, subpath); + try { + console.error(`[esbuild] Trying to install package "${pkg}" using npm`); + installUsingNPM(pkg, subpath, binPath); + } catch (e2) { + console.error(`[esbuild] Failed to install package "${pkg}" using npm: ${e2 && e2.message || e2}`); + try { + await downloadDirectlyFromNPM(pkg, subpath, binPath); + } catch (e3) { + throw new Error(`Failed to install package "${pkg}"`); + } + } + } + maybeOptimizePackage(binPath); +} +checkAndPreparePackage().then(() => { + if (isToPathJS) { + validateBinaryVersion(process.execPath, toPath); + } else { + validateBinaryVersion(toPath); + } +}); diff --git a/node_modules/esbuild/lib/main.d.ts b/node_modules/esbuild/lib/main.d.ts new file mode 100644 index 0000000..d5c6ac9 --- /dev/null +++ b/node_modules/esbuild/lib/main.d.ts @@ -0,0 +1,705 @@ +export type Platform = 'browser' | 'node' | 'neutral' +export type Format = 'iife' | 'cjs' | 'esm' +export type Loader = 'base64' | 'binary' | 'copy' | 'css' | 'dataurl' | 'default' | 'empty' | 'file' | 'js' | 'json' | 'jsx' | 'local-css' | 'text' | 'ts' | 'tsx' +export type LogLevel = 'verbose' | 'debug' | 'info' | 'warning' | 'error' | 'silent' +export type Charset = 'ascii' | 'utf8' +export type Drop = 'console' | 'debugger' + +interface CommonOptions { + /** Documentation: https://esbuild.github.io/api/#sourcemap */ + sourcemap?: boolean | 'linked' | 'inline' | 'external' | 'both' + /** Documentation: https://esbuild.github.io/api/#legal-comments */ + legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external' + /** Documentation: https://esbuild.github.io/api/#source-root */ + sourceRoot?: string + /** Documentation: https://esbuild.github.io/api/#sources-content */ + sourcesContent?: boolean + + /** Documentation: https://esbuild.github.io/api/#format */ + format?: Format + /** Documentation: https://esbuild.github.io/api/#global-name */ + globalName?: string + /** Documentation: https://esbuild.github.io/api/#target */ + target?: string | string[] + /** Documentation: https://esbuild.github.io/api/#supported */ + supported?: Record + /** Documentation: https://esbuild.github.io/api/#platform */ + platform?: Platform + + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleProps?: RegExp + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + reserveProps?: RegExp + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleQuoted?: boolean + /** Documentation: https://esbuild.github.io/api/#mangle-props */ + mangleCache?: Record + /** Documentation: https://esbuild.github.io/api/#drop */ + drop?: Drop[] + /** Documentation: https://esbuild.github.io/api/#drop-labels */ + dropLabels?: string[] + /** Documentation: https://esbuild.github.io/api/#minify */ + minify?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifyWhitespace?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifyIdentifiers?: boolean + /** Documentation: https://esbuild.github.io/api/#minify */ + minifySyntax?: boolean + /** Documentation: https://esbuild.github.io/api/#line-limit */ + lineLimit?: number + /** Documentation: https://esbuild.github.io/api/#charset */ + charset?: Charset + /** Documentation: https://esbuild.github.io/api/#tree-shaking */ + treeShaking?: boolean + /** Documentation: https://esbuild.github.io/api/#ignore-annotations */ + ignoreAnnotations?: boolean + + /** Documentation: https://esbuild.github.io/api/#jsx */ + jsx?: 'transform' | 'preserve' | 'automatic' + /** Documentation: https://esbuild.github.io/api/#jsx-factory */ + jsxFactory?: string + /** Documentation: https://esbuild.github.io/api/#jsx-fragment */ + jsxFragment?: string + /** Documentation: https://esbuild.github.io/api/#jsx-import-source */ + jsxImportSource?: string + /** Documentation: https://esbuild.github.io/api/#jsx-development */ + jsxDev?: boolean + /** Documentation: https://esbuild.github.io/api/#jsx-side-effects */ + jsxSideEffects?: boolean + + /** Documentation: https://esbuild.github.io/api/#define */ + define?: { [key: string]: string } + /** Documentation: https://esbuild.github.io/api/#pure */ + pure?: string[] + /** Documentation: https://esbuild.github.io/api/#keep-names */ + keepNames?: boolean + + /** Documentation: https://esbuild.github.io/api/#color */ + color?: boolean + /** Documentation: https://esbuild.github.io/api/#log-level */ + logLevel?: LogLevel + /** Documentation: https://esbuild.github.io/api/#log-limit */ + logLimit?: number + /** Documentation: https://esbuild.github.io/api/#log-override */ + logOverride?: Record + + /** Documentation: https://esbuild.github.io/api/#tsconfig-raw */ + tsconfigRaw?: string | TsconfigRaw +} + +export interface TsconfigRaw { + compilerOptions?: { + alwaysStrict?: boolean + baseUrl?: string + experimentalDecorators?: boolean + importsNotUsedAsValues?: 'remove' | 'preserve' | 'error' + jsx?: 'preserve' | 'react-native' | 'react' | 'react-jsx' | 'react-jsxdev' + jsxFactory?: string + jsxFragmentFactory?: string + jsxImportSource?: string + paths?: Record + preserveValueImports?: boolean + strict?: boolean + target?: string + useDefineForClassFields?: boolean + verbatimModuleSyntax?: boolean + } +} + +export interface BuildOptions extends CommonOptions { + /** Documentation: https://esbuild.github.io/api/#bundle */ + bundle?: boolean + /** Documentation: https://esbuild.github.io/api/#splitting */ + splitting?: boolean + /** Documentation: https://esbuild.github.io/api/#preserve-symlinks */ + preserveSymlinks?: boolean + /** Documentation: https://esbuild.github.io/api/#outfile */ + outfile?: string + /** Documentation: https://esbuild.github.io/api/#metafile */ + metafile?: boolean + /** Documentation: https://esbuild.github.io/api/#outdir */ + outdir?: string + /** Documentation: https://esbuild.github.io/api/#outbase */ + outbase?: string + /** Documentation: https://esbuild.github.io/api/#external */ + external?: string[] + /** Documentation: https://esbuild.github.io/api/#packages */ + packages?: 'external' + /** Documentation: https://esbuild.github.io/api/#alias */ + alias?: Record + /** Documentation: https://esbuild.github.io/api/#loader */ + loader?: { [ext: string]: Loader } + /** Documentation: https://esbuild.github.io/api/#resolve-extensions */ + resolveExtensions?: string[] + /** Documentation: https://esbuild.github.io/api/#main-fields */ + mainFields?: string[] + /** Documentation: https://esbuild.github.io/api/#conditions */ + conditions?: string[] + /** Documentation: https://esbuild.github.io/api/#write */ + write?: boolean + /** Documentation: https://esbuild.github.io/api/#allow-overwrite */ + allowOverwrite?: boolean + /** Documentation: https://esbuild.github.io/api/#tsconfig */ + tsconfig?: string + /** Documentation: https://esbuild.github.io/api/#out-extension */ + outExtension?: { [ext: string]: string } + /** Documentation: https://esbuild.github.io/api/#public-path */ + publicPath?: string + /** Documentation: https://esbuild.github.io/api/#entry-names */ + entryNames?: string + /** Documentation: https://esbuild.github.io/api/#chunk-names */ + chunkNames?: string + /** Documentation: https://esbuild.github.io/api/#asset-names */ + assetNames?: string + /** Documentation: https://esbuild.github.io/api/#inject */ + inject?: string[] + /** Documentation: https://esbuild.github.io/api/#banner */ + banner?: { [type: string]: string } + /** Documentation: https://esbuild.github.io/api/#footer */ + footer?: { [type: string]: string } + /** Documentation: https://esbuild.github.io/api/#entry-points */ + entryPoints?: string[] | Record | { in: string, out: string }[] + /** Documentation: https://esbuild.github.io/api/#stdin */ + stdin?: StdinOptions + /** Documentation: https://esbuild.github.io/plugins/ */ + plugins?: Plugin[] + /** Documentation: https://esbuild.github.io/api/#working-directory */ + absWorkingDir?: string + /** Documentation: https://esbuild.github.io/api/#node-paths */ + nodePaths?: string[]; // The "NODE_PATH" variable from Node.js +} + +export interface StdinOptions { + contents: string | Uint8Array + resolveDir?: string + sourcefile?: string + loader?: Loader +} + +export interface Message { + id: string + pluginName: string + text: string + location: Location | null + notes: Note[] + + /** + * Optional user-specified data that is passed through unmodified. You can + * use this to stash the original error, for example. + */ + detail: any +} + +export interface Note { + text: string + location: Location | null +} + +export interface Location { + file: string + namespace: string + /** 1-based */ + line: number + /** 0-based, in bytes */ + column: number + /** in bytes */ + length: number + lineText: string + suggestion: string +} + +export interface OutputFile { + path: string + contents: Uint8Array + hash: string + /** "contents" as text (changes automatically with "contents") */ + readonly text: string +} + +export interface BuildResult { + errors: Message[] + warnings: Message[] + /** Only when "write: false" */ + outputFiles: OutputFile[] | (ProvidedOptions['write'] extends false ? never : undefined) + /** Only when "metafile: true" */ + metafile: Metafile | (ProvidedOptions['metafile'] extends true ? never : undefined) + /** Only when "mangleCache" is present */ + mangleCache: Record | (ProvidedOptions['mangleCache'] extends Object ? never : undefined) +} + +export interface BuildFailure extends Error { + errors: Message[] + warnings: Message[] +} + +/** Documentation: https://esbuild.github.io/api/#serve-arguments */ +export interface ServeOptions { + port?: number + host?: string + servedir?: string + keyfile?: string + certfile?: string + fallback?: string + onRequest?: (args: ServeOnRequestArgs) => void +} + +export interface ServeOnRequestArgs { + remoteAddress: string + method: string + path: string + status: number + /** The time to generate the response, not to send it */ + timeInMS: number +} + +/** Documentation: https://esbuild.github.io/api/#serve-return-values */ +export interface ServeResult { + port: number + host: string +} + +export interface TransformOptions extends CommonOptions { + /** Documentation: https://esbuild.github.io/api/#sourcefile */ + sourcefile?: string + /** Documentation: https://esbuild.github.io/api/#loader */ + loader?: Loader + /** Documentation: https://esbuild.github.io/api/#banner */ + banner?: string + /** Documentation: https://esbuild.github.io/api/#footer */ + footer?: string +} + +export interface TransformResult { + code: string + map: string + warnings: Message[] + /** Only when "mangleCache" is present */ + mangleCache: Record | (ProvidedOptions['mangleCache'] extends Object ? never : undefined) + /** Only when "legalComments" is "external" */ + legalComments: string | (ProvidedOptions['legalComments'] extends 'external' ? never : undefined) +} + +export interface TransformFailure extends Error { + errors: Message[] + warnings: Message[] +} + +export interface Plugin { + name: string + setup: (build: PluginBuild) => (void | Promise) +} + +export interface PluginBuild { + /** Documentation: https://esbuild.github.io/plugins/#build-options */ + initialOptions: BuildOptions + + /** Documentation: https://esbuild.github.io/plugins/#resolve */ + resolve(path: string, options?: ResolveOptions): Promise + + /** Documentation: https://esbuild.github.io/plugins/#on-start */ + onStart(callback: () => + (OnStartResult | null | void | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-end */ + onEnd(callback: (result: BuildResult) => + (OnEndResult | null | void | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-resolve */ + onResolve(options: OnResolveOptions, callback: (args: OnResolveArgs) => + (OnResolveResult | null | undefined | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-load */ + onLoad(options: OnLoadOptions, callback: (args: OnLoadArgs) => + (OnLoadResult | null | undefined | Promise)): void + + /** Documentation: https://esbuild.github.io/plugins/#on-dispose */ + onDispose(callback: () => void): void + + // This is a full copy of the esbuild library in case you need it + esbuild: { + context: typeof context, + build: typeof build, + buildSync: typeof buildSync, + transform: typeof transform, + transformSync: typeof transformSync, + formatMessages: typeof formatMessages, + formatMessagesSync: typeof formatMessagesSync, + analyzeMetafile: typeof analyzeMetafile, + analyzeMetafileSync: typeof analyzeMetafileSync, + initialize: typeof initialize, + version: typeof version, + } +} + +/** Documentation: https://esbuild.github.io/plugins/#resolve-options */ +export interface ResolveOptions { + pluginName?: string + importer?: string + namespace?: string + resolveDir?: string + kind?: ImportKind + pluginData?: any + with?: Record +} + +/** Documentation: https://esbuild.github.io/plugins/#resolve-results */ +export interface ResolveResult { + errors: Message[] + warnings: Message[] + + path: string + external: boolean + sideEffects: boolean + namespace: string + suffix: string + pluginData: any +} + +export interface OnStartResult { + errors?: PartialMessage[] + warnings?: PartialMessage[] +} + +export interface OnEndResult { + errors?: PartialMessage[] + warnings?: PartialMessage[] +} + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-options */ +export interface OnResolveOptions { + filter: RegExp + namespace?: string +} + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-arguments */ +export interface OnResolveArgs { + path: string + importer: string + namespace: string + resolveDir: string + kind: ImportKind + pluginData: any + with: Record +} + +export type ImportKind = + | 'entry-point' + + // JS + | 'import-statement' + | 'require-call' + | 'dynamic-import' + | 'require-resolve' + + // CSS + | 'import-rule' + | 'composes-from' + | 'url-token' + +/** Documentation: https://esbuild.github.io/plugins/#on-resolve-results */ +export interface OnResolveResult { + pluginName?: string + + errors?: PartialMessage[] + warnings?: PartialMessage[] + + path?: string + external?: boolean + sideEffects?: boolean + namespace?: string + suffix?: string + pluginData?: any + + watchFiles?: string[] + watchDirs?: string[] +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-options */ +export interface OnLoadOptions { + filter: RegExp + namespace?: string +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-arguments */ +export interface OnLoadArgs { + path: string + namespace: string + suffix: string + pluginData: any + with: Record +} + +/** Documentation: https://esbuild.github.io/plugins/#on-load-results */ +export interface OnLoadResult { + pluginName?: string + + errors?: PartialMessage[] + warnings?: PartialMessage[] + + contents?: string | Uint8Array + resolveDir?: string + loader?: Loader + pluginData?: any + + watchFiles?: string[] + watchDirs?: string[] +} + +export interface PartialMessage { + id?: string + pluginName?: string + text?: string + location?: Partial | null + notes?: PartialNote[] + detail?: any +} + +export interface PartialNote { + text?: string + location?: Partial | null +} + +/** Documentation: https://esbuild.github.io/api/#metafile */ +export interface Metafile { + inputs: { + [path: string]: { + bytes: number + imports: { + path: string + kind: ImportKind + external?: boolean + original?: string + with?: Record + }[] + format?: 'cjs' | 'esm' + with?: Record + } + } + outputs: { + [path: string]: { + bytes: number + inputs: { + [path: string]: { + bytesInOutput: number + } + } + imports: { + path: string + kind: ImportKind | 'file-loader' + external?: boolean + }[] + exports: string[] + entryPoint?: string + cssBundle?: string + } + } +} + +export interface FormatMessagesOptions { + kind: 'error' | 'warning' + color?: boolean + terminalWidth?: number +} + +export interface AnalyzeMetafileOptions { + color?: boolean + verbose?: boolean +} + +export interface WatchOptions { +} + +export interface BuildContext { + /** Documentation: https://esbuild.github.io/api/#rebuild */ + rebuild(): Promise> + + /** Documentation: https://esbuild.github.io/api/#watch */ + watch(options?: WatchOptions): Promise + + /** Documentation: https://esbuild.github.io/api/#serve */ + serve(options?: ServeOptions): Promise + + cancel(): Promise + dispose(): Promise +} + +// This is a TypeScript type-level function which replaces any keys in "In" +// that aren't in "Out" with "never". We use this to reject properties with +// typos in object literals. See: https://stackoverflow.com/questions/49580725 +type SameShape = In & { [Key in Exclude]: never } + +/** + * This function invokes the "esbuild" command-line tool for you. It returns a + * promise that either resolves with a "BuildResult" object or rejects with a + * "BuildFailure" object. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function build(options: SameShape): Promise> + +/** + * This is the advanced long-running form of "build" that supports additional + * features such as watch mode and a local development server. + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function context(options: SameShape): Promise> + +/** + * This function transforms a single JavaScript file. It can be used to minify + * JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript + * to older JavaScript. It returns a promise that is either resolved with a + * "TransformResult" object or rejected with a "TransformFailure" object. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#transform + */ +export declare function transform(input: string | Uint8Array, options?: SameShape): Promise> + +/** + * Converts log messages to formatted message strings suitable for printing in + * the terminal. This allows you to reuse the built-in behavior of esbuild's + * log message formatter. This is a batch-oriented API for efficiency. + * + * - Works in node: yes + * - Works in browser: yes + */ +export declare function formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise + +/** + * Pretty-prints an analysis of the metafile JSON to a string. This is just for + * convenience to be able to match esbuild's pretty-printing exactly. If you want + * to customize it, you can just inspect the data in the metafile yourself. + * + * - Works in node: yes + * - Works in browser: yes + * + * Documentation: https://esbuild.github.io/api/#analyze + */ +export declare function analyzeMetafile(metafile: Metafile | string, options?: AnalyzeMetafileOptions): Promise + +/** + * A synchronous version of "build". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#build + */ +export declare function buildSync(options: SameShape): BuildResult + +/** + * A synchronous version of "transform". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#transform + */ +export declare function transformSync(input: string | Uint8Array, options?: SameShape): TransformResult + +/** + * A synchronous version of "formatMessages". + * + * - Works in node: yes + * - Works in browser: no + */ +export declare function formatMessagesSync(messages: PartialMessage[], options: FormatMessagesOptions): string[] + +/** + * A synchronous version of "analyzeMetafile". + * + * - Works in node: yes + * - Works in browser: no + * + * Documentation: https://esbuild.github.io/api/#analyze + */ +export declare function analyzeMetafileSync(metafile: Metafile | string, options?: AnalyzeMetafileOptions): string + +/** + * This configures the browser-based version of esbuild. It is necessary to + * call this first and wait for the returned promise to be resolved before + * making other API calls when using esbuild in the browser. + * + * - Works in node: yes + * - Works in browser: yes ("options" is required) + * + * Documentation: https://esbuild.github.io/api/#browser + */ +export declare function initialize(options: InitializeOptions): Promise + +export interface InitializeOptions { + /** + * The URL of the "esbuild.wasm" file. This must be provided when running + * esbuild in the browser. + */ + wasmURL?: string | URL + + /** + * The result of calling "new WebAssembly.Module(buffer)" where "buffer" + * is a typed array or ArrayBuffer containing the binary code of the + * "esbuild.wasm" file. + * + * You can use this as an alternative to "wasmURL" for environments where it's + * not possible to download the WebAssembly module. + */ + wasmModule?: WebAssembly.Module + + /** + * By default esbuild runs the WebAssembly-based browser API in a web worker + * to avoid blocking the UI thread. This can be disabled by setting "worker" + * to false. + */ + worker?: boolean +} + +export let version: string + +// Call this function to terminate esbuild's child process. The child process +// is not terminated and re-created after each API call because it's more +// efficient to keep it around when there are multiple API calls. +// +// In node this happens automatically before the parent node process exits. So +// you only need to call this if you know you will not make any more esbuild +// API calls and you want to clean up resources. +// +// Unlike node, Deno lacks the necessary APIs to clean up child processes +// automatically. You must manually call stop() in Deno when you're done +// using esbuild or Deno will continue running forever. +// +// Another reason you might want to call this is if you are using esbuild from +// within a Deno test. Deno fails tests that create a child process without +// killing it before the test ends, so you have to call this function (and +// await the returned promise) in every Deno test that uses esbuild. +export declare function stop(): Promise + +// Note: These declarations exist to avoid type errors when you omit "dom" from +// "lib" in your "tsconfig.json" file. TypeScript confusingly declares the +// global "WebAssembly" type in "lib.dom.d.ts" even though it has nothing to do +// with the browser DOM and is present in many non-browser JavaScript runtimes +// (e.g. node and deno). Declaring it here allows esbuild's API to be used in +// these scenarios. +// +// There's an open issue about getting this problem corrected (although these +// declarations will need to remain even if this is fixed for backward +// compatibility with older TypeScript versions): +// +// https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/826 +// +declare global { + namespace WebAssembly { + interface Module { + } + } + interface URL { + } +} diff --git a/node_modules/esbuild/lib/main.js b/node_modules/esbuild/lib/main.js new file mode 100644 index 0000000..555613c --- /dev/null +++ b/node_modules/esbuild/lib/main.js @@ -0,0 +1,2239 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// lib/npm/node.ts +var node_exports = {}; +__export(node_exports, { + analyzeMetafile: () => analyzeMetafile, + analyzeMetafileSync: () => analyzeMetafileSync, + build: () => build, + buildSync: () => buildSync, + context: () => context, + default: () => node_default, + formatMessages: () => formatMessages, + formatMessagesSync: () => formatMessagesSync, + initialize: () => initialize, + stop: () => stop, + transform: () => transform, + transformSync: () => transformSync, + version: () => version +}); +module.exports = __toCommonJS(node_exports); + +// lib/shared/stdio_protocol.ts +function encodePacket(packet) { + let visit = (value) => { + if (value === null) { + bb.write8(0); + } else if (typeof value === "boolean") { + bb.write8(1); + bb.write8(+value); + } else if (typeof value === "number") { + bb.write8(2); + bb.write32(value | 0); + } else if (typeof value === "string") { + bb.write8(3); + bb.write(encodeUTF8(value)); + } else if (value instanceof Uint8Array) { + bb.write8(4); + bb.write(value); + } else if (value instanceof Array) { + bb.write8(5); + bb.write32(value.length); + for (let item of value) { + visit(item); + } + } else { + let keys = Object.keys(value); + bb.write8(6); + bb.write32(keys.length); + for (let key of keys) { + bb.write(encodeUTF8(key)); + visit(value[key]); + } + } + }; + let bb = new ByteBuffer(); + bb.write32(0); + bb.write32(packet.id << 1 | +!packet.isRequest); + visit(packet.value); + writeUInt32LE(bb.buf, bb.len - 4, 0); + return bb.buf.subarray(0, bb.len); +} +function decodePacket(bytes) { + let visit = () => { + switch (bb.read8()) { + case 0: + return null; + case 1: + return !!bb.read8(); + case 2: + return bb.read32(); + case 3: + return decodeUTF8(bb.read()); + case 4: + return bb.read(); + case 5: { + let count = bb.read32(); + let value2 = []; + for (let i = 0; i < count; i++) { + value2.push(visit()); + } + return value2; + } + case 6: { + let count = bb.read32(); + let value2 = {}; + for (let i = 0; i < count; i++) { + value2[decodeUTF8(bb.read())] = visit(); + } + return value2; + } + default: + throw new Error("Invalid packet"); + } + }; + let bb = new ByteBuffer(bytes); + let id = bb.read32(); + let isRequest = (id & 1) === 0; + id >>>= 1; + let value = visit(); + if (bb.ptr !== bytes.length) { + throw new Error("Invalid packet"); + } + return { id, isRequest, value }; +} +var ByteBuffer = class { + constructor(buf = new Uint8Array(1024)) { + this.buf = buf; + this.len = 0; + this.ptr = 0; + } + _write(delta) { + if (this.len + delta > this.buf.length) { + let clone = new Uint8Array((this.len + delta) * 2); + clone.set(this.buf); + this.buf = clone; + } + this.len += delta; + return this.len - delta; + } + write8(value) { + let offset = this._write(1); + this.buf[offset] = value; + } + write32(value) { + let offset = this._write(4); + writeUInt32LE(this.buf, value, offset); + } + write(bytes) { + let offset = this._write(4 + bytes.length); + writeUInt32LE(this.buf, bytes.length, offset); + this.buf.set(bytes, offset + 4); + } + _read(delta) { + if (this.ptr + delta > this.buf.length) { + throw new Error("Invalid packet"); + } + this.ptr += delta; + return this.ptr - delta; + } + read8() { + return this.buf[this._read(1)]; + } + read32() { + return readUInt32LE(this.buf, this._read(4)); + } + read() { + let length = this.read32(); + let bytes = new Uint8Array(length); + let ptr = this._read(bytes.length); + bytes.set(this.buf.subarray(ptr, ptr + length)); + return bytes; + } +}; +var encodeUTF8; +var decodeUTF8; +var encodeInvariant; +if (typeof TextEncoder !== "undefined" && typeof TextDecoder !== "undefined") { + let encoder = new TextEncoder(); + let decoder = new TextDecoder(); + encodeUTF8 = (text) => encoder.encode(text); + decodeUTF8 = (bytes) => decoder.decode(bytes); + encodeInvariant = 'new TextEncoder().encode("")'; +} else if (typeof Buffer !== "undefined") { + encodeUTF8 = (text) => Buffer.from(text); + decodeUTF8 = (bytes) => { + let { buffer, byteOffset, byteLength } = bytes; + return Buffer.from(buffer, byteOffset, byteLength).toString(); + }; + encodeInvariant = 'Buffer.from("")'; +} else { + throw new Error("No UTF-8 codec found"); +} +if (!(encodeUTF8("") instanceof Uint8Array)) + throw new Error(`Invariant violation: "${encodeInvariant} instanceof Uint8Array" is incorrectly false + +This indicates that your JavaScript environment is broken. You cannot use +esbuild in this environment because esbuild relies on this invariant. This +is not a problem with esbuild. You need to fix your environment instead. +`); +function readUInt32LE(buffer, offset) { + return buffer[offset++] | buffer[offset++] << 8 | buffer[offset++] << 16 | buffer[offset++] << 24; +} +function writeUInt32LE(buffer, value, offset) { + buffer[offset++] = value; + buffer[offset++] = value >> 8; + buffer[offset++] = value >> 16; + buffer[offset++] = value >> 24; +} + +// lib/shared/common.ts +var quote = JSON.stringify; +var buildLogLevelDefault = "warning"; +var transformLogLevelDefault = "silent"; +function validateTarget(target) { + validateStringValue(target, "target"); + if (target.indexOf(",") >= 0) throw new Error(`Invalid target: ${target}`); + return target; +} +var canBeAnything = () => null; +var mustBeBoolean = (value) => typeof value === "boolean" ? null : "a boolean"; +var mustBeString = (value) => typeof value === "string" ? null : "a string"; +var mustBeRegExp = (value) => value instanceof RegExp ? null : "a RegExp object"; +var mustBeInteger = (value) => typeof value === "number" && value === (value | 0) ? null : "an integer"; +var mustBeFunction = (value) => typeof value === "function" ? null : "a function"; +var mustBeArray = (value) => Array.isArray(value) ? null : "an array"; +var mustBeObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? null : "an object"; +var mustBeEntryPoints = (value) => typeof value === "object" && value !== null ? null : "an array or an object"; +var mustBeWebAssemblyModule = (value) => value instanceof WebAssembly.Module ? null : "a WebAssembly.Module"; +var mustBeObjectOrNull = (value) => typeof value === "object" && !Array.isArray(value) ? null : "an object or null"; +var mustBeStringOrBoolean = (value) => typeof value === "string" || typeof value === "boolean" ? null : "a string or a boolean"; +var mustBeStringOrObject = (value) => typeof value === "string" || typeof value === "object" && value !== null && !Array.isArray(value) ? null : "a string or an object"; +var mustBeStringOrArray = (value) => typeof value === "string" || Array.isArray(value) ? null : "a string or an array"; +var mustBeStringOrUint8Array = (value) => typeof value === "string" || value instanceof Uint8Array ? null : "a string or a Uint8Array"; +var mustBeStringOrURL = (value) => typeof value === "string" || value instanceof URL ? null : "a string or a URL"; +function getFlag(object, keys, key, mustBeFn) { + let value = object[key]; + keys[key + ""] = true; + if (value === void 0) return void 0; + let mustBe = mustBeFn(value); + if (mustBe !== null) throw new Error(`${quote(key)} must be ${mustBe}`); + return value; +} +function checkForInvalidFlags(object, keys, where) { + for (let key in object) { + if (!(key in keys)) { + throw new Error(`Invalid option ${where}: ${quote(key)}`); + } + } +} +function validateInitializeOptions(options) { + let keys = /* @__PURE__ */ Object.create(null); + let wasmURL = getFlag(options, keys, "wasmURL", mustBeStringOrURL); + let wasmModule = getFlag(options, keys, "wasmModule", mustBeWebAssemblyModule); + let worker = getFlag(options, keys, "worker", mustBeBoolean); + checkForInvalidFlags(options, keys, "in initialize() call"); + return { + wasmURL, + wasmModule, + worker + }; +} +function validateMangleCache(mangleCache) { + let validated; + if (mangleCache !== void 0) { + validated = /* @__PURE__ */ Object.create(null); + for (let key in mangleCache) { + let value = mangleCache[key]; + if (typeof value === "string" || value === false) { + validated[key] = value; + } else { + throw new Error(`Expected ${quote(key)} in mangle cache to map to either a string or false`); + } + } + } + return validated; +} +function pushLogFlags(flags, options, keys, isTTY2, logLevelDefault) { + let color = getFlag(options, keys, "color", mustBeBoolean); + let logLevel = getFlag(options, keys, "logLevel", mustBeString); + let logLimit = getFlag(options, keys, "logLimit", mustBeInteger); + if (color !== void 0) flags.push(`--color=${color}`); + else if (isTTY2) flags.push(`--color=true`); + flags.push(`--log-level=${logLevel || logLevelDefault}`); + flags.push(`--log-limit=${logLimit || 0}`); +} +function validateStringValue(value, what, key) { + if (typeof value !== "string") { + throw new Error(`Expected value for ${what}${key !== void 0 ? " " + quote(key) : ""} to be a string, got ${typeof value} instead`); + } + return value; +} +function pushCommonFlags(flags, options, keys) { + let legalComments = getFlag(options, keys, "legalComments", mustBeString); + let sourceRoot = getFlag(options, keys, "sourceRoot", mustBeString); + let sourcesContent = getFlag(options, keys, "sourcesContent", mustBeBoolean); + let target = getFlag(options, keys, "target", mustBeStringOrArray); + let format = getFlag(options, keys, "format", mustBeString); + let globalName = getFlag(options, keys, "globalName", mustBeString); + let mangleProps = getFlag(options, keys, "mangleProps", mustBeRegExp); + let reserveProps = getFlag(options, keys, "reserveProps", mustBeRegExp); + let mangleQuoted = getFlag(options, keys, "mangleQuoted", mustBeBoolean); + let minify = getFlag(options, keys, "minify", mustBeBoolean); + let minifySyntax = getFlag(options, keys, "minifySyntax", mustBeBoolean); + let minifyWhitespace = getFlag(options, keys, "minifyWhitespace", mustBeBoolean); + let minifyIdentifiers = getFlag(options, keys, "minifyIdentifiers", mustBeBoolean); + let lineLimit = getFlag(options, keys, "lineLimit", mustBeInteger); + let drop = getFlag(options, keys, "drop", mustBeArray); + let dropLabels = getFlag(options, keys, "dropLabels", mustBeArray); + let charset = getFlag(options, keys, "charset", mustBeString); + let treeShaking = getFlag(options, keys, "treeShaking", mustBeBoolean); + let ignoreAnnotations = getFlag(options, keys, "ignoreAnnotations", mustBeBoolean); + let jsx = getFlag(options, keys, "jsx", mustBeString); + let jsxFactory = getFlag(options, keys, "jsxFactory", mustBeString); + let jsxFragment = getFlag(options, keys, "jsxFragment", mustBeString); + let jsxImportSource = getFlag(options, keys, "jsxImportSource", mustBeString); + let jsxDev = getFlag(options, keys, "jsxDev", mustBeBoolean); + let jsxSideEffects = getFlag(options, keys, "jsxSideEffects", mustBeBoolean); + let define = getFlag(options, keys, "define", mustBeObject); + let logOverride = getFlag(options, keys, "logOverride", mustBeObject); + let supported = getFlag(options, keys, "supported", mustBeObject); + let pure = getFlag(options, keys, "pure", mustBeArray); + let keepNames = getFlag(options, keys, "keepNames", mustBeBoolean); + let platform = getFlag(options, keys, "platform", mustBeString); + let tsconfigRaw = getFlag(options, keys, "tsconfigRaw", mustBeStringOrObject); + if (legalComments) flags.push(`--legal-comments=${legalComments}`); + if (sourceRoot !== void 0) flags.push(`--source-root=${sourceRoot}`); + if (sourcesContent !== void 0) flags.push(`--sources-content=${sourcesContent}`); + if (target) { + if (Array.isArray(target)) flags.push(`--target=${Array.from(target).map(validateTarget).join(",")}`); + else flags.push(`--target=${validateTarget(target)}`); + } + if (format) flags.push(`--format=${format}`); + if (globalName) flags.push(`--global-name=${globalName}`); + if (platform) flags.push(`--platform=${platform}`); + if (tsconfigRaw) flags.push(`--tsconfig-raw=${typeof tsconfigRaw === "string" ? tsconfigRaw : JSON.stringify(tsconfigRaw)}`); + if (minify) flags.push("--minify"); + if (minifySyntax) flags.push("--minify-syntax"); + if (minifyWhitespace) flags.push("--minify-whitespace"); + if (minifyIdentifiers) flags.push("--minify-identifiers"); + if (lineLimit) flags.push(`--line-limit=${lineLimit}`); + if (charset) flags.push(`--charset=${charset}`); + if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`); + if (ignoreAnnotations) flags.push(`--ignore-annotations`); + if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, "drop")}`); + if (dropLabels) flags.push(`--drop-labels=${Array.from(dropLabels).map((what) => validateStringValue(what, "dropLabels")).join(",")}`); + if (mangleProps) flags.push(`--mangle-props=${mangleProps.source}`); + if (reserveProps) flags.push(`--reserve-props=${reserveProps.source}`); + if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`); + if (jsx) flags.push(`--jsx=${jsx}`); + if (jsxFactory) flags.push(`--jsx-factory=${jsxFactory}`); + if (jsxFragment) flags.push(`--jsx-fragment=${jsxFragment}`); + if (jsxImportSource) flags.push(`--jsx-import-source=${jsxImportSource}`); + if (jsxDev) flags.push(`--jsx-dev`); + if (jsxSideEffects) flags.push(`--jsx-side-effects`); + if (define) { + for (let key in define) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid define: ${key}`); + flags.push(`--define:${key}=${validateStringValue(define[key], "define", key)}`); + } + } + if (logOverride) { + for (let key in logOverride) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid log override: ${key}`); + flags.push(`--log-override:${key}=${validateStringValue(logOverride[key], "log override", key)}`); + } + } + if (supported) { + for (let key in supported) { + if (key.indexOf("=") >= 0) throw new Error(`Invalid supported: ${key}`); + const value = supported[key]; + if (typeof value !== "boolean") throw new Error(`Expected value for supported ${quote(key)} to be a boolean, got ${typeof value} instead`); + flags.push(`--supported:${key}=${value}`); + } + } + if (pure) for (let fn of pure) flags.push(`--pure:${validateStringValue(fn, "pure")}`); + if (keepNames) flags.push(`--keep-names`); +} +function flagsForBuildOptions(callName, options, isTTY2, logLevelDefault, writeDefault) { + var _a2; + let flags = []; + let entries = []; + let keys = /* @__PURE__ */ Object.create(null); + let stdinContents = null; + let stdinResolveDir = null; + pushLogFlags(flags, options, keys, isTTY2, logLevelDefault); + pushCommonFlags(flags, options, keys); + let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean); + let bundle = getFlag(options, keys, "bundle", mustBeBoolean); + let splitting = getFlag(options, keys, "splitting", mustBeBoolean); + let preserveSymlinks = getFlag(options, keys, "preserveSymlinks", mustBeBoolean); + let metafile = getFlag(options, keys, "metafile", mustBeBoolean); + let outfile = getFlag(options, keys, "outfile", mustBeString); + let outdir = getFlag(options, keys, "outdir", mustBeString); + let outbase = getFlag(options, keys, "outbase", mustBeString); + let tsconfig = getFlag(options, keys, "tsconfig", mustBeString); + let resolveExtensions = getFlag(options, keys, "resolveExtensions", mustBeArray); + let nodePathsInput = getFlag(options, keys, "nodePaths", mustBeArray); + let mainFields = getFlag(options, keys, "mainFields", mustBeArray); + let conditions = getFlag(options, keys, "conditions", mustBeArray); + let external = getFlag(options, keys, "external", mustBeArray); + let packages = getFlag(options, keys, "packages", mustBeString); + let alias = getFlag(options, keys, "alias", mustBeObject); + let loader = getFlag(options, keys, "loader", mustBeObject); + let outExtension = getFlag(options, keys, "outExtension", mustBeObject); + let publicPath = getFlag(options, keys, "publicPath", mustBeString); + let entryNames = getFlag(options, keys, "entryNames", mustBeString); + let chunkNames = getFlag(options, keys, "chunkNames", mustBeString); + let assetNames = getFlag(options, keys, "assetNames", mustBeString); + let inject = getFlag(options, keys, "inject", mustBeArray); + let banner = getFlag(options, keys, "banner", mustBeObject); + let footer = getFlag(options, keys, "footer", mustBeObject); + let entryPoints = getFlag(options, keys, "entryPoints", mustBeEntryPoints); + let absWorkingDir = getFlag(options, keys, "absWorkingDir", mustBeString); + let stdin = getFlag(options, keys, "stdin", mustBeObject); + let write = (_a2 = getFlag(options, keys, "write", mustBeBoolean)) != null ? _a2 : writeDefault; + let allowOverwrite = getFlag(options, keys, "allowOverwrite", mustBeBoolean); + let mangleCache = getFlag(options, keys, "mangleCache", mustBeObject); + keys.plugins = true; + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (sourcemap) flags.push(`--sourcemap${sourcemap === true ? "" : `=${sourcemap}`}`); + if (bundle) flags.push("--bundle"); + if (allowOverwrite) flags.push("--allow-overwrite"); + if (splitting) flags.push("--splitting"); + if (preserveSymlinks) flags.push("--preserve-symlinks"); + if (metafile) flags.push(`--metafile`); + if (outfile) flags.push(`--outfile=${outfile}`); + if (outdir) flags.push(`--outdir=${outdir}`); + if (outbase) flags.push(`--outbase=${outbase}`); + if (tsconfig) flags.push(`--tsconfig=${tsconfig}`); + if (packages) flags.push(`--packages=${packages}`); + if (resolveExtensions) { + let values = []; + for (let value of resolveExtensions) { + validateStringValue(value, "resolve extension"); + if (value.indexOf(",") >= 0) throw new Error(`Invalid resolve extension: ${value}`); + values.push(value); + } + flags.push(`--resolve-extensions=${values.join(",")}`); + } + if (publicPath) flags.push(`--public-path=${publicPath}`); + if (entryNames) flags.push(`--entry-names=${entryNames}`); + if (chunkNames) flags.push(`--chunk-names=${chunkNames}`); + if (assetNames) flags.push(`--asset-names=${assetNames}`); + if (mainFields) { + let values = []; + for (let value of mainFields) { + validateStringValue(value, "main field"); + if (value.indexOf(",") >= 0) throw new Error(`Invalid main field: ${value}`); + values.push(value); + } + flags.push(`--main-fields=${values.join(",")}`); + } + if (conditions) { + let values = []; + for (let value of conditions) { + validateStringValue(value, "condition"); + if (value.indexOf(",") >= 0) throw new Error(`Invalid condition: ${value}`); + values.push(value); + } + flags.push(`--conditions=${values.join(",")}`); + } + if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, "external")}`); + if (alias) { + for (let old in alias) { + if (old.indexOf("=") >= 0) throw new Error(`Invalid package name in alias: ${old}`); + flags.push(`--alias:${old}=${validateStringValue(alias[old], "alias", old)}`); + } + } + if (banner) { + for (let type in banner) { + if (type.indexOf("=") >= 0) throw new Error(`Invalid banner file type: ${type}`); + flags.push(`--banner:${type}=${validateStringValue(banner[type], "banner", type)}`); + } + } + if (footer) { + for (let type in footer) { + if (type.indexOf("=") >= 0) throw new Error(`Invalid footer file type: ${type}`); + flags.push(`--footer:${type}=${validateStringValue(footer[type], "footer", type)}`); + } + } + if (inject) for (let path3 of inject) flags.push(`--inject:${validateStringValue(path3, "inject")}`); + if (loader) { + for (let ext in loader) { + if (ext.indexOf("=") >= 0) throw new Error(`Invalid loader extension: ${ext}`); + flags.push(`--loader:${ext}=${validateStringValue(loader[ext], "loader", ext)}`); + } + } + if (outExtension) { + for (let ext in outExtension) { + if (ext.indexOf("=") >= 0) throw new Error(`Invalid out extension: ${ext}`); + flags.push(`--out-extension:${ext}=${validateStringValue(outExtension[ext], "out extension", ext)}`); + } + } + if (entryPoints) { + if (Array.isArray(entryPoints)) { + for (let i = 0, n = entryPoints.length; i < n; i++) { + let entryPoint = entryPoints[i]; + if (typeof entryPoint === "object" && entryPoint !== null) { + let entryPointKeys = /* @__PURE__ */ Object.create(null); + let input = getFlag(entryPoint, entryPointKeys, "in", mustBeString); + let output = getFlag(entryPoint, entryPointKeys, "out", mustBeString); + checkForInvalidFlags(entryPoint, entryPointKeys, "in entry point at index " + i); + if (input === void 0) throw new Error('Missing property "in" for entry point at index ' + i); + if (output === void 0) throw new Error('Missing property "out" for entry point at index ' + i); + entries.push([output, input]); + } else { + entries.push(["", validateStringValue(entryPoint, "entry point at index " + i)]); + } + } + } else { + for (let key in entryPoints) { + entries.push([key, validateStringValue(entryPoints[key], "entry point", key)]); + } + } + } + if (stdin) { + let stdinKeys = /* @__PURE__ */ Object.create(null); + let contents = getFlag(stdin, stdinKeys, "contents", mustBeStringOrUint8Array); + let resolveDir = getFlag(stdin, stdinKeys, "resolveDir", mustBeString); + let sourcefile = getFlag(stdin, stdinKeys, "sourcefile", mustBeString); + let loader2 = getFlag(stdin, stdinKeys, "loader", mustBeString); + checkForInvalidFlags(stdin, stdinKeys, 'in "stdin" object'); + if (sourcefile) flags.push(`--sourcefile=${sourcefile}`); + if (loader2) flags.push(`--loader=${loader2}`); + if (resolveDir) stdinResolveDir = resolveDir; + if (typeof contents === "string") stdinContents = encodeUTF8(contents); + else if (contents instanceof Uint8Array) stdinContents = contents; + } + let nodePaths = []; + if (nodePathsInput) { + for (let value of nodePathsInput) { + value += ""; + nodePaths.push(value); + } + } + return { + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir, + nodePaths, + mangleCache: validateMangleCache(mangleCache) + }; +} +function flagsForTransformOptions(callName, options, isTTY2, logLevelDefault) { + let flags = []; + let keys = /* @__PURE__ */ Object.create(null); + pushLogFlags(flags, options, keys, isTTY2, logLevelDefault); + pushCommonFlags(flags, options, keys); + let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean); + let sourcefile = getFlag(options, keys, "sourcefile", mustBeString); + let loader = getFlag(options, keys, "loader", mustBeString); + let banner = getFlag(options, keys, "banner", mustBeString); + let footer = getFlag(options, keys, "footer", mustBeString); + let mangleCache = getFlag(options, keys, "mangleCache", mustBeObject); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (sourcemap) flags.push(`--sourcemap=${sourcemap === true ? "external" : sourcemap}`); + if (sourcefile) flags.push(`--sourcefile=${sourcefile}`); + if (loader) flags.push(`--loader=${loader}`); + if (banner) flags.push(`--banner=${banner}`); + if (footer) flags.push(`--footer=${footer}`); + return { + flags, + mangleCache: validateMangleCache(mangleCache) + }; +} +function createChannel(streamIn) { + const requestCallbacksByKey = {}; + const closeData = { didClose: false, reason: "" }; + let responseCallbacks = {}; + let nextRequestID = 0; + let nextBuildKey = 0; + let stdout = new Uint8Array(16 * 1024); + let stdoutUsed = 0; + let readFromStdout = (chunk) => { + let limit = stdoutUsed + chunk.length; + if (limit > stdout.length) { + let swap = new Uint8Array(limit * 2); + swap.set(stdout); + stdout = swap; + } + stdout.set(chunk, stdoutUsed); + stdoutUsed += chunk.length; + let offset = 0; + while (offset + 4 <= stdoutUsed) { + let length = readUInt32LE(stdout, offset); + if (offset + 4 + length > stdoutUsed) { + break; + } + offset += 4; + handleIncomingPacket(stdout.subarray(offset, offset + length)); + offset += length; + } + if (offset > 0) { + stdout.copyWithin(0, offset, stdoutUsed); + stdoutUsed -= offset; + } + }; + let afterClose = (error) => { + closeData.didClose = true; + if (error) closeData.reason = ": " + (error.message || error); + const text = "The service was stopped" + closeData.reason; + for (let id in responseCallbacks) { + responseCallbacks[id](text, null); + } + responseCallbacks = {}; + }; + let sendRequest = (refs, value, callback) => { + if (closeData.didClose) return callback("The service is no longer running" + closeData.reason, null); + let id = nextRequestID++; + responseCallbacks[id] = (error, response) => { + try { + callback(error, response); + } finally { + if (refs) refs.unref(); + } + }; + if (refs) refs.ref(); + streamIn.writeToStdin(encodePacket({ id, isRequest: true, value })); + }; + let sendResponse = (id, value) => { + if (closeData.didClose) throw new Error("The service is no longer running" + closeData.reason); + streamIn.writeToStdin(encodePacket({ id, isRequest: false, value })); + }; + let handleRequest = async (id, request) => { + try { + if (request.command === "ping") { + sendResponse(id, {}); + return; + } + if (typeof request.key === "number") { + const requestCallbacks = requestCallbacksByKey[request.key]; + if (!requestCallbacks) { + return; + } + const callback = requestCallbacks[request.command]; + if (callback) { + await callback(id, request); + return; + } + } + throw new Error(`Invalid command: ` + request.command); + } catch (e) { + const errors = [extractErrorMessageV8(e, streamIn, null, void 0, "")]; + try { + sendResponse(id, { errors }); + } catch { + } + } + }; + let isFirstPacket = true; + let handleIncomingPacket = (bytes) => { + if (isFirstPacket) { + isFirstPacket = false; + let binaryVersion = String.fromCharCode(...bytes); + if (binaryVersion !== "0.21.5") { + throw new Error(`Cannot start service: Host version "${"0.21.5"}" does not match binary version ${quote(binaryVersion)}`); + } + return; + } + let packet = decodePacket(bytes); + if (packet.isRequest) { + handleRequest(packet.id, packet.value); + } else { + let callback = responseCallbacks[packet.id]; + delete responseCallbacks[packet.id]; + if (packet.value.error) callback(packet.value.error, {}); + else callback(null, packet.value); + } + }; + let buildOrContext = ({ callName, refs, options, isTTY: isTTY2, defaultWD: defaultWD2, callback }) => { + let refCount = 0; + const buildKey = nextBuildKey++; + const requestCallbacks = {}; + const buildRefs = { + ref() { + if (++refCount === 1) { + if (refs) refs.ref(); + } + }, + unref() { + if (--refCount === 0) { + delete requestCallbacksByKey[buildKey]; + if (refs) refs.unref(); + } + } + }; + requestCallbacksByKey[buildKey] = requestCallbacks; + buildRefs.ref(); + buildOrContextImpl( + callName, + buildKey, + sendRequest, + sendResponse, + buildRefs, + streamIn, + requestCallbacks, + options, + isTTY2, + defaultWD2, + (err, res) => { + try { + callback(err, res); + } finally { + buildRefs.unref(); + } + } + ); + }; + let transform2 = ({ callName, refs, input, options, isTTY: isTTY2, fs: fs3, callback }) => { + const details = createObjectStash(); + let start = (inputPath) => { + try { + if (typeof input !== "string" && !(input instanceof Uint8Array)) + throw new Error('The input to "transform" must be a string or a Uint8Array'); + let { + flags, + mangleCache + } = flagsForTransformOptions(callName, options, isTTY2, transformLogLevelDefault); + let request = { + command: "transform", + flags, + inputFS: inputPath !== null, + input: inputPath !== null ? encodeUTF8(inputPath) : typeof input === "string" ? encodeUTF8(input) : input + }; + if (mangleCache) request.mangleCache = mangleCache; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + let errors = replaceDetailsInMessages(response.errors, details); + let warnings = replaceDetailsInMessages(response.warnings, details); + let outstanding = 1; + let next = () => { + if (--outstanding === 0) { + let result = { + warnings, + code: response.code, + map: response.map, + mangleCache: void 0, + legalComments: void 0 + }; + if ("legalComments" in response) result.legalComments = response == null ? void 0 : response.legalComments; + if (response.mangleCache) result.mangleCache = response == null ? void 0 : response.mangleCache; + callback(null, result); + } + }; + if (errors.length > 0) return callback(failureErrorWithLog("Transform failed", errors, warnings), null); + if (response.codeFS) { + outstanding++; + fs3.readFile(response.code, (err, contents) => { + if (err !== null) { + callback(err, null); + } else { + response.code = contents; + next(); + } + }); + } + if (response.mapFS) { + outstanding++; + fs3.readFile(response.map, (err, contents) => { + if (err !== null) { + callback(err, null); + } else { + response.map = contents; + next(); + } + }); + } + next(); + }); + } catch (e) { + let flags = []; + try { + pushLogFlags(flags, options, {}, isTTY2, transformLogLevelDefault); + } catch { + } + const error = extractErrorMessageV8(e, streamIn, details, void 0, ""); + sendRequest(refs, { command: "error", flags, error }, () => { + error.detail = details.load(error.detail); + callback(failureErrorWithLog("Transform failed", [error], []), null); + }); + } + }; + if ((typeof input === "string" || input instanceof Uint8Array) && input.length > 1024 * 1024) { + let next = start; + start = () => fs3.writeFile(input, next); + } + start(null); + }; + let formatMessages2 = ({ callName, refs, messages, options, callback }) => { + if (!options) throw new Error(`Missing second argument in ${callName}() call`); + let keys = {}; + let kind = getFlag(options, keys, "kind", mustBeString); + let color = getFlag(options, keys, "color", mustBeBoolean); + let terminalWidth = getFlag(options, keys, "terminalWidth", mustBeInteger); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + if (kind === void 0) throw new Error(`Missing "kind" in ${callName}() call`); + if (kind !== "error" && kind !== "warning") throw new Error(`Expected "kind" to be "error" or "warning" in ${callName}() call`); + let request = { + command: "format-msgs", + messages: sanitizeMessages(messages, "messages", null, "", terminalWidth), + isWarning: kind === "warning" + }; + if (color !== void 0) request.color = color; + if (terminalWidth !== void 0) request.terminalWidth = terminalWidth; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + callback(null, response.messages); + }); + }; + let analyzeMetafile2 = ({ callName, refs, metafile, options, callback }) => { + if (options === void 0) options = {}; + let keys = {}; + let color = getFlag(options, keys, "color", mustBeBoolean); + let verbose = getFlag(options, keys, "verbose", mustBeBoolean); + checkForInvalidFlags(options, keys, `in ${callName}() call`); + let request = { + command: "analyze-metafile", + metafile + }; + if (color !== void 0) request.color = color; + if (verbose !== void 0) request.verbose = verbose; + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + callback(null, response.result); + }); + }; + return { + readFromStdout, + afterClose, + service: { + buildOrContext, + transform: transform2, + formatMessages: formatMessages2, + analyzeMetafile: analyzeMetafile2 + } + }; +} +function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY2, defaultWD2, callback) { + const details = createObjectStash(); + const isContext = callName === "context"; + const handleError = (e, pluginName) => { + const flags = []; + try { + pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault); + } catch { + } + const message = extractErrorMessageV8(e, streamIn, details, void 0, pluginName); + sendRequest(refs, { command: "error", flags, error: message }, () => { + message.detail = details.load(message.detail); + callback(failureErrorWithLog(isContext ? "Context failed" : "Build failed", [message], []), null); + }); + }; + let plugins; + if (typeof options === "object") { + const value = options.plugins; + if (value !== void 0) { + if (!Array.isArray(value)) return handleError(new Error(`"plugins" must be an array`), ""); + plugins = value; + } + } + if (plugins && plugins.length > 0) { + if (streamIn.isSync) return handleError(new Error("Cannot use plugins in synchronous API calls"), ""); + handlePlugins( + buildKey, + sendRequest, + sendResponse, + refs, + streamIn, + requestCallbacks, + options, + plugins, + details + ).then( + (result) => { + if (!result.ok) return handleError(result.error, result.pluginName); + try { + buildOrContextContinue(result.requestPlugins, result.runOnEndCallbacks, result.scheduleOnDisposeCallbacks); + } catch (e) { + handleError(e, ""); + } + }, + (e) => handleError(e, "") + ); + return; + } + try { + buildOrContextContinue(null, (result, done) => done([], []), () => { + }); + } catch (e) { + handleError(e, ""); + } + function buildOrContextContinue(requestPlugins, runOnEndCallbacks, scheduleOnDisposeCallbacks) { + const writeDefault = streamIn.hasFS; + const { + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir, + nodePaths, + mangleCache + } = flagsForBuildOptions(callName, options, isTTY2, buildLogLevelDefault, writeDefault); + if (write && !streamIn.hasFS) throw new Error(`The "write" option is unavailable in this environment`); + const request = { + command: "build", + key: buildKey, + entries, + flags, + write, + stdinContents, + stdinResolveDir, + absWorkingDir: absWorkingDir || defaultWD2, + nodePaths, + context: isContext + }; + if (requestPlugins) request.plugins = requestPlugins; + if (mangleCache) request.mangleCache = mangleCache; + const buildResponseToResult = (response, callback2) => { + const result = { + errors: replaceDetailsInMessages(response.errors, details), + warnings: replaceDetailsInMessages(response.warnings, details), + outputFiles: void 0, + metafile: void 0, + mangleCache: void 0 + }; + const originalErrors = result.errors.slice(); + const originalWarnings = result.warnings.slice(); + if (response.outputFiles) result.outputFiles = response.outputFiles.map(convertOutputFiles); + if (response.metafile) result.metafile = JSON.parse(response.metafile); + if (response.mangleCache) result.mangleCache = response.mangleCache; + if (response.writeToStdout !== void 0) console.log(decodeUTF8(response.writeToStdout).replace(/\n$/, "")); + runOnEndCallbacks(result, (onEndErrors, onEndWarnings) => { + if (originalErrors.length > 0 || onEndErrors.length > 0) { + const error = failureErrorWithLog("Build failed", originalErrors.concat(onEndErrors), originalWarnings.concat(onEndWarnings)); + return callback2(error, null, onEndErrors, onEndWarnings); + } + callback2(null, result, onEndErrors, onEndWarnings); + }); + }; + let latestResultPromise; + let provideLatestResult; + if (isContext) + requestCallbacks["on-end"] = (id, request2) => new Promise((resolve) => { + buildResponseToResult(request2, (err, result, onEndErrors, onEndWarnings) => { + const response = { + errors: onEndErrors, + warnings: onEndWarnings + }; + if (provideLatestResult) provideLatestResult(err, result); + latestResultPromise = void 0; + provideLatestResult = void 0; + sendResponse(id, response); + resolve(); + }); + }); + sendRequest(refs, request, (error, response) => { + if (error) return callback(new Error(error), null); + if (!isContext) { + return buildResponseToResult(response, (err, res) => { + scheduleOnDisposeCallbacks(); + return callback(err, res); + }); + } + if (response.errors.length > 0) { + return callback(failureErrorWithLog("Context failed", response.errors, response.warnings), null); + } + let didDispose = false; + const result = { + rebuild: () => { + if (!latestResultPromise) latestResultPromise = new Promise((resolve, reject) => { + let settlePromise; + provideLatestResult = (err, result2) => { + if (!settlePromise) settlePromise = () => err ? reject(err) : resolve(result2); + }; + const triggerAnotherBuild = () => { + const request2 = { + command: "rebuild", + key: buildKey + }; + sendRequest(refs, request2, (error2, response2) => { + if (error2) { + reject(new Error(error2)); + } else if (settlePromise) { + settlePromise(); + } else { + triggerAnotherBuild(); + } + }); + }; + triggerAnotherBuild(); + }); + return latestResultPromise; + }, + watch: (options2 = {}) => new Promise((resolve, reject) => { + if (!streamIn.hasFS) throw new Error(`Cannot use the "watch" API in this environment`); + const keys = {}; + checkForInvalidFlags(options2, keys, `in watch() call`); + const request2 = { + command: "watch", + key: buildKey + }; + sendRequest(refs, request2, (error2) => { + if (error2) reject(new Error(error2)); + else resolve(void 0); + }); + }), + serve: (options2 = {}) => new Promise((resolve, reject) => { + if (!streamIn.hasFS) throw new Error(`Cannot use the "serve" API in this environment`); + const keys = {}; + const port = getFlag(options2, keys, "port", mustBeInteger); + const host = getFlag(options2, keys, "host", mustBeString); + const servedir = getFlag(options2, keys, "servedir", mustBeString); + const keyfile = getFlag(options2, keys, "keyfile", mustBeString); + const certfile = getFlag(options2, keys, "certfile", mustBeString); + const fallback = getFlag(options2, keys, "fallback", mustBeString); + const onRequest = getFlag(options2, keys, "onRequest", mustBeFunction); + checkForInvalidFlags(options2, keys, `in serve() call`); + const request2 = { + command: "serve", + key: buildKey, + onRequest: !!onRequest + }; + if (port !== void 0) request2.port = port; + if (host !== void 0) request2.host = host; + if (servedir !== void 0) request2.servedir = servedir; + if (keyfile !== void 0) request2.keyfile = keyfile; + if (certfile !== void 0) request2.certfile = certfile; + if (fallback !== void 0) request2.fallback = fallback; + sendRequest(refs, request2, (error2, response2) => { + if (error2) return reject(new Error(error2)); + if (onRequest) { + requestCallbacks["serve-request"] = (id, request3) => { + onRequest(request3.args); + sendResponse(id, {}); + }; + } + resolve(response2); + }); + }), + cancel: () => new Promise((resolve) => { + if (didDispose) return resolve(); + const request2 = { + command: "cancel", + key: buildKey + }; + sendRequest(refs, request2, () => { + resolve(); + }); + }), + dispose: () => new Promise((resolve) => { + if (didDispose) return resolve(); + didDispose = true; + const request2 = { + command: "dispose", + key: buildKey + }; + sendRequest(refs, request2, () => { + resolve(); + scheduleOnDisposeCallbacks(); + refs.unref(); + }); + }) + }; + refs.ref(); + callback(null, result); + }); + } +} +var handlePlugins = async (buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, initialOptions, plugins, details) => { + let onStartCallbacks = []; + let onEndCallbacks = []; + let onResolveCallbacks = {}; + let onLoadCallbacks = {}; + let onDisposeCallbacks = []; + let nextCallbackID = 0; + let i = 0; + let requestPlugins = []; + let isSetupDone = false; + plugins = [...plugins]; + for (let item of plugins) { + let keys = {}; + if (typeof item !== "object") throw new Error(`Plugin at index ${i} must be an object`); + const name = getFlag(item, keys, "name", mustBeString); + if (typeof name !== "string" || name === "") throw new Error(`Plugin at index ${i} is missing a name`); + try { + let setup = getFlag(item, keys, "setup", mustBeFunction); + if (typeof setup !== "function") throw new Error(`Plugin is missing a setup function`); + checkForInvalidFlags(item, keys, `on plugin ${quote(name)}`); + let plugin = { + name, + onStart: false, + onEnd: false, + onResolve: [], + onLoad: [] + }; + i++; + let resolve = (path3, options = {}) => { + if (!isSetupDone) throw new Error('Cannot call "resolve" before plugin setup has completed'); + if (typeof path3 !== "string") throw new Error(`The path to resolve must be a string`); + let keys2 = /* @__PURE__ */ Object.create(null); + let pluginName = getFlag(options, keys2, "pluginName", mustBeString); + let importer = getFlag(options, keys2, "importer", mustBeString); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + let resolveDir = getFlag(options, keys2, "resolveDir", mustBeString); + let kind = getFlag(options, keys2, "kind", mustBeString); + let pluginData = getFlag(options, keys2, "pluginData", canBeAnything); + let importAttributes = getFlag(options, keys2, "with", mustBeObject); + checkForInvalidFlags(options, keys2, "in resolve() call"); + return new Promise((resolve2, reject) => { + const request = { + command: "resolve", + path: path3, + key: buildKey, + pluginName: name + }; + if (pluginName != null) request.pluginName = pluginName; + if (importer != null) request.importer = importer; + if (namespace != null) request.namespace = namespace; + if (resolveDir != null) request.resolveDir = resolveDir; + if (kind != null) request.kind = kind; + else throw new Error(`Must specify "kind" when calling "resolve"`); + if (pluginData != null) request.pluginData = details.store(pluginData); + if (importAttributes != null) request.with = sanitizeStringMap(importAttributes, "with"); + sendRequest(refs, request, (error, response) => { + if (error !== null) reject(new Error(error)); + else resolve2({ + errors: replaceDetailsInMessages(response.errors, details), + warnings: replaceDetailsInMessages(response.warnings, details), + path: response.path, + external: response.external, + sideEffects: response.sideEffects, + namespace: response.namespace, + suffix: response.suffix, + pluginData: details.load(response.pluginData) + }); + }); + }); + }; + let promise = setup({ + initialOptions, + resolve, + onStart(callback) { + let registeredText = `This error came from the "onStart" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onStart"); + onStartCallbacks.push({ name, callback, note: registeredNote }); + plugin.onStart = true; + }, + onEnd(callback) { + let registeredText = `This error came from the "onEnd" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onEnd"); + onEndCallbacks.push({ name, callback, note: registeredNote }); + plugin.onEnd = true; + }, + onResolve(options, callback) { + let registeredText = `This error came from the "onResolve" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onResolve"); + let keys2 = {}; + let filter = getFlag(options, keys2, "filter", mustBeRegExp); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + checkForInvalidFlags(options, keys2, `in onResolve() call for plugin ${quote(name)}`); + if (filter == null) throw new Error(`onResolve() call is missing a filter`); + let id = nextCallbackID++; + onResolveCallbacks[id] = { name, callback, note: registeredNote }; + plugin.onResolve.push({ id, filter: filter.source, namespace: namespace || "" }); + }, + onLoad(options, callback) { + let registeredText = `This error came from the "onLoad" callback registered here:`; + let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onLoad"); + let keys2 = {}; + let filter = getFlag(options, keys2, "filter", mustBeRegExp); + let namespace = getFlag(options, keys2, "namespace", mustBeString); + checkForInvalidFlags(options, keys2, `in onLoad() call for plugin ${quote(name)}`); + if (filter == null) throw new Error(`onLoad() call is missing a filter`); + let id = nextCallbackID++; + onLoadCallbacks[id] = { name, callback, note: registeredNote }; + plugin.onLoad.push({ id, filter: filter.source, namespace: namespace || "" }); + }, + onDispose(callback) { + onDisposeCallbacks.push(callback); + }, + esbuild: streamIn.esbuild + }); + if (promise) await promise; + requestPlugins.push(plugin); + } catch (e) { + return { ok: false, error: e, pluginName: name }; + } + } + requestCallbacks["on-start"] = async (id, request) => { + let response = { errors: [], warnings: [] }; + await Promise.all(onStartCallbacks.map(async ({ name, callback, note }) => { + try { + let result = await callback(); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onStart() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + checkForInvalidFlags(result, keys, `from onStart() callback in plugin ${quote(name)}`); + if (errors != null) response.errors.push(...sanitizeMessages(errors, "errors", details, name, void 0)); + if (warnings != null) response.warnings.push(...sanitizeMessages(warnings, "warnings", details, name, void 0)); + } + } catch (e) { + response.errors.push(extractErrorMessageV8(e, streamIn, details, note && note(), name)); + } + })); + sendResponse(id, response); + }; + requestCallbacks["on-resolve"] = async (id, request) => { + let response = {}, name = "", callback, note; + for (let id2 of request.ids) { + try { + ({ name, callback, note } = onResolveCallbacks[id2]); + let result = await callback({ + path: request.path, + importer: request.importer, + namespace: request.namespace, + resolveDir: request.resolveDir, + kind: request.kind, + pluginData: details.load(request.pluginData), + with: request.with + }); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onResolve() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let pluginName = getFlag(result, keys, "pluginName", mustBeString); + let path3 = getFlag(result, keys, "path", mustBeString); + let namespace = getFlag(result, keys, "namespace", mustBeString); + let suffix = getFlag(result, keys, "suffix", mustBeString); + let external = getFlag(result, keys, "external", mustBeBoolean); + let sideEffects = getFlag(result, keys, "sideEffects", mustBeBoolean); + let pluginData = getFlag(result, keys, "pluginData", canBeAnything); + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + let watchFiles = getFlag(result, keys, "watchFiles", mustBeArray); + let watchDirs = getFlag(result, keys, "watchDirs", mustBeArray); + checkForInvalidFlags(result, keys, `from onResolve() callback in plugin ${quote(name)}`); + response.id = id2; + if (pluginName != null) response.pluginName = pluginName; + if (path3 != null) response.path = path3; + if (namespace != null) response.namespace = namespace; + if (suffix != null) response.suffix = suffix; + if (external != null) response.external = external; + if (sideEffects != null) response.sideEffects = sideEffects; + if (pluginData != null) response.pluginData = details.store(pluginData); + if (errors != null) response.errors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) response.warnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles"); + if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs"); + break; + } + } catch (e) { + response = { id: id2, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }; + break; + } + } + sendResponse(id, response); + }; + requestCallbacks["on-load"] = async (id, request) => { + let response = {}, name = "", callback, note; + for (let id2 of request.ids) { + try { + ({ name, callback, note } = onLoadCallbacks[id2]); + let result = await callback({ + path: request.path, + namespace: request.namespace, + suffix: request.suffix, + pluginData: details.load(request.pluginData), + with: request.with + }); + if (result != null) { + if (typeof result !== "object") throw new Error(`Expected onLoad() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let pluginName = getFlag(result, keys, "pluginName", mustBeString); + let contents = getFlag(result, keys, "contents", mustBeStringOrUint8Array); + let resolveDir = getFlag(result, keys, "resolveDir", mustBeString); + let pluginData = getFlag(result, keys, "pluginData", canBeAnything); + let loader = getFlag(result, keys, "loader", mustBeString); + let errors = getFlag(result, keys, "errors", mustBeArray); + let warnings = getFlag(result, keys, "warnings", mustBeArray); + let watchFiles = getFlag(result, keys, "watchFiles", mustBeArray); + let watchDirs = getFlag(result, keys, "watchDirs", mustBeArray); + checkForInvalidFlags(result, keys, `from onLoad() callback in plugin ${quote(name)}`); + response.id = id2; + if (pluginName != null) response.pluginName = pluginName; + if (contents instanceof Uint8Array) response.contents = contents; + else if (contents != null) response.contents = encodeUTF8(contents); + if (resolveDir != null) response.resolveDir = resolveDir; + if (pluginData != null) response.pluginData = details.store(pluginData); + if (loader != null) response.loader = loader; + if (errors != null) response.errors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) response.warnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles"); + if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs"); + break; + } + } catch (e) { + response = { id: id2, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }; + break; + } + } + sendResponse(id, response); + }; + let runOnEndCallbacks = (result, done) => done([], []); + if (onEndCallbacks.length > 0) { + runOnEndCallbacks = (result, done) => { + (async () => { + const onEndErrors = []; + const onEndWarnings = []; + for (const { name, callback, note } of onEndCallbacks) { + let newErrors; + let newWarnings; + try { + const value = await callback(result); + if (value != null) { + if (typeof value !== "object") throw new Error(`Expected onEnd() callback in plugin ${quote(name)} to return an object`); + let keys = {}; + let errors = getFlag(value, keys, "errors", mustBeArray); + let warnings = getFlag(value, keys, "warnings", mustBeArray); + checkForInvalidFlags(value, keys, `from onEnd() callback in plugin ${quote(name)}`); + if (errors != null) newErrors = sanitizeMessages(errors, "errors", details, name, void 0); + if (warnings != null) newWarnings = sanitizeMessages(warnings, "warnings", details, name, void 0); + } + } catch (e) { + newErrors = [extractErrorMessageV8(e, streamIn, details, note && note(), name)]; + } + if (newErrors) { + onEndErrors.push(...newErrors); + try { + result.errors.push(...newErrors); + } catch { + } + } + if (newWarnings) { + onEndWarnings.push(...newWarnings); + try { + result.warnings.push(...newWarnings); + } catch { + } + } + } + done(onEndErrors, onEndWarnings); + })(); + }; + } + let scheduleOnDisposeCallbacks = () => { + for (const cb of onDisposeCallbacks) { + setTimeout(() => cb(), 0); + } + }; + isSetupDone = true; + return { + ok: true, + requestPlugins, + runOnEndCallbacks, + scheduleOnDisposeCallbacks + }; +}; +function createObjectStash() { + const map = /* @__PURE__ */ new Map(); + let nextID = 0; + return { + load(id) { + return map.get(id); + }, + store(value) { + if (value === void 0) return -1; + const id = nextID++; + map.set(id, value); + return id; + } + }; +} +function extractCallerV8(e, streamIn, ident) { + let note; + let tried = false; + return () => { + if (tried) return note; + tried = true; + try { + let lines = (e.stack + "").split("\n"); + lines.splice(1, 1); + let location = parseStackLinesV8(streamIn, lines, ident); + if (location) { + note = { text: e.message, location }; + return note; + } + } catch { + } + }; +} +function extractErrorMessageV8(e, streamIn, stash, note, pluginName) { + let text = "Internal error"; + let location = null; + try { + text = (e && e.message || e) + ""; + } catch { + } + try { + location = parseStackLinesV8(streamIn, (e.stack + "").split("\n"), ""); + } catch { + } + return { id: "", pluginName, text, location, notes: note ? [note] : [], detail: stash ? stash.store(e) : -1 }; +} +function parseStackLinesV8(streamIn, lines, ident) { + let at = " at "; + if (streamIn.readFileSync && !lines[0].startsWith(at) && lines[1].startsWith(at)) { + for (let i = 1; i < lines.length; i++) { + let line = lines[i]; + if (!line.startsWith(at)) continue; + line = line.slice(at.length); + while (true) { + let match = /^(?:new |async )?\S+ \((.*)\)$/.exec(line); + if (match) { + line = match[1]; + continue; + } + match = /^eval at \S+ \((.*)\)(?:, \S+:\d+:\d+)?$/.exec(line); + if (match) { + line = match[1]; + continue; + } + match = /^(\S+):(\d+):(\d+)$/.exec(line); + if (match) { + let contents; + try { + contents = streamIn.readFileSync(match[1], "utf8"); + } catch { + break; + } + let lineText = contents.split(/\r\n|\r|\n|\u2028|\u2029/)[+match[2] - 1] || ""; + let column = +match[3] - 1; + let length = lineText.slice(column, column + ident.length) === ident ? ident.length : 0; + return { + file: match[1], + namespace: "file", + line: +match[2], + column: encodeUTF8(lineText.slice(0, column)).length, + length: encodeUTF8(lineText.slice(column, column + length)).length, + lineText: lineText + "\n" + lines.slice(1).join("\n"), + suggestion: "" + }; + } + break; + } + } + } + return null; +} +function failureErrorWithLog(text, errors, warnings) { + let limit = 5; + text += errors.length < 1 ? "" : ` with ${errors.length} error${errors.length < 2 ? "" : "s"}:` + errors.slice(0, limit + 1).map((e, i) => { + if (i === limit) return "\n..."; + if (!e.location) return ` +error: ${e.text}`; + let { file, line, column } = e.location; + let pluginText = e.pluginName ? `[plugin: ${e.pluginName}] ` : ""; + return ` +${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`; + }).join(""); + let error = new Error(text); + for (const [key, value] of [["errors", errors], ["warnings", warnings]]) { + Object.defineProperty(error, key, { + configurable: true, + enumerable: true, + get: () => value, + set: (value2) => Object.defineProperty(error, key, { + configurable: true, + enumerable: true, + value: value2 + }) + }); + } + return error; +} +function replaceDetailsInMessages(messages, stash) { + for (const message of messages) { + message.detail = stash.load(message.detail); + } + return messages; +} +function sanitizeLocation(location, where, terminalWidth) { + if (location == null) return null; + let keys = {}; + let file = getFlag(location, keys, "file", mustBeString); + let namespace = getFlag(location, keys, "namespace", mustBeString); + let line = getFlag(location, keys, "line", mustBeInteger); + let column = getFlag(location, keys, "column", mustBeInteger); + let length = getFlag(location, keys, "length", mustBeInteger); + let lineText = getFlag(location, keys, "lineText", mustBeString); + let suggestion = getFlag(location, keys, "suggestion", mustBeString); + checkForInvalidFlags(location, keys, where); + if (lineText) { + const relevantASCII = lineText.slice( + 0, + (column && column > 0 ? column : 0) + (length && length > 0 ? length : 0) + (terminalWidth && terminalWidth > 0 ? terminalWidth : 80) + ); + if (!/[\x7F-\uFFFF]/.test(relevantASCII) && !/\n/.test(lineText)) { + lineText = relevantASCII; + } + } + return { + file: file || "", + namespace: namespace || "", + line: line || 0, + column: column || 0, + length: length || 0, + lineText: lineText || "", + suggestion: suggestion || "" + }; +} +function sanitizeMessages(messages, property, stash, fallbackPluginName, terminalWidth) { + let messagesClone = []; + let index = 0; + for (const message of messages) { + let keys = {}; + let id = getFlag(message, keys, "id", mustBeString); + let pluginName = getFlag(message, keys, "pluginName", mustBeString); + let text = getFlag(message, keys, "text", mustBeString); + let location = getFlag(message, keys, "location", mustBeObjectOrNull); + let notes = getFlag(message, keys, "notes", mustBeArray); + let detail = getFlag(message, keys, "detail", canBeAnything); + let where = `in element ${index} of "${property}"`; + checkForInvalidFlags(message, keys, where); + let notesClone = []; + if (notes) { + for (const note of notes) { + let noteKeys = {}; + let noteText = getFlag(note, noteKeys, "text", mustBeString); + let noteLocation = getFlag(note, noteKeys, "location", mustBeObjectOrNull); + checkForInvalidFlags(note, noteKeys, where); + notesClone.push({ + text: noteText || "", + location: sanitizeLocation(noteLocation, where, terminalWidth) + }); + } + } + messagesClone.push({ + id: id || "", + pluginName: pluginName || fallbackPluginName, + text: text || "", + location: sanitizeLocation(location, where, terminalWidth), + notes: notesClone, + detail: stash ? stash.store(detail) : -1 + }); + index++; + } + return messagesClone; +} +function sanitizeStringArray(values, property) { + const result = []; + for (const value of values) { + if (typeof value !== "string") throw new Error(`${quote(property)} must be an array of strings`); + result.push(value); + } + return result; +} +function sanitizeStringMap(map, property) { + const result = /* @__PURE__ */ Object.create(null); + for (const key in map) { + const value = map[key]; + if (typeof value !== "string") throw new Error(`key ${quote(key)} in object ${quote(property)} must be a string`); + result[key] = value; + } + return result; +} +function convertOutputFiles({ path: path3, contents, hash }) { + let text = null; + return { + path: path3, + contents, + hash, + get text() { + const binary = this.contents; + if (text === null || binary !== contents) { + contents = binary; + text = decodeUTF8(binary); + } + return text; + } + }; +} + +// lib/npm/node-platform.ts +var fs = require("fs"); +var os = require("os"); +var path = require("path"); +var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH; +var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild"; +var packageDarwin_arm64 = "@esbuild/darwin-arm64"; +var packageDarwin_x64 = "@esbuild/darwin-x64"; +var knownWindowsPackages = { + "win32 arm64 LE": "@esbuild/win32-arm64", + "win32 ia32 LE": "@esbuild/win32-ia32", + "win32 x64 LE": "@esbuild/win32-x64" +}; +var knownUnixlikePackages = { + "aix ppc64 BE": "@esbuild/aix-ppc64", + "android arm64 LE": "@esbuild/android-arm64", + "darwin arm64 LE": "@esbuild/darwin-arm64", + "darwin x64 LE": "@esbuild/darwin-x64", + "freebsd arm64 LE": "@esbuild/freebsd-arm64", + "freebsd x64 LE": "@esbuild/freebsd-x64", + "linux arm LE": "@esbuild/linux-arm", + "linux arm64 LE": "@esbuild/linux-arm64", + "linux ia32 LE": "@esbuild/linux-ia32", + "linux mips64el LE": "@esbuild/linux-mips64el", + "linux ppc64 LE": "@esbuild/linux-ppc64", + "linux riscv64 LE": "@esbuild/linux-riscv64", + "linux s390x BE": "@esbuild/linux-s390x", + "linux x64 LE": "@esbuild/linux-x64", + "linux loong64 LE": "@esbuild/linux-loong64", + "netbsd x64 LE": "@esbuild/netbsd-x64", + "openbsd x64 LE": "@esbuild/openbsd-x64", + "sunos x64 LE": "@esbuild/sunos-x64" +}; +var knownWebAssemblyFallbackPackages = { + "android arm LE": "@esbuild/android-arm", + "android x64 LE": "@esbuild/android-x64" +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + let isWASM = false; + let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; + if (platformKey in knownWindowsPackages) { + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + } else if (platformKey in knownUnixlikePackages) { + pkg = knownUnixlikePackages[platformKey]; + subpath = "bin/esbuild"; + } else if (platformKey in knownWebAssemblyFallbackPackages) { + pkg = knownWebAssemblyFallbackPackages[platformKey]; + subpath = "bin/esbuild"; + isWASM = true; + } else { + throw new Error(`Unsupported platform: ${platformKey}`); + } + return { pkg, subpath, isWASM }; +} +function pkgForSomeOtherPlatform() { + const libMainJS = require.resolve("esbuild"); + const nodeModulesDirectory = path.dirname(path.dirname(path.dirname(libMainJS))); + if (path.basename(nodeModulesDirectory) === "node_modules") { + for (const unixKey in knownUnixlikePackages) { + try { + const pkg = knownUnixlikePackages[unixKey]; + if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg; + } catch { + } + } + for (const windowsKey in knownWindowsPackages) { + try { + const pkg = knownWindowsPackages[windowsKey]; + if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg; + } catch { + } + } + } + return null; +} +function downloadedBinPath(pkg, subpath) { + const esbuildLibDir = path.dirname(require.resolve("esbuild")); + return path.join(esbuildLibDir, `downloaded-${pkg.replace("/", "-")}-${path.basename(subpath)}`); +} +function generateBinPath() { + if (isValidBinaryPath(ESBUILD_BINARY_PATH)) { + if (!fs.existsSync(ESBUILD_BINARY_PATH)) { + console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`); + } else { + return { binPath: ESBUILD_BINARY_PATH, isWASM: false }; + } + } + const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) { + binPath = downloadedBinPath(pkg, subpath); + if (!fs.existsSync(binPath)) { + try { + require.resolve(pkg); + } catch { + const otherPkg = pkgForSomeOtherPlatform(); + if (otherPkg) { + let suggestions = ` +Specifically the "${otherPkg}" package is present but this platform +needs the "${pkg}" package instead. People often get into this +situation by installing esbuild on Windows or macOS and copying "node_modules" +into a Docker image that runs Linux, or by copying "node_modules" between +Windows and WSL environments. + +If you are installing with npm, you can try not copying the "node_modules" +directory when you copy the files over, and running "npm ci" or "npm install" +on the destination platform after the copy. Or you could consider using yarn +instead of npm which has built-in support for installing a package on multiple +platforms simultaneously. + +If you are installing with yarn, you can try listing both this platform and the +other platform in your ".yarnrc.yml" file using the "supportedArchitectures" +feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures +Keep in mind that this means multiple copies of esbuild will be present. +`; + if (pkg === packageDarwin_x64 && otherPkg === packageDarwin_arm64 || pkg === packageDarwin_arm64 && otherPkg === packageDarwin_x64) { + suggestions = ` +Specifically the "${otherPkg}" package is present but this platform +needs the "${pkg}" package instead. People often get into this +situation by installing esbuild with npm running inside of Rosetta 2 and then +trying to use it with node running outside of Rosetta 2, or vice versa (Rosetta +2 is Apple's on-the-fly x86_64-to-arm64 translation service). + +If you are installing with npm, you can try ensuring that both npm and node are +not running under Rosetta 2 and then reinstalling esbuild. This likely involves +changing how you installed npm and/or node. For example, installing node with +the universal installer here should work: https://nodejs.org/en/download/. Or +you could consider using yarn instead of npm which has built-in support for +installing a package on multiple platforms simultaneously. + +If you are installing with yarn, you can try listing both "arm64" and "x64" +in your ".yarnrc.yml" file using the "supportedArchitectures" feature: +https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures +Keep in mind that this means multiple copies of esbuild will be present. +`; + } + throw new Error(` +You installed esbuild for another platform than the one you're currently using. +This won't work because esbuild is written with native code and needs to +install a platform-specific binary executable. +${suggestions} +Another alternative is to use the "esbuild-wasm" package instead, which works +the same way on all platforms. But it comes with a heavy performance cost and +can sometimes be 10x slower than the "esbuild" package, so you may also not +want to do that. +`); + } + throw new Error(`The package "${pkg}" could not be found, and is needed by esbuild. + +If you are installing esbuild with npm, make sure that you don't specify the +"--no-optional" or "--omit=optional" flags. The "optionalDependencies" feature +of "package.json" is used by esbuild to install the correct binary executable +for your current platform.`); + } + throw e; + } + } + if (/\.zip\//.test(binPath)) { + let pnpapi; + try { + pnpapi = require("pnpapi"); + } catch (e) { + } + if (pnpapi) { + const root = pnpapi.getPackageInformation(pnpapi.topLevel).packageLocation; + const binTargetPath = path.join( + root, + "node_modules", + ".cache", + "esbuild", + `pnpapi-${pkg.replace("/", "-")}-${"0.21.5"}-${path.basename(subpath)}` + ); + if (!fs.existsSync(binTargetPath)) { + fs.mkdirSync(path.dirname(binTargetPath), { recursive: true }); + fs.copyFileSync(binPath, binTargetPath); + fs.chmodSync(binTargetPath, 493); + } + return { binPath: binTargetPath, isWASM }; + } + } + return { binPath, isWASM }; +} + +// lib/npm/node.ts +var child_process = require("child_process"); +var crypto = require("crypto"); +var path2 = require("path"); +var fs2 = require("fs"); +var os2 = require("os"); +var tty = require("tty"); +var worker_threads; +if (process.env.ESBUILD_WORKER_THREADS !== "0") { + try { + worker_threads = require("worker_threads"); + } catch { + } + let [major, minor] = process.versions.node.split("."); + if ( + // { + if ((!ESBUILD_BINARY_PATH || false) && (path2.basename(__filename) !== "main.js" || path2.basename(__dirname) !== "lib")) { + throw new Error( + `The esbuild JavaScript API cannot be bundled. Please mark the "esbuild" package as external so it's not included in the bundle. + +More information: The file containing the code for esbuild's JavaScript API (${__filename}) does not appear to be inside the esbuild package on the file system, which usually means that the esbuild package was bundled into another file. This is problematic because the API needs to run a binary executable inside the esbuild package which is located using a relative path from the API code to the executable. If the esbuild package is bundled, the relative path will be incorrect and the executable won't be found.` + ); + } + if (false) { + return ["node", [path2.join(__dirname, "..", "bin", "esbuild")]]; + } else { + const { binPath, isWASM } = generateBinPath(); + if (isWASM) { + return ["node", [binPath]]; + } else { + return [binPath, []]; + } + } +}; +var isTTY = () => tty.isatty(2); +var fsSync = { + readFile(tempFile, callback) { + try { + let contents = fs2.readFileSync(tempFile, "utf8"); + try { + fs2.unlinkSync(tempFile); + } catch { + } + callback(null, contents); + } catch (err) { + callback(err, null); + } + }, + writeFile(contents, callback) { + try { + let tempFile = randomFileName(); + fs2.writeFileSync(tempFile, contents); + callback(tempFile); + } catch { + callback(null); + } + } +}; +var fsAsync = { + readFile(tempFile, callback) { + try { + fs2.readFile(tempFile, "utf8", (err, contents) => { + try { + fs2.unlink(tempFile, () => callback(err, contents)); + } catch { + callback(err, contents); + } + }); + } catch (err) { + callback(err, null); + } + }, + writeFile(contents, callback) { + try { + let tempFile = randomFileName(); + fs2.writeFile(tempFile, contents, (err) => err !== null ? callback(null) : callback(tempFile)); + } catch { + callback(null); + } + } +}; +var version = "0.21.5"; +var build = (options) => ensureServiceIsRunning().build(options); +var context = (buildOptions) => ensureServiceIsRunning().context(buildOptions); +var transform = (input, options) => ensureServiceIsRunning().transform(input, options); +var formatMessages = (messages, options) => ensureServiceIsRunning().formatMessages(messages, options); +var analyzeMetafile = (messages, options) => ensureServiceIsRunning().analyzeMetafile(messages, options); +var buildSync = (options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.buildSync(options); + } + let result; + runServiceSync((service) => service.buildOrContext({ + callName: "buildSync", + refs: null, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var transformSync = (input, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.transformSync(input, options); + } + let result; + runServiceSync((service) => service.transform({ + callName: "transformSync", + refs: null, + input, + options: options || {}, + isTTY: isTTY(), + fs: fsSync, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var formatMessagesSync = (messages, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.formatMessagesSync(messages, options); + } + let result; + runServiceSync((service) => service.formatMessages({ + callName: "formatMessagesSync", + refs: null, + messages, + options, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var analyzeMetafileSync = (metafile, options) => { + if (worker_threads && !isInternalWorkerThread) { + if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads); + return workerThreadService.analyzeMetafileSync(metafile, options); + } + let result; + runServiceSync((service) => service.analyzeMetafile({ + callName: "analyzeMetafileSync", + refs: null, + metafile: typeof metafile === "string" ? metafile : JSON.stringify(metafile), + options, + callback: (err, res) => { + if (err) throw err; + result = res; + } + })); + return result; +}; +var stop = () => { + if (stopService) stopService(); + if (workerThreadService) workerThreadService.stop(); + return Promise.resolve(); +}; +var initializeWasCalled = false; +var initialize = (options) => { + options = validateInitializeOptions(options || {}); + if (options.wasmURL) throw new Error(`The "wasmURL" option only works in the browser`); + if (options.wasmModule) throw new Error(`The "wasmModule" option only works in the browser`); + if (options.worker) throw new Error(`The "worker" option only works in the browser`); + if (initializeWasCalled) throw new Error('Cannot call "initialize" more than once'); + ensureServiceIsRunning(); + initializeWasCalled = true; + return Promise.resolve(); +}; +var defaultWD = process.cwd(); +var longLivedService; +var stopService; +var ensureServiceIsRunning = () => { + if (longLivedService) return longLivedService; + let [command, args] = esbuildCommandAndArgs(); + let child = child_process.spawn(command, args.concat(`--service=${"0.21.5"}`, "--ping"), { + windowsHide: true, + stdio: ["pipe", "pipe", "inherit"], + cwd: defaultWD + }); + let { readFromStdout, afterClose, service } = createChannel({ + writeToStdin(bytes) { + child.stdin.write(bytes, (err) => { + if (err) afterClose(err); + }); + }, + readFileSync: fs2.readFileSync, + isSync: false, + hasFS: true, + esbuild: node_exports + }); + child.stdin.on("error", afterClose); + child.on("error", afterClose); + const stdin = child.stdin; + const stdout = child.stdout; + stdout.on("data", readFromStdout); + stdout.on("end", afterClose); + stopService = () => { + stdin.destroy(); + stdout.destroy(); + child.kill(); + initializeWasCalled = false; + longLivedService = void 0; + stopService = void 0; + }; + let refCount = 0; + child.unref(); + if (stdin.unref) { + stdin.unref(); + } + if (stdout.unref) { + stdout.unref(); + } + const refs = { + ref() { + if (++refCount === 1) child.ref(); + }, + unref() { + if (--refCount === 0) child.unref(); + } + }; + longLivedService = { + build: (options) => new Promise((resolve, reject) => { + service.buildOrContext({ + callName: "build", + refs, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => err ? reject(err) : resolve(res) + }); + }), + context: (options) => new Promise((resolve, reject) => service.buildOrContext({ + callName: "context", + refs, + options, + isTTY: isTTY(), + defaultWD, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + transform: (input, options) => new Promise((resolve, reject) => service.transform({ + callName: "transform", + refs, + input, + options: options || {}, + isTTY: isTTY(), + fs: fsAsync, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + formatMessages: (messages, options) => new Promise((resolve, reject) => service.formatMessages({ + callName: "formatMessages", + refs, + messages, + options, + callback: (err, res) => err ? reject(err) : resolve(res) + })), + analyzeMetafile: (metafile, options) => new Promise((resolve, reject) => service.analyzeMetafile({ + callName: "analyzeMetafile", + refs, + metafile: typeof metafile === "string" ? metafile : JSON.stringify(metafile), + options, + callback: (err, res) => err ? reject(err) : resolve(res) + })) + }; + return longLivedService; +}; +var runServiceSync = (callback) => { + let [command, args] = esbuildCommandAndArgs(); + let stdin = new Uint8Array(); + let { readFromStdout, afterClose, service } = createChannel({ + writeToStdin(bytes) { + if (stdin.length !== 0) throw new Error("Must run at most one command"); + stdin = bytes; + }, + isSync: true, + hasFS: true, + esbuild: node_exports + }); + callback(service); + let stdout = child_process.execFileSync(command, args.concat(`--service=${"0.21.5"}`), { + cwd: defaultWD, + windowsHide: true, + input: stdin, + // We don't know how large the output could be. If it's too large, the + // command will fail with ENOBUFS. Reserve 16mb for now since that feels + // like it should be enough. Also allow overriding this with an environment + // variable. + maxBuffer: +process.env.ESBUILD_MAX_BUFFER || 16 * 1024 * 1024 + }); + readFromStdout(stdout); + afterClose(null); +}; +var randomFileName = () => { + return path2.join(os2.tmpdir(), `esbuild-${crypto.randomBytes(32).toString("hex")}`); +}; +var workerThreadService = null; +var startWorkerThreadService = (worker_threads2) => { + let { port1: mainPort, port2: workerPort } = new worker_threads2.MessageChannel(); + let worker = new worker_threads2.Worker(__filename, { + workerData: { workerPort, defaultWD, esbuildVersion: "0.21.5" }, + transferList: [workerPort], + // From node's documentation: https://nodejs.org/api/worker_threads.html + // + // Take care when launching worker threads from preload scripts (scripts loaded + // and run using the `-r` command line flag). Unless the `execArgv` option is + // explicitly set, new Worker threads automatically inherit the command line flags + // from the running process and will preload the same preload scripts as the main + // thread. If the preload script unconditionally launches a worker thread, every + // thread spawned will spawn another until the application crashes. + // + execArgv: [] + }); + let nextID = 0; + let fakeBuildError = (text) => { + let error = new Error(`Build failed with 1 error: +error: ${text}`); + let errors = [{ id: "", pluginName: "", text, location: null, notes: [], detail: void 0 }]; + error.errors = errors; + error.warnings = []; + return error; + }; + let validateBuildSyncOptions = (options) => { + if (!options) return; + let plugins = options.plugins; + if (plugins && plugins.length > 0) throw fakeBuildError(`Cannot use plugins in synchronous API calls`); + }; + let applyProperties = (object, properties) => { + for (let key in properties) { + object[key] = properties[key]; + } + }; + let runCallSync = (command, args) => { + let id = nextID++; + let sharedBuffer = new SharedArrayBuffer(8); + let sharedBufferView = new Int32Array(sharedBuffer); + let msg = { sharedBuffer, id, command, args }; + worker.postMessage(msg); + let status = Atomics.wait(sharedBufferView, 0, 0); + if (status !== "ok" && status !== "not-equal") throw new Error("Internal error: Atomics.wait() failed: " + status); + let { message: { id: id2, resolve, reject, properties } } = worker_threads2.receiveMessageOnPort(mainPort); + if (id !== id2) throw new Error(`Internal error: Expected id ${id} but got id ${id2}`); + if (reject) { + applyProperties(reject, properties); + throw reject; + } + return resolve; + }; + worker.unref(); + return { + buildSync(options) { + validateBuildSyncOptions(options); + return runCallSync("build", [options]); + }, + transformSync(input, options) { + return runCallSync("transform", [input, options]); + }, + formatMessagesSync(messages, options) { + return runCallSync("formatMessages", [messages, options]); + }, + analyzeMetafileSync(metafile, options) { + return runCallSync("analyzeMetafile", [metafile, options]); + }, + stop() { + worker.terminate(); + workerThreadService = null; + } + }; +}; +var startSyncServiceWorker = () => { + let workerPort = worker_threads.workerData.workerPort; + let parentPort = worker_threads.parentPort; + let extractProperties = (object) => { + let properties = {}; + if (object && typeof object === "object") { + for (let key in object) { + properties[key] = object[key]; + } + } + return properties; + }; + try { + let service = ensureServiceIsRunning(); + defaultWD = worker_threads.workerData.defaultWD; + parentPort.on("message", (msg) => { + (async () => { + let { sharedBuffer, id, command, args } = msg; + let sharedBufferView = new Int32Array(sharedBuffer); + try { + switch (command) { + case "build": + workerPort.postMessage({ id, resolve: await service.build(args[0]) }); + break; + case "transform": + workerPort.postMessage({ id, resolve: await service.transform(args[0], args[1]) }); + break; + case "formatMessages": + workerPort.postMessage({ id, resolve: await service.formatMessages(args[0], args[1]) }); + break; + case "analyzeMetafile": + workerPort.postMessage({ id, resolve: await service.analyzeMetafile(args[0], args[1]) }); + break; + default: + throw new Error(`Invalid command: ${command}`); + } + } catch (reject) { + workerPort.postMessage({ id, reject, properties: extractProperties(reject) }); + } + Atomics.add(sharedBufferView, 0, 1); + Atomics.notify(sharedBufferView, 0, Infinity); + })(); + }); + } catch (reject) { + parentPort.on("message", (msg) => { + let { sharedBuffer, id } = msg; + let sharedBufferView = new Int32Array(sharedBuffer); + workerPort.postMessage({ id, reject, properties: extractProperties(reject) }); + Atomics.add(sharedBufferView, 0, 1); + Atomics.notify(sharedBufferView, 0, Infinity); + }); + } +}; +if (isInternalWorkerThread) { + startSyncServiceWorker(); +} +var node_default = node_exports; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + analyzeMetafile, + analyzeMetafileSync, + build, + buildSync, + context, + formatMessages, + formatMessagesSync, + initialize, + stop, + transform, + transformSync, + version +}); diff --git a/node_modules/esbuild/package.json b/node_modules/esbuild/package.json new file mode 100644 index 0000000..fe253fb --- /dev/null +++ b/node_modules/esbuild/package.json @@ -0,0 +1,46 @@ +{ + "name": "esbuild", + "version": "0.21.5", + "description": "An extremely fast JavaScript and CSS bundler and minifier.", + "repository": { + "type": "git", + "url": "git+https://github.com/evanw/esbuild.git" + }, + "scripts": { + "postinstall": "node install.js" + }, + "main": "lib/main.js", + "types": "lib/main.d.ts", + "engines": { + "node": ">=12" + }, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + }, + "license": "MIT" +} diff --git a/node_modules/estree-walker/LICENSE b/node_modules/estree-walker/LICENSE new file mode 100644 index 0000000..63b6209 --- /dev/null +++ b/node_modules/estree-walker/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2015-20 [these people](https://github.com/Rich-Harris/estree-walker/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/estree-walker/README.md b/node_modules/estree-walker/README.md new file mode 100644 index 0000000..d739d1b --- /dev/null +++ b/node_modules/estree-walker/README.md @@ -0,0 +1,48 @@ +# estree-walker + +Simple utility for walking an [ESTree](https://github.com/estree/estree)-compliant AST, such as one generated by [acorn](https://github.com/marijnh/acorn). + + +## Installation + +```bash +npm i estree-walker +``` + + +## Usage + +```js +var walk = require('estree-walker').walk; +var acorn = require('acorn'); + +ast = acorn.parse(sourceCode, options); // https://github.com/acornjs/acorn + +walk(ast, { + enter(node, parent, prop, index) { + // some code happens + }, + leave(node, parent, prop, index) { + // some code happens + } +}); +``` + +Inside the `enter` function, calling `this.skip()` will prevent the node's children being walked, or the `leave` function (which is optional) being called. + +Call `this.replace(new_node)` in either `enter` or `leave` to replace the current node with a new one. + +Call `this.remove()` in either `enter` or `leave` to remove the current node. + +## Why not use estraverse? + +The ESTree spec is evolving to accommodate ES6/7. I've had a couple of experiences where [estraverse](https://github.com/estools/estraverse) was unable to handle an AST generated by recent versions of acorn, because it hard-codes visitor keys. + +estree-walker, by contrast, simply enumerates a node's properties to find child nodes (and child lists of nodes), and is therefore resistant to spec changes. It's also much smaller. (The performance, if you're wondering, is basically identical.) + +None of which should be taken as criticism of estraverse, which has more features and has been battle-tested in many more situations, and for which I'm very grateful. + + +## License + +MIT diff --git a/node_modules/estree-walker/package.json b/node_modules/estree-walker/package.json new file mode 100644 index 0000000..c9f54ed --- /dev/null +++ b/node_modules/estree-walker/package.json @@ -0,0 +1,38 @@ +{ + "name": "estree-walker", + "description": "Traverse an ESTree-compliant AST", + "version": "3.0.3", + "private": false, + "author": "Rich Harris", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/Rich-Harris/estree-walker" + }, + "type": "module", + "module": "./src/index.js", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./types/index.d.ts", + "import": "./src/index.js" + } + }, + "types": "types/index.d.ts", + "scripts": { + "prepublishOnly": "tsc && npm test", + "test": "uvu test" + }, + "dependencies": { + "@types/estree": "^1.0.0" + }, + "devDependencies": { + "typescript": "^4.9.0", + "uvu": "^0.5.1" + }, + "files": [ + "src", + "types", + "README.md" + ] +} diff --git a/node_modules/estree-walker/src/async.js b/node_modules/estree-walker/src/async.js new file mode 100644 index 0000000..f068c71 --- /dev/null +++ b/node_modules/estree-walker/src/async.js @@ -0,0 +1,152 @@ +import { WalkerBase } from './walker.js'; + +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => Promise} AsyncHandler + */ + +export class AsyncWalker extends WalkerBase { + /** + * + * @param {AsyncHandler} [enter] + * @param {AsyncHandler} [leave] + */ + constructor(enter, leave) { + super(); + + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + + /** @type {AsyncHandler | undefined} */ + this.enter = enter; + + /** @type {AsyncHandler | undefined} */ + this.leave = leave; + } + + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Promise} + */ + async visit(node, parent, prop, index) { + if (node) { + if (this.enter) { + const _should_skip = this.should_skip; + const _should_remove = this.should_remove; + const _replacement = this.replacement; + this.should_skip = false; + this.should_remove = false; + this.replacement = null; + + await this.enter.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const skipped = this.should_skip; + const removed = this.should_remove; + + this.should_skip = _should_skip; + this.should_remove = _should_remove; + this.replacement = _replacement; + + if (skipped) return node; + if (removed) return null; + } + + /** @type {keyof Node} */ + let key; + + for (key in node) { + /** @type {unknown} */ + const value = node[key]; + + if (value && typeof value === 'object') { + if (Array.isArray(value)) { + const nodes = /** @type {Array} */ (value); + for (let i = 0; i < nodes.length; i += 1) { + const item = nodes[i]; + if (isNode(item)) { + if (!(await this.visit(item, node, key, i))) { + // removed + i--; + } + } + } + } else if (isNode(value)) { + await this.visit(value, node, key, null); + } + } + } + + if (this.leave) { + const _replacement = this.replacement; + const _should_remove = this.should_remove; + this.replacement = null; + this.should_remove = false; + + await this.leave.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const removed = this.should_remove; + + this.replacement = _replacement; + this.should_remove = _should_remove; + + if (removed) return null; + } + } + + return node; + } +} + +/** + * Ducktype a node. + * + * @param {unknown} value + * @returns {value is Node} + */ +function isNode(value) { + return ( + value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string' + ); +} diff --git a/node_modules/estree-walker/src/index.js b/node_modules/estree-walker/src/index.js new file mode 100644 index 0000000..933ea4f --- /dev/null +++ b/node_modules/estree-walker/src/index.js @@ -0,0 +1,34 @@ +import { SyncWalker } from './sync.js'; +import { AsyncWalker } from './async.js'; + +/** + * @typedef {import('estree').Node} Node + * @typedef {import('./sync.js').SyncHandler} SyncHandler + * @typedef {import('./async.js').AsyncHandler} AsyncHandler + */ + +/** + * @param {Node} ast + * @param {{ + * enter?: SyncHandler + * leave?: SyncHandler + * }} walker + * @returns {Node | null} + */ +export function walk(ast, { enter, leave }) { + const instance = new SyncWalker(enter, leave); + return instance.visit(ast, null); +} + +/** + * @param {Node} ast + * @param {{ + * enter?: AsyncHandler + * leave?: AsyncHandler + * }} walker + * @returns {Promise} + */ +export async function asyncWalk(ast, { enter, leave }) { + const instance = new AsyncWalker(enter, leave); + return await instance.visit(ast, null); +} diff --git a/node_modules/estree-walker/src/sync.js b/node_modules/estree-walker/src/sync.js new file mode 100644 index 0000000..171fb36 --- /dev/null +++ b/node_modules/estree-walker/src/sync.js @@ -0,0 +1,152 @@ +import { WalkerBase } from './walker.js'; + +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => void} SyncHandler + */ + +export class SyncWalker extends WalkerBase { + /** + * + * @param {SyncHandler} [enter] + * @param {SyncHandler} [leave] + */ + constructor(enter, leave) { + super(); + + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + + /** @type {SyncHandler | undefined} */ + this.enter = enter; + + /** @type {SyncHandler | undefined} */ + this.leave = leave; + } + + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Node | null} + */ + visit(node, parent, prop, index) { + if (node) { + if (this.enter) { + const _should_skip = this.should_skip; + const _should_remove = this.should_remove; + const _replacement = this.replacement; + this.should_skip = false; + this.should_remove = false; + this.replacement = null; + + this.enter.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const skipped = this.should_skip; + const removed = this.should_remove; + + this.should_skip = _should_skip; + this.should_remove = _should_remove; + this.replacement = _replacement; + + if (skipped) return node; + if (removed) return null; + } + + /** @type {keyof Node} */ + let key; + + for (key in node) { + /** @type {unknown} */ + const value = node[key]; + + if (value && typeof value === 'object') { + if (Array.isArray(value)) { + const nodes = /** @type {Array} */ (value); + for (let i = 0; i < nodes.length; i += 1) { + const item = nodes[i]; + if (isNode(item)) { + if (!this.visit(item, node, key, i)) { + // removed + i--; + } + } + } + } else if (isNode(value)) { + this.visit(value, node, key, null); + } + } + } + + if (this.leave) { + const _replacement = this.replacement; + const _should_remove = this.should_remove; + this.replacement = null; + this.should_remove = false; + + this.leave.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const removed = this.should_remove; + + this.replacement = _replacement; + this.should_remove = _should_remove; + + if (removed) return null; + } + } + + return node; + } +} + +/** + * Ducktype a node. + * + * @param {unknown} value + * @returns {value is Node} + */ +function isNode(value) { + return ( + value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string' + ); +} diff --git a/node_modules/estree-walker/src/walker.js b/node_modules/estree-walker/src/walker.js new file mode 100644 index 0000000..6dc6bd7 --- /dev/null +++ b/node_modules/estree-walker/src/walker.js @@ -0,0 +1,61 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef {{ + * skip: () => void; + * remove: () => void; + * replace: (node: Node) => void; + * }} WalkerContext + */ + +export class WalkerBase { + constructor() { + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + * @param {Node} node + */ + replace(parent, prop, index, node) { + if (parent && prop) { + if (index != null) { + /** @type {Array} */ (parent[prop])[index] = node; + } else { + /** @type {Node} */ (parent[prop]) = node; + } + } + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + */ + remove(parent, prop, index) { + if (parent && prop) { + if (index !== null && index !== undefined) { + /** @type {Array} */ (parent[prop]).splice(index, 1); + } else { + delete parent[prop]; + } + } + } +} diff --git a/node_modules/estree-walker/types/async.d.ts b/node_modules/estree-walker/types/async.d.ts new file mode 100644 index 0000000..db0825a --- /dev/null +++ b/node_modules/estree-walker/types/async.d.ts @@ -0,0 +1,36 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => Promise} AsyncHandler + */ +export class AsyncWalker extends WalkerBase { + /** + * + * @param {AsyncHandler} [enter] + * @param {AsyncHandler} [leave] + */ + constructor(enter?: AsyncHandler | undefined, leave?: AsyncHandler | undefined); + /** @type {AsyncHandler | undefined} */ + enter: AsyncHandler | undefined; + /** @type {AsyncHandler | undefined} */ + leave: AsyncHandler | undefined; + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Promise} + */ + visit(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Promise; +} +export type Node = import('estree').Node; +export type WalkerContext = import('./walker.js').WalkerContext; +export type AsyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => Promise; +import { WalkerBase } from "./walker.js"; diff --git a/node_modules/estree-walker/types/index.d.ts b/node_modules/estree-walker/types/index.d.ts new file mode 100644 index 0000000..c25afed --- /dev/null +++ b/node_modules/estree-walker/types/index.d.ts @@ -0,0 +1,32 @@ +/** + * @typedef {import('estree').Node} Node + * @typedef {import('./sync.js').SyncHandler} SyncHandler + * @typedef {import('./async.js').AsyncHandler} AsyncHandler + */ +/** + * @param {Node} ast + * @param {{ + * enter?: SyncHandler + * leave?: SyncHandler + * }} walker + * @returns {Node | null} + */ +export function walk(ast: Node, { enter, leave }: { + enter?: SyncHandler; + leave?: SyncHandler; +}): Node | null; +/** + * @param {Node} ast + * @param {{ + * enter?: AsyncHandler + * leave?: AsyncHandler + * }} walker + * @returns {Promise} + */ +export function asyncWalk(ast: Node, { enter, leave }: { + enter?: AsyncHandler; + leave?: AsyncHandler; +}): Promise; +export type Node = import('estree').Node; +export type SyncHandler = import('./sync.js').SyncHandler; +export type AsyncHandler = import('./async.js').AsyncHandler; diff --git a/node_modules/estree-walker/types/sync.d.ts b/node_modules/estree-walker/types/sync.d.ts new file mode 100644 index 0000000..3612b7f --- /dev/null +++ b/node_modules/estree-walker/types/sync.d.ts @@ -0,0 +1,36 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => void} SyncHandler + */ +export class SyncWalker extends WalkerBase { + /** + * + * @param {SyncHandler} [enter] + * @param {SyncHandler} [leave] + */ + constructor(enter?: SyncHandler | undefined, leave?: SyncHandler | undefined); + /** @type {SyncHandler | undefined} */ + enter: SyncHandler | undefined; + /** @type {SyncHandler | undefined} */ + leave: SyncHandler | undefined; + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Node | null} + */ + visit(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Node | null; +} +export type Node = import('estree').Node; +export type WalkerContext = import('./walker.js').WalkerContext; +export type SyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => void; +import { WalkerBase } from "./walker.js"; diff --git a/node_modules/estree-walker/types/walker.d.ts b/node_modules/estree-walker/types/walker.d.ts new file mode 100644 index 0000000..a3fa29c --- /dev/null +++ b/node_modules/estree-walker/types/walker.d.ts @@ -0,0 +1,39 @@ +/** + * @typedef { import('estree').Node} Node + * @typedef {{ + * skip: () => void; + * remove: () => void; + * replace: (node: Node) => void; + * }} WalkerContext + */ +export class WalkerBase { + /** @type {boolean} */ + should_skip: boolean; + /** @type {boolean} */ + should_remove: boolean; + /** @type {Node | null} */ + replacement: Node | null; + /** @type {WalkerContext} */ + context: WalkerContext; + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + * @param {Node} node + */ + replace(parent: Parent | null | undefined, prop: keyof Parent | null | undefined, index: number | null | undefined, node: Node): void; + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + */ + remove(parent: Parent_1 | null | undefined, prop: keyof Parent_1 | null | undefined, index: number | null | undefined): void; +} +export type Node = import('estree').Node; +export type WalkerContext = { + skip: () => void; + remove: () => void; + replace: (node: Node) => void; +}; diff --git a/node_modules/execa/index.d.ts b/node_modules/execa/index.d.ts new file mode 100644 index 0000000..7cef754 --- /dev/null +++ b/node_modules/execa/index.d.ts @@ -0,0 +1,955 @@ +import {type Buffer} from 'node:buffer'; +import {type ChildProcess} from 'node:child_process'; +import {type Stream, type Readable as ReadableStream, type Writable as WritableStream} from 'node:stream'; + +export type StdioOption = + | 'pipe' + | 'overlapped' + | 'ipc' + | 'ignore' + | 'inherit' + | Stream + | number + | undefined; + +type EncodingOption = + | 'utf8' + // eslint-disable-next-line unicorn/text-encoding-identifier-case + | 'utf-8' + | 'utf16le' + | 'utf-16le' + | 'ucs2' + | 'ucs-2' + | 'latin1' + | 'binary' + | 'ascii' + | 'hex' + | 'base64' + | 'base64url' + | 'buffer' + | null + | undefined; +type DefaultEncodingOption = 'utf8'; +type BufferEncodingOption = 'buffer' | null; + +export type CommonOptions = { + /** + Kill the spawned process when the parent process exits unless either: + - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached) + - the parent process is terminated abruptly, for example, with `SIGKILL` as opposed to `SIGTERM` or a normal exit + + @default true + */ + readonly cleanup?: boolean; + + /** + Prefer locally installed binaries when looking for a binary to execute. + + If you `$ npm install foo`, you can then `execa('foo')`. + + @default `true` with `$`, `false` otherwise + */ + readonly preferLocal?: boolean; + + /** + Preferred path to find locally installed binaries in (use with `preferLocal`). + + @default process.cwd() + */ + readonly localDir?: string | URL; + + /** + Path to the Node.js executable to use in child processes. + + This can be either an absolute path or a path relative to the `cwd` option. + + Requires `preferLocal` to be `true`. + + For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. + + @default process.execPath + */ + readonly execPath?: string; + + /** + Buffer the output from the spawned process. When set to `false`, you must read the output of `stdout` and `stderr` (or `all` if the `all` option is `true`). Otherwise the returned promise will not be resolved/rejected. + + If the spawned process fails, `error.stdout`, `error.stderr`, and `error.all` will contain the buffered data. + + @default true + */ + readonly buffer?: boolean; + + /** + Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + + @default `inherit` with `$`, `pipe` otherwise + */ + readonly stdin?: StdioOption; + + /** + Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + + @default 'pipe' + */ + readonly stdout?: StdioOption; + + /** + Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + + @default 'pipe' + */ + readonly stderr?: StdioOption; + + /** + Setting this to `false` resolves the promise with the error instead of rejecting it. + + @default true + */ + readonly reject?: boolean; + + /** + Add an `.all` property on the promise and the resolved value. The property contains the output of the process with `stdout` and `stderr` interleaved. + + @default false + */ + readonly all?: boolean; + + /** + Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output. + + @default true + */ + readonly stripFinalNewline?: boolean; + + /** + Set to `false` if you don't want to extend the environment variables when providing the `env` property. + + @default true + */ + readonly extendEnv?: boolean; + + /** + Current working directory of the child process. + + @default process.cwd() + */ + readonly cwd?: string | URL; + + /** + Environment key-value pairs. Extends automatically from `process.env`. Set `extendEnv` to `false` if you don't want this. + + @default process.env + */ + readonly env?: NodeJS.ProcessEnv; + + /** + Explicitly set the value of `argv[0]` sent to the child process. This will be set to `command` or `file` if not specified. + */ + readonly argv0?: string; + + /** + Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration. + + @default 'pipe' + */ + readonly stdio?: 'pipe' | 'overlapped' | 'ignore' | 'inherit' | readonly StdioOption[]; + + /** + Specify the kind of serialization used for sending messages between processes when using the `stdio: 'ipc'` option or `execaNode()`: + - `json`: Uses `JSON.stringify()` and `JSON.parse()`. + - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) + + [More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) + + @default 'json' + */ + readonly serialization?: 'json' | 'advanced'; + + /** + Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached). + + @default false + */ + readonly detached?: boolean; + + /** + Sets the user identity of the process. + */ + readonly uid?: number; + + /** + Sets the group identity of the process. + */ + readonly gid?: number; + + /** + If `true`, runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows. + + We recommend against using this option since it is: + - not cross-platform, encouraging shell-specific syntax. + - slower, because of the additional shell interpretation. + - unsafe, potentially allowing command injection. + + @default false + */ + readonly shell?: boolean | string; + + /** + Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `'buffer'` or `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string. + + @default 'utf8' + */ + readonly encoding?: EncodingType; + + /** + If `timeout` is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than `timeout` milliseconds. + + @default 0 + */ + readonly timeout?: number; + + /** + Largest amount of data in bytes allowed on `stdout` or `stderr`. Default: 100 MB. + + @default 100_000_000 + */ + readonly maxBuffer?: number; + + /** + Signal value to be used when the spawned process will be killed. + + @default 'SIGTERM' + */ + readonly killSignal?: string | number; + + /** + You can abort the spawned process using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). + + When `AbortController.abort()` is called, [`.isCanceled`](https://github.com/sindresorhus/execa#iscanceled) becomes `true`. + + @example + ``` + import {execa} from 'execa'; + + const abortController = new AbortController(); + const subprocess = execa('node', [], {signal: abortController.signal}); + + setTimeout(() => { + abortController.abort(); + }, 1000); + + try { + await subprocess; + } catch (error) { + console.log(subprocess.killed); // true + console.log(error.isCanceled); // true + } + ``` + */ + readonly signal?: AbortSignal; + + /** + If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`. + + @default false + */ + readonly windowsVerbatimArguments?: boolean; + + /** + On Windows, do not create a new console window. Please note this also prevents `CTRL-C` [from working](https://github.com/nodejs/node/issues/29837) on Windows. + + @default true + */ + readonly windowsHide?: boolean; + + /** + Print each command on `stderr` before executing it. + + This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process. + + @default false + */ + readonly verbose?: boolean; +}; + +export type Options = { + /** + Write some input to the `stdin` of your binary. + + If the input is a file, use the `inputFile` option instead. + */ + readonly input?: string | Buffer | ReadableStream; + + /** + Use a file as input to the the `stdin` of your binary. + + If the input is not a file, use the `input` option instead. + */ + readonly inputFile?: string; +} & CommonOptions; + +export type SyncOptions = { + /** + Write some input to the `stdin` of your binary. + + If the input is a file, use the `inputFile` option instead. + */ + readonly input?: string | Buffer; + + /** + Use a file as input to the the `stdin` of your binary. + + If the input is not a file, use the `input` option instead. + */ + readonly inputFile?: string; +} & CommonOptions; + +export type NodeOptions = { + /** + The Node.js executable to use. + + @default process.execPath + */ + readonly nodePath?: string; + + /** + List of [CLI options](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable. + + @default process.execArgv + */ + readonly nodeOptions?: string[]; +} & Options; + +type StdoutStderrAll = string | Buffer | undefined; + +export type ExecaReturnBase = { + /** + The file and arguments that were run, for logging purposes. + + This is not escaped and should not be executed directly as a process, including using `execa()` or `execaCommand()`. + */ + command: string; + + /** + Same as `command` but escaped. + + This is meant to be copy and pasted into a shell, for debugging purposes. + Since the escaping is fairly basic, this should not be executed directly as a process, including using `execa()` or `execaCommand()`. + */ + escapedCommand: string; + + /** + The numeric exit code of the process that was run. + */ + exitCode: number; + + /** + The output of the process on stdout. + */ + stdout: StdoutStderrType; + + /** + The output of the process on stderr. + */ + stderr: StdoutStderrType; + + /** + Whether the process failed to run. + */ + failed: boolean; + + /** + Whether the process timed out. + */ + timedOut: boolean; + + /** + Whether the process was killed. + */ + killed: boolean; + + /** + The name of the signal that was used to terminate the process. For example, `SIGFPE`. + + If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. + */ + signal?: string; + + /** + A human-friendly description of the signal that was used to terminate the process. For example, `Floating point arithmetic error`. + + If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen. + */ + signalDescription?: string; + + /** + The `cwd` of the command if provided in the command options. Otherwise it is `process.cwd()`. + */ + cwd: string; +}; + +export type ExecaSyncReturnValue = { +} & ExecaReturnBase; + +/** +Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance. + +The child process fails when: +- its exit code is not `0` +- it was killed with a signal +- timing out +- being canceled +- there's not enough memory or there are already too many child processes +*/ +export type ExecaReturnValue = { + /** + The output of the process with `stdout` and `stderr` interleaved. + + This is `undefined` if either: + - the `all` option is `false` (default value) + - `execaSync()` was used + */ + all?: StdoutStderrType; + + /** + Whether the process was canceled. + + You can cancel the spawned process using the [`signal`](https://github.com/sindresorhus/execa#signal-1) option. + */ + isCanceled: boolean; +} & ExecaSyncReturnValue; + +export type ExecaSyncError = { + /** + Error message when the child process failed to run. In addition to the underlying error message, it also contains some information related to why the child process errored. + + The child process stderr then stdout are appended to the end, separated with newlines and not interleaved. + */ + message: string; + + /** + This is the same as the `message` property except it does not include the child process stdout/stderr. + */ + shortMessage: string; + + /** + Original error message. This is the same as the `message` property except it includes neither the child process stdout/stderr nor some additional information added by Execa. + + This is `undefined` unless the child process exited due to an `error` event or a timeout. + */ + originalMessage?: string; +} & Error & ExecaReturnBase; + +export type ExecaError = { + /** + The output of the process with `stdout` and `stderr` interleaved. + + This is `undefined` if either: + - the `all` option is `false` (default value) + - `execaSync()` was used + */ + all?: StdoutStderrType; + + /** + Whether the process was canceled. + */ + isCanceled: boolean; +} & ExecaSyncError; + +export type KillOptions = { + /** + Milliseconds to wait for the child process to terminate before sending `SIGKILL`. + + Can be disabled with `false`. + + @default 5000 + */ + forceKillAfterTimeout?: number | false; +}; + +export type ExecaChildPromise = { + /** + Stream combining/interleaving [`stdout`](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout) and [`stderr`](https://nodejs.org/api/child_process.html#child_process_subprocess_stderr). + + This is `undefined` if either: + - the `all` option is `false` (the default value) + - both `stdout` and `stderr` options are set to [`'inherit'`, `'ipc'`, `Stream` or `integer`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio) + */ + all?: ReadableStream; + + catch( + onRejected?: (reason: ExecaError) => ResultType | PromiseLike + ): Promise | ResultType>; + + /** + Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal), except if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. Note that this graceful termination does not work on Windows, because Windows [doesn't support signals](https://nodejs.org/api/process.html#process_signal_events) (`SIGKILL` and `SIGTERM` has the same effect of force-killing the process immediately.) If you want to achieve graceful termination on Windows, you have to use other means, such as [`taskkill`](https://github.com/sindresorhus/taskkill). + */ + kill(signal?: string, options?: KillOptions): void; + + /** + Similar to [`childProcess.kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal). This used to be preferred when cancelling the child process execution as the error is more descriptive and [`childProcessResult.isCanceled`](#iscanceled) is set to `true`. But now this is deprecated and you should either use `.kill()` or the `signal` option when creating the child process. + */ + cancel(): void; + + /** + [Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be: + - Another `execa()` return value + - A writable stream + - A file path string + + If the `target` is another `execa()` return value, it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the final result. + + The `stdout` option] must be kept as `pipe`, its default value. + */ + pipeStdout?>(target: Target): Target; + pipeStdout?(target: WritableStream | string): ExecaChildProcess; + + /** + Like `pipeStdout()` but piping the child process's `stderr` instead. + + The `stderr` option must be kept as `pipe`, its default value. + */ + pipeStderr?>(target: Target): Target; + pipeStderr?(target: WritableStream | string): ExecaChildProcess; + + /** + Combines both `pipeStdout()` and `pipeStderr()`. + + Either the `stdout` option or the `stderr` option must be kept as `pipe`, their default value. Also, the `all` option must be set to `true`. + */ + pipeAll?>(target: Target): Target; + pipeAll?(target: WritableStream | string): ExecaChildProcess; +}; + +export type ExecaChildProcess = ChildProcess & +ExecaChildPromise & +Promise>; + +/** +Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a `childProcess`. + +Arguments are automatically escaped. They can contain any character, including spaces. + +This is the preferred method when executing single commands. + +@param file - The program/script to execute. +@param arguments - Arguments to pass to `file` on execution. +@returns An `ExecaChildProcess` that is both: + - a `Promise` resolving or rejecting with a `childProcessResult`. + - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. +@throws A `childProcessResult` error + +@example Promise interface +``` +import {execa} from 'execa'; + +const {stdout} = await execa('echo', ['unicorns']); +console.log(stdout); +//=> 'unicorns' +``` + +@example Redirect output to a file +``` +import {execa} from 'execa'; + +// Similar to `echo unicorns > stdout.txt` in Bash +await execa('echo', ['unicorns']).pipeStdout('stdout.txt'); + +// Similar to `echo unicorns 2> stdout.txt` in Bash +await execa('echo', ['unicorns']).pipeStderr('stderr.txt'); + +// Similar to `echo unicorns &> stdout.txt` in Bash +await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt'); +``` + +@example Redirect input from a file +``` +import {execa} from 'execa'; + +// Similar to `cat < stdin.txt` in Bash +const {stdout} = await execa('cat', {inputFile: 'stdin.txt'}); +console.log(stdout); +//=> 'unicorns' +``` + +@example Save and pipe output from a child process +``` +import {execa} from 'execa'; + +const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout); +// Prints `unicorns` +console.log(stdout); +// Also returns 'unicorns' +``` + +@example Pipe multiple processes +``` +import {execa} from 'execa'; + +// Similar to `echo unicorns | cat` in Bash +const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat')); +console.log(stdout); +//=> 'unicorns' +``` + +@example Handling errors +``` +import {execa} from 'execa'; + +// Catching an error +try { + await execa('unknown', ['command']); +} catch (error) { + console.log(error); + /* + { + message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', + errno: -2, + code: 'ENOENT', + syscall: 'spawn unknown', + path: 'unknown', + spawnargs: ['command'], + originalMessage: 'spawn unknown ENOENT', + shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', + command: 'unknown command', + escapedCommand: 'unknown command', + stdout: '', + stderr: '', + failed: true, + timedOut: false, + isCanceled: false, + killed: false, + cwd: '/path/to/cwd' + } + \*\/ +} +``` + +@example Graceful termination +``` +const subprocess = execa('node'); + +setTimeout(() => { + subprocess.kill('SIGTERM', { + forceKillAfterTimeout: 2000 + }); +}, 1000); +``` +*/ +export function execa( + file: string, + arguments?: readonly string[], + options?: Options +): ExecaChildProcess; +export function execa( + file: string, + arguments?: readonly string[], + options?: Options +): ExecaChildProcess; +export function execa(file: string, options?: Options): ExecaChildProcess; +export function execa(file: string, options?: Options): ExecaChildProcess; + +/** +Same as `execa()` but synchronous. + +@param file - The program/script to execute. +@param arguments - Arguments to pass to `file` on execution. +@returns A `childProcessResult` object +@throws A `childProcessResult` error + +@example Promise interface +``` +import {execa} from 'execa'; + +const {stdout} = execaSync('echo', ['unicorns']); +console.log(stdout); +//=> 'unicorns' +``` + +@example Redirect input from a file +``` +import {execa} from 'execa'; + +// Similar to `cat < stdin.txt` in Bash +const {stdout} = execaSync('cat', {inputFile: 'stdin.txt'}); +console.log(stdout); +//=> 'unicorns' +``` + +@example Handling errors +``` +import {execa} from 'execa'; + +// Catching an error +try { + execaSync('unknown', ['command']); +} catch (error) { + console.log(error); + /* + { + message: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT', + errno: -2, + code: 'ENOENT', + syscall: 'spawnSync unknown', + path: 'unknown', + spawnargs: ['command'], + originalMessage: 'spawnSync unknown ENOENT', + shortMessage: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT', + command: 'unknown command', + escapedCommand: 'unknown command', + stdout: '', + stderr: '', + failed: true, + timedOut: false, + isCanceled: false, + killed: false, + cwd: '/path/to/cwd' + } + \*\/ +} +``` +*/ +export function execaSync( + file: string, + arguments?: readonly string[], + options?: SyncOptions +): ExecaSyncReturnValue; +export function execaSync( + file: string, + arguments?: readonly string[], + options?: SyncOptions +): ExecaSyncReturnValue; +export function execaSync(file: string, options?: SyncOptions): ExecaSyncReturnValue; +export function execaSync( + file: string, + options?: SyncOptions +): ExecaSyncReturnValue; + +/** +Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`. + +Arguments are automatically escaped. They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`. + +This is the preferred method when executing a user-supplied `command` string, such as in a REPL. + +@param command - The program/script to execute and its arguments. +@returns An `ExecaChildProcess` that is both: + - a `Promise` resolving or rejecting with a `childProcessResult`. + - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. +@throws A `childProcessResult` error + +@example +``` +import {execaCommand} from 'execa'; + +const {stdout} = await execaCommand('echo unicorns'); +console.log(stdout); +//=> 'unicorns' +``` +*/ +export function execaCommand(command: string, options?: Options): ExecaChildProcess; +export function execaCommand(command: string, options?: Options): ExecaChildProcess; + +/** +Same as `execaCommand()` but synchronous. + +@param command - The program/script to execute and its arguments. +@returns A `childProcessResult` object +@throws A `childProcessResult` error + +@example +``` +import {execaCommandSync} from 'execa'; + +const {stdout} = execaCommandSync('echo unicorns'); +console.log(stdout); +//=> 'unicorns' +``` +*/ +export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue; +export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue; + +type TemplateExpression = + | string + | number + | ExecaReturnValue + | ExecaSyncReturnValue + | Array | ExecaSyncReturnValue>; + +type Execa$ = { + /** + Returns a new instance of `$` but with different default `options`. Consecutive calls are merged to previous ones. + + This can be used to either: + - Set options for a specific command: `` $(options)`command` `` + - Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand` `` + + @param options - Options to set + @returns A new instance of `$` with those `options` set + + @example + ``` + import {$} from 'execa'; + + const $$ = $({stdio: 'inherit'}); + + await $$`echo unicorns`; + //=> 'unicorns' + + await $$`echo rainbows`; + //=> 'rainbows' + ``` + */ + (options: Options): Execa$; + (options: Options): Execa$; + (options: Options): Execa$; + ( + templates: TemplateStringsArray, + ...expressions: TemplateExpression[] + ): ExecaChildProcess; + + /** + Same as $\`command\` but synchronous. + + @returns A `childProcessResult` object + @throws A `childProcessResult` error + + @example Basic + ``` + import {$} from 'execa'; + + const branch = $.sync`git branch --show-current`; + $.sync`dep deploy --branch=${branch}`; + ``` + + @example Multiple arguments + ``` + import {$} from 'execa'; + + const args = ['unicorns', '&', 'rainbows!']; + const {stdout} = $.sync`echo ${args}`; + console.log(stdout); + //=> 'unicorns & rainbows!' + ``` + + @example With options + ``` + import {$} from 'execa'; + + $.sync({stdio: 'inherit'})`echo unicorns`; + //=> 'unicorns' + ``` + + @example Shared options + ``` + import {$} from 'execa'; + + const $$ = $({stdio: 'inherit'}); + + $$.sync`echo unicorns`; + //=> 'unicorns' + + $$.sync`echo rainbows`; + //=> 'rainbows' + ``` + */ + sync( + templates: TemplateStringsArray, + ...expressions: TemplateExpression[] + ): ExecaSyncReturnValue; +}; + +/** +Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`. + +Arguments are automatically escaped. They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``. + +This is the preferred method when executing multiple commands in a script file. + +The `command` string can inject any `${value}` with the following types: string, number, `childProcess` or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used. + +@returns An `ExecaChildProcess` that is both: + - a `Promise` resolving or rejecting with a `childProcessResult`. + - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. +@throws A `childProcessResult` error + +@example Basic +``` +import {$} from 'execa'; + +const branch = await $`git branch --show-current`; +await $`dep deploy --branch=${branch}`; +``` + +@example Multiple arguments +``` +import {$} from 'execa'; + +const args = ['unicorns', '&', 'rainbows!']; +const {stdout} = await $`echo ${args}`; +console.log(stdout); +//=> 'unicorns & rainbows!' +``` + +@example With options +``` +import {$} from 'execa'; + +await $({stdio: 'inherit'})`echo unicorns`; +//=> 'unicorns' +``` + +@example Shared options +``` +import {$} from 'execa'; + +const $$ = $({stdio: 'inherit'}); + +await $$`echo unicorns`; +//=> 'unicorns' + +await $$`echo rainbows`; +//=> 'rainbows' +``` +*/ +export const $: Execa$; + +/** +Execute a Node.js script as a child process. + +Arguments are automatically escaped. They can contain any character, including spaces. + +This is the preferred method when executing Node.js files. + +Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options): + - the current Node version and options are used. This can be overridden using the `nodePath` and `nodeOptions` options. + - the `shell` option cannot be used + - an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to `stdio` + +@param scriptPath - Node.js script to execute. +@param arguments - Arguments to pass to `scriptPath` on execution. +@returns An `ExecaChildProcess` that is both: + - a `Promise` resolving or rejecting with a `childProcessResult`. + - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties. +@throws A `childProcessResult` error + +@example +``` +import {execa} from 'execa'; + +await execaNode('scriptPath', ['argument']); +``` +*/ +export function execaNode( + scriptPath: string, + arguments?: readonly string[], + options?: NodeOptions +): ExecaChildProcess; +export function execaNode( + scriptPath: string, + arguments?: readonly string[], + options?: NodeOptions +): ExecaChildProcess; +export function execaNode(scriptPath: string, options?: NodeOptions): ExecaChildProcess; +export function execaNode(scriptPath: string, options?: NodeOptions): ExecaChildProcess; diff --git a/node_modules/execa/index.js b/node_modules/execa/index.js new file mode 100644 index 0000000..fa41762 --- /dev/null +++ b/node_modules/execa/index.js @@ -0,0 +1,309 @@ +import {Buffer} from 'node:buffer'; +import path from 'node:path'; +import childProcess from 'node:child_process'; +import process from 'node:process'; +import crossSpawn from 'cross-spawn'; +import stripFinalNewline from 'strip-final-newline'; +import {npmRunPathEnv} from 'npm-run-path'; +import onetime from 'onetime'; +import {makeError} from './lib/error.js'; +import {normalizeStdio, normalizeStdioNode} from './lib/stdio.js'; +import {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} from './lib/kill.js'; +import {addPipeMethods} from './lib/pipe.js'; +import {handleInput, getSpawnedResult, makeAllStream, handleInputSync} from './lib/stream.js'; +import {mergePromise, getSpawnedPromise} from './lib/promise.js'; +import {joinCommand, parseCommand, parseTemplates, getEscapedCommand} from './lib/command.js'; +import {logCommand, verboseDefault} from './lib/verbose.js'; + +const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; + +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; + + if (preferLocal) { + return npmRunPathEnv({env, cwd: localDir, execPath}); + } + + return env; +}; + +const handleArguments = (file, args, options = {}) => { + const parsed = crossSpawn._parse(file, args, options); + file = parsed.command; + args = parsed.args; + options = parsed.options; + + options = { + maxBuffer: DEFAULT_MAX_BUFFER, + buffer: true, + stripFinalNewline: true, + extendEnv: true, + preferLocal: false, + localDir: options.cwd || process.cwd(), + execPath: process.execPath, + encoding: 'utf8', + reject: true, + cleanup: true, + all: false, + windowsHide: true, + verbose: verboseDefault, + ...options, + }; + + options.env = getEnv(options); + + options.stdio = normalizeStdio(options); + + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + args.unshift('/q'); + } + + return {file, args, options, parsed}; +}; + +const handleOutput = (options, value, error) => { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execaSync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; + } + + if (options.stripFinalNewline) { + return stripFinalNewline(value); + } + + return value; +}; + +export function execa(file, args, options) { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); + const escapedCommand = getEscapedCommand(file, args); + logCommand(escapedCommand, parsed.options); + + validateTimeout(parsed.options); + + let spawned; + try { + spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); + } catch (error) { + // Ensure the returned error is always both a promise and a child process + const dummySpawned = new childProcess.ChildProcess(); + const errorPromise = Promise.reject(makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + escapedCommand, + parsed, + timedOut: false, + isCanceled: false, + killed: false, + })); + mergePromise(dummySpawned, errorPromise); + return dummySpawned; + } + + const spawnedPromise = getSpawnedPromise(spawned); + const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); + const processDone = setExitHandler(spawned, parsed.options, timedPromise); + + const context = {isCanceled: false}; + + spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); + spawned.cancel = spawnedCancel.bind(null, spawned, context); + + const handlePromise = async () => { + const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); + const stdout = handleOutput(parsed.options, stdoutResult); + const stderr = handleOutput(parsed.options, stderrResult); + const all = handleOutput(parsed.options, allResult); + + if (error || exitCode !== 0 || signal !== null) { + const returnedError = makeError({ + error, + exitCode, + signal, + stdout, + stderr, + all, + command, + escapedCommand, + parsed, + timedOut, + isCanceled: context.isCanceled || (parsed.options.signal ? parsed.options.signal.aborted : false), + killed: spawned.killed, + }); + + if (!parsed.options.reject) { + return returnedError; + } + + throw returnedError; + } + + return { + command, + escapedCommand, + exitCode: 0, + stdout, + stderr, + all, + failed: false, + timedOut: false, + isCanceled: false, + killed: false, + }; + }; + + const handlePromiseOnce = onetime(handlePromise); + + handleInput(spawned, parsed.options); + + spawned.all = makeAllStream(spawned, parsed.options); + + addPipeMethods(spawned); + mergePromise(spawned, handlePromiseOnce); + return spawned; +} + +export function execaSync(file, args, options) { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); + const escapedCommand = getEscapedCommand(file, args); + logCommand(escapedCommand, parsed.options); + + const input = handleInputSync(parsed.options); + + let result; + try { + result = childProcess.spawnSync(parsed.file, parsed.args, {...parsed.options, input}); + } catch (error) { + throw makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + escapedCommand, + parsed, + timedOut: false, + isCanceled: false, + killed: false, + }); + } + + const stdout = handleOutput(parsed.options, result.stdout, result.error); + const stderr = handleOutput(parsed.options, result.stderr, result.error); + + if (result.error || result.status !== 0 || result.signal !== null) { + const error = makeError({ + stdout, + stderr, + error: result.error, + signal: result.signal, + exitCode: result.status, + command, + escapedCommand, + parsed, + timedOut: result.error && result.error.code === 'ETIMEDOUT', + isCanceled: false, + killed: result.signal !== null, + }); + + if (!parsed.options.reject) { + return error; + } + + throw error; + } + + return { + command, + escapedCommand, + exitCode: 0, + stdout, + stderr, + failed: false, + timedOut: false, + isCanceled: false, + killed: false, + }; +} + +const normalizeScriptStdin = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined + ? {stdin: 'inherit'} + : {}; + +const normalizeScriptOptions = (options = {}) => ({ + preferLocal: true, + ...normalizeScriptStdin(options), + ...options, +}); + +function create$(options) { + function $(templatesOrOptions, ...expressions) { + if (!Array.isArray(templatesOrOptions)) { + return create$({...options, ...templatesOrOptions}); + } + + const [file, ...args] = parseTemplates(templatesOrOptions, expressions); + return execa(file, args, normalizeScriptOptions(options)); + } + + $.sync = (templates, ...expressions) => { + if (!Array.isArray(templates)) { + throw new TypeError('Please use $(options).sync`command` instead of $.sync(options)`command`.'); + } + + const [file, ...args] = parseTemplates(templates, expressions); + return execaSync(file, args, normalizeScriptOptions(options)); + }; + + return $; +} + +export const $ = create$(); + +export function execaCommand(command, options) { + const [file, ...args] = parseCommand(command); + return execa(file, args, options); +} + +export function execaCommandSync(command, options) { + const [file, ...args] = parseCommand(command); + return execaSync(file, args, options); +} + +export function execaNode(scriptPath, args, options = {}) { + if (args && !Array.isArray(args) && typeof args === 'object') { + options = args; + args = []; + } + + const stdio = normalizeStdioNode(options); + const defaultExecArgv = process.execArgv.filter(arg => !arg.startsWith('--inspect')); + + const { + nodePath = process.execPath, + nodeOptions = defaultExecArgv, + } = options; + + return execa( + nodePath, + [ + ...nodeOptions, + scriptPath, + ...(Array.isArray(args) ? args : []), + ], + { + ...options, + stdin: undefined, + stdout: undefined, + stderr: undefined, + stdio, + shell: false, + }, + ); +} diff --git a/node_modules/execa/lib/command.js b/node_modules/execa/lib/command.js new file mode 100644 index 0000000..727ce5f --- /dev/null +++ b/node_modules/execa/lib/command.js @@ -0,0 +1,119 @@ +import {Buffer} from 'node:buffer'; +import {ChildProcess} from 'node:child_process'; + +const normalizeArgs = (file, args = []) => { + if (!Array.isArray(args)) { + return [file]; + } + + return [file, ...args]; +}; + +const NO_ESCAPE_REGEXP = /^[\w.-]+$/; + +const escapeArg = arg => { + if (typeof arg !== 'string' || NO_ESCAPE_REGEXP.test(arg)) { + return arg; + } + + return `"${arg.replaceAll('"', '\\"')}"`; +}; + +export const joinCommand = (file, args) => normalizeArgs(file, args).join(' '); + +export const getEscapedCommand = (file, args) => normalizeArgs(file, args).map(arg => escapeArg(arg)).join(' '); + +const SPACES_REGEXP = / +/g; + +// Handle `execaCommand()` +export const parseCommand = command => { + const tokens = []; + for (const token of command.trim().split(SPACES_REGEXP)) { + // Allow spaces to be escaped by a backslash if not meant as a delimiter + const previousToken = tokens.at(-1); + if (previousToken && previousToken.endsWith('\\')) { + // Merge previous token with current one + tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + } else { + tokens.push(token); + } + } + + return tokens; +}; + +const parseExpression = expression => { + const typeOfExpression = typeof expression; + + if (typeOfExpression === 'string') { + return expression; + } + + if (typeOfExpression === 'number') { + return String(expression); + } + + if ( + typeOfExpression === 'object' + && expression !== null + && !(expression instanceof ChildProcess) + && 'stdout' in expression + ) { + const typeOfStdout = typeof expression.stdout; + + if (typeOfStdout === 'string') { + return expression.stdout; + } + + if (Buffer.isBuffer(expression.stdout)) { + return expression.stdout.toString(); + } + + throw new TypeError(`Unexpected "${typeOfStdout}" stdout in template expression`); + } + + throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`); +}; + +const concatTokens = (tokens, nextTokens, isNew) => isNew || tokens.length === 0 || nextTokens.length === 0 + ? [...tokens, ...nextTokens] + : [ + ...tokens.slice(0, -1), + `${tokens.at(-1)}${nextTokens[0]}`, + ...nextTokens.slice(1), + ]; + +const parseTemplate = ({templates, expressions, tokens, index, template}) => { + const templateString = template ?? templates.raw[index]; + const templateTokens = templateString.split(SPACES_REGEXP).filter(Boolean); + const newTokens = concatTokens( + tokens, + templateTokens, + templateString.startsWith(' '), + ); + + if (index === expressions.length) { + return newTokens; + } + + const expression = expressions[index]; + const expressionTokens = Array.isArray(expression) + ? expression.map(expression => parseExpression(expression)) + : [parseExpression(expression)]; + return concatTokens( + newTokens, + expressionTokens, + templateString.endsWith(' '), + ); +}; + +export const parseTemplates = (templates, expressions) => { + let tokens = []; + + for (const [index, template] of templates.entries()) { + tokens = parseTemplate({templates, expressions, tokens, index, template}); + } + + return tokens; +}; + diff --git a/node_modules/execa/lib/error.js b/node_modules/execa/lib/error.js new file mode 100644 index 0000000..5e80c52 --- /dev/null +++ b/node_modules/execa/lib/error.js @@ -0,0 +1,87 @@ +import process from 'node:process'; +import {signalsByName} from 'human-signals'; + +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } + + if (isCanceled) { + return 'was canceled'; + } + + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } + + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; + } + + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } + + return 'failed'; +}; + +export const makeError = ({ + stdout, + stderr, + all, + error, + signal, + exitCode, + command, + escapedCommand, + timedOut, + isCanceled, + killed, + parsed: {options: {timeout, cwd = process.cwd()}}, +}) => { + // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. + // We normalize them to `undefined` + exitCode = exitCode === null ? undefined : exitCode; + signal = signal === null ? undefined : signal; + const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; + + const errorCode = error && error.code; + + const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); + const execaMessage = `Command ${prefix}: ${command}`; + const isError = Object.prototype.toString.call(error) === '[object Error]'; + const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; + const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); + + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); + } + + error.shortMessage = shortMessage; + error.command = command; + error.escapedCommand = escapedCommand; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; + error.cwd = cwd; + + if (all !== undefined) { + error.all = all; + } + + if ('bufferedData' in error) { + delete error.bufferedData; + } + + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; + + return error; +}; diff --git a/node_modules/execa/lib/kill.js b/node_modules/execa/lib/kill.js new file mode 100644 index 0000000..12ce0a1 --- /dev/null +++ b/node_modules/execa/lib/kill.js @@ -0,0 +1,102 @@ +import os from 'node:os'; +import {onExit} from 'signal-exit'; + +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + +// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior +export const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { + const killResult = kill(signal); + setKillTimeout(kill, signal, options, killResult); + return killResult; +}; + +const setKillTimeout = (kill, signal, options, killResult) => { + if (!shouldForceKill(signal, options, killResult)) { + return; + } + + const timeout = getForceKillAfterTimeout(options); + const t = setTimeout(() => { + kill('SIGKILL'); + }, timeout); + + // Guarded because there's no `.unref()` when `execa` is used in the renderer + // process in Electron. This cannot be tested since we don't run tests in + // Electron. + // istanbul ignore else + if (t.unref) { + t.unref(); + } +}; + +const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => isSigterm(signal) && forceKillAfterTimeout !== false && killResult; + +const isSigterm = signal => signal === os.constants.signals.SIGTERM + || (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); + +const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { + if (forceKillAfterTimeout === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } + + if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); + } + + return forceKillAfterTimeout; +}; + +// `childProcess.cancel()` +export const spawnedCancel = (spawned, context) => { + const killResult = spawned.kill(); + + if (killResult) { + context.isCanceled = true; + } +}; + +const timeoutKill = (spawned, signal, reject) => { + spawned.kill(signal); + reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); +}; + +// `timeout` option handling +export const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { + if (timeout === 0 || timeout === undefined) { + return spawnedPromise; + } + + let timeoutId; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = setTimeout(() => { + timeoutKill(spawned, killSignal, reject); + }, timeout); + }); + + const safeSpawnedPromise = spawnedPromise.finally(() => { + clearTimeout(timeoutId); + }); + + return Promise.race([timeoutPromise, safeSpawnedPromise]); +}; + +export const validateTimeout = ({timeout}) => { + if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } +}; + +// `cleanup` option handling +export const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { + if (!cleanup || detached) { + return timedPromise; + } + + const removeExitHandler = onExit(() => { + spawned.kill(); + }); + + return timedPromise.finally(() => { + removeExitHandler(); + }); +}; diff --git a/node_modules/execa/lib/pipe.js b/node_modules/execa/lib/pipe.js new file mode 100644 index 0000000..e73ffcc --- /dev/null +++ b/node_modules/execa/lib/pipe.js @@ -0,0 +1,42 @@ +import {createWriteStream} from 'node:fs'; +import {ChildProcess} from 'node:child_process'; +import {isWritableStream} from 'is-stream'; + +const isExecaChildProcess = target => target instanceof ChildProcess && typeof target.then === 'function'; + +const pipeToTarget = (spawned, streamName, target) => { + if (typeof target === 'string') { + spawned[streamName].pipe(createWriteStream(target)); + return spawned; + } + + if (isWritableStream(target)) { + spawned[streamName].pipe(target); + return spawned; + } + + if (!isExecaChildProcess(target)) { + throw new TypeError('The second argument must be a string, a stream or an Execa child process.'); + } + + if (!isWritableStream(target.stdin)) { + throw new TypeError('The target child process\'s stdin must be available.'); + } + + spawned[streamName].pipe(target.stdin); + return target; +}; + +export const addPipeMethods = spawned => { + if (spawned.stdout !== null) { + spawned.pipeStdout = pipeToTarget.bind(undefined, spawned, 'stdout'); + } + + if (spawned.stderr !== null) { + spawned.pipeStderr = pipeToTarget.bind(undefined, spawned, 'stderr'); + } + + if (spawned.all !== undefined) { + spawned.pipeAll = pipeToTarget.bind(undefined, spawned, 'all'); + } +}; diff --git a/node_modules/execa/lib/promise.js b/node_modules/execa/lib/promise.js new file mode 100644 index 0000000..a4773f3 --- /dev/null +++ b/node_modules/execa/lib/promise.js @@ -0,0 +1,36 @@ +// eslint-disable-next-line unicorn/prefer-top-level-await +const nativePromisePrototype = (async () => {})().constructor.prototype; + +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), +]); + +// The return value is a mixin of `childProcess` and `Promise` +export const mergePromise = (spawned, promise) => { + for (const [property, descriptor] of descriptors) { + // Starting the main `promise` is deferred to avoid consuming streams + const value = typeof promise === 'function' + ? (...args) => Reflect.apply(descriptor.value, promise(), args) + : descriptor.value.bind(promise); + + Reflect.defineProperty(spawned, property, {...descriptor, value}); + } +}; + +// Use promises instead of `child_process` events +export const getSpawnedPromise = spawned => new Promise((resolve, reject) => { + spawned.on('exit', (exitCode, signal) => { + resolve({exitCode, signal}); + }); + + spawned.on('error', error => { + reject(error); + }); + + if (spawned.stdin) { + spawned.stdin.on('error', error => { + reject(error); + }); + } +}); diff --git a/node_modules/execa/lib/stdio.js b/node_modules/execa/lib/stdio.js new file mode 100644 index 0000000..e8c1132 --- /dev/null +++ b/node_modules/execa/lib/stdio.js @@ -0,0 +1,49 @@ +const aliases = ['stdin', 'stdout', 'stderr']; + +const hasAlias = options => aliases.some(alias => options[alias] !== undefined); + +export const normalizeStdio = options => { + if (!options) { + return; + } + + const {stdio} = options; + + if (stdio === undefined) { + return aliases.map(alias => options[alias]); + } + + if (hasAlias(options)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); + } + + if (typeof stdio === 'string') { + return stdio; + } + + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + + const length = Math.max(stdio.length, aliases.length); + return Array.from({length}, (value, index) => stdio[index]); +}; + +// `ipc` is pushed unless it is already present +export const normalizeStdioNode = options => { + const stdio = normalizeStdio(options); + + if (stdio === 'ipc') { + return 'ipc'; + } + + if (stdio === undefined || typeof stdio === 'string') { + return [stdio, stdio, stdio, 'ipc']; + } + + if (stdio.includes('ipc')) { + return stdio; + } + + return [...stdio, 'ipc']; +}; diff --git a/node_modules/execa/lib/stream.js b/node_modules/execa/lib/stream.js new file mode 100644 index 0000000..4e06459 --- /dev/null +++ b/node_modules/execa/lib/stream.js @@ -0,0 +1,133 @@ +import {createReadStream, readFileSync} from 'node:fs'; +import {setTimeout} from 'node:timers/promises'; +import {isStream} from 'is-stream'; +import getStream, {getStreamAsBuffer} from 'get-stream'; +import mergeStream from 'merge-stream'; + +const validateInputOptions = input => { + if (input !== undefined) { + throw new TypeError('The `input` and `inputFile` options cannot be both set.'); + } +}; + +const getInputSync = ({input, inputFile}) => { + if (typeof inputFile !== 'string') { + return input; + } + + validateInputOptions(input); + return readFileSync(inputFile); +}; + +// `input` and `inputFile` option in sync mode +export const handleInputSync = options => { + const input = getInputSync(options); + + if (isStream(input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } + + return input; +}; + +const getInput = ({input, inputFile}) => { + if (typeof inputFile !== 'string') { + return input; + } + + validateInputOptions(input); + return createReadStream(inputFile); +}; + +// `input` and `inputFile` option in async mode +export const handleInput = (spawned, options) => { + const input = getInput(options); + + if (input === undefined) { + return; + } + + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); + } +}; + +// `all` interleaves `stdout` and `stderr` +export const makeAllStream = (spawned, {all}) => { + if (!all || (!spawned.stdout && !spawned.stderr)) { + return; + } + + const mixed = mergeStream(); + + if (spawned.stdout) { + mixed.add(spawned.stdout); + } + + if (spawned.stderr) { + mixed.add(spawned.stderr); + } + + return mixed; +}; + +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +const getBufferedData = async (stream, streamPromise) => { + // When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve + if (!stream || streamPromise === undefined) { + return; + } + + // Wait for the `all` stream to receive the last chunk before destroying the stream + await setTimeout(0); + + stream.destroy(); + + try { + return await streamPromise; + } catch (error) { + return error.bufferedData; + } +}; + +const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { + if (!stream || !buffer) { + return; + } + + // eslint-disable-next-line unicorn/text-encoding-identifier-case + if (encoding === 'utf8' || encoding === 'utf-8') { + return getStream(stream, {maxBuffer}); + } + + if (encoding === null || encoding === 'buffer') { + return getStreamAsBuffer(stream, {maxBuffer}); + } + + return applyEncoding(stream, maxBuffer, encoding); +}; + +const applyEncoding = async (stream, maxBuffer, encoding) => { + const buffer = await getStreamAsBuffer(stream, {maxBuffer}); + return buffer.toString(encoding); +}; + +// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) +export const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { + const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); + const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); + const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); + + try { + return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); + } catch (error) { + return Promise.all([ + {error, signal: error.signal, timedOut: error.timedOut}, + getBufferedData(stdout, stdoutPromise), + getBufferedData(stderr, stderrPromise), + getBufferedData(all, allPromise), + ]); + } +}; diff --git a/node_modules/execa/lib/verbose.js b/node_modules/execa/lib/verbose.js new file mode 100644 index 0000000..5f5490e --- /dev/null +++ b/node_modules/execa/lib/verbose.js @@ -0,0 +1,19 @@ +import {debuglog} from 'node:util'; +import process from 'node:process'; + +export const verboseDefault = debuglog('execa').enabled; + +const padField = (field, padding) => String(field).padStart(padding, '0'); + +const getTimestamp = () => { + const date = new Date(); + return `${padField(date.getHours(), 2)}:${padField(date.getMinutes(), 2)}:${padField(date.getSeconds(), 2)}.${padField(date.getMilliseconds(), 3)}`; +}; + +export const logCommand = (escapedCommand, {verbose}) => { + if (!verbose) { + return; + } + + process.stderr.write(`[${getTimestamp()}] ${escapedCommand}\n`); +}; diff --git a/node_modules/execa/license b/node_modules/execa/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/execa/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/execa/package.json b/node_modules/execa/package.json new file mode 100644 index 0000000..24ff179 --- /dev/null +++ b/node_modules/execa/package.json @@ -0,0 +1,90 @@ +{ + "name": "execa", + "version": "8.0.1", + "description": "Process execution for humans", + "license": "MIT", + "repository": "sindresorhus/execa", + "funding": "https://github.com/sindresorhus/execa?sponsor=1", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "engines": { + "node": ">=16.17" + }, + "scripts": { + "test": "xo && c8 ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts", + "lib" + ], + "keywords": [ + "exec", + "child", + "process", + "execute", + "fork", + "execfile", + "spawn", + "file", + "shell", + "bin", + "binary", + "binaries", + "npm", + "path", + "local", + "zx" + ], + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "devDependencies": { + "@types/node": "^20.4.0", + "ava": "^5.2.0", + "c8": "^8.0.1", + "get-node": "^14.2.0", + "is-running": "^2.1.0", + "p-event": "^6.0.0", + "path-key": "^4.0.0", + "tempfile": "^5.0.0", + "tsd": "^0.28.1", + "xo": "^0.55.0" + }, + "c8": { + "reporter": [ + "text", + "lcov" + ], + "exclude": [ + "**/fixtures/**", + "**/test.js", + "**/test/**" + ] + }, + "ava": { + "workerThreads": false + }, + "xo": { + "rules": { + "unicorn/no-empty-file": "off", + "@typescript-eslint/ban-types": "off" + } + } +} diff --git a/node_modules/execa/readme.md b/node_modules/execa/readme.md new file mode 100644 index 0000000..1babbe5 --- /dev/null +++ b/node_modules/execa/readme.md @@ -0,0 +1,822 @@ + + + execa logo + +
+ +[![Coverage Status](https://codecov.io/gh/sindresorhus/execa/branch/main/graph/badge.svg)](https://codecov.io/gh/sindresorhus/execa) + +> Process execution for humans + +
+ +--- + +
+

+

+ + Sindre's open source work is supported by the community + +

+ Special thanks to: +
+
+ + + + + Transloadit logo + + +
+
+

+
+ +--- + +
+ +## Why + +This package improves [`child_process`](https://nodejs.org/api/child_process.html) methods with: + +- [Promise interface](#execacommandcommand-options). +- [Scripts interface](#scripts-interface), like `zx`. +- Improved [Windows support](https://github.com/IndigoUnited/node-cross-spawn#why), including [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) binaries. +- Executes [locally installed binaries](#preferlocal) without `npx`. +- [Cleans up](#cleanup) child processes when the parent process ends. +- [Graceful termination](#optionsforcekillaftertimeout). +- Get [interleaved output](#all) from `stdout` and `stderr` similar to what is printed on the terminal. +- [Strips the final newline](#stripfinalnewline) from the output so you don't have to do `stdout.trim()`. +- Convenience methods to pipe processes' [input](#input) and [output](#redirect-output-to-a-file). +- Can specify file and arguments [as a single string](#execacommandcommand-options) without a shell. +- [Verbose mode](#verbose-mode) for debugging. +- More descriptive errors. +- Higher max buffer: 100 MB instead of 1 MB. + +## Install + +```sh +npm install execa +``` + +## Usage + +### Promise interface + +```js +import {execa} from 'execa'; + +const {stdout} = await execa('echo', ['unicorns']); +console.log(stdout); +//=> 'unicorns' +``` + +### Scripts interface + +For more information about Execa scripts, please see [this page](docs/scripts.md). + +#### Basic + +```js +import {$} from 'execa'; + +const branch = await $`git branch --show-current`; +await $`dep deploy --branch=${branch}`; +``` + +#### Multiple arguments + +```js +import {$} from 'execa'; + +const args = ['unicorns', '&', 'rainbows!']; +const {stdout} = await $`echo ${args}`; +console.log(stdout); +//=> 'unicorns & rainbows!' +``` + +#### With options + +```js +import {$} from 'execa'; + +await $({stdio: 'inherit'})`echo unicorns`; +//=> 'unicorns' +``` + +#### Shared options + +```js +import {$} from 'execa'; + +const $$ = $({stdio: 'inherit'}); + +await $$`echo unicorns`; +//=> 'unicorns' + +await $$`echo rainbows`; +//=> 'rainbows' +``` + +#### Verbose mode + +```sh +> node file.js +unicorns +rainbows + +> NODE_DEBUG=execa node file.js +[16:50:03.305] echo unicorns +unicorns +[16:50:03.308] echo rainbows +rainbows +``` + +### Input/output + +#### Redirect output to a file + +```js +import {execa} from 'execa'; + +// Similar to `echo unicorns > stdout.txt` in Bash +await execa('echo', ['unicorns']).pipeStdout('stdout.txt'); + +// Similar to `echo unicorns 2> stdout.txt` in Bash +await execa('echo', ['unicorns']).pipeStderr('stderr.txt'); + +// Similar to `echo unicorns &> stdout.txt` in Bash +await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt'); +``` + +#### Redirect input from a file + +```js +import {execa} from 'execa'; + +// Similar to `cat < stdin.txt` in Bash +const {stdout} = await execa('cat', {inputFile: 'stdin.txt'}); +console.log(stdout); +//=> 'unicorns' +``` + +#### Save and pipe output from a child process + +```js +import {execa} from 'execa'; + +const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout); +// Prints `unicorns` +console.log(stdout); +// Also returns 'unicorns' +``` + +#### Pipe multiple processes + +```js +import {execa} from 'execa'; + +// Similar to `echo unicorns | cat` in Bash +const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat')); +console.log(stdout); +//=> 'unicorns' +``` + +### Handling Errors + +```js +import {execa} from 'execa'; + +// Catching an error +try { + await execa('unknown', ['command']); +} catch (error) { + console.log(error); + /* + { + message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', + errno: -2, + code: 'ENOENT', + syscall: 'spawn unknown', + path: 'unknown', + spawnargs: ['command'], + originalMessage: 'spawn unknown ENOENT', + shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT', + command: 'unknown command', + escapedCommand: 'unknown command', + stdout: '', + stderr: '', + failed: true, + timedOut: false, + isCanceled: false, + killed: false + } + */ +} +``` + +### Graceful termination + +Using SIGTERM, and after 2 seconds, kill it with SIGKILL. + +```js +const subprocess = execa('node'); + +setTimeout(() => { + subprocess.kill('SIGTERM', { + forceKillAfterTimeout: 2000 + }); +}, 1000); +``` + +## API + +### Methods + +#### execa(file, arguments?, options?) + +Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess). + +Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces. + +This is the preferred method when executing single commands. + +#### execaNode(scriptPath, arguments?, options?) + +Executes a Node.js file using `node scriptPath ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess). + +Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces. + +This is the preferred method when executing Node.js files. + +Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options): + - the current Node version and options are used. This can be overridden using the [`nodePath`](#nodepath-for-node-only) and [`nodeOptions`](#nodeoptions-for-node-only) options. + - the [`shell`](#shell) option cannot be used + - an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio) + +#### $\`command\` + +Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess). + +Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``. + +This is the preferred method when executing multiple commands in a script file. + +The `command` string can inject any `${value}` with the following types: string, number, [`childProcess`](#childprocess) or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used. + +For more information, please see [this section](#scripts-interface) and [this page](docs/scripts.md). + +#### $(options) + +Returns a new instance of [`$`](#command) but with different default `options`. Consecutive calls are merged to previous ones. + +This can be used to either: + - Set options for a specific command: `` $(options)`command` `` + - Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand`; `` + +#### execaCommand(command, options?) + +Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess). + +Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`. + +This is the preferred method when executing a user-supplied `command` string, such as in a REPL. + +### execaSync(file, arguments?, options?) + +Same as [`execa()`](#execacommandcommand-options) but synchronous. + +Returns or throws a [`childProcessResult`](#childProcessResult). + +### $.sync\`command\` + +Same as [$\`command\`](#command) but synchronous. + +Returns or throws a [`childProcessResult`](#childProcessResult). + +### execaCommandSync(command, options?) + +Same as [`execaCommand()`](#execacommand-command-options) but synchronous. + +Returns or throws a [`childProcessResult`](#childProcessResult). + +### Shell syntax + +For all the [methods above](#methods), no shell interpreter (Bash, cmd.exe, etc.) is used unless the [`shell` option](#shell) is set. This means shell-specific characters and expressions (`$variable`, `&&`, `||`, `;`, `|`, etc.) have no special meaning and do not need to be escaped. + +### childProcess + +The return value of all [asynchronous methods](#methods) is both: + - a `Promise` resolving or rejecting with a [`childProcessResult`](#childProcessResult). + - a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with the following additional methods and properties. + +#### kill(signal?, options?) + +Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal) except: if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. + +Note that this graceful termination does not work on Windows, because Windows [doesn't support signals](https://nodejs.org/api/process.html#process_signal_events) (`SIGKILL` and `SIGTERM` has the same effect of force-killing the process immediately.) If you want to achieve graceful termination on Windows, you have to use other means, such as [`taskkill`](https://github.com/sindresorhus/taskkill). + +##### options.forceKillAfterTimeout + +Type: `number | false`\ +Default: `5000` + +Milliseconds to wait for the child process to terminate before sending `SIGKILL`. + +Can be disabled with `false`. + +#### all + +Type: `ReadableStream | undefined` + +Stream combining/interleaving [`stdout`](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout) and [`stderr`](https://nodejs.org/api/child_process.html#child_process_subprocess_stderr). + +This is `undefined` if either: + - the [`all` option](#all-2) is `false` (the default value) + - both [`stdout`](#stdout-1) and [`stderr`](#stderr-1) options are set to [`'inherit'`, `'ipc'`, `Stream` or `integer`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio) + +#### pipeStdout(target) + +[Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be: + - Another [`execa()` return value](#pipe-multiple-processes) + - A [writable stream](#save-and-pipe-output-from-a-child-process) + - A [file path string](#redirect-output-to-a-file) + +If the `target` is another [`execa()` return value](#execacommandcommand-options), it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the [final result](#childprocessresult). + +The [`stdout` option](#stdout-1) must be kept as `pipe`, its default value. + +#### pipeStderr(target) + +Like [`pipeStdout()`](#pipestdouttarget) but piping the child process's `stderr` instead. + +The [`stderr` option](#stderr-1) must be kept as `pipe`, its default value. + +#### pipeAll(target) + +Combines both [`pipeStdout()`](#pipestdouttarget) and [`pipeStderr()`](#pipestderrtarget). + +Either the [`stdout` option](#stdout-1) or the [`stderr` option](#stderr-1) must be kept as `pipe`, their default value. Also, the [`all` option](#all-2) must be set to `true`. + +### childProcessResult + +Type: `object` + +Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance. + +The child process [fails](#failed) when: +- its [exit code](#exitcode) is not `0` +- it was [killed](#killed) with a [signal](#signal) +- [timing out](#timedout) +- [being canceled](#iscanceled) +- there's not enough memory or there are already too many child processes + +#### command + +Type: `string` + +The file and arguments that were run, for logging purposes. + +This is not escaped and should not be executed directly as a process, including using [`execa()`](#execafile-arguments-options) or [`execaCommand()`](#execacommandcommand-options). + +#### escapedCommand + +Type: `string` + +Same as [`command`](#command-1) but escaped. + +This is meant to be copy and pasted into a shell, for debugging purposes. +Since the escaping is fairly basic, this should not be executed directly as a process, including using [`execa()`](#execafile-arguments-options) or [`execaCommand()`](#execacommandcommand-options). + +#### exitCode + +Type: `number` + +The numeric exit code of the process that was run. + +#### stdout + +Type: `string | Buffer` + +The output of the process on stdout. + +#### stderr + +Type: `string | Buffer` + +The output of the process on stderr. + +#### all + +Type: `string | Buffer | undefined` + +The output of the process with `stdout` and `stderr` interleaved. + +This is `undefined` if either: + - the [`all` option](#all-2) is `false` (the default value) + - `execaSync()` was used + +#### failed + +Type: `boolean` + +Whether the process failed to run. + +#### timedOut + +Type: `boolean` + +Whether the process timed out. + +#### isCanceled + +Type: `boolean` + +Whether the process was canceled. + +You can cancel the spawned process using the [`signal`](#signal-1) option. + +#### killed + +Type: `boolean` + +Whether the process was killed. + +#### signal + +Type: `string | undefined` + +The name of the signal that was used to terminate the process. For example, `SIGFPE`. + +If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. + +#### signalDescription + +Type: `string | undefined` + +A human-friendly description of the signal that was used to terminate the process. For example, `Floating point arithmetic error`. + +If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen. + +#### cwd + +Type: `string` + +The `cwd` of the command if provided in the [command options](#cwd-1). Otherwise it is `process.cwd()`. + +#### message + +Type: `string` + +Error message when the child process failed to run. In addition to the [underlying error message](#originalMessage), it also contains some information related to why the child process errored. + +The child process [stderr](#stderr) then [stdout](#stdout) are appended to the end, separated with newlines and not interleaved. + +#### shortMessage + +Type: `string` + +This is the same as the [`message` property](#message) except it does not include the child process stdout/stderr. + +#### originalMessage + +Type: `string | undefined` + +Original error message. This is the same as the `message` property except it includes neither the child process stdout/stderr nor some additional information added by Execa. + +This is `undefined` unless the child process exited due to an `error` event or a timeout. + +### options + +Type: `object` + +#### cleanup + +Type: `boolean`\ +Default: `true` + +Kill the spawned process when the parent process exits unless either: + - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached) + - the parent process is terminated abruptly, for example, with `SIGKILL` as opposed to `SIGTERM` or a normal exit + +#### preferLocal + +Type: `boolean`\ +Default: `true` with [`$`](#command), `false` otherwise + +Prefer locally installed binaries when looking for a binary to execute.\ +If you `$ npm install foo`, you can then `execa('foo')`. + +#### localDir + +Type: `string | URL`\ +Default: `process.cwd()` + +Preferred path to find locally installed binaries in (use with `preferLocal`). + +#### execPath + +Type: `string`\ +Default: `process.execPath` (Current Node.js executable) + +Path to the Node.js executable to use in child processes. + +This can be either an absolute path or a path relative to the [`cwd` option](#cwd). + +Requires [`preferLocal`](#preferlocal) to be `true`. + +For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. + +#### buffer + +Type: `boolean`\ +Default: `true` + +Buffer the output from the spawned process. When set to `false`, you must read the output of [`stdout`](#stdout-1) and [`stderr`](#stderr-1) (or [`all`](#all) if the [`all`](#all-2) option is `true`). Otherwise the returned promise will not be resolved/rejected. + +If the spawned process fails, [`error.stdout`](#stdout), [`error.stderr`](#stderr), and [`error.all`](#all) will contain the buffered data. + +#### input + +Type: `string | Buffer | stream.Readable` + +Write some input to the `stdin` of your binary.\ +Streams are not allowed when using the synchronous methods. + +If the input is a file, use the [`inputFile` option](#inputfile) instead. + +#### inputFile + +Type: `string` + +Use a file as input to the the `stdin` of your binary. + +If the input is not a file, use the [`input` option](#input) instead. + +#### stdin + +Type: `string | number | Stream | undefined`\ +Default: `inherit` with [`$`](#command), `pipe` otherwise + +Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + +#### stdout + +Type: `string | number | Stream | undefined`\ +Default: `pipe` + +Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + +#### stderr + +Type: `string | number | Stream | undefined`\ +Default: `pipe` + +Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio). + +#### all + +Type: `boolean`\ +Default: `false` + +Add an `.all` property on the [promise](#all) and the [resolved value](#all-1). The property contains the output of the process with `stdout` and `stderr` interleaved. + +#### reject + +Type: `boolean`\ +Default: `true` + +Setting this to `false` resolves the promise with the error instead of rejecting it. + +#### stripFinalNewline + +Type: `boolean`\ +Default: `true` + +Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output. + +#### extendEnv + +Type: `boolean`\ +Default: `true` + +Set to `false` if you don't want to extend the environment variables when providing the `env` property. + +--- + +Execa also accepts the below options which are the same as the options for [`child_process#spawn()`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)/[`child_process#exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) + +#### cwd + +Type: `string | URL`\ +Default: `process.cwd()` + +Current working directory of the child process. + +#### env + +Type: `object`\ +Default: `process.env` + +Environment key-value pairs. Extends automatically from `process.env`. Set [`extendEnv`](#extendenv) to `false` if you don't want this. + +#### argv0 + +Type: `string` + +Explicitly set the value of `argv[0]` sent to the child process. This will be set to `file` if not specified. + +#### stdio + +Type: `string | string[]`\ +Default: `pipe` + +Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration. + +#### serialization + +Type: `string`\ +Default: `'json'` + +Specify the kind of serialization used for sending messages between processes when using the [`stdio: 'ipc'`](#stdio) option or [`execaNode()`](#execanodescriptpath-arguments-options): + - `json`: Uses `JSON.stringify()` and `JSON.parse()`. + - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) + +[More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) + +#### detached + +Type: `boolean` + +Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached). + +#### uid + +Type: `number` + +Sets the user identity of the process. + +#### gid + +Type: `number` + +Sets the group identity of the process. + +#### shell + +Type: `boolean | string`\ +Default: `false` + +If `true`, runs `file` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows. + +We recommend against using this option since it is: +- not cross-platform, encouraging shell-specific syntax. +- slower, because of the additional shell interpretation. +- unsafe, potentially allowing command injection. + +#### encoding + +Type: `string | null`\ +Default: `utf8` + +Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `'buffer'` or `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string. + +#### timeout + +Type: `number`\ +Default: `0` + +If timeout is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than timeout milliseconds. + +#### maxBuffer + +Type: `number`\ +Default: `100_000_000` (100 MB) + +Largest amount of data in bytes allowed on `stdout` or `stderr`. + +#### killSignal + +Type: `string | number`\ +Default: `SIGTERM` + +Signal value to be used when the spawned process will be killed. + +#### signal + +Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) + +You can abort the spawned process using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). + +When `AbortController.abort()` is called, [`.isCanceled`](#iscanceled) becomes `true`. + +#### windowsVerbatimArguments + +Type: `boolean`\ +Default: `false` + +If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`. + +#### windowsHide + +Type: `boolean`\ +Default: `true` + +On Windows, do not create a new console window. Please note this also prevents `CTRL-C` [from working](https://github.com/nodejs/node/issues/29837) on Windows. + +#### verbose + +Type: `boolean`\ +Default: `false` + +[Print each command](#verbose-mode) on `stderr` before executing it. + +This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process. + +#### nodePath *(For `.node()` only)* + +Type: `string`\ +Default: [`process.execPath`](https://nodejs.org/api/process.html#process_process_execpath) + +Node.js executable used to create the child process. + +#### nodeOptions *(For `.node()` only)* + +Type: `string[]`\ +Default: [`process.execArgv`](https://nodejs.org/api/process.html#process_process_execargv) + +List of [CLI options](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable. + +## Tips + +### Retry on error + +Gracefully handle failures by using automatic retries and exponential backoff with the [`p-retry`](https://github.com/sindresorhus/p-retry) package: + +```js +import pRetry from 'p-retry'; + +const run = async () => { + const results = await execa('curl', ['-sSL', 'https://sindresorhus.com/unicorn']); + return results; +}; + +console.log(await pRetry(run, {retries: 5})); +``` + +### Cancelling a spawned process + +```js +import {execa} from 'execa'; + +const abortController = new AbortController(); +const subprocess = execa('node', [], {signal: abortController.signal}); + +setTimeout(() => { + abortController.abort(); +}, 1000); + +try { + await subprocess; +} catch (error) { + console.log(subprocess.killed); // true + console.log(error.isCanceled); // true +} +``` + +### Execute the current package's binary + +```js +import {getBinPath} from 'get-bin-path'; + +const binPath = await getBinPath(); +await execa(binPath); +``` + +`execa` can be combined with [`get-bin-path`](https://github.com/ehmicky/get-bin-path) to test the current package's binary. As opposed to hard-coding the path to the binary, this validates that the `package.json` `bin` field is correctly set up. + +## Related + +- [gulp-execa](https://github.com/ehmicky/gulp-execa) - Gulp plugin for `execa` +- [nvexeca](https://github.com/ehmicky/nvexeca) - Run `execa` using any Node.js version +- [sudo-prompt](https://github.com/jorangreef/sudo-prompt) - Run commands with elevated privileges. + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [@ehmicky](https://github.com/ehmicky) + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/get-func-name/LICENSE b/node_modules/get-func-name/LICENSE new file mode 100644 index 0000000..7ea799f --- /dev/null +++ b/node_modules/get-func-name/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/get-func-name/README.md b/node_modules/get-func-name/README.md new file mode 100644 index 0000000..e908416 --- /dev/null +++ b/node_modules/get-func-name/README.md @@ -0,0 +1,123 @@ +

+ + ChaiJS +
+ get-func-name +
+

+ +

+ Utility for getting a function's name for node and the browser. +

+ +

+ + license:mit + + + tag:? + + + build:? + + + coverage:? + + + npm:? + + + dependencies:? + + + devDependencies:? + +
+ + Selenium Test Status + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is get-func-name? + +This is a module to retrieve a function's name securely and consistently both in NodeJS and the browser. + +## Installation + +### Node.js + +`get-func-name` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install get-func-name + +### Browsers + +You can also use it within the browser; install via npm and use the `get-func-name.js` file found within the download. For example: + +```html + +``` + +## Usage + +The module `get-func-name` exports the following method: + +* `getFuncName(fn)` - Returns the name of a function. + +```js +var getFuncName = require('get-func-name'); +``` + +#### .getFuncName(fun) + +```js +var getFuncName = require('get-func-name'); + +var unknownFunction = function myCoolFunction(word) { + return word + 'is cool'; +}; + +var anonymousFunction = (function () { + return function () {}; +}()); + +getFuncName(unknownFunction) // 'myCoolFunction' +getFuncName(anonymousFunction) // '' +``` diff --git a/node_modules/get-func-name/get-func-name.js b/node_modules/get-func-name/get-func-name.js new file mode 100644 index 0000000..0070ed4 --- /dev/null +++ b/node_modules/get-func-name/get-func-name.js @@ -0,0 +1 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + * MIT Licensed + */ + +/** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + +var toString = Function.prototype.toString; +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; +var maxFunctionSourceLength = 512; +function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // eslint-disable-next-line prefer-reflect + var functionSource = toString.call(aFunc); + // To avoid unconstrained resource consumption due to pathalogically large function names, + // we limit the available return value to be less than 512 characters. + if (functionSource.indexOf('(') > maxFunctionSourceLength) { + return name; + } + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = functionSource.match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; +} + +module.exports = getFuncName; diff --git a/node_modules/get-func-name/package.json b/node_modules/get-func-name/package.json new file mode 100644 index 0000000..0eb8838 --- /dev/null +++ b/node_modules/get-func-name/package.json @@ -0,0 +1,85 @@ +{ + "name": "get-func-name", + "version": "2.0.2", + "description": "Utility for getting a function's name for node and the browser", + "keywords": [ + "get-func-name", + "chai util" + ], + "license": "MIT", + "author": "Jake Luer (http://alogicalparadox.com)", + "contributors": [ + "Keith Cirkel (https://github.com/keithamus)", + "Lucas Fernandes da Costa (https://github.com/lucasfcosta)", + "Grant Snodgrass (https://github.com/meeber)", + "Lucas Vieira (https://github.com/vieiralucas)", + "Aleksey Shvayka (https://github.com/shvaikalesh)" + ], + "files": [ + "index.js", + "get-func-name.js" + ], + "main": "./index.js", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/get-func-name.git" + }, + "scripts": { + "build": "browserify --bare $npm_package_main --standalone getFuncName -o get-func-name.js", + "lint": "eslint --ignore-path .gitignore .", + "prepublish": "npm run build", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser && npm run upload-coverage", + "test:browser": "karma start --singleRun=true", + "test:node": "istanbul cover _mocha", + "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0" + }, + "config": { + "ghooks": { + "commit-msg": "validate-commit-msg" + } + }, + "eslintConfig": { + "extends": [ + "strict/es5" + ], + "env": { + "es6": true + }, + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": 0, + "max-statements": 0 + } + }, + "dependencies": {}, + "devDependencies": { + "browserify": "^13.0.0", + "browserify-istanbul": "^2.0.0", + "coveralls": "2.11.14", + "eslint": "^2.4.0", + "eslint-config-strict": "^9.1.0", + "eslint-plugin-filenames": "^1.1.0", + "ghooks": "^1.0.1", + "istanbul": "^0.4.2", + "karma": "^1.3.0", + "karma-browserify": "^5.0.2", + "karma-coverage": "^1.1.1", + "karma-mocha": "^1.2.0", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sauce-launcher": "^1.0.0", + "lcov-result-merger": "^1.0.2", + "mocha": "^3.1.2", + "phantomjs-prebuilt": "^2.1.5", + "semantic-release": "^4.3.5", + "simple-assert": "^1.0.0", + "travis-after-all": "^1.4.4", + "validate-commit-msg": "^2.3.1" + }, + "engines": { + "node": "*" + } +} diff --git a/node_modules/get-stream/license b/node_modules/get-stream/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/get-stream/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/get-stream/package.json b/node_modules/get-stream/package.json new file mode 100644 index 0000000..bfd9a00 --- /dev/null +++ b/node_modules/get-stream/package.json @@ -0,0 +1,53 @@ +{ + "name": "get-stream", + "version": "8.0.1", + "description": "Get a stream as a string, Buffer, ArrayBuffer or array", + "license": "MIT", + "repository": "sindresorhus/get-stream", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./source/index.d.ts", + "default": "./source/index.js" + }, + "engines": { + "node": ">=16" + }, + "scripts": { + "benchmark": "node benchmarks/index.js", + "test": "xo && ava && tsd --typings=source/index.d.ts --files=source/index.test-d.ts" + }, + "files": [ + "source", + "!*.test-d.ts" + ], + "keywords": [ + "get", + "stream", + "promise", + "concat", + "string", + "text", + "buffer", + "read", + "data", + "consume", + "readable", + "readablestream", + "object", + "concat" + ], + "devDependencies": { + "@types/node": "^20.5.0", + "ava": "^5.3.1", + "precise-now": "^2.0.0", + "stream-json": "^1.8.0", + "tsd": "^0.28.1", + "xo": "^0.56.0" + } +} diff --git a/node_modules/get-stream/readme.md b/node_modules/get-stream/readme.md new file mode 100644 index 0000000..7f04b94 --- /dev/null +++ b/node_modules/get-stream/readme.md @@ -0,0 +1,291 @@ +# get-stream + +> Get a stream as a string, Buffer, ArrayBuffer or array + +## Features + +- Works in any JavaScript environment ([Node.js](#nodejs-streams), [browsers](#web-streams), etc.). +- Supports [text streams](#getstreamstream-options), [binary streams](#getstreamasbufferstream-options) and [object streams](#getstreamasarraystream-options). +- Supports [async iterables](#async-iterables). +- Can set a [maximum stream size](#maxbuffer). +- Returns [partially read data](#errors) when the stream errors. +- [Fast](#benchmarks). + +## Install + +```sh +npm install get-stream +``` + +## Usage + +### Node.js streams + +```js +import fs from 'node:fs'; +import getStream from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); + +console.log(await getStream(stream)); +/* + ,,))))))));, + __)))))))))))))), +\|/ -\(((((''''((((((((. +-*-==//////(('' . `)))))), +/|\ ))| o ;-. '((((( ,(, + ( `| / ) ;))))' ,_))^;(~ + | | | ,))((((_ _____------~~~-. %,;(;(>';'~ + o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ + ; ''''```` `: `:::|\,__,%% );`'; ~ + | _ ) / `:|`----' `-' + ______/\/~ | / / + /~;;.____/;;' / ___--,-( `;;;/ + / // _;______;'------~~~~~ /;;/\ / + // | | / ; \;;,\ + (<_ | ; /',/-----' _> + \_| ||_ //~;~~~~~~~~~ + `\_| (,~~ + \~\ + ~~ +*/ +``` + +### Web streams + +```js +import getStream from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream)); +``` + +### Async iterables + +```js +import {opendir} from 'node:fs/promises'; +import {getStreamAsArray} from 'get-stream'; + +const asyncIterable = await opendir(directory); +console.log(await getStreamAsArray(asyncIterable)); +``` + +## API + +The following methods read the stream's contents and return it as a promise. + +### getStream(stream, options?) + +`stream`: [`stream.Readable`](https://nodejs.org/api/stream.html#class-streamreadable), [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream), or [`AsyncIterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols)\ +`options`: [`Options`](#options) + +Get the given `stream` as a string. + +### getStreamAsBuffer(stream, options?) + +Get the given `stream` as a Node.js [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer). + +```js +import {getStreamAsBuffer} from 'get-stream'; + +const stream = fs.createReadStream('unicorn.png'); +console.log(await getStreamAsBuffer(stream)); +``` + +### getStreamAsArrayBuffer(stream, options?) + +Get the given `stream` as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). + +```js +import {getStreamAsArrayBuffer} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArrayBuffer(readableStream)); +``` + +### getStreamAsArray(stream, options?) + +Get the given `stream` as an array. Unlike [other methods](#api), this supports [streams of objects](https://nodejs.org/api/stream.html#object-mode). + +```js +import {getStreamAsArray} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArray(readableStream)); +``` + +#### options + +Type: `object` + +##### maxBuffer + +Type: `number`\ +Default: `Infinity` + +Maximum length of the stream. If exceeded, the promise will be rejected with a `MaxBufferError`. + +Depending on the [method](#api), the length is measured with [`string.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length), [`buffer.length`](https://nodejs.org/api/buffer.html#buflength), [`arrayBuffer.byteLength`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength) or [`array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). + +## Errors + +If the stream errors, the returned promise will be rejected with the `error`. Any contents already read from the stream will be set to `error.bufferedData`, which is a `string`, a `Buffer`, an `ArrayBuffer` or an array depending on the [method used](#api). + +```js +import getStream from 'get-stream'; + +try { + await getStream(streamThatErrorsAtTheEnd('unicorn')); +} catch (error) { + console.log(error.bufferedData); + //=> 'unicorn' +} +``` + +## Tips + +### Alternatives + +If you do not need the [`maxBuffer`](#maxbuffer) option, [`error.bufferedData`](#errors), nor browser support, you can use the following methods instead of this package. + +#### [`streamConsumers.text()`](https://nodejs.org/api/webstreams.html#streamconsumerstextstream) + +```js +import fs from 'node:fs'; +import {text} from 'node:stream/consumers'; + +const stream = fs.createReadStream('unicorn.txt', {encoding: 'utf8'}); +console.log(await text(stream)) +``` + +#### [`streamConsumers.buffer()`](https://nodejs.org/api/webstreams.html#streamconsumersbufferstream) + +```js +import {buffer} from 'node:stream/consumers'; + +console.log(await buffer(stream)) +``` + +#### [`streamConsumers.arrayBuffer()`](https://nodejs.org/api/webstreams.html#streamconsumersarraybufferstream) + +```js +import {arrayBuffer} from 'node:stream/consumers'; + +console.log(await arrayBuffer(stream)) +``` + +#### [`readable.toArray()`](https://nodejs.org/api/stream.html#readabletoarrayoptions) + +```js +console.log(await stream.toArray()) +``` + +#### [`Array.fromAsync()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync) + +If your [environment supports it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync#browser_compatibility): + +```js +console.log(await Array.fromAsync(stream)) +``` + +### Non-UTF-8 encoding + +When all of the following conditions apply: + - [`getStream()`](#getstreamstream-options) is used (as opposed to [`getStreamAsBuffer()`](#getstreamasbufferstream-options) or [`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options)) + - The stream is binary (not text) + - The stream's encoding is not UTF-8 (for example, it is UTF-16, hexadecimal, or Base64) + +Then the stream must be decoded using a transform stream like [`TextDecoderStream`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoderStream) or [`b64`](https://github.com/hapijs/b64). + +```js +import getStream from 'get-stream'; + +const textDecoderStream = new TextDecoderStream('utf-16le'); +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream.pipeThrough(textDecoderStream))); +``` + +### Blobs + +[`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options) can be used to create [Blobs](https://developer.mozilla.org/en-US/docs/Web/API/Blob). + +```js +import {getStreamAsArrayBuffer} from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); +console.log(new Blob([await getStreamAsArrayBuffer(stream)])); +``` + +### JSON streaming + +[`getStreamAsArray()`](#getstreamasarraystream-options) can be combined with JSON streaming utilities to parse JSON incrementally. + +```js +import fs from 'node:fs'; +import {compose as composeStreams} from 'node:stream'; +import {getStreamAsArray} from 'get-stream'; +import streamJson from 'stream-json'; +import streamJsonArray from 'stream-json/streamers/StreamArray.js'; + +const stream = fs.createReadStream('big-array-of-objects.json'); +console.log(await getStreamAsArray( + composeStreams(stream, streamJson.parser(), streamJsonArray.streamArray()), +)); +``` + +## Benchmarks + +### Node.js stream (100 MB, binary) + +- `getStream()`: 142ms +- `text()`: 139ms +- `getStreamAsBuffer()`: 106ms +- `buffer()`: 83ms +- `getStreamAsArrayBuffer()`: 105ms +- `arrayBuffer()`: 81ms +- `getStreamAsArray()`: 24ms +- `stream.toArray()`: 21ms + +### Node.js stream (100 MB, text) + +- `getStream()`: 90ms +- `text()`: 89ms +- `getStreamAsBuffer()`: 127ms +- `buffer()`: 192ms +- `getStreamAsArrayBuffer()`: 129ms +- `arrayBuffer()`: 195ms +- `getStreamAsArray()`: 89ms +- `stream.toArray()`: 90ms + +### Web ReadableStream (100 MB, binary) + +- `getStream()`: 223ms +- `text()`: 221ms +- `getStreamAsBuffer()`: 182ms +- `buffer()`: 153ms +- `getStreamAsArrayBuffer()`: 171ms +- `arrayBuffer()`: 155ms +- `getStreamAsArray()`: 83ms + +### Web ReadableStream (100 MB, text) + +- `getStream()`: 141ms +- `text()`: 139ms +- `getStreamAsBuffer()`: 91ms +- `buffer()`: 80ms +- `getStreamAsArrayBuffer()`: 89ms +- `arrayBuffer()`: 81ms +- `getStreamAsArray()`: 21ms + +[Benchmarks' source file](benchmarks/index.js). + +## FAQ + +### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)? + +This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, `Buffer`, an `ArrayBuffer` or an array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package. + +## Related + +- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer +- [into-stream](https://github.com/sindresorhus/into-stream) - The opposite of this package diff --git a/node_modules/get-stream/source/array-buffer.js b/node_modules/get-stream/source/array-buffer.js new file mode 100644 index 0000000..a547405 --- /dev/null +++ b/node_modules/get-stream/source/array-buffer.js @@ -0,0 +1,84 @@ +import {getStreamContents} from './contents.js'; +import {noop, throwObjectStream, getLengthProp} from './utils.js'; + +export async function getStreamAsArrayBuffer(stream, options) { + return getStreamContents(stream, arrayBufferMethods, options); +} + +const initArrayBuffer = () => ({contents: new ArrayBuffer(0)}); + +const useTextEncoder = chunk => textEncoder.encode(chunk); +const textEncoder = new TextEncoder(); + +const useUint8Array = chunk => new Uint8Array(chunk); + +const useUint8ArrayWithOffset = chunk => new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); + +const truncateArrayBufferChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +// `contents` is an increasingly growing `Uint8Array`. +const addArrayBufferChunk = (convertedChunk, {contents, length: previousLength}, length) => { + const newContents = hasArrayBufferResize() ? resizeArrayBuffer(contents, length) : resizeArrayBufferSlow(contents, length); + new Uint8Array(newContents).set(convertedChunk, previousLength); + return newContents; +}; + +// Without `ArrayBuffer.resize()`, `contents` size is always a power of 2. +// This means its last bytes are zeroes (not stream data), which need to be +// trimmed at the end with `ArrayBuffer.slice()`. +const resizeArrayBufferSlow = (contents, length) => { + if (length <= contents.byteLength) { + return contents; + } + + const arrayBuffer = new ArrayBuffer(getNewContentsLength(length)); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// With `ArrayBuffer.resize()`, `contents` size matches exactly the size of +// the stream data. It does not include extraneous zeroes to trim at the end. +// The underlying `ArrayBuffer` does allocate a number of bytes that is a power +// of 2, but those bytes are only visible after calling `ArrayBuffer.resize()`. +const resizeArrayBuffer = (contents, length) => { + if (length <= contents.maxByteLength) { + contents.resize(length); + return contents; + } + + const arrayBuffer = new ArrayBuffer(length, {maxByteLength: getNewContentsLength(length)}); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// Retrieve the closest `length` that is both >= and a power of 2 +const getNewContentsLength = length => SCALE_FACTOR ** Math.ceil(Math.log(length) / Math.log(SCALE_FACTOR)); + +const SCALE_FACTOR = 2; + +const finalizeArrayBuffer = ({contents, length}) => hasArrayBufferResize() ? contents : contents.slice(0, length); + +// `ArrayBuffer.slice()` is slow. When `ArrayBuffer.resize()` is available +// (Node >=20.0.0, Safari >=16.4 and Chrome), we can use it instead. +// eslint-disable-next-line no-warning-comments +// TODO: remove after dropping support for Node 20. +// eslint-disable-next-line no-warning-comments +// TODO: use `ArrayBuffer.transferToFixedLength()` instead once it is available +const hasArrayBufferResize = () => 'resize' in ArrayBuffer.prototype; + +const arrayBufferMethods = { + init: initArrayBuffer, + convertChunk: { + string: useTextEncoder, + buffer: useUint8Array, + arrayBuffer: useUint8Array, + dataView: useUint8ArrayWithOffset, + typedArray: useUint8ArrayWithOffset, + others: throwObjectStream, + }, + getSize: getLengthProp, + truncateChunk: truncateArrayBufferChunk, + addChunk: addArrayBufferChunk, + getFinalChunk: noop, + finalize: finalizeArrayBuffer, +}; diff --git a/node_modules/get-stream/source/array.js b/node_modules/get-stream/source/array.js new file mode 100644 index 0000000..468bad1 --- /dev/null +++ b/node_modules/get-stream/source/array.js @@ -0,0 +1,32 @@ +import {getStreamContents} from './contents.js'; +import {identity, noop, getContentsProp} from './utils.js'; + +export async function getStreamAsArray(stream, options) { + return getStreamContents(stream, arrayMethods, options); +} + +const initArray = () => ({contents: []}); + +const increment = () => 1; + +const addArrayChunk = (convertedChunk, {contents}) => { + contents.push(convertedChunk); + return contents; +}; + +const arrayMethods = { + init: initArray, + convertChunk: { + string: identity, + buffer: identity, + arrayBuffer: identity, + dataView: identity, + typedArray: identity, + others: identity, + }, + getSize: increment, + truncateChunk: noop, + addChunk: addArrayChunk, + getFinalChunk: noop, + finalize: getContentsProp, +}; diff --git a/node_modules/get-stream/source/buffer.js b/node_modules/get-stream/source/buffer.js new file mode 100644 index 0000000..7d22d78 --- /dev/null +++ b/node_modules/get-stream/source/buffer.js @@ -0,0 +1,20 @@ +import {getStreamAsArrayBuffer} from './array-buffer.js'; + +export async function getStreamAsBuffer(stream, options) { + if (!('Buffer' in globalThis)) { + throw new Error('getStreamAsBuffer() is only supported in Node.js'); + } + + try { + return arrayBufferToNodeBuffer(await getStreamAsArrayBuffer(stream, options)); + } catch (error) { + if (error.bufferedData !== undefined) { + error.bufferedData = arrayBufferToNodeBuffer(error.bufferedData); + } + + throw error; + } +} + +// eslint-disable-next-line n/prefer-global/buffer +const arrayBufferToNodeBuffer = arrayBuffer => globalThis.Buffer.from(arrayBuffer); diff --git a/node_modules/get-stream/source/contents.js b/node_modules/get-stream/source/contents.js new file mode 100644 index 0000000..2ca36f2 --- /dev/null +++ b/node_modules/get-stream/source/contents.js @@ -0,0 +1,101 @@ +export const getStreamContents = async (stream, {init, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, finalize}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => { + if (!isAsyncIterable(stream)) { + throw new Error('The first argument must be a Readable, a ReadableStream, or an async iterable.'); + } + + const state = init(); + state.length = 0; + + try { + for await (const chunk of stream) { + const chunkType = getChunkType(chunk); + const convertedChunk = convertChunk[chunkType](chunk, state); + appendChunk({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}); + } + + appendFinalChunk({state, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}); + return finalize(state); + } catch (error) { + error.bufferedData = finalize(state); + throw error; + } +}; + +const appendFinalChunk = ({state, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}) => { + const convertedChunk = getFinalChunk(state); + if (convertedChunk !== undefined) { + appendChunk({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}); + } +}; + +const appendChunk = ({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}) => { + const chunkSize = getSize(convertedChunk); + const newLength = state.length + chunkSize; + + if (newLength <= maxBuffer) { + addNewChunk(convertedChunk, state, addChunk, newLength); + return; + } + + const truncatedChunk = truncateChunk(convertedChunk, maxBuffer - state.length); + + if (truncatedChunk !== undefined) { + addNewChunk(truncatedChunk, state, addChunk, maxBuffer); + } + + throw new MaxBufferError(); +}; + +const addNewChunk = (convertedChunk, state, addChunk, newLength) => { + state.contents = addChunk(convertedChunk, state, newLength); + state.length = newLength; +}; + +const isAsyncIterable = stream => typeof stream === 'object' && stream !== null && typeof stream[Symbol.asyncIterator] === 'function'; + +const getChunkType = chunk => { + const typeOfChunk = typeof chunk; + + if (typeOfChunk === 'string') { + return 'string'; + } + + if (typeOfChunk !== 'object' || chunk === null) { + return 'others'; + } + + // eslint-disable-next-line n/prefer-global/buffer + if (globalThis.Buffer?.isBuffer(chunk)) { + return 'buffer'; + } + + const prototypeName = objectToString.call(chunk); + + if (prototypeName === '[object ArrayBuffer]') { + return 'arrayBuffer'; + } + + if (prototypeName === '[object DataView]') { + return 'dataView'; + } + + if ( + Number.isInteger(chunk.byteLength) + && Number.isInteger(chunk.byteOffset) + && objectToString.call(chunk.buffer) === '[object ArrayBuffer]' + ) { + return 'typedArray'; + } + + return 'others'; +}; + +const {toString: objectToString} = Object.prototype; + +export class MaxBufferError extends Error { + name = 'MaxBufferError'; + + constructor() { + super('maxBuffer exceeded'); + } +} diff --git a/node_modules/get-stream/source/index.d.ts b/node_modules/get-stream/source/index.d.ts new file mode 100644 index 0000000..0a456ca --- /dev/null +++ b/node_modules/get-stream/source/index.d.ts @@ -0,0 +1,119 @@ +import {type Readable} from 'node:stream'; +import {type Buffer} from 'node:buffer'; + +export class MaxBufferError extends Error { + readonly name: 'MaxBufferError'; + constructor(); +} + +type TextStreamItem = string | Buffer | ArrayBuffer | ArrayBufferView; +export type AnyStream = Readable | ReadableStream | AsyncIterable; + +export type Options = { + /** + Maximum length of the stream. If exceeded, the promise will be rejected with a `MaxBufferError`. + + Depending on the [method](#api), the length is measured with [`string.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length), [`buffer.length`](https://nodejs.org/api/buffer.html#buflength), [`arrayBuffer.byteLength`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength) or [`array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). + + @default Infinity + */ + readonly maxBuffer?: number; +}; + +/** +Get the given `stream` as a string. + +@returns The stream's contents as a promise. + +@example +``` +import fs from 'node:fs'; +import getStream from 'get-stream'; + +const stream = fs.createReadStream('unicorn.txt'); + +console.log(await getStream(stream)); +// ,,))))))));, +// __)))))))))))))), +// \|/ -\(((((''''((((((((. +// -*-==//////(('' . `)))))), +// /|\ ))| o ;-. '((((( ,(, +// ( `| / ) ;))))' ,_))^;(~ +// | | | ,))((((_ _____------~~~-. %,;(;(>';'~ +// o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~ +// ; ''''```` `: `:::|\,__,%% );`'; ~ +// | _ ) / `:|`----' `-' +// ______/\/~ | / / +// /~;;.____/;;' / ___--,-( `;;;/ +// / // _;______;'------~~~~~ /;;/\ / +// // | | / ; \;;,\ +// (<_ | ; /',/-----' _> +// \_| ||_ //~;~~~~~~~~~ +// `\_| (,~~ +// \~\ +// ~~ +``` + +@example +``` +import getStream from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStream(readableStream)); +``` + +@example +``` +import {opendir} from 'node:fs/promises'; +import {getStreamAsArray} from 'get-stream'; + +const asyncIterable = await opendir(directory); +console.log(await getStreamAsArray(asyncIterable)); +``` +*/ +export default function getStream(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as a Node.js [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsBuffer} from 'get-stream'; + +const stream = fs.createReadStream('unicorn.png'); +console.log(await getStreamAsBuffer(stream)); +``` +*/ +export function getStreamAsBuffer(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsArrayBuffer} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArrayBuffer(readableStream)); +``` +*/ +export function getStreamAsArrayBuffer(stream: AnyStream, options?: Options): Promise; + +/** +Get the given `stream` as an array. Unlike [other methods](#api), this supports [streams of objects](https://nodejs.org/api/stream.html#object-mode). + +@returns The stream's contents as a promise. + +@example +``` +import {getStreamAsArray} from 'get-stream'; + +const {body: readableStream} = await fetch('https://example.com'); +console.log(await getStreamAsArray(readableStream)); +``` +*/ +export function getStreamAsArray(stream: AnyStream, options?: Options): Promise; diff --git a/node_modules/get-stream/source/index.js b/node_modules/get-stream/source/index.js new file mode 100644 index 0000000..43c2dd4 --- /dev/null +++ b/node_modules/get-stream/source/index.js @@ -0,0 +1,5 @@ +export {getStreamAsArray} from './array.js'; +export {getStreamAsArrayBuffer} from './array-buffer.js'; +export {getStreamAsBuffer} from './buffer.js'; +export {getStreamAsString as default} from './string.js'; +export {MaxBufferError} from './contents.js'; diff --git a/node_modules/get-stream/source/string.js b/node_modules/get-stream/source/string.js new file mode 100644 index 0000000..90f94b9 --- /dev/null +++ b/node_modules/get-stream/source/string.js @@ -0,0 +1,36 @@ +import {getStreamContents} from './contents.js'; +import {identity, getContentsProp, throwObjectStream, getLengthProp} from './utils.js'; + +export async function getStreamAsString(stream, options) { + return getStreamContents(stream, stringMethods, options); +} + +const initString = () => ({contents: '', textDecoder: new TextDecoder()}); + +const useTextDecoder = (chunk, {textDecoder}) => textDecoder.decode(chunk, {stream: true}); + +const addStringChunk = (convertedChunk, {contents}) => contents + convertedChunk; + +const truncateStringChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +const getFinalStringChunk = ({textDecoder}) => { + const finalChunk = textDecoder.decode(); + return finalChunk === '' ? undefined : finalChunk; +}; + +const stringMethods = { + init: initString, + convertChunk: { + string: identity, + buffer: useTextDecoder, + arrayBuffer: useTextDecoder, + dataView: useTextDecoder, + typedArray: useTextDecoder, + others: throwObjectStream, + }, + getSize: getLengthProp, + truncateChunk: truncateStringChunk, + addChunk: addStringChunk, + getFinalChunk: getFinalStringChunk, + finalize: getContentsProp, +}; diff --git a/node_modules/get-stream/source/utils.js b/node_modules/get-stream/source/utils.js new file mode 100644 index 0000000..af8d5e2 --- /dev/null +++ b/node_modules/get-stream/source/utils.js @@ -0,0 +1,11 @@ +export const identity = value => value; + +export const noop = () => undefined; + +export const getContentsProp = ({contents}) => contents; + +export const throwObjectStream = chunk => { + throw new Error(`Streams in object mode are not supported: ${String(chunk)}`); +}; + +export const getLengthProp = convertedChunk => convertedChunk.length; diff --git a/node_modules/human-signals/LICENSE b/node_modules/human-signals/LICENSE new file mode 100644 index 0000000..642f59b --- /dev/null +++ b/node_modules/human-signals/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 ehmicky + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/human-signals/README.md b/node_modules/human-signals/README.md new file mode 100644 index 0000000..00d975c --- /dev/null +++ b/node_modules/human-signals/README.md @@ -0,0 +1,168 @@ +[![Node](https://img.shields.io/badge/-Node.js-808080?logo=node.js&colorA=404040&logoColor=66cc33)](https://www.npmjs.com/package/human-signals) +[![TypeScript](https://img.shields.io/badge/-Typed-808080?logo=typescript&colorA=404040&logoColor=0096ff)](/src/main.d.ts) +[![Codecov](https://img.shields.io/badge/-Tested%20100%25-808080?logo=codecov&colorA=404040)](https://codecov.io/gh/ehmicky/human-signals) +[![Mastodon](https://img.shields.io/badge/-Mastodon-808080.svg?logo=mastodon&colorA=404040&logoColor=9590F9)](https://fosstodon.org/@ehmicky) +[![Medium](https://img.shields.io/badge/-Medium-808080.svg?logo=medium&colorA=404040)](https://medium.com/@ehmicky) + +Human-friendly process signals. + +This is a map of known process signals with some information about each signal. + +Unlike +[`os.constants.signals`](https://nodejs.org/api/os.html#os_signal_constants) +this includes: + +- human-friendly [descriptions](#description) +- [default actions](#action), including whether they [can be prevented](#forced) +- whether the signal is [supported](#supported) by the current OS + +# Example + +```js +import { signalsByName, signalsByNumber } from 'human-signals' + +console.log(signalsByName.SIGINT) +// { +// name: 'SIGINT', +// number: 2, +// description: 'User interruption with CTRL-C', +// supported: true, +// action: 'terminate', +// forced: false, +// standard: 'ansi' +// } + +console.log(signalsByNumber[8]) +// { +// name: 'SIGFPE', +// number: 8, +// description: 'Floating point arithmetic error', +// supported: true, +// action: 'core', +// forced: false, +// standard: 'ansi' +// } +``` + +# Install + +```bash +npm install human-signals +``` + +This package works in Node.js >=16.17.0. + +This is an ES module. It must be loaded using +[an `import` or `import()` statement](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c), +not `require()`. If TypeScript is used, it must be configured to +[output ES modules](https://www.typescriptlang.org/docs/handbook/esm-node.html), +not CommonJS. + +# Usage + +## signalsByName + +_Type_: `object` + +Object whose keys are signal [names](#name) and values are +[signal objects](#signal). + +## signalsByNumber + +_Type_: `object` + +Object whose keys are signal [numbers](#number) and values are +[signal objects](#signal). + +## signal + +_Type_: `object` + +Signal object with the following properties. + +### name + +_Type_: `string` + +Standard name of the signal, for example `'SIGINT'`. + +### number + +_Type_: `number` + +Code number of the signal, for example `2`. While most `number` are +cross-platform, some are different between different OS. + +### description + +_Type_: `string` + +Human-friendly description for the signal, for example +`'User interruption with CTRL-C'`. + +### supported + +_Type_: `boolean` + +Whether the current OS can handle this signal in Node.js using +[`process.on(name, handler)`](https://nodejs.org/api/process.html#process_signal_events). + +The list of supported signals +[is OS-specific](https://github.com/ehmicky/cross-platform-node-guide/blob/main/docs/6_networking_ipc/signals.md#cross-platform-signals). + +### action + +_Type_: `string`\ +_Enum_: `'terminate'`, `'core'`, `'ignore'`, `'pause'`, `'unpause'` + +What is the default action for this signal when it is not handled. + +### forced + +_Type_: `boolean` + +Whether the signal's default action cannot be prevented. This is `true` for +`SIGTERM`, `SIGKILL` and `SIGSTOP`. + +### standard + +_Type_: `string`\ +_Enum_: `'ansi'`, `'posix'`, `'bsd'`, `'systemv'`, `'other'` + +Which standard defined that signal. + +# Support + +For any question, _don't hesitate_ to [submit an issue on GitHub](../../issues). + +Everyone is welcome regardless of personal background. We enforce a +[Code of conduct](CODE_OF_CONDUCT.md) in order to promote a positive and +inclusive environment. + +# Contributing + +This project was made with ❤️. The simplest way to give back is by starring and +sharing it online. + +If the documentation is unclear or has a typo, please click on the page's `Edit` +button (pencil icon) and suggest a correction. + +If you would like to help us fix a bug or add a new feature, please check our +[guidelines](CONTRIBUTING.md). Pull requests are welcome! + +Thanks go to our wonderful contributors: + + + + + + + + + +

ehmicky

💻 🎨 🤔 📖

electrovir

💻
+ + + + + diff --git a/node_modules/human-signals/build/src/core.js b/node_modules/human-signals/build/src/core.js new file mode 100644 index 0000000..a3885ce --- /dev/null +++ b/node_modules/human-signals/build/src/core.js @@ -0,0 +1,273 @@ + + +export const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix" +}, +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi" +}, +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix" +}, +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi" +}, +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix" +}, +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi" +}, +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd" +}, +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd" +}, +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other" +}, +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi" +}, +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true +}, +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix" +}, +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi" +}, +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix" +}, +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix" +}, +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix" +}, +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi" +}, +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other" +}, +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix" +}, +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other" +}, +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true +}, +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true +}, +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix" +}, +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix" +}, +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other" +}, +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix" +}, +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd" +}, +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd" +}, +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd" +}, +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd" +}, +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd" +}, +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd" +}, +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other" +}, +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other" +}, +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other" +}, +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv" +}, +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other" +}, +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other" +}]; \ No newline at end of file diff --git a/node_modules/human-signals/build/src/main.d.ts b/node_modules/human-signals/build/src/main.d.ts new file mode 100644 index 0000000..864d501 --- /dev/null +++ b/node_modules/human-signals/build/src/main.d.ts @@ -0,0 +1,73 @@ +/** + * What is the default action for this signal when it is not handled. + */ +export type SignalAction = 'terminate' | 'core' | 'ignore' | 'pause' | 'unpause' + +/** + * Which standard defined that signal. + */ +export type SignalStandard = 'ansi' | 'posix' | 'bsd' | 'systemv' | 'other' + +/** + * Standard name of the signal, for example 'SIGINT'. + */ +export type SignalName = `SIG${string}` + +/** + * Code number of the signal, for example 2. + * While most number are cross-platform, some are different between different + * OS. + */ +export type SignalNumber = number + +export interface Signal { + /** + * Standard name of the signal, for example 'SIGINT'. + */ + name: SignalName + + /** + * Code number of the signal, for example 2. + * While most number are cross-platform, some are different between different + * OS. + */ + number: SignalNumber + + /** + * Human-friendly description for the signal, for example + * 'User interruption with CTRL-C'. + */ + description: string + + /** + * Whether the current OS can handle this signal in Node.js using + * `process.on(name, handler)`. The list of supported signals is OS-specific. + */ + supported: boolean + + /** + * What is the default action for this signal when it is not handled. + */ + action: SignalAction + + /** + * Whether the signal's default action cannot be prevented. + * This is true for SIGTERM, SIGKILL and SIGSTOP. + */ + forced: boolean + + /** + * Which standard defined that signal. + */ + standard: SignalStandard +} + +/** + * Object whose keys are signal names and values are signal objects. + */ +export declare const signalsByName: { [signalName: SignalName]: Signal } + +/** + * Object whose keys are signal numbers and values are signal objects. + */ +export declare const signalsByNumber: { [signalNumber: SignalNumber]: Signal } diff --git a/node_modules/human-signals/build/src/main.js b/node_modules/human-signals/build/src/main.js new file mode 100644 index 0000000..1c97801 --- /dev/null +++ b/node_modules/human-signals/build/src/main.js @@ -0,0 +1,70 @@ +import{constants}from"node:os"; + +import{SIGRTMAX}from"./realtime.js"; +import{getSignals}from"./signals.js"; + + + +const getSignalsByName=()=>{ +const signals=getSignals(); +return Object.fromEntries(signals.map(getSignalByName)) +}; + +const getSignalByName=({ +name, +number, +description, +supported, +action, +forced, +standard +})=>[name,{name,number,description,supported,action,forced,standard}]; + +export const signalsByName=getSignalsByName(); + + + + +const getSignalsByNumber=()=>{ +const signals=getSignals(); +const length=SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals) +); +return Object.assign({},...signalsA) +}; + +const getSignalByNumber=(number,signals)=>{ +const signal=findSignalByNumber(number,signals); + +if(signal===undefined){ +return{} +} + +const{name,description,supported,action,forced,standard}=signal; +return{ +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard +} +} +}; + + + +const findSignalByNumber=(number,signals)=>{ +const signal=signals.find(({name})=>constants.signals[name]===number); + +if(signal!==undefined){ +return signal +} + +return signals.find((signalA)=>signalA.number===number) +}; + +export const signalsByNumber=getSignalsByNumber(); \ No newline at end of file diff --git a/node_modules/human-signals/build/src/realtime.js b/node_modules/human-signals/build/src/realtime.js new file mode 100644 index 0000000..76ab69d --- /dev/null +++ b/node_modules/human-signals/build/src/realtime.js @@ -0,0 +1,16 @@ + +export const getRealtimeSignals=()=>{ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal) +}; + +const getRealtimeSignal=(value,index)=>({ +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix" +}); + +const SIGRTMIN=34; +export const SIGRTMAX=64; \ No newline at end of file diff --git a/node_modules/human-signals/build/src/signals.js b/node_modules/human-signals/build/src/signals.js new file mode 100644 index 0000000..14e4c73 --- /dev/null +++ b/node_modules/human-signals/build/src/signals.js @@ -0,0 +1,34 @@ +import{constants}from"node:os"; + +import{SIGNALS}from"./core.js"; +import{getRealtimeSignals}from"./realtime.js"; + + + +export const getSignals=()=>{ +const realtimeSignals=getRealtimeSignals(); +const signals=[...SIGNALS,...realtimeSignals].map(normalizeSignal); +return signals +}; + + + + + + + +const normalizeSignal=({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard +})=>{ +const{ +signals:{[name]:constantSignal} +}=constants; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return{name,number,description,supported,action,forced,standard} +}; \ No newline at end of file diff --git a/node_modules/human-signals/package.json b/node_modules/human-signals/package.json new file mode 100644 index 0000000..bb614d6 --- /dev/null +++ b/node_modules/human-signals/package.json @@ -0,0 +1,61 @@ +{ + "name": "human-signals", + "version": "5.0.0", + "type": "module", + "exports": { + "types": "./build/src/main.d.ts", + "default": "./build/src/main.js" + }, + "main": "./build/src/main.js", + "types": "./build/src/main.d.ts", + "files": [ + "build/src/**/*.{js,json,d.ts}", + "!build/src/**/*.test.js", + "!build/src/{helpers,fixtures}" + ], + "sideEffects": false, + "scripts": { + "test": "gulp test" + }, + "description": "Human-friendly process signals", + "keywords": [ + "signal", + "signals", + "handlers", + "error-handling", + "interrupts", + "sigterm", + "sigint", + "irq", + "process", + "exit", + "exit-code", + "status", + "operating-system", + "es6", + "javascript", + "typescript", + "linux", + "macos", + "windows", + "nodejs" + ], + "license": "Apache-2.0", + "homepage": "https://www.github.com/ehmicky/human-signals", + "repository": "ehmicky/human-signals", + "bugs": { + "url": "https://github.com/ehmicky/human-signals/issues" + }, + "author": "ehmicky (https://github.com/ehmicky)", + "directories": { + "lib": "src" + }, + "devDependencies": { + "@ehmicky/dev-tasks": "^2.0.80", + "ajv": "^8.12.0", + "test-each": "^6.0.0" + }, + "engines": { + "node": ">=16.17.0" + } +} diff --git a/node_modules/is-stream/index.d.ts b/node_modules/is-stream/index.d.ts new file mode 100644 index 0000000..df994e0 --- /dev/null +++ b/node_modules/is-stream/index.d.ts @@ -0,0 +1,81 @@ +import { + Stream, + Writable as WritableStream, + Readable as ReadableStream, + Duplex as DuplexStream, + Transform as TransformStream, +} from 'node:stream'; + +/** +@returns Whether `stream` is a [`Stream`](https://nodejs.org/api/stream.html#stream_stream). + +@example +``` +import fs from 'node:fs'; +import {isStream} from 'is-stream'; + +isStream(fs.createReadStream('unicorn.png')); +//=> true + +isStream({}); +//=> false +``` +*/ +export function isStream(stream: unknown): stream is Stream; + +/** +@returns Whether `stream` is a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). + +@example +``` +import fs from 'node:fs'; +import {isWritableStream} from 'is-stream'; + +isWritableStream(fs.createWriteStrem('unicorn.txt')); +//=> true +``` +*/ +export function isWritableStream(stream: unknown): stream is WritableStream; + +/** +@returns Whether `stream` is a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). + +@example +``` +import fs from 'node:fs'; +import {isReadableStream} from 'is-stream'; + +isReadableStream(fs.createReadStream('unicorn.png')); +//=> true +``` +*/ +export function isReadableStream(stream: unknown): stream is ReadableStream; + +/** +@returns Whether `stream` is a [`stream.Duplex`](https://nodejs.org/api/stream.html#stream_class_stream_duplex). + +@example +``` +import {Duplex as DuplexStream} from 'node:stream'; +import {isDuplexStream} from 'is-stream'; + +isDuplexStream(new DuplexStream()); +//=> true +``` +*/ +export function isDuplexStream(stream: unknown): stream is DuplexStream; + +/** +@returns Whether `stream` is a [`stream.Transform`](https://nodejs.org/api/stream.html#stream_class_stream_transform). + +@example +``` +import fs from 'node:fs'; +import StringifyStream from 'streaming-json-stringify'; +import {isTransformStream} from 'is-stream'; + +isTransformStream(StringifyStream()); +//=> true +``` +*/ +export function isTransformStream(stream: unknown): stream is TransformStream; diff --git a/node_modules/is-stream/index.js b/node_modules/is-stream/index.js new file mode 100644 index 0000000..887e601 --- /dev/null +++ b/node_modules/is-stream/index.js @@ -0,0 +1,29 @@ +export function isStream(stream) { + return stream !== null + && typeof stream === 'object' + && typeof stream.pipe === 'function'; +} + +export function isWritableStream(stream) { + return isStream(stream) + && stream.writable !== false + && typeof stream._write === 'function' + && typeof stream._writableState === 'object'; +} + +export function isReadableStream(stream) { + return isStream(stream) + && stream.readable !== false + && typeof stream._read === 'function' + && typeof stream._readableState === 'object'; +} + +export function isDuplexStream(stream) { + return isWritableStream(stream) + && isReadableStream(stream); +} + +export function isTransformStream(stream) { + return isDuplexStream(stream) + && typeof stream._transform === 'function'; +} diff --git a/node_modules/is-stream/license b/node_modules/is-stream/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/is-stream/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/is-stream/package.json b/node_modules/is-stream/package.json new file mode 100644 index 0000000..47d5761 --- /dev/null +++ b/node_modules/is-stream/package.json @@ -0,0 +1,44 @@ +{ + "name": "is-stream", + "version": "3.0.0", + "description": "Check if something is a Node.js stream", + "license": "MIT", + "repository": "sindresorhus/is-stream", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": "./index.js", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "stream", + "type", + "streams", + "writable", + "readable", + "duplex", + "transform", + "check", + "detect", + "is" + ], + "devDependencies": { + "@types/node": "^16.4.13", + "ava": "^3.15.0", + "tempy": "^1.0.1", + "tsd": "^0.17.0", + "xo": "^0.44.0" + } +} diff --git a/node_modules/is-stream/readme.md b/node_modules/is-stream/readme.md new file mode 100644 index 0000000..c6f8c1b --- /dev/null +++ b/node_modules/is-stream/readme.md @@ -0,0 +1,60 @@ +# is-stream + +> Check if something is a [Node.js stream](https://nodejs.org/api/stream.html) + +## Install + +``` +$ npm install is-stream +``` + +## Usage + +```js +import fs from 'node:fs'; +import {isStream} from 'is-stream'; + +isStream(fs.createReadStream('unicorn.png')); +//=> true + +isStream({}); +//=> false +``` + +## API + +### isStream(stream) + +Returns a `boolean` for whether it's a [`Stream`](https://nodejs.org/api/stream.html#stream_stream). + +#### isWritableStream(stream) + +Returns a `boolean` for whether it's a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable). + +#### isReadableStream(stream) + +Returns a `boolean` for whether it's a [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). + +#### isDuplexStream(stream) + +Returns a `boolean` for whether it's a [`stream.Duplex`](https://nodejs.org/api/stream.html#stream_class_stream_duplex). + +#### isTransformStream(stream) + +Returns a `boolean` for whether it's a [`stream.Transform`](https://nodejs.org/api/stream.html#stream_class_stream_transform). + +## Related + +- [is-file-stream](https://github.com/jamestalmage/is-file-stream) - Detect if a stream is a file stream + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/isexe/.npmignore b/node_modules/isexe/.npmignore new file mode 100644 index 0000000..c1cb757 --- /dev/null +++ b/node_modules/isexe/.npmignore @@ -0,0 +1,2 @@ +.nyc_output/ +coverage/ diff --git a/node_modules/isexe/LICENSE b/node_modules/isexe/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/isexe/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/isexe/README.md b/node_modules/isexe/README.md new file mode 100644 index 0000000..35769e8 --- /dev/null +++ b/node_modules/isexe/README.md @@ -0,0 +1,51 @@ +# isexe + +Minimal module to check if a file is executable, and a normal file. + +Uses `fs.stat` and tests against the `PATHEXT` environment variable on +Windows. + +## USAGE + +```javascript +var isexe = require('isexe') +isexe('some-file-name', function (err, isExe) { + if (err) { + console.error('probably file does not exist or something', err) + } else if (isExe) { + console.error('this thing can be run') + } else { + console.error('cannot be run') + } +}) + +// same thing but synchronous, throws errors +var isExe = isexe.sync('some-file-name') + +// treat errors as just "not executable" +isexe('maybe-missing-file', { ignoreErrors: true }, callback) +var isExe = isexe.sync('maybe-missing-file', { ignoreErrors: true }) +``` + +## API + +### `isexe(path, [options], [callback])` + +Check if the path is executable. If no callback provided, and a +global `Promise` object is available, then a Promise will be returned. + +Will raise whatever errors may be raised by `fs.stat`, unless +`options.ignoreErrors` is set to true. + +### `isexe.sync(path, [options])` + +Same as `isexe` but returns the value and throws any errors raised. + +### Options + +* `ignoreErrors` Treat all errors as "no, this is not executable", but + don't raise them. +* `uid` Number to use as the user id +* `gid` Number to use as the group id +* `pathExt` List of path extensions to use instead of `PATHEXT` + environment variable on Windows. diff --git a/node_modules/isexe/index.js b/node_modules/isexe/index.js new file mode 100644 index 0000000..553fb32 --- /dev/null +++ b/node_modules/isexe/index.js @@ -0,0 +1,57 @@ +var fs = require('fs') +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = require('./windows.js') +} else { + core = require('./mode.js') +} + +module.exports = isexe +isexe.sync = sync + +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} diff --git a/node_modules/isexe/mode.js b/node_modules/isexe/mode.js new file mode 100644 index 0000000..1995ea4 --- /dev/null +++ b/node_modules/isexe/mode.js @@ -0,0 +1,41 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} + +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} + +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() + + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 + + return ret +} diff --git a/node_modules/isexe/package.json b/node_modules/isexe/package.json new file mode 100644 index 0000000..e452689 --- /dev/null +++ b/node_modules/isexe/package.json @@ -0,0 +1,31 @@ +{ + "name": "isexe", + "version": "2.0.0", + "description": "Minimal module to check if a file is executable.", + "main": "index.js", + "directories": { + "test": "test" + }, + "devDependencies": { + "mkdirp": "^0.5.1", + "rimraf": "^2.5.0", + "tap": "^10.3.0" + }, + "scripts": { + "test": "tap test/*.js --100", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --all; git push origin --tags" + }, + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/isexe.git" + }, + "keywords": [], + "bugs": { + "url": "https://github.com/isaacs/isexe/issues" + }, + "homepage": "https://github.com/isaacs/isexe#readme" +} diff --git a/node_modules/isexe/test/basic.js b/node_modules/isexe/test/basic.js new file mode 100644 index 0000000..d926df6 --- /dev/null +++ b/node_modules/isexe/test/basic.js @@ -0,0 +1,221 @@ +var t = require('tap') +var fs = require('fs') +var path = require('path') +var fixture = path.resolve(__dirname, 'fixtures') +var meow = fixture + '/meow.cat' +var mine = fixture + '/mine.cat' +var ours = fixture + '/ours.cat' +var fail = fixture + '/fail.false' +var noent = fixture + '/enoent.exe' +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') + +var isWindows = process.platform === 'win32' +var hasAccess = typeof fs.access === 'function' +var winSkip = isWindows && 'windows' +var accessSkip = !hasAccess && 'no fs.access function' +var hasPromise = typeof Promise === 'function' +var promiseSkip = !hasPromise && 'no global Promise' + +function reset () { + delete require.cache[require.resolve('../')] + return require('../') +} + +t.test('setup fixtures', function (t) { + rimraf.sync(fixture) + mkdirp.sync(fixture) + fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n') + fs.chmodSync(meow, parseInt('0755', 8)) + fs.writeFileSync(fail, '#!/usr/bin/env false\n') + fs.chmodSync(fail, parseInt('0644', 8)) + fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n') + fs.chmodSync(mine, parseInt('0744', 8)) + fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n') + fs.chmodSync(ours, parseInt('0754', 8)) + t.end() +}) + +t.test('promise', { skip: promiseSkip }, function (t) { + var isexe = reset() + t.test('meow async', function (t) { + isexe(meow).then(function (is) { + t.ok(is) + t.end() + }) + }) + t.test('fail async', function (t) { + isexe(fail).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.test('noent async', function (t) { + isexe(noent).catch(function (er) { + t.ok(er) + t.end() + }) + }) + t.test('noent ignore async', function (t) { + isexe(noent, { ignoreErrors: true }).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.end() +}) + +t.test('no promise', function (t) { + global.Promise = null + var isexe = reset() + t.throws('try to meow a promise', function () { + isexe(meow) + }) + t.end() +}) + +t.test('access', { skip: accessSkip || winSkip }, function (t) { + runTest(t) +}) + +t.test('mode', { skip: winSkip }, function (t) { + delete fs.access + delete fs.accessSync + var isexe = reset() + t.ok(isexe.sync(ours, { uid: 0, gid: 0 })) + t.ok(isexe.sync(mine, { uid: 0, gid: 0 })) + runTest(t) +}) + +t.test('windows', function (t) { + global.TESTING_WINDOWS = true + var pathExt = '.EXE;.CAT;.CMD;.COM' + t.test('pathExt option', function (t) { + runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' }) + }) + t.test('pathExt env', function (t) { + process.env.PATHEXT = pathExt + runTest(t) + }) + t.test('no pathExt', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: '', skipFail: true }) + }) + t.test('pathext with empty entry', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: ';' + pathExt, skipFail: true }) + }) + t.end() +}) + +t.test('cleanup', function (t) { + rimraf.sync(fixture) + t.end() +}) + +function runTest (t, options) { + var isexe = reset() + + var optionsIgnore = Object.create(options || {}) + optionsIgnore.ignoreErrors = true + + if (!options || !options.skipFail) { + t.notOk(isexe.sync(fail, options)) + } + t.notOk(isexe.sync(noent, optionsIgnore)) + if (!options) { + t.ok(isexe.sync(meow)) + } else { + t.ok(isexe.sync(meow, options)) + } + + t.ok(isexe.sync(mine, options)) + t.ok(isexe.sync(ours, options)) + t.throws(function () { + isexe.sync(noent, options) + }) + + t.test('meow async', function (t) { + if (!options) { + isexe(meow, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } else { + isexe(meow, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } + }) + + t.test('mine async', function (t) { + isexe(mine, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + t.test('ours async', function (t) { + isexe(ours, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + if (!options || !options.skipFail) { + t.test('fail async', function (t) { + isexe(fail, options, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + } + + t.test('noent async', function (t) { + isexe(noent, options, function (er, is) { + t.ok(er) + t.notOk(is) + t.end() + }) + }) + + t.test('noent ignore async', function (t) { + isexe(noent, optionsIgnore, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + + t.test('directory is not executable', function (t) { + isexe(__dirname, options, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + + t.end() +} diff --git a/node_modules/isexe/windows.js b/node_modules/isexe/windows.js new file mode 100644 index 0000000..3499673 --- /dev/null +++ b/node_modules/isexe/windows.js @@ -0,0 +1,42 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT + + if (!pathext) { + return true + } + + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} + +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) +} diff --git a/node_modules/js-tokens/LICENSE b/node_modules/js-tokens/LICENSE new file mode 100644 index 0000000..f07e1ac --- /dev/null +++ b/node_modules/js-tokens/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Simon Lydell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/js-tokens/README.md b/node_modules/js-tokens/README.md new file mode 100644 index 0000000..ee52150 --- /dev/null +++ b/node_modules/js-tokens/README.md @@ -0,0 +1,14 @@ +# js-tokens + +The tiny, regex powered, lenient, _almost_ spec-compliant JavaScript tokenizer that never fails. + +```js +const jsTokens = require("js-tokens"); + +const jsString = 'JSON.stringify({k:3.14**2}, null /*replacer*/, "\\t")'; + +Array.from(jsTokens(jsString), (token) => token.value).join("|"); +// JSON|.|stringify|(|{|k|:|3.14|**|2|}|,| |null| |/*replacer*/|,| |"\t"|) +``` + +**[➡️ Full readme](https://github.com/lydell/js-tokens/)** \ No newline at end of file diff --git a/node_modules/js-tokens/index.d.ts b/node_modules/js-tokens/index.d.ts new file mode 100644 index 0000000..d67cac0 --- /dev/null +++ b/node_modules/js-tokens/index.d.ts @@ -0,0 +1,37 @@ +export declare type Token = + | { type: "StringLiteral"; value: string; closed: boolean } + | { type: "NoSubstitutionTemplate"; value: string; closed: boolean } + | { type: "TemplateHead"; value: string } + | { type: "TemplateMiddle"; value: string } + | { type: "TemplateTail"; value: string; closed: boolean } + | { type: "RegularExpressionLiteral"; value: string; closed: boolean } + | { type: "MultiLineComment"; value: string; closed: boolean } + | { type: "SingleLineComment"; value: string } + | { type: "HashbangComment"; value: string } + | { type: "IdentifierName"; value: string } + | { type: "PrivateIdentifier"; value: string } + | { type: "NumericLiteral"; value: string } + | { type: "Punctuator"; value: string } + | { type: "WhiteSpace"; value: string } + | { type: "LineTerminatorSequence"; value: string } + | { type: "Invalid"; value: string }; + +export declare type JSXToken = + | { type: "JSXString"; value: string; closed: boolean } + | { type: "JSXText"; value: string } + | { type: "JSXIdentifier"; value: string } + | { type: "JSXPunctuator"; value: string } + | { type: "JSXInvalid"; value: string }; + +declare function jsTokens( + input: string, + options: { jsx: true }, +): Iterable; + +declare function jsTokens( + input: string, + options?: { jsx?: boolean }, +): Iterable; + +// @ts-expect-error TypeScript complains about _both_ exporting types _and_ using `export =` but it seems to work fine in practice. +export = jsTokens; diff --git a/node_modules/js-tokens/index.js b/node_modules/js-tokens/index.js new file mode 100644 index 0000000..1afeff9 --- /dev/null +++ b/node_modules/js-tokens/index.js @@ -0,0 +1,396 @@ +// Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell +// License: MIT. +var HashbangComment, Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace, jsTokens; +RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:[^\]\\\n\r\u2028\u2029]+|\\.)*\]?|[^\/[\\\n\r\u2028\u2029]+|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; +Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; +Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]+|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; +StringLiteral = /(['"])(?:[^'"\\\n\r]+|(?!\1)['"]|\\(?:\r\n|[^]))*(\1)?/y; +NumericLiteral = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; +Template = /[`}](?:[^`\\$]+|\\[^]|\$(?!\{))*(`|\$\{)?/y; +WhiteSpace = /[\t\v\f\ufeff\p{Zs}]+/yu; +LineTerminatorSequence = /\r?\n|[\r\u2028\u2029]/y; +MultiLineComment = /\/\*(?:[^*]+|\*(?!\/))*(\*\/)?/y; +SingleLineComment = /\/\/.*/y; +HashbangComment = /^#!.*/; +JSXPunctuator = /[<>.:={}]|\/(?![\/*])/y; +JSXIdentifier = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; +JSXString = /(['"])(?:[^'"]+|(?!\1)['"])*(\1)?/y; +JSXText = /[^<>{}]+/y; +TokensPrecedingExpression = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; +TokensNotPrecedingObjectLiteral = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; +KeywordsWithExpressionAfter = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; +KeywordsWithNoLineTerminatorAfter = /^(?:return|throw|yield)$/; +Newline = RegExp(LineTerminatorSequence.source); +module.exports = jsTokens = function*(input, {jsx = false} = {}) { + var braces, firstCodePoint, isExpression, lastIndex, lastSignificantToken, length, match, mode, nextLastIndex, nextLastSignificantToken, parenNesting, postfixIncDec, punctuator, stack; + ({length} = input); + lastIndex = 0; + lastSignificantToken = ""; + stack = [ + {tag: "JS"} + ]; + braces = []; + parenNesting = 0; + postfixIncDec = false; + if (match = HashbangComment.exec(input)) { + yield ({ + type: "HashbangComment", + value: match[0] + }); + lastIndex = match[0].length; + } + while (lastIndex < length) { + mode = stack[stack.length - 1]; + switch (mode.tag) { + case "JS": + case "JSNonExpressionParen": + case "InterpolationInTemplate": + case "InterpolationInJSX": + if (input[lastIndex] === "/" && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + RegularExpressionLiteral.lastIndex = lastIndex; + if (match = RegularExpressionLiteral.exec(input)) { + lastIndex = RegularExpressionLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "RegularExpressionLiteral", + value: match[0], + closed: match[1] !== void 0 && match[1] !== "\\" + }); + continue; + } + } + Punctuator.lastIndex = lastIndex; + if (match = Punctuator.exec(input)) { + punctuator = match[0]; + nextLastIndex = Punctuator.lastIndex; + nextLastSignificantToken = punctuator; + switch (punctuator) { + case "(": + if (lastSignificantToken === "?NonExpressionParenKeyword") { + stack.push({ + tag: "JSNonExpressionParen", + nesting: parenNesting + }); + } + parenNesting++; + postfixIncDec = false; + break; + case ")": + parenNesting--; + postfixIncDec = true; + if (mode.tag === "JSNonExpressionParen" && parenNesting === mode.nesting) { + stack.pop(); + nextLastSignificantToken = "?NonExpressionParenEnd"; + postfixIncDec = false; + } + break; + case "{": + Punctuator.lastIndex = 0; + isExpression = !TokensNotPrecedingObjectLiteral.test(lastSignificantToken) && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken)); + braces.push(isExpression); + postfixIncDec = false; + break; + case "}": + switch (mode.tag) { + case "InterpolationInTemplate": + if (braces.length === mode.nesting) { + Template.lastIndex = lastIndex; + match = Template.exec(input); + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + postfixIncDec = false; + yield ({ + type: "TemplateMiddle", + value: match[0] + }); + } else { + stack.pop(); + postfixIncDec = true; + yield ({ + type: "TemplateTail", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "InterpolationInJSX": + if (braces.length === mode.nesting) { + stack.pop(); + lastIndex += 1; + lastSignificantToken = "}"; + yield ({ + type: "JSXPunctuator", + value: "}" + }); + continue; + } + } + postfixIncDec = braces.pop(); + nextLastSignificantToken = postfixIncDec ? "?ExpressionBraceEnd" : "}"; + break; + case "]": + postfixIncDec = true; + break; + case "++": + case "--": + nextLastSignificantToken = postfixIncDec ? "?PostfixIncDec" : "?UnaryIncDec"; + break; + case "<": + if (jsx && (TokensPrecedingExpression.test(lastSignificantToken) || KeywordsWithExpressionAfter.test(lastSignificantToken))) { + stack.push({tag: "JSXTag"}); + lastIndex += 1; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: punctuator + }); + continue; + } + postfixIncDec = false; + break; + default: + postfixIncDec = false; + } + lastIndex = nextLastIndex; + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "Punctuator", + value: punctuator + }); + continue; + } + Identifier.lastIndex = lastIndex; + if (match = Identifier.exec(input)) { + lastIndex = Identifier.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "for": + case "if": + case "while": + case "with": + if (lastSignificantToken !== "." && lastSignificantToken !== "?.") { + nextLastSignificantToken = "?NonExpressionParenKeyword"; + } + } + lastSignificantToken = nextLastSignificantToken; + postfixIncDec = !KeywordsWithExpressionAfter.test(match[0]); + yield ({ + type: match[1] === "#" ? "PrivateIdentifier" : "IdentifierName", + value: match[0] + }); + continue; + } + StringLiteral.lastIndex = lastIndex; + if (match = StringLiteral.exec(input)) { + lastIndex = StringLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "StringLiteral", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + NumericLiteral.lastIndex = lastIndex; + if (match = NumericLiteral.exec(input)) { + lastIndex = NumericLiteral.lastIndex; + lastSignificantToken = match[0]; + postfixIncDec = true; + yield ({ + type: "NumericLiteral", + value: match[0] + }); + continue; + } + Template.lastIndex = lastIndex; + if (match = Template.exec(input)) { + lastIndex = Template.lastIndex; + lastSignificantToken = match[0]; + if (match[1] === "${") { + lastSignificantToken = "?InterpolationInTemplate"; + stack.push({ + tag: "InterpolationInTemplate", + nesting: braces.length + }); + postfixIncDec = false; + yield ({ + type: "TemplateHead", + value: match[0] + }); + } else { + postfixIncDec = true; + yield ({ + type: "NoSubstitutionTemplate", + value: match[0], + closed: match[1] === "`" + }); + } + continue; + } + break; + case "JSXTag": + case "JSXTagEnd": + JSXPunctuator.lastIndex = lastIndex; + if (match = JSXPunctuator.exec(input)) { + lastIndex = JSXPunctuator.lastIndex; + nextLastSignificantToken = match[0]; + switch (match[0]) { + case "<": + stack.push({tag: "JSXTag"}); + break; + case ">": + stack.pop(); + if (lastSignificantToken === "/" || mode.tag === "JSXTagEnd") { + nextLastSignificantToken = "?JSX"; + postfixIncDec = true; + } else { + stack.push({tag: "JSXChildren"}); + } + break; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + nextLastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + break; + case "/": + if (lastSignificantToken === "<") { + stack.pop(); + if (stack[stack.length - 1].tag === "JSXChildren") { + stack.pop(); + } + stack.push({tag: "JSXTagEnd"}); + } + } + lastSignificantToken = nextLastSignificantToken; + yield ({ + type: "JSXPunctuator", + value: match[0] + }); + continue; + } + JSXIdentifier.lastIndex = lastIndex; + if (match = JSXIdentifier.exec(input)) { + lastIndex = JSXIdentifier.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXIdentifier", + value: match[0] + }); + continue; + } + JSXString.lastIndex = lastIndex; + if (match = JSXString.exec(input)) { + lastIndex = JSXString.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXString", + value: match[0], + closed: match[2] !== void 0 + }); + continue; + } + break; + case "JSXChildren": + JSXText.lastIndex = lastIndex; + if (match = JSXText.exec(input)) { + lastIndex = JSXText.lastIndex; + lastSignificantToken = match[0]; + yield ({ + type: "JSXText", + value: match[0] + }); + continue; + } + switch (input[lastIndex]) { + case "<": + stack.push({tag: "JSXTag"}); + lastIndex++; + lastSignificantToken = "<"; + yield ({ + type: "JSXPunctuator", + value: "<" + }); + continue; + case "{": + stack.push({ + tag: "InterpolationInJSX", + nesting: braces.length + }); + lastIndex++; + lastSignificantToken = "?InterpolationInJSX"; + postfixIncDec = false; + yield ({ + type: "JSXPunctuator", + value: "{" + }); + continue; + } + } + WhiteSpace.lastIndex = lastIndex; + if (match = WhiteSpace.exec(input)) { + lastIndex = WhiteSpace.lastIndex; + yield ({ + type: "WhiteSpace", + value: match[0] + }); + continue; + } + LineTerminatorSequence.lastIndex = lastIndex; + if (match = LineTerminatorSequence.exec(input)) { + lastIndex = LineTerminatorSequence.lastIndex; + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + yield ({ + type: "LineTerminatorSequence", + value: match[0] + }); + continue; + } + MultiLineComment.lastIndex = lastIndex; + if (match = MultiLineComment.exec(input)) { + lastIndex = MultiLineComment.lastIndex; + if (Newline.test(match[0])) { + postfixIncDec = false; + if (KeywordsWithNoLineTerminatorAfter.test(lastSignificantToken)) { + lastSignificantToken = "?NoLineTerminatorHere"; + } + } + yield ({ + type: "MultiLineComment", + value: match[0], + closed: match[1] !== void 0 + }); + continue; + } + SingleLineComment.lastIndex = lastIndex; + if (match = SingleLineComment.exec(input)) { + lastIndex = SingleLineComment.lastIndex; + postfixIncDec = false; + yield ({ + type: "SingleLineComment", + value: match[0] + }); + continue; + } + firstCodePoint = String.fromCodePoint(input.codePointAt(lastIndex)); + lastIndex += firstCodePoint.length; + lastSignificantToken = firstCodePoint; + postfixIncDec = false; + yield ({ + type: mode.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", + value: firstCodePoint + }); + } + return void 0; +}; diff --git a/node_modules/js-tokens/package.json b/node_modules/js-tokens/package.json new file mode 100644 index 0000000..b868c1c --- /dev/null +++ b/node_modules/js-tokens/package.json @@ -0,0 +1,22 @@ +{ + "name": "js-tokens", + "version": "9.0.1", + "author": "Simon Lydell", + "license": "MIT", + "description": "Tiny JavaScript tokenizer.", + "repository": "lydell/js-tokens", + "type": "commonjs", + "exports": "./index.js", + "keywords": [ + "JavaScript", + "js", + "ECMAScript", + "es", + "token", + "tokens", + "tokenize", + "tokenizer", + "regex", + "regexp" + ] +} diff --git a/node_modules/local-pkg/LICENSE b/node_modules/local-pkg/LICENSE new file mode 100644 index 0000000..d47cea5 --- /dev/null +++ b/node_modules/local-pkg/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/local-pkg/README.md b/node_modules/local-pkg/README.md new file mode 100644 index 0000000..2a2ab1d --- /dev/null +++ b/node_modules/local-pkg/README.md @@ -0,0 +1,55 @@ +# local-pkg + +[![NPM version](https://img.shields.io/npm/v/local-pkg?color=a1b858&label=)](https://www.npmjs.com/package/local-pkg) + +Get information on local packages. Works on both CJS and ESM. + +## Install + +```bash +npm i local-pkg +``` + +## Usage + +```ts +import { + getPackageInfo, + importModule, + isPackageExists, + resolveModule, +} from 'local-pkg' + +isPackageExists('local-pkg') // true +isPackageExists('foo') // false + +await getPackageInfo('local-pkg') +/* { + * name: "local-pkg", + * version: "0.1.0", + * rootPath: "/path/to/node_modules/local-pkg", + * packageJson: { + * ... + * } + * } + */ + +// similar to `require.resolve` but works also in ESM +resolveModule('local-pkg') +// '/path/to/node_modules/local-pkg/dist/index.cjs' + +// similar to `await import()` but works also in CJS +const { importModule } = await importModule('local-pkg') +``` + +## Sponsors + +

+ + + +

+ +## License + +[MIT](./LICENSE) License © 2021 [Anthony Fu](https://github.com/antfu) diff --git a/node_modules/local-pkg/dist/index.cjs b/node_modules/local-pkg/dist/index.cjs new file mode 100644 index 0000000..e368b7b --- /dev/null +++ b/node_modules/local-pkg/dist/index.cjs @@ -0,0 +1,409 @@ +'use strict'; + +const fs = require('node:fs'); +const fsp = require('node:fs/promises'); +const node_module = require('node:module'); +const path = require('node:path'); +const process = require('node:process'); +const node_url = require('node:url'); +const mlly = require('mlly'); + +var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; +function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } + +const fs__default = /*#__PURE__*/_interopDefaultCompat(fs); +const fsp__default = /*#__PURE__*/_interopDefaultCompat(fsp); +const path__default = /*#__PURE__*/_interopDefaultCompat(path); +const process__default = /*#__PURE__*/_interopDefaultCompat(process); + +/* +How it works: +`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value. +*/ + +class Node { + value; + next; + + constructor(value) { + this.value = value; + } +} + +class Queue { + #head; + #tail; + #size; + + constructor() { + this.clear(); + } + + enqueue(value) { + const node = new Node(value); + + if (this.#head) { + this.#tail.next = node; + this.#tail = node; + } else { + this.#head = node; + this.#tail = node; + } + + this.#size++; + } + + dequeue() { + const current = this.#head; + if (!current) { + return; + } + + this.#head = this.#head.next; + this.#size--; + return current.value; + } + + clear() { + this.#head = undefined; + this.#tail = undefined; + this.#size = 0; + } + + get size() { + return this.#size; + } + + * [Symbol.iterator]() { + let current = this.#head; + + while (current) { + yield current.value; + current = current.next; + } + } +} + +function pLimit(concurrency) { + if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { + throw new TypeError('Expected `concurrency` to be a number from 1 and up'); + } + + const queue = new Queue(); + let activeCount = 0; + + const next = () => { + activeCount--; + + if (queue.size > 0) { + queue.dequeue()(); + } + }; + + const run = async (fn, resolve, args) => { + activeCount++; + + const result = (async () => fn(...args))(); + + resolve(result); + + try { + await result; + } catch {} + + next(); + }; + + const enqueue = (fn, resolve, args) => { + queue.enqueue(run.bind(undefined, fn, resolve, args)); + + (async () => { + // This function needs to wait until the next microtask before comparing + // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously + // when the run function is dequeued and called. The comparison in the if-statement + // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. + await Promise.resolve(); + + if (activeCount < concurrency && queue.size > 0) { + queue.dequeue()(); + } + })(); + }; + + const generator = (fn, ...args) => new Promise(resolve => { + enqueue(fn, resolve, args); + }); + + Object.defineProperties(generator, { + activeCount: { + get: () => activeCount, + }, + pendingCount: { + get: () => queue.size, + }, + clearQueue: { + value: () => { + queue.clear(); + }, + }, + }); + + return generator; +} + +class EndError extends Error { + constructor(value) { + super(); + this.value = value; + } +} + +// The input can also be a promise, so we await it. +const testElement = async (element, tester) => tester(await element); + +// The input can also be a promise, so we `Promise.all()` them both. +const finder = async element => { + const values = await Promise.all(element); + if (values[1] === true) { + throw new EndError(values[0]); + } + + return false; +}; + +async function pLocate( + iterable, + tester, + { + concurrency = Number.POSITIVE_INFINITY, + preserveOrder = true, + } = {}, +) { + const limit = pLimit(concurrency); + + // Start all the promises concurrently with optional limit. + const items = [...iterable].map(element => [element, limit(testElement, element, tester)]); + + // Check the promises either serially or concurrently. + const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY); + + try { + await Promise.all(items.map(element => checkLimit(finder, element))); + } catch (error) { + if (error instanceof EndError) { + return error.value; + } + + throw error; + } +} + +const typeMappings = { + directory: 'isDirectory', + file: 'isFile', +}; + +function checkType(type) { + if (Object.hasOwnProperty.call(typeMappings, type)) { + return; + } + + throw new Error(`Invalid type specified: ${type}`); +} + +const matchType = (type, stat) => stat[typeMappings[type]](); + +const toPath$1 = urlOrPath => urlOrPath instanceof URL ? node_url.fileURLToPath(urlOrPath) : urlOrPath; + +async function locatePath( + paths, + { + cwd = process__default.cwd(), + type = 'file', + allowSymlinks = true, + concurrency, + preserveOrder, + } = {}, +) { + checkType(type); + cwd = toPath$1(cwd); + + const statFunction = allowSymlinks ? fs.promises.stat : fs.promises.lstat; + + return pLocate(paths, async path_ => { + try { + const stat = await statFunction(path__default.resolve(cwd, path_)); + return matchType(type, stat); + } catch { + return false; + } + }, {concurrency, preserveOrder}); +} + +const toPath = urlOrPath => urlOrPath instanceof URL ? node_url.fileURLToPath(urlOrPath) : urlOrPath; + +const findUpStop = Symbol('findUpStop'); + +async function findUpMultiple(name, options = {}) { + let directory = path__default.resolve(toPath(options.cwd) || ''); + const {root} = path__default.parse(directory); + const stopAt = path__default.resolve(directory, options.stopAt || root); + const limit = options.limit || Number.POSITIVE_INFINITY; + const paths = [name].flat(); + + const runMatcher = async locateOptions => { + if (typeof name !== 'function') { + return locatePath(paths, locateOptions); + } + + const foundPath = await name(locateOptions.cwd); + if (typeof foundPath === 'string') { + return locatePath([foundPath], locateOptions); + } + + return foundPath; + }; + + const matches = []; + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + const foundPath = await runMatcher({...options, cwd: directory}); + + if (foundPath === findUpStop) { + break; + } + + if (foundPath) { + matches.push(path__default.resolve(directory, foundPath)); + } + + if (directory === stopAt || matches.length >= limit) { + break; + } + + directory = path__default.dirname(directory); + } + + return matches; +} + +async function findUp(name, options = {}) { + const matches = await findUpMultiple(name, {...options, limit: 1}); + return matches[0]; +} + +function _resolve(path$1, options = {}) { + if (options.platform === "auto" || !options.platform) + options.platform = process__default.platform === "win32" ? "win32" : "posix"; + if (process__default.versions.pnp) { + const paths = options.paths || []; + if (paths.length === 0) + paths.push(process__default.cwd()); + const targetRequire = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))); + try { + return targetRequire.resolve(path$1, { paths }); + } catch { + } + } + const modulePath = mlly.resolvePathSync(path$1, { + url: options.paths + }); + if (options.platform === "win32") + return path.win32.normalize(modulePath); + return modulePath; +} +function resolveModule(name, options = {}) { + try { + return _resolve(name, options); + } catch { + return void 0; + } +} +async function importModule(path) { + const i = await import(path); + if (i) + return mlly.interopDefault(i); + return i; +} +function isPackageExists(name, options = {}) { + return !!resolvePackage(name, options); +} +function getPackageJsonPath(name, options = {}) { + const entry = resolvePackage(name, options); + if (!entry) + return; + return searchPackageJSON(entry); +} +async function getPackageInfo(name, options = {}) { + const packageJsonPath = getPackageJsonPath(name, options); + if (!packageJsonPath) + return; + const packageJson = JSON.parse(await fs__default.promises.readFile(packageJsonPath, "utf8")); + return { + name, + version: packageJson.version, + rootPath: path.dirname(packageJsonPath), + packageJsonPath, + packageJson + }; +} +function getPackageInfoSync(name, options = {}) { + const packageJsonPath = getPackageJsonPath(name, options); + if (!packageJsonPath) + return; + const packageJson = JSON.parse(fs__default.readFileSync(packageJsonPath, "utf8")); + return { + name, + version: packageJson.version, + rootPath: path.dirname(packageJsonPath), + packageJsonPath, + packageJson + }; +} +function resolvePackage(name, options = {}) { + try { + return _resolve(`${name}/package.json`, options); + } catch { + } + try { + return _resolve(name, options); + } catch (e) { + if (e.code !== "MODULE_NOT_FOUND" && e.code !== "ERR_MODULE_NOT_FOUND") + console.error(e); + return false; + } +} +function searchPackageJSON(dir) { + let packageJsonPath; + while (true) { + if (!dir) + return; + const newDir = path.dirname(dir); + if (newDir === dir) + return; + dir = newDir; + packageJsonPath = path.join(dir, "package.json"); + if (fs__default.existsSync(packageJsonPath)) + break; + } + return packageJsonPath; +} +async function loadPackageJSON(cwd = process__default.cwd()) { + const path = await findUp("package.json", { cwd }); + if (!path || !fs__default.existsSync(path)) + return null; + return JSON.parse(await fsp__default.readFile(path, "utf-8")); +} +async function isPackageListed(name, cwd) { + const pkg = await loadPackageJSON(cwd) || {}; + return name in (pkg.dependencies || {}) || name in (pkg.devDependencies || {}); +} + +exports.getPackageInfo = getPackageInfo; +exports.getPackageInfoSync = getPackageInfoSync; +exports.importModule = importModule; +exports.isPackageExists = isPackageExists; +exports.isPackageListed = isPackageListed; +exports.loadPackageJSON = loadPackageJSON; +exports.resolveModule = resolveModule; diff --git a/node_modules/local-pkg/dist/index.d.cts b/node_modules/local-pkg/dist/index.d.cts new file mode 100644 index 0000000..f2e4df7 --- /dev/null +++ b/node_modules/local-pkg/dist/index.d.cts @@ -0,0 +1,38 @@ +import { PackageJson } from 'pkg-types'; + +interface PackageInfo { + name: string; + rootPath: string; + packageJsonPath: string; + version: string; + packageJson: PackageJson; +} +interface PackageResolvingOptions { + paths?: string[]; + /** + * @default 'auto' + * Resolve path as posix or win32 + */ + platform?: 'posix' | 'win32' | 'auto'; +} +declare function resolveModule(name: string, options?: PackageResolvingOptions): string | undefined; +declare function importModule(path: string): Promise; +declare function isPackageExists(name: string, options?: PackageResolvingOptions): boolean; +declare function getPackageInfo(name: string, options?: PackageResolvingOptions): Promise<{ + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined>; +declare function getPackageInfoSync(name: string, options?: PackageResolvingOptions): { + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined; +declare function loadPackageJSON(cwd?: string): Promise; +declare function isPackageListed(name: string, cwd?: string): Promise; + +export { type PackageInfo, type PackageResolvingOptions, getPackageInfo, getPackageInfoSync, importModule, isPackageExists, isPackageListed, loadPackageJSON, resolveModule }; diff --git a/node_modules/local-pkg/dist/index.d.mts b/node_modules/local-pkg/dist/index.d.mts new file mode 100644 index 0000000..f2e4df7 --- /dev/null +++ b/node_modules/local-pkg/dist/index.d.mts @@ -0,0 +1,38 @@ +import { PackageJson } from 'pkg-types'; + +interface PackageInfo { + name: string; + rootPath: string; + packageJsonPath: string; + version: string; + packageJson: PackageJson; +} +interface PackageResolvingOptions { + paths?: string[]; + /** + * @default 'auto' + * Resolve path as posix or win32 + */ + platform?: 'posix' | 'win32' | 'auto'; +} +declare function resolveModule(name: string, options?: PackageResolvingOptions): string | undefined; +declare function importModule(path: string): Promise; +declare function isPackageExists(name: string, options?: PackageResolvingOptions): boolean; +declare function getPackageInfo(name: string, options?: PackageResolvingOptions): Promise<{ + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined>; +declare function getPackageInfoSync(name: string, options?: PackageResolvingOptions): { + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined; +declare function loadPackageJSON(cwd?: string): Promise; +declare function isPackageListed(name: string, cwd?: string): Promise; + +export { type PackageInfo, type PackageResolvingOptions, getPackageInfo, getPackageInfoSync, importModule, isPackageExists, isPackageListed, loadPackageJSON, resolveModule }; diff --git a/node_modules/local-pkg/dist/index.d.ts b/node_modules/local-pkg/dist/index.d.ts new file mode 100644 index 0000000..f2e4df7 --- /dev/null +++ b/node_modules/local-pkg/dist/index.d.ts @@ -0,0 +1,38 @@ +import { PackageJson } from 'pkg-types'; + +interface PackageInfo { + name: string; + rootPath: string; + packageJsonPath: string; + version: string; + packageJson: PackageJson; +} +interface PackageResolvingOptions { + paths?: string[]; + /** + * @default 'auto' + * Resolve path as posix or win32 + */ + platform?: 'posix' | 'win32' | 'auto'; +} +declare function resolveModule(name: string, options?: PackageResolvingOptions): string | undefined; +declare function importModule(path: string): Promise; +declare function isPackageExists(name: string, options?: PackageResolvingOptions): boolean; +declare function getPackageInfo(name: string, options?: PackageResolvingOptions): Promise<{ + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined>; +declare function getPackageInfoSync(name: string, options?: PackageResolvingOptions): { + name: string; + version: string | undefined; + rootPath: string; + packageJsonPath: string; + packageJson: PackageJson; +} | undefined; +declare function loadPackageJSON(cwd?: string): Promise; +declare function isPackageListed(name: string, cwd?: string): Promise; + +export { type PackageInfo, type PackageResolvingOptions, getPackageInfo, getPackageInfoSync, importModule, isPackageExists, isPackageListed, loadPackageJSON, resolveModule }; diff --git a/node_modules/local-pkg/dist/index.mjs b/node_modules/local-pkg/dist/index.mjs new file mode 100644 index 0000000..5ab48b6 --- /dev/null +++ b/node_modules/local-pkg/dist/index.mjs @@ -0,0 +1,393 @@ +import fs, { promises } from 'node:fs'; +import fsp from 'node:fs/promises'; +import { createRequire } from 'node:module'; +import path, { dirname, win32, join } from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; +import { interopDefault, resolvePathSync } from 'mlly'; + +/* +How it works: +`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value. +*/ + +class Node { + value; + next; + + constructor(value) { + this.value = value; + } +} + +class Queue { + #head; + #tail; + #size; + + constructor() { + this.clear(); + } + + enqueue(value) { + const node = new Node(value); + + if (this.#head) { + this.#tail.next = node; + this.#tail = node; + } else { + this.#head = node; + this.#tail = node; + } + + this.#size++; + } + + dequeue() { + const current = this.#head; + if (!current) { + return; + } + + this.#head = this.#head.next; + this.#size--; + return current.value; + } + + clear() { + this.#head = undefined; + this.#tail = undefined; + this.#size = 0; + } + + get size() { + return this.#size; + } + + * [Symbol.iterator]() { + let current = this.#head; + + while (current) { + yield current.value; + current = current.next; + } + } +} + +function pLimit(concurrency) { + if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { + throw new TypeError('Expected `concurrency` to be a number from 1 and up'); + } + + const queue = new Queue(); + let activeCount = 0; + + const next = () => { + activeCount--; + + if (queue.size > 0) { + queue.dequeue()(); + } + }; + + const run = async (fn, resolve, args) => { + activeCount++; + + const result = (async () => fn(...args))(); + + resolve(result); + + try { + await result; + } catch {} + + next(); + }; + + const enqueue = (fn, resolve, args) => { + queue.enqueue(run.bind(undefined, fn, resolve, args)); + + (async () => { + // This function needs to wait until the next microtask before comparing + // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously + // when the run function is dequeued and called. The comparison in the if-statement + // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. + await Promise.resolve(); + + if (activeCount < concurrency && queue.size > 0) { + queue.dequeue()(); + } + })(); + }; + + const generator = (fn, ...args) => new Promise(resolve => { + enqueue(fn, resolve, args); + }); + + Object.defineProperties(generator, { + activeCount: { + get: () => activeCount, + }, + pendingCount: { + get: () => queue.size, + }, + clearQueue: { + value: () => { + queue.clear(); + }, + }, + }); + + return generator; +} + +class EndError extends Error { + constructor(value) { + super(); + this.value = value; + } +} + +// The input can also be a promise, so we await it. +const testElement = async (element, tester) => tester(await element); + +// The input can also be a promise, so we `Promise.all()` them both. +const finder = async element => { + const values = await Promise.all(element); + if (values[1] === true) { + throw new EndError(values[0]); + } + + return false; +}; + +async function pLocate( + iterable, + tester, + { + concurrency = Number.POSITIVE_INFINITY, + preserveOrder = true, + } = {}, +) { + const limit = pLimit(concurrency); + + // Start all the promises concurrently with optional limit. + const items = [...iterable].map(element => [element, limit(testElement, element, tester)]); + + // Check the promises either serially or concurrently. + const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY); + + try { + await Promise.all(items.map(element => checkLimit(finder, element))); + } catch (error) { + if (error instanceof EndError) { + return error.value; + } + + throw error; + } +} + +const typeMappings = { + directory: 'isDirectory', + file: 'isFile', +}; + +function checkType(type) { + if (Object.hasOwnProperty.call(typeMappings, type)) { + return; + } + + throw new Error(`Invalid type specified: ${type}`); +} + +const matchType = (type, stat) => stat[typeMappings[type]](); + +const toPath$1 = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; + +async function locatePath( + paths, + { + cwd = process.cwd(), + type = 'file', + allowSymlinks = true, + concurrency, + preserveOrder, + } = {}, +) { + checkType(type); + cwd = toPath$1(cwd); + + const statFunction = allowSymlinks ? promises.stat : promises.lstat; + + return pLocate(paths, async path_ => { + try { + const stat = await statFunction(path.resolve(cwd, path_)); + return matchType(type, stat); + } catch { + return false; + } + }, {concurrency, preserveOrder}); +} + +const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; + +const findUpStop = Symbol('findUpStop'); + +async function findUpMultiple(name, options = {}) { + let directory = path.resolve(toPath(options.cwd) || ''); + const {root} = path.parse(directory); + const stopAt = path.resolve(directory, options.stopAt || root); + const limit = options.limit || Number.POSITIVE_INFINITY; + const paths = [name].flat(); + + const runMatcher = async locateOptions => { + if (typeof name !== 'function') { + return locatePath(paths, locateOptions); + } + + const foundPath = await name(locateOptions.cwd); + if (typeof foundPath === 'string') { + return locatePath([foundPath], locateOptions); + } + + return foundPath; + }; + + const matches = []; + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + const foundPath = await runMatcher({...options, cwd: directory}); + + if (foundPath === findUpStop) { + break; + } + + if (foundPath) { + matches.push(path.resolve(directory, foundPath)); + } + + if (directory === stopAt || matches.length >= limit) { + break; + } + + directory = path.dirname(directory); + } + + return matches; +} + +async function findUp(name, options = {}) { + const matches = await findUpMultiple(name, {...options, limit: 1}); + return matches[0]; +} + +function _resolve(path, options = {}) { + if (options.platform === "auto" || !options.platform) + options.platform = process.platform === "win32" ? "win32" : "posix"; + if (process.versions.pnp) { + const paths = options.paths || []; + if (paths.length === 0) + paths.push(process.cwd()); + const targetRequire = createRequire(import.meta.url); + try { + return targetRequire.resolve(path, { paths }); + } catch { + } + } + const modulePath = resolvePathSync(path, { + url: options.paths + }); + if (options.platform === "win32") + return win32.normalize(modulePath); + return modulePath; +} +function resolveModule(name, options = {}) { + try { + return _resolve(name, options); + } catch { + return void 0; + } +} +async function importModule(path) { + const i = await import(path); + if (i) + return interopDefault(i); + return i; +} +function isPackageExists(name, options = {}) { + return !!resolvePackage(name, options); +} +function getPackageJsonPath(name, options = {}) { + const entry = resolvePackage(name, options); + if (!entry) + return; + return searchPackageJSON(entry); +} +async function getPackageInfo(name, options = {}) { + const packageJsonPath = getPackageJsonPath(name, options); + if (!packageJsonPath) + return; + const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, "utf8")); + return { + name, + version: packageJson.version, + rootPath: dirname(packageJsonPath), + packageJsonPath, + packageJson + }; +} +function getPackageInfoSync(name, options = {}) { + const packageJsonPath = getPackageJsonPath(name, options); + if (!packageJsonPath) + return; + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); + return { + name, + version: packageJson.version, + rootPath: dirname(packageJsonPath), + packageJsonPath, + packageJson + }; +} +function resolvePackage(name, options = {}) { + try { + return _resolve(`${name}/package.json`, options); + } catch { + } + try { + return _resolve(name, options); + } catch (e) { + if (e.code !== "MODULE_NOT_FOUND" && e.code !== "ERR_MODULE_NOT_FOUND") + console.error(e); + return false; + } +} +function searchPackageJSON(dir) { + let packageJsonPath; + while (true) { + if (!dir) + return; + const newDir = dirname(dir); + if (newDir === dir) + return; + dir = newDir; + packageJsonPath = join(dir, "package.json"); + if (fs.existsSync(packageJsonPath)) + break; + } + return packageJsonPath; +} +async function loadPackageJSON(cwd = process.cwd()) { + const path = await findUp("package.json", { cwd }); + if (!path || !fs.existsSync(path)) + return null; + return JSON.parse(await fsp.readFile(path, "utf-8")); +} +async function isPackageListed(name, cwd) { + const pkg = await loadPackageJSON(cwd) || {}; + return name in (pkg.dependencies || {}) || name in (pkg.devDependencies || {}); +} + +export { getPackageInfo, getPackageInfoSync, importModule, isPackageExists, isPackageListed, loadPackageJSON, resolveModule }; diff --git a/node_modules/local-pkg/package.json b/node_modules/local-pkg/package.json new file mode 100644 index 0000000..9f751ff --- /dev/null +++ b/node_modules/local-pkg/package.json @@ -0,0 +1,65 @@ +{ + "name": "local-pkg", + "type": "module", + "version": "0.5.1", + "packageManager": "pnpm@9.13.2", + "description": "Get information on local packages.", + "author": "Anthony Fu ", + "license": "MIT", + "funding": "https://github.com/sponsors/antfu", + "homepage": "https://github.com/antfu/local-pkg#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/antfu/local-pkg.git" + }, + "bugs": { + "url": "https://github.com/antfu/local-pkg/issues" + }, + "keywords": [ + "package" + ], + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + } + }, + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=14" + }, + "scripts": { + "prepublishOnly": "nr build", + "build": "unbuild", + "lint": "eslint .", + "release": "bumpp && npm publish", + "typecheck": "tsc --noEmit", + "test": "vitest run && node ./test/cjs.cjs && node ./test/esm.mjs" + }, + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "devDependencies": { + "@antfu/eslint-config": "^3.9.2", + "@antfu/ni": "^0.23.1", + "@antfu/utils": "^0.7.10", + "@types/chai": "^5.0.1", + "@types/node": "^22.9.0", + "bumpp": "^9.8.1", + "chai": "^5.1.2", + "eslint": "^9.15.0", + "esno": "^4.8.0", + "find-up": "^6.3.0", + "typescript": "^5.6.3", + "unbuild": "^2.0.0", + "vitest": "^2.1.5" + } +} diff --git a/node_modules/loupe/CHANGELOG.md b/node_modules/loupe/CHANGELOG.md new file mode 100644 index 0000000..11799db --- /dev/null +++ b/node_modules/loupe/CHANGELOG.md @@ -0,0 +1,5 @@ + +0.0.1 / 2013-12-17 +================== + + * Initial port from chai.js diff --git a/node_modules/loupe/LICENSE b/node_modules/loupe/LICENSE new file mode 100644 index 0000000..b0c8a5a --- /dev/null +++ b/node_modules/loupe/LICENSE @@ -0,0 +1,9 @@ +(The MIT License) + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/loupe/README.md b/node_modules/loupe/README.md new file mode 100644 index 0000000..44f61d3 --- /dev/null +++ b/node_modules/loupe/README.md @@ -0,0 +1,63 @@ +![npm](https://img.shields.io/npm/v/loupe?logo=npm) +![Build](https://github.com/chaijs/loupe/workflows/Build/badge.svg?branch=master) +![Codecov branch](https://img.shields.io/codecov/c/github/chaijs/loupe/master?logo=codecov) + +# What is loupe? + +Loupe turns the object you give it into a string. It's similar to Node.js' `util.inspect()` function, but it works cross platform, in most modern browsers as well as Node. + +## Installation + +### Node.js + +`loupe` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install loupe + +### Browsers + +You can also use it within the browser; install via npm and use the `loupe.js` file found within the download. For example: + +```html + +``` + +## Usage + +``` js +const { inspect } = require('loupe'); +``` + +```js +inspect({ foo: 'bar' }); // => "{ foo: 'bar' }" +inspect(1); // => '1' +inspect('foo'); // => "'foo'" +inspect([ 1, 2, 3 ]); // => '[ 1, 2, 3 ]' +inspect(/Test/g); // => '/Test/g' + +// ... +``` + +## Tests + +```bash +$ npm test +``` + +Coverage: + +```bash +$ npm run upload-coverage +``` + +## License + +(The MIT License) + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/loupe/index.js b/node_modules/loupe/index.js new file mode 100644 index 0000000..01e0b3c --- /dev/null +++ b/node_modules/loupe/index.js @@ -0,0 +1,219 @@ +/* ! + * loupe + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +import inspectArray from './lib/array' +import inspectTypedArray from './lib/typedarray' +import inspectDate from './lib/date' +import inspectFunction from './lib/function' +import inspectMap from './lib/map' +import inspectNumber from './lib/number' +import inspectBigInt from './lib/bigint' +import inspectRegExp from './lib/regexp' +import inspectSet from './lib/set' +import inspectString from './lib/string' +import inspectSymbol from './lib/symbol' +import inspectPromise from './lib/promise' +import inspectClass from './lib/class' +import inspectObject from './lib/object' +import inspectArguments from './lib/arguments' +import inspectError from './lib/error' +import inspectHTMLElement, { inspectHTMLCollection } from './lib/html' + +import { normaliseOptions } from './lib/helpers' + +const symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function' +const chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect' +let nodeInspect = false +try { + // eslint-disable-next-line global-require + const nodeUtil = require('util') + nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false +} catch (noNodeInspect) { + nodeInspect = false +} + +function FakeMap() { + // eslint-disable-next-line prefer-template + this.key = 'chai/loupe__' + Math.random() + Date.now() +} +FakeMap.prototype = { + // eslint-disable-next-line object-shorthand + get: function get(key) { + return key[this.key] + }, + // eslint-disable-next-line object-shorthand + has: function has(key) { + return this.key in key + }, + // eslint-disable-next-line object-shorthand + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this.key, { + // eslint-disable-next-line object-shorthand + value: value, + configurable: true, + }) + } + }, +} +const constructorMap = new (typeof WeakMap === 'function' ? WeakMap : FakeMap)() +const stringTagMap = {} +const baseTypesMap = { + undefined: (value, options) => options.stylize('undefined', 'undefined'), + null: (value, options) => options.stylize(null, 'null'), + + boolean: (value, options) => options.stylize(value, 'boolean'), + Boolean: (value, options) => options.stylize(value, 'boolean'), + + number: inspectNumber, + Number: inspectNumber, + + bigint: inspectBigInt, + BigInt: inspectBigInt, + + string: inspectString, + String: inspectString, + + function: inspectFunction, + Function: inspectFunction, + + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: inspectPromise, + + // WeakSet, WeakMap are totally opaque to us + WeakSet: (value, options) => options.stylize('WeakSet{…}', 'special'), + WeakMap: (value, options) => options.stylize('WeakMap{…}', 'special'), + + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + + Generator: () => '', + DataView: () => '', + ArrayBuffer: () => '', + + Error: inspectError, + + HTMLCollection: inspectHTMLCollection, + NodeList: inspectHTMLCollection, +} + +// eslint-disable-next-line complexity +const inspectCustom = (value, options, type) => { + if (chaiInspect in value && typeof value[chaiInspect] === 'function') { + return value[chaiInspect](options) + } + + if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') { + return value[nodeInspect](options.depth, options) + } + + if ('inspect' in value && typeof value.inspect === 'function') { + return value.inspect(options.depth, options) + } + + if ('constructor' in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options) + } + + if (stringTagMap[type]) { + return stringTagMap[type](value, options) + } + + return '' +} + +const toString = Object.prototype.toString + +// eslint-disable-next-line complexity +export function inspect(value, options) { + options = normaliseOptions(options) + options.inspect = inspect + const { customInspect } = options + let type = value === null ? 'null' : typeof value + if (type === 'object') { + type = toString.call(value).slice(8, -1) + } + + // If it is a base value that we already support, then use Loupe's inspector + if (baseTypesMap[type]) { + return baseTypesMap[type](value, options) + } + + // If `options.customInspect` is set to true then try to use the custom inspector + if (customInspect && value) { + const output = inspectCustom(value, options, type) + if (output) { + if (typeof output === 'string') return output + return inspect(output, options) + } + } + + const proto = value ? Object.getPrototypeOf(value) : false + // If it's a plain Object then use Loupe's inspector + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options) + } + + // Specifically account for HTMLElements + // eslint-disable-next-line no-undef + if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) { + return inspectHTMLElement(value, options) + } + + if ('constructor' in value) { + // If it is a class, inspect it like an object but add the constructor name + if (value.constructor !== Object) { + return inspectClass(value, options) + } + + // If it is an object with an anonymous prototype, display it as an object. + return inspectObject(value, options) + } + + // last chance to check if it's an object + if (value === Object(value)) { + return inspectObject(value, options) + } + + // We have run out of options! Just stringify the value + return options.stylize(String(value), type) +} + +export function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false + } + constructorMap.set(constructor, inspector) + return true +} + +export function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false + } + stringTagMap[stringTag] = inspector + return true +} + +export const custom = chaiInspect + +export default inspect diff --git a/node_modules/loupe/lib/arguments.js b/node_modules/loupe/lib/arguments.js new file mode 100644 index 0000000..e7d3a6d --- /dev/null +++ b/node_modules/loupe/lib/arguments.js @@ -0,0 +1,7 @@ +import { inspectList } from './helpers' + +export default function inspectArguments(args, options) { + if (args.length === 0) return 'Arguments[]' + options.truncate -= 13 + return `Arguments[ ${inspectList(args, options)} ]` +} diff --git a/node_modules/loupe/lib/array.js b/node_modules/loupe/lib/array.js new file mode 100644 index 0000000..c377029 --- /dev/null +++ b/node_modules/loupe/lib/array.js @@ -0,0 +1,20 @@ +import { inspectProperty, inspectList } from './helpers' + +export default function inspectArray(array, options) { + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + const nonIndexProperties = Object.keys(array).slice(array.length) + if (!array.length && !nonIndexProperties.length) return '[]' + options.truncate -= 4 + const listContents = inspectList(array, options) + options.truncate -= listContents.length + let propertyContents = '' + if (nonIndexProperties.length) { + propertyContents = inspectList( + nonIndexProperties.map(key => [key, array[key]]), + options, + inspectProperty + ) + } + return `[ ${listContents}${propertyContents ? `, ${propertyContents}` : ''} ]` +} diff --git a/node_modules/loupe/lib/bigint.js b/node_modules/loupe/lib/bigint.js new file mode 100644 index 0000000..d93db78 --- /dev/null +++ b/node_modules/loupe/lib/bigint.js @@ -0,0 +1,7 @@ +import { truncate, truncator } from './helpers' + +export default function inspectBigInt(number, options) { + let nums = truncate(number.toString(), options.truncate - 1) + if (nums !== truncator) nums += 'n' + return options.stylize(nums, 'bigint') +} diff --git a/node_modules/loupe/lib/class.js b/node_modules/loupe/lib/class.js new file mode 100644 index 0000000..cd949af --- /dev/null +++ b/node_modules/loupe/lib/class.js @@ -0,0 +1,18 @@ +import getFuncName from 'get-func-name' +import inspectObject from './object' + +const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false + +export default function inspectClass(value, options) { + let name = '' + if (toStringTag && toStringTag in value) { + name = value[toStringTag] + } + name = name || getFuncName(value.constructor) + // Babel transforms anonymous classes to the name `_class` + if (!name || name === '_class') { + name = '' + } + options.truncate -= name.length + return `${name}${inspectObject(value, options)}` +} diff --git a/node_modules/loupe/lib/date.js b/node_modules/loupe/lib/date.js new file mode 100644 index 0000000..9d15962 --- /dev/null +++ b/node_modules/loupe/lib/date.js @@ -0,0 +1,14 @@ +import { truncate } from './helpers' + +export default function inspectDate(dateObject, options) { + const stringRepresentation = dateObject.toJSON() + + if (stringRepresentation === null) { + return 'Invalid Date' + } + + const split = stringRepresentation.split('T') + const date = split[0] + // If we need to - truncate the time portion, but never the date + return options.stylize(`${date}T${truncate(split[1], options.truncate - date.length - 1)}`, 'date') +} diff --git a/node_modules/loupe/lib/error.js b/node_modules/loupe/lib/error.js new file mode 100644 index 0000000..1fabaa9 --- /dev/null +++ b/node_modules/loupe/lib/error.js @@ -0,0 +1,34 @@ +import { truncate, inspectList, inspectProperty } from './helpers' + +const errorKeys = [ + 'stack', + 'line', + 'column', + 'name', + 'message', + 'fileName', + 'lineNumber', + 'columnNumber', + 'number', + 'description', +] + +export default function inspectObject(error, options) { + const properties = Object.getOwnPropertyNames(error).filter(key => errorKeys.indexOf(key) === -1) + const name = error.name + options.truncate -= name.length + let message = '' + if (typeof error.message === 'string') { + message = truncate(error.message, options.truncate) + } else { + properties.unshift('message') + } + message = message ? `: ${message}` : '' + options.truncate -= message.length + 5 + const propertyContents = inspectList( + properties.map(key => [key, error[key]]), + options, + inspectProperty + ) + return `${name}${message}${propertyContents ? ` { ${propertyContents} }` : ''}` +} diff --git a/node_modules/loupe/lib/function.js b/node_modules/loupe/lib/function.js new file mode 100644 index 0000000..75b7c55 --- /dev/null +++ b/node_modules/loupe/lib/function.js @@ -0,0 +1,10 @@ +import getFunctionName from 'get-func-name' +import { truncate } from './helpers' + +export default function inspectFunction(func, options) { + const name = getFunctionName(func) + if (!name) { + return options.stylize('[Function]', 'special') + } + return options.stylize(`[Function ${truncate(name, options.truncate - 11)}]`, 'special') +} diff --git a/node_modules/loupe/lib/helpers.js b/node_modules/loupe/lib/helpers.js new file mode 100644 index 0000000..8a883d6 --- /dev/null +++ b/node_modules/loupe/lib/helpers.js @@ -0,0 +1,177 @@ +const ansiColors = { + bold: ['1', '22'], + dim: ['2', '22'], + italic: ['3', '23'], + underline: ['4', '24'], + // 5 & 6 are blinking + inverse: ['7', '27'], + hidden: ['8', '28'], + strike: ['9', '29'], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ['30', '39'], + red: ['31', '39'], + green: ['32', '39'], + yellow: ['33', '39'], + blue: ['34', '39'], + magenta: ['35', '39'], + cyan: ['36', '39'], + white: ['37', '39'], + + brightblack: ['30;1', '39'], + brightred: ['31;1', '39'], + brightgreen: ['32;1', '39'], + brightyellow: ['33;1', '39'], + brightblue: ['34;1', '39'], + brightmagenta: ['35;1', '39'], + brightcyan: ['36;1', '39'], + brightwhite: ['37;1', '39'], + + grey: ['90', '39'], +} + +const styles = { + special: 'cyan', + number: 'yellow', + bigint: 'yellow', + boolean: 'yellow', + undefined: 'grey', + null: 'bold', + string: 'green', + symbol: 'green', + date: 'magenta', + regexp: 'red', +} + +export const truncator = '…' + +function colorise(value, styleType) { + const color = ansiColors[styles[styleType]] || ansiColors[styleType] + if (!color) { + return String(value) + } + return `\u001b[${color[0]}m${String(value)}\u001b[${color[1]}m` +} + +export function normaliseOptions({ + showHidden = false, + depth = 2, + colors = false, + customInspect = true, + showProxy = false, + maxArrayLength = Infinity, + breakLength = Infinity, + seen = [], + // eslint-disable-next-line no-shadow + truncate = Infinity, + stylize = String, +} = {}) { + const options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate), + seen, + stylize, + } + if (options.colors) { + options.stylize = colorise + } + return options +} + +export function truncate(string, length, tail = truncator) { + string = String(string) + const tailLength = tail.length + const stringLength = string.length + if (tailLength > length && stringLength > tailLength) { + return tail + } + if (stringLength > length && stringLength > tailLength) { + return `${string.slice(0, length - tailLength)}${tail}` + } + return string +} + +// eslint-disable-next-line complexity +export function inspectList(list, options, inspectItem, separator = ', ') { + inspectItem = inspectItem || options.inspect + const size = list.length + if (size === 0) return '' + const originalLength = options.truncate + let output = '' + let peek = '' + let truncated = '' + for (let i = 0; i < size; i += 1) { + const last = i + 1 === list.length + const secondToLast = i + 2 === list.length + truncated = `${truncator}(${list.length - i})` + const value = list[i] + + // If there is more than one remaining we need to account for a separator of `, ` + options.truncate = originalLength - output.length - (last ? 0 : separator.length) + const string = peek || inspectItem(value, options) + (last ? '' : separator) + const nextLength = output.length + string.length + const truncatedLength = nextLength + truncated.length + + // If this is the last element, and adding it would + // take us over length, but adding the truncator wouldn't - then break now + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break + } + + // If this isn't the last or second to last element to scan, + // but the string is already over length then break here + if (!last && !secondToLast && truncatedLength > originalLength) { + break + } + + // Peek at the next string to determine if we should + // break early before adding this item to the output + peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator) + + // If we have one element left, but this element and + // the next takes over length, the break early + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break + } + + output += string + + // If the next element takes us to length - + // but there are more after that, then we should truncate now + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = `${truncator}(${list.length - i - 1})` + break + } + + truncated = '' + } + return `${output}${truncated}` +} + +function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key + } + return JSON.stringify(key) + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'") +} + +export function inspectProperty([key, value], options) { + options.truncate -= 2 + if (typeof key === 'string') { + key = quoteComplexKey(key) + } else if (typeof key !== 'number') { + key = `[${options.inspect(key, options)}]` + } + options.truncate -= key.length + value = options.inspect(value, options) + return `${key}: ${value}` +} diff --git a/node_modules/loupe/lib/html.js b/node_modules/loupe/lib/html.js new file mode 100644 index 0000000..e39cd34 --- /dev/null +++ b/node_modules/loupe/lib/html.js @@ -0,0 +1,40 @@ +import { truncator, inspectList } from './helpers' + +export function inspectAttribute([key, value], options) { + options.truncate -= 3 + if (!value) { + return `${options.stylize(key, 'yellow')}` + } + return `${options.stylize(key, 'yellow')}=${options.stylize(`"${value}"`, 'string')}` +} + +export function inspectHTMLCollection(collection, options) { + // eslint-disable-next-line no-use-before-define + return inspectList(collection, options, inspectHTML, '\n') +} + +export default function inspectHTML(element, options) { + const properties = element.getAttributeNames() + const name = element.tagName.toLowerCase() + const head = options.stylize(`<${name}`, 'special') + const headClose = options.stylize(`>`, 'special') + const tail = options.stylize(``, 'special') + options.truncate -= name.length * 2 + 5 + let propertyContents = '' + if (properties.length > 0) { + propertyContents += ' ' + propertyContents += inspectList( + properties.map(key => [key, element.getAttribute(key)]), + options, + inspectAttribute, + ' ' + ) + } + options.truncate -= propertyContents.length + const truncate = options.truncate + let children = inspectHTMLCollection(element.children, options) + if (children && children.length > truncate) { + children = `${truncator}(${element.children.length})` + } + return `${head}${propertyContents}${headClose}${children}${tail}` +} diff --git a/node_modules/loupe/lib/map.js b/node_modules/loupe/lib/map.js new file mode 100644 index 0000000..2842e30 --- /dev/null +++ b/node_modules/loupe/lib/map.js @@ -0,0 +1,27 @@ +import { inspectList } from './helpers' + +function inspectMapEntry([key, value], options) { + options.truncate -= 4 + key = options.inspect(key, options) + options.truncate -= key.length + value = options.inspect(value, options) + return `${key} => ${value}` +} + +// IE11 doesn't support `map.entries()` +function mapToEntries(map) { + const entries = [] + map.forEach((value, key) => { + entries.push([key, value]) + }) + return entries +} + +export default function inspectMap(map, options) { + const size = map.size - 1 + if (size <= 0) { + return 'Map{}' + } + options.truncate -= 7 + return `Map{ ${inspectList(mapToEntries(map), options, inspectMapEntry)} }` +} diff --git a/node_modules/loupe/lib/number.js b/node_modules/loupe/lib/number.js new file mode 100644 index 0000000..9def128 --- /dev/null +++ b/node_modules/loupe/lib/number.js @@ -0,0 +1,18 @@ +import { truncate } from './helpers' + +const isNaN = Number.isNaN || (i => i !== i) // eslint-disable-line no-self-compare +export default function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize('NaN', 'number') + } + if (number === Infinity) { + return options.stylize('Infinity', 'number') + } + if (number === -Infinity) { + return options.stylize('-Infinity', 'number') + } + if (number === 0) { + return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number') + } + return options.stylize(truncate(number, options.truncate), 'number') +} diff --git a/node_modules/loupe/lib/object.js b/node_modules/loupe/lib/object.js new file mode 100644 index 0000000..4cbb87f --- /dev/null +++ b/node_modules/loupe/lib/object.js @@ -0,0 +1,31 @@ +import { inspectProperty, inspectList } from './helpers' + +export default function inspectObject(object, options) { + const properties = Object.getOwnPropertyNames(object) + const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [] + if (properties.length === 0 && symbols.length === 0) { + return '{}' + } + options.truncate -= 4 + options.seen = options.seen || [] + if (options.seen.indexOf(object) >= 0) { + return '[Circular]' + } + options.seen.push(object) + const propertyContents = inspectList( + properties.map(key => [key, object[key]]), + options, + inspectProperty + ) + const symbolContents = inspectList( + symbols.map(key => [key, object[key]]), + options, + inspectProperty + ) + options.seen.pop() + let sep = '' + if (propertyContents && symbolContents) { + sep = ', ' + } + return `{ ${propertyContents}${sep}${symbolContents} }` +} diff --git a/node_modules/loupe/lib/promise.js b/node_modules/loupe/lib/promise.js new file mode 100644 index 0000000..327e9f4 --- /dev/null +++ b/node_modules/loupe/lib/promise.js @@ -0,0 +1,16 @@ +let getPromiseValue = () => 'Promise{…}' +try { + const { getPromiseDetails, kPending, kRejected } = process.binding('util') + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = (value, options) => { + const [state, innerValue] = getPromiseDetails(value) + if (state === kPending) { + return 'Promise{}' + } + return `Promise${state === kRejected ? '!' : ''}{${options.inspect(innerValue, options)}}` + } + } +} catch (notNode) { + /* ignore */ +} +export default getPromiseValue diff --git a/node_modules/loupe/lib/regexp.js b/node_modules/loupe/lib/regexp.js new file mode 100644 index 0000000..edad917 --- /dev/null +++ b/node_modules/loupe/lib/regexp.js @@ -0,0 +1,8 @@ +import { truncate } from './helpers' + +export default function inspectRegExp(value, options) { + const flags = value.toString().split('/')[2] + const sourceLength = options.truncate - (2 + flags.length) + const source = value.source + return options.stylize(`/${truncate(source, sourceLength)}/${flags}`, 'regexp') +} diff --git a/node_modules/loupe/lib/set.js b/node_modules/loupe/lib/set.js new file mode 100644 index 0000000..99a1300 --- /dev/null +++ b/node_modules/loupe/lib/set.js @@ -0,0 +1,16 @@ +import { inspectList } from './helpers' + +// IE11 doesn't support `Array.from(set)` +function arrayFromSet(set) { + const values = [] + set.forEach(value => { + values.push(value) + }) + return values +} + +export default function inspectSet(set, options) { + if (set.size === 0) return 'Set{}' + options.truncate -= 7 + return `Set{ ${inspectList(arrayFromSet(set), options)} }` +} diff --git a/node_modules/loupe/lib/string.js b/node_modules/loupe/lib/string.js new file mode 100644 index 0000000..2af66cf --- /dev/null +++ b/node_modules/loupe/lib/string.js @@ -0,0 +1,29 @@ +import { truncate } from './helpers' + +const stringEscapeChars = new RegExp( + "['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + + '\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]', + 'g' +) + +const escapeCharacters = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + "'": "\\'", + '\\': '\\\\', +} +const hex = 16 +const unicodeLength = 4 +function escape(char) { + return escapeCharacters[char] || `\\u${`0000${char.charCodeAt(0).toString(hex)}`.slice(-unicodeLength)}` +} + +export default function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape) + } + return options.stylize(`'${truncate(string, options.truncate - 2)}'`, 'string') +} diff --git a/node_modules/loupe/lib/symbol.js b/node_modules/loupe/lib/symbol.js new file mode 100644 index 0000000..f98beec --- /dev/null +++ b/node_modules/loupe/lib/symbol.js @@ -0,0 +1,6 @@ +export default function inspectSymbol(value) { + if ('description' in Symbol.prototype) { + return value.description ? `Symbol(${value.description})` : 'Symbol()' + } + return value.toString() +} diff --git a/node_modules/loupe/lib/typedarray.js b/node_modules/loupe/lib/typedarray.js new file mode 100644 index 0000000..b98c045 --- /dev/null +++ b/node_modules/loupe/lib/typedarray.js @@ -0,0 +1,45 @@ +import getFuncName from 'get-func-name' +import { truncator, truncate, inspectProperty, inspectList } from './helpers' + +const getArrayName = array => { + // We need to special case Node.js' Buffers, which report to be Uint8Array + if (typeof Buffer === 'function' && array instanceof Buffer) { + return 'Buffer' + } + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag] + } + return getFuncName(array.constructor) +} + +export default function inspectTypedArray(array, options) { + const name = getArrayName(array) + options.truncate -= name.length + 4 + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + const nonIndexProperties = Object.keys(array).slice(array.length) + if (!array.length && !nonIndexProperties.length) return `${name}[]` + // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply + // stylise the toString() value of them + let output = '' + for (let i = 0; i < array.length; i++) { + const string = `${options.stylize(truncate(array[i], options.truncate), 'number')}${ + i === array.length - 1 ? '' : ', ' + }` + options.truncate -= string.length + if (array[i] !== array.length && options.truncate <= 3) { + output += `${truncator}(${array.length - array[i] + 1})` + break + } + output += string + } + let propertyContents = '' + if (nonIndexProperties.length) { + propertyContents = inspectList( + nonIndexProperties.map(key => [key, array[key]]), + options, + inspectProperty + ) + } + return `${name}[ ${output}${propertyContents ? `, ${propertyContents}` : ''} ]` +} diff --git a/node_modules/loupe/loupe.js b/node_modules/loupe/loupe.js new file mode 100644 index 0000000..5e1c239 --- /dev/null +++ b/node_modules/loupe/loupe.js @@ -0,0 +1,891 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.loupe = {})); +}(this, (function (exports) { 'use strict'; + + function _typeof(obj) { + "@babel/helpers - typeof"; + + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArrayLimit(arr, i) { + if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var ansiColors = { + bold: ['1', '22'], + dim: ['2', '22'], + italic: ['3', '23'], + underline: ['4', '24'], + // 5 & 6 are blinking + inverse: ['7', '27'], + hidden: ['8', '28'], + strike: ['9', '29'], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ['30', '39'], + red: ['31', '39'], + green: ['32', '39'], + yellow: ['33', '39'], + blue: ['34', '39'], + magenta: ['35', '39'], + cyan: ['36', '39'], + white: ['37', '39'], + brightblack: ['30;1', '39'], + brightred: ['31;1', '39'], + brightgreen: ['32;1', '39'], + brightyellow: ['33;1', '39'], + brightblue: ['34;1', '39'], + brightmagenta: ['35;1', '39'], + brightcyan: ['36;1', '39'], + brightwhite: ['37;1', '39'], + grey: ['90', '39'] + }; + var styles = { + special: 'cyan', + number: 'yellow', + bigint: 'yellow', + boolean: 'yellow', + undefined: 'grey', + null: 'bold', + string: 'green', + symbol: 'green', + date: 'magenta', + regexp: 'red' + }; + var truncator = '…'; + + function colorise(value, styleType) { + var color = ansiColors[styles[styleType]] || ansiColors[styleType]; + + if (!color) { + return String(value); + } + + return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m"); + } + + function normaliseOptions() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref$showHidden = _ref.showHidden, + showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden, + _ref$depth = _ref.depth, + depth = _ref$depth === void 0 ? 2 : _ref$depth, + _ref$colors = _ref.colors, + colors = _ref$colors === void 0 ? false : _ref$colors, + _ref$customInspect = _ref.customInspect, + customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect, + _ref$showProxy = _ref.showProxy, + showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy, + _ref$maxArrayLength = _ref.maxArrayLength, + maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength, + _ref$breakLength = _ref.breakLength, + breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength, + _ref$seen = _ref.seen, + seen = _ref$seen === void 0 ? [] : _ref$seen, + _ref$truncate = _ref.truncate, + truncate = _ref$truncate === void 0 ? Infinity : _ref$truncate, + _ref$stylize = _ref.stylize, + stylize = _ref$stylize === void 0 ? String : _ref$stylize; + + var options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate), + seen: seen, + stylize: stylize + }; + + if (options.colors) { + options.stylize = colorise; + } + + return options; + } + function truncate(string, length) { + var tail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : truncator; + string = String(string); + var tailLength = tail.length; + var stringLength = string.length; + + if (tailLength > length && stringLength > tailLength) { + return tail; + } + + if (stringLength > length && stringLength > tailLength) { + return "".concat(string.slice(0, length - tailLength)).concat(tail); + } + + return string; + } // eslint-disable-next-line complexity + + function inspectList(list, options, inspectItem) { + var separator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ', '; + inspectItem = inspectItem || options.inspect; + var size = list.length; + if (size === 0) return ''; + var originalLength = options.truncate; + var output = ''; + var peek = ''; + var truncated = ''; + + for (var i = 0; i < size; i += 1) { + var last = i + 1 === list.length; + var secondToLast = i + 2 === list.length; + truncated = "".concat(truncator, "(").concat(list.length - i, ")"); + var value = list[i]; // If there is more than one remaining we need to account for a separator of `, ` + + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + var string = peek || inspectItem(value, options) + (last ? '' : separator); + var nextLength = output.length + string.length; + var truncatedLength = nextLength + truncated.length; // If this is the last element, and adding it would + // take us over length, but adding the truncator wouldn't - then break now + + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } // If this isn't the last or second to last element to scan, + // but the string is already over length then break here + + + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } // Peek at the next string to determine if we should + // break early before adding this item to the output + + + peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator); // If we have one element left, but this element and + // the next takes over length, the break early + + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + + output += string; // If the next element takes us to length - + // but there are more after that, then we should truncate now + + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")"); + break; + } + + truncated = ''; + } + + return "".concat(output).concat(truncated); + } + + function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + + return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); + } + + function inspectProperty(_ref2, options) { + var _ref3 = _slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; + + options.truncate -= 2; + + if (typeof key === 'string') { + key = quoteComplexKey(key); + } else if (typeof key !== 'number') { + key = "[".concat(options.inspect(key, options), "]"); + } + + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, ": ").concat(value); + } + + function inspectArray(array, options) { + // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return '[]'; + options.truncate -= 4; + var listContents = inspectList(array, options); + options.truncate -= listContents.length; + var propertyContents = ''; + + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function (key) { + return [key, array[key]]; + }), options, inspectProperty); + } + + return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); + } + + /* ! + * Chai - getFuncName utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + + /** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + + var toString = Function.prototype.toString; + var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; + var maxFunctionSourceLength = 512; + function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // eslint-disable-next-line prefer-reflect + var functionSource = toString.call(aFunc); + // To avoid unconstrained resource consumption due to pathalogically large function names, + // we limit the available return value to be less than 512 characters. + if (functionSource.indexOf('(') > maxFunctionSourceLength) { + return name; + } + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = functionSource.match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; + } + + var getFuncName_1 = getFuncName; + + var getArrayName = function getArrayName(array) { + // We need to special case Node.js' Buffers, which report to be Uint8Array + if (typeof Buffer === 'function' && array instanceof Buffer) { + return 'Buffer'; + } + + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + + return getFuncName_1(array.constructor); + }; + + function inspectTypedArray(array, options) { + var name = getArrayName(array); + options.truncate -= name.length + 4; // Object.keys will always output the Array indices first, so we can slice by + // `array.length` to get non-index properties + + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) return "".concat(name, "[]"); // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply + // stylise the toString() value of them + + var output = ''; + + for (var i = 0; i < array.length; i++) { + var string = "".concat(options.stylize(truncate(array[i], options.truncate), 'number')).concat(i === array.length - 1 ? '' : ', '); + options.truncate -= string.length; + + if (array[i] !== array.length && options.truncate <= 3) { + output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")"); + break; + } + + output += string; + } + + var propertyContents = ''; + + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function (key) { + return [key, array[key]]; + }), options, inspectProperty); + } + + return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); + } + + function inspectDate(dateObject, options) { + var stringRepresentation = dateObject.toJSON(); + + if (stringRepresentation === null) { + return 'Invalid Date'; + } + + var split = stringRepresentation.split('T'); + var date = split[0]; // If we need to - truncate the time portion, but never the date + + return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), 'date'); + } + + function inspectFunction(func, options) { + var name = getFuncName_1(func); + + if (!name) { + return options.stylize('[Function]', 'special'); + } + + return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), 'special'); + } + + function inspectMapEntry(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, " => ").concat(value); + } // IE11 doesn't support `map.entries()` + + + function mapToEntries(map) { + var entries = []; + map.forEach(function (value, key) { + entries.push([key, value]); + }); + return entries; + } + + function inspectMap(map, options) { + var size = map.size - 1; + + if (size <= 0) { + return 'Map{}'; + } + + options.truncate -= 7; + return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }"); + } + + var isNaN = Number.isNaN || function (i) { + return i !== i; + }; // eslint-disable-line no-self-compare + + + function inspectNumber(number, options) { + if (isNaN(number)) { + return options.stylize('NaN', 'number'); + } + + if (number === Infinity) { + return options.stylize('Infinity', 'number'); + } + + if (number === -Infinity) { + return options.stylize('-Infinity', 'number'); + } + + if (number === 0) { + return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number'); + } + + return options.stylize(truncate(number, options.truncate), 'number'); + } + + function inspectBigInt(number, options) { + var nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) nums += 'n'; + return options.stylize(nums, 'bigint'); + } + + function inspectRegExp(value, options) { + var flags = value.toString().split('/')[2]; + var sourceLength = options.truncate - (2 + flags.length); + var source = value.source; + return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), 'regexp'); + } + + function arrayFromSet(set) { + var values = []; + set.forEach(function (value) { + values.push(value); + }); + return values; + } + + function inspectSet(set, options) { + if (set.size === 0) return 'Set{}'; + options.truncate -= 7; + return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }"); + } + + var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + "\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", 'g'); + var escapeCharacters = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + "'": "\\'", + '\\': '\\\\' + }; + var hex = 16; + var unicodeLength = 4; + + function escape(char) { + return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength)); + } + + function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape); + } + + return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), 'string'); + } + + function inspectSymbol(value) { + if ('description' in Symbol.prototype) { + return value.description ? "Symbol(".concat(value.description, ")") : 'Symbol()'; + } + + return value.toString(); + } + + var getPromiseValue = function getPromiseValue() { + return 'Promise{…}'; + }; + + try { + var _process$binding = process.binding('util'), + getPromiseDetails = _process$binding.getPromiseDetails, + kPending = _process$binding.kPending, + kRejected = _process$binding.kRejected; + + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = function getPromiseValue(value, options) { + var _getPromiseDetails = getPromiseDetails(value), + _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2), + state = _getPromiseDetails2[0], + innerValue = _getPromiseDetails2[1]; + + if (state === kPending) { + return 'Promise{}'; + } + + return "Promise".concat(state === kRejected ? '!' : '', "{").concat(options.inspect(innerValue, options), "}"); + }; + } + } catch (notNode) { + /* ignore */ + } + + var inspectPromise = getPromiseValue; + + function inspectObject(object, options) { + var properties = Object.getOwnPropertyNames(object); + var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + + if (properties.length === 0 && symbols.length === 0) { + return '{}'; + } + + options.truncate -= 4; + options.seen = options.seen || []; + + if (options.seen.indexOf(object) >= 0) { + return '[Circular]'; + } + + options.seen.push(object); + var propertyContents = inspectList(properties.map(function (key) { + return [key, object[key]]; + }), options, inspectProperty); + var symbolContents = inspectList(symbols.map(function (key) { + return [key, object[key]]; + }), options, inspectProperty); + options.seen.pop(); + var sep = ''; + + if (propertyContents && symbolContents) { + sep = ', '; + } + + return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }"); + } + + var toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false; + function inspectClass(value, options) { + var name = ''; + + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + + name = name || getFuncName_1(value.constructor); // Babel transforms anonymous classes to the name `_class` + + if (!name || name === '_class') { + name = ''; + } + + options.truncate -= name.length; + return "".concat(name).concat(inspectObject(value, options)); + } + + function inspectArguments(args, options) { + if (args.length === 0) return 'Arguments[]'; + options.truncate -= 13; + return "Arguments[ ".concat(inspectList(args, options), " ]"); + } + + var errorKeys = ['stack', 'line', 'column', 'name', 'message', 'fileName', 'lineNumber', 'columnNumber', 'number', 'description']; + function inspectObject$1(error, options) { + var properties = Object.getOwnPropertyNames(error).filter(function (key) { + return errorKeys.indexOf(key) === -1; + }); + var name = error.name; + options.truncate -= name.length; + var message = ''; + + if (typeof error.message === 'string') { + message = truncate(error.message, options.truncate); + } else { + properties.unshift('message'); + } + + message = message ? ": ".concat(message) : ''; + options.truncate -= message.length + 5; + var propertyContents = inspectList(properties.map(function (key) { + return [key, error[key]]; + }), options, inspectProperty); + return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : ''); + } + + function inspectAttribute(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + options.truncate -= 3; + + if (!value) { + return "".concat(options.stylize(key, 'yellow')); + } + + return "".concat(options.stylize(key, 'yellow'), "=").concat(options.stylize("\"".concat(value, "\""), 'string')); + } + function inspectHTMLCollection(collection, options) { + // eslint-disable-next-line no-use-before-define + return inspectList(collection, options, inspectHTML, '\n'); + } + function inspectHTML(element, options) { + var properties = element.getAttributeNames(); + var name = element.tagName.toLowerCase(); + var head = options.stylize("<".concat(name), 'special'); + var headClose = options.stylize(">", 'special'); + var tail = options.stylize(""), 'special'); + options.truncate -= name.length * 2 + 5; + var propertyContents = ''; + + if (properties.length > 0) { + propertyContents += ' '; + propertyContents += inspectList(properties.map(function (key) { + return [key, element.getAttribute(key)]; + }), options, inspectAttribute, ' '); + } + + options.truncate -= propertyContents.length; + var truncate = options.truncate; + var children = inspectHTMLCollection(element.children, options); + + if (children && children.length > truncate) { + children = "".concat(truncator, "(").concat(element.children.length, ")"); + } + + return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail); + } + + var symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function'; + var chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect'; + var nodeInspect = false; + + try { + // eslint-disable-next-line global-require + var nodeUtil = require('util'); + + nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; + } catch (noNodeInspect) { + nodeInspect = false; + } + + function FakeMap() { + // eslint-disable-next-line prefer-template + this.key = 'chai/loupe__' + Math.random() + Date.now(); + } + + FakeMap.prototype = { + // eslint-disable-next-line object-shorthand + get: function get(key) { + return key[this.key]; + }, + // eslint-disable-next-line object-shorthand + has: function has(key) { + return this.key in key; + }, + // eslint-disable-next-line object-shorthand + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this.key, { + // eslint-disable-next-line object-shorthand + value: value, + configurable: true + }); + } + } + }; + var constructorMap = new (typeof WeakMap === 'function' ? WeakMap : FakeMap)(); + var stringTagMap = {}; + var baseTypesMap = { + undefined: function undefined$1(value, options) { + return options.stylize('undefined', 'undefined'); + }, + null: function _null(value, options) { + return options.stylize(null, 'null'); + }, + boolean: function boolean(value, options) { + return options.stylize(value, 'boolean'); + }, + Boolean: function Boolean(value, options) { + return options.stylize(value, 'boolean'); + }, + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: inspectPromise, + // WeakSet, WeakMap are totally opaque to us + WeakSet: function WeakSet(value, options) { + return options.stylize('WeakSet{…}', 'special'); + }, + WeakMap: function WeakMap(value, options) { + return options.stylize('WeakMap{…}', 'special'); + }, + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: function Generator() { + return ''; + }, + DataView: function DataView() { + return ''; + }, + ArrayBuffer: function ArrayBuffer() { + return ''; + }, + Error: inspectObject$1, + HTMLCollection: inspectHTMLCollection, + NodeList: inspectHTMLCollection + }; // eslint-disable-next-line complexity + + var inspectCustom = function inspectCustom(value, options, type) { + if (chaiInspect in value && typeof value[chaiInspect] === 'function') { + return value[chaiInspect](options); + } + + if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') { + return value[nodeInspect](options.depth, options); + } + + if ('inspect' in value && typeof value.inspect === 'function') { + return value.inspect(options.depth, options); + } + + if ('constructor' in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + + if (stringTagMap[type]) { + return stringTagMap[type](value, options); + } + + return ''; + }; + + var toString$1 = Object.prototype.toString; // eslint-disable-next-line complexity + + function inspect(value, options) { + options = normaliseOptions(options); + options.inspect = inspect; + var _options = options, + customInspect = _options.customInspect; + var type = value === null ? 'null' : _typeof(value); + + if (type === 'object') { + type = toString$1.call(value).slice(8, -1); + } // If it is a base value that we already support, then use Loupe's inspector + + + if (baseTypesMap[type]) { + return baseTypesMap[type](value, options); + } // If `options.customInspect` is set to true then try to use the custom inspector + + + if (customInspect && value) { + var output = inspectCustom(value, options, type); + + if (output) { + if (typeof output === 'string') return output; + return inspect(output, options); + } + } + + var proto = value ? Object.getPrototypeOf(value) : false; // If it's a plain Object then use Loupe's inspector + + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } // Specifically account for HTMLElements + // eslint-disable-next-line no-undef + + + if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) { + return inspectHTML(value, options); + } + + if ('constructor' in value) { + // If it is a class, inspect it like an object but add the constructor name + if (value.constructor !== Object) { + return inspectClass(value, options); + } // If it is an object with an anonymous prototype, display it as an object. + + + return inspectObject(value, options); + } // last chance to check if it's an object + + + if (value === Object(value)) { + return inspectObject(value, options); + } // We have run out of options! Just stringify the value + + + return options.stylize(String(value), type); + } + function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false; + } + + constructorMap.set(constructor, inspector); + return true; + } + function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false; + } + + stringTagMap[stringTag] = inspector; + return true; + } + var custom = chaiInspect; + + exports.custom = custom; + exports.default = inspect; + exports.inspect = inspect; + exports.registerConstructor = registerConstructor; + exports.registerStringTag = registerStringTag; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/node_modules/loupe/package.json b/node_modules/loupe/package.json new file mode 100644 index 0000000..ae185c8 --- /dev/null +++ b/node_modules/loupe/package.json @@ -0,0 +1,141 @@ +{ + "name": "loupe", + "version": "2.3.7", + "description": "Inspect utility for Node.js and browsers", + "homepage": "https://github.com/chaijs/loupe", + "license": "MIT", + "author": "Veselin Todorov ", + "contributors": [ + "Keith Cirkel (https://github.com/keithamus)" + ], + "main": "./loupe.js", + "module": "./index.js", + "browser": { + "./index.js": "./loupe.js", + "util": false + }, + "repository": { + "type": "git", + "url": "https://github.com/chaijs/loupe" + }, + "files": [ + "loupe.js", + "index.js", + "lib/*" + ], + "scripts": { + "bench": "node -r esm bench", + "commit-msg": "commitlint -x angular", + "lint": "eslint --ignore-path .gitignore .", + "prepare": "rollup -c rollup.conf.js", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "test": "npm run test:node && npm run test:browser", + "pretest:browser": "npm run prepare", + "test:browser": "karma start --singleRun=true", + "posttest:browser": "npm run upload-coverage", + "test:node": "nyc mocha -r esm", + "posttest:node": "nyc report --report-dir \"coverage/node-$(node --version)\" --reporter=lcovonly && npm run upload-coverage", + "upload-coverage": "codecov" + }, + "eslintConfig": { + "root": true, + "parserOptions": { + "ecmaVersion": 2020 + }, + "env": { + "es6": true + }, + "plugins": [ + "filenames", + "prettier" + ], + "extends": [ + "strict/es6" + ], + "rules": { + "comma-dangle": "off", + "func-style": "off", + "no-magic-numbers": "off", + "class-methods-use-this": "off", + "array-bracket-spacing": "off", + "array-element-newline": "off", + "space-before-function-paren": "off", + "arrow-parens": "off", + "template-curly-spacing": "off", + "quotes": "off", + "generator-star-spacing": "off", + "prefer-destructuring": "off", + "no-mixed-operators": "off", + "id-blacklist": "off", + "curly": "off", + "semi": [ + "error", + "never" + ], + "prettier/prettier": [ + "error", + { + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "trailingComma": "es5", + "arrowParens": "avoid", + "bracketSpacing": true + } + ] + } + }, + "prettier": { + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "trailingComma": "es5", + "arrowParens": "avoid", + "bracketSpacing": true + }, + "dependencies": { + "get-func-name": "^2.0.1" + }, + "devDependencies": { + "@babel/core": "^7.12.10", + "@babel/preset-env": "^7.12.11", + "@commitlint/cli": "^11.0.0", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.1.0", + "benchmark": "^2.1.4", + "chai": "^4.2.0", + "codecov": "^3.8.1", + "commitlint-config-angular": "^11.0.0", + "core-js": "^3.8.3", + "cross-env": "^7.0.3", + "eslint": "^7.18.0", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "eslint-plugin-prettier": "^3.3.1", + "esm": "^3.2.25", + "husky": "^4.3.8", + "karma": "^5.2.3", + "karma-chrome-launcher": "^3.1.0", + "karma-coverage": "^2.0.3", + "karma-edge-launcher": "^0.4.2", + "karma-firefox-launcher": "^2.1.0", + "karma-ie-launcher": "^1.0.0", + "karma-mocha": "^2.0.1", + "karma-opera-launcher": "^1.0.0", + "karma-safari-launcher": "^1.0.0", + "karma-safaritechpreview-launcher": "^2.0.2", + "karma-sauce-launcher": "^4.3.4", + "mocha": "^8.2.1", + "nyc": "^15.1.0", + "prettier": "^2.2.1", + "rollup": "^2.37.1", + "rollup-plugin-babel": "^4.4.0", + "rollup-plugin-istanbul": "^3.0.0", + "semantic-release": "^17.3.6", + "simple-assert": "^1.0.0" + } +} diff --git a/node_modules/magic-string/LICENSE b/node_modules/magic-string/LICENSE new file mode 100644 index 0000000..667e8b4 --- /dev/null +++ b/node_modules/magic-string/LICENSE @@ -0,0 +1,7 @@ +Copyright 2018 Rich Harris + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/magic-string/README.md b/node_modules/magic-string/README.md new file mode 100644 index 0000000..2dc316c --- /dev/null +++ b/node_modules/magic-string/README.md @@ -0,0 +1,325 @@ +# magic-string + + + build status + + + npm version + + + license + + +Suppose you have some source code. You want to make some light modifications to it - replacing a few characters here and there, wrapping it with a header and footer, etc - and ideally you'd like to generate a [source map](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/) at the end of it. You've thought about using something like [recast](https://github.com/benjamn/recast) (which allows you to generate an AST from some JavaScript, manipulate it, and reprint it with a sourcemap without losing your comments and formatting), but it seems like overkill for your needs (or maybe the source code isn't JavaScript). + +Your requirements are, frankly, rather niche. But they're requirements that I also have, and for which I made magic-string. It's a small, fast utility for manipulating strings and generating sourcemaps. + +## Installation + +magic-string works in both node.js and browser environments. For node, install with npm: + +```bash +npm i magic-string +``` + +To use in browser, grab the [magic-string.umd.js](https://unpkg.com/magic-string/dist/magic-string.umd.js) file and add it to your page: + +```html + +``` + +(It also works with various module systems, if you prefer that sort of thing - it has a dependency on [vlq](https://github.com/Rich-Harris/vlq).) + +## Usage + +These examples assume you're in node.js, or something similar: + +```js +import MagicString from 'magic-string'; +import fs from 'fs'; + +const s = new MagicString('problems = 99'); + +s.update(0, 8, 'answer'); +s.toString(); // 'answer = 99' + +s.update(11, 13, '42'); // character indices always refer to the original string +s.toString(); // 'answer = 42' + +s.prepend('var ').append(';'); // most methods are chainable +s.toString(); // 'var answer = 42;' + +const map = s.generateMap({ + source: 'source.js', + file: 'converted.js.map', + includeContent: true, +}); // generates a v3 sourcemap + +fs.writeFileSync('converted.js', s.toString()); +fs.writeFileSync('converted.js.map', map.toString()); +``` + +You can pass an options argument: + +```js +const s = new MagicString(someCode, { + // these options will be used if you later call `bundle.addSource( s )` - see below + filename: 'foo.js', + indentExclusionRanges: [ + /*...*/ + ], + // mark source as ignore in DevTools, see below #Bundling + ignoreList: false, + // adjust the incoming position - see below + offset: 0, +}); +``` + +## Properties + +### s.offset + +Sets the offset property to adjust the incoming position for the following APIs: `slice`, `update`, `overwrite`, `appendLeft`, `prependLeft`, `appendRight`, `prependRight`, `move`, `reset`, and `remove`. + +Example usage: + +```ts +const s = new MagicString('hello world', { offset: 0 }); +s.offset = 6; +s.slice() === 'world'; +``` + +## Methods + +### s.addSourcemapLocation( index ) + +Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is `false` (see below). + +### s.append( content ) + +Appends the specified content to the end of the string. Returns `this`. + +### s.appendLeft( index, content ) + +Appends the specified `content` at the `index` in the original string. If a range _ending_ with `index` is subsequently moved, the insert will be moved with it. Returns `this`. See also `s.prependLeft(...)`. + +### s.appendRight( index, content ) + +Appends the specified `content` at the `index` in the original string. If a range _starting_ with `index` is subsequently moved, the insert will be moved with it. Returns `this`. See also `s.prependRight(...)`. + +### s.clone() + +Does what you'd expect. + +### s.generateDecodedMap( options ) + +Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. See `generateMap` documentation below for options details. Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + +### s.generateMap( options ) + +Generates a [version 3 sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit). All options are, well, optional: + +- `file` - the filename where you plan to write the sourcemap +- `source` - the filename of the file containing the original source +- `includeContent` - whether to include the original content in the map's `sourcesContent` array +- `hires` - whether the mapping should be high-resolution. Hi-res mappings map every single character, meaning (for example) your devtools will always be able to pinpoint the exact location of function calls and so on. With lo-res mappings, devtools may only be able to identify the correct line - but they're quicker to generate and less bulky. You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary instead of per character, suitable for string semantics that are separated by words. If sourcemap locations have been specified with `s.addSourcemapLocation()`, they will be used here. + +The returned sourcemap has two (non-enumerable) methods attached for convenience: + +- `toString` - returns the equivalent of `JSON.stringify(map)` +- `toUrl` - returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + +```js +code += '\n//# sourceMappingURL=' + map.toUrl(); +``` + +### s.hasChanged() + +Indicates if the string has been changed. + +### s.indent( prefix[, options] ) + +Prefixes each line of the string with `prefix`. If `prefix` is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. Returns `this`. + +The `options` argument can have an `exclude` property, which is an array of `[start, end]` character ranges. These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + +### s.insertLeft( index, content ) + +**DEPRECATED** since 0.17 – use `s.appendLeft(...)` instead + +### s.insertRight( index, content ) + +**DEPRECATED** since 0.17 – use `s.prependRight(...)` instead + +### s.isEmpty() + +Returns true if the resulting source is empty (disregarding white space). + +### s.locate( index ) + +**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30) + +### s.locateOrigin( index ) + +**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30) + +### s.move( start, end, index ) + +Moves the characters from `start` and `end` to `index`. Returns `this`. + +### s.overwrite( start, end, content[, options] ) + +Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in that range. The same restrictions as `s.remove()` apply. Returns `this`. + +The fourth argument is optional. It can have a `storeName` property — if `true`, the original name will be stored for later inclusion in a sourcemap's `names` array — and a `contentOnly` property which determines whether only the content is overwritten, or anything that was appended/prepended to the range as well. + +It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + +### s.prepend( content ) + +Prepends the string with the specified content. Returns `this`. + +### s.prependLeft ( index, content ) + +Same as `s.appendLeft(...)`, except that the inserted content will go _before_ any previous appends or prepends at `index` + +### s.prependRight ( index, content ) + +Same as `s.appendRight(...)`, except that the inserted content will go _before_ any previous appends or prepends at `index` + +### s.replace( regexpOrString, substitution ) + +String replacement with RegExp or string. The `substitution` parameter supports strings and functions. Returns `this`. + +```ts +import MagicString from 'magic-string'; + +const s = new MagicString(source); + +s.replace('foo', 'bar'); +s.replace('foo', (str, index, s) => str + '-' + index); +s.replace(/foo/g, 'bar'); +s.replace(/(\w)(\d+)/g, (_, $1, $2) => $1.toUpperCase() + $2); +``` + +The differences from [`String.replace`](<(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace)>): + +- It will always match against the **original string** +- It mutates the magic string state (use `.clone()` to be immutable) + +### s.replaceAll( regexpOrString, substitution ) + +Same as `s.replace`, but replace all matched strings instead of just one. +If `regexpOrString` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the builtin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll). Returns `this`. + +### s.remove( start, end ) + +Removes the characters from `start` to `end` (of the original string, **not** the generated string). Removing the same content twice, or making removals that partially overlap, will cause an error. Returns `this`. + +### s.reset( start, end ) + +Resets the characters from `start` to `end` (of the original string, **not** the generated string). +It can be used to restore previously removed characters and discard unwanted changes. + +### s.slice( start, end ) + +Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. Throws error if the indices are for characters that were already removed. + +### s.snip( start, end ) + +Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + +### s.toString() + +Returns the generated string. + +### s.trim([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. Returns `this`. + +### s.trimStart([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. Returns `this`. + +### s.trimEnd([ charType ]) + +Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. Returns `this`. + +### s.trimLines() + +Removes empty lines from the start and end. Returns `this`. + +### s.update( start, end, content[, options] ) + +Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. Returns `this`. + +The fourth argument is optional. It can have a `storeName` property — if `true`, the original name will be stored for later inclusion in a sourcemap's `names` array — and an `overwrite` property which defaults to `false` and determines whether anything that was appended/prepended to the range will be overwritten along with the original content. + +`s.update(start, end, content)` is equivalent to `s.overwrite(start, end, content, { contentOnly: true })`. + +## Bundling + +To concatenate several sources, use `MagicString.Bundle`: + +```js +const bundle = new MagicString.Bundle(); + +bundle.addSource({ + filename: 'foo.js', + content: new MagicString('var answer = 42;'), +}); + +bundle.addSource({ + filename: 'bar.js', + content: new MagicString('console.log( answer )'), +}); + +// Sources can be marked as ignore-listed, which provides a hint to debuggers +// to not step into this code and also don't show the source files depending +// on user preferences. +bundle.addSource({ + filename: 'some-3rdparty-library.js', + content: new MagicString('function myLib(){}'), + ignoreList: false, // <-- +}); + +// Advanced: a source can include an `indentExclusionRanges` property +// alongside `filename` and `content`. This will be passed to `s.indent()` +// - see documentation above + +bundle + .indent() // optionally, pass an indent string, otherwise it will be guessed + .prepend('(function () {\n') + .append('}());'); + +bundle.toString(); +// (function () { +// var answer = 42; +// console.log( answer ); +// }()); + +// options are as per `s.generateMap()` above +const map = bundle.generateMap({ + file: 'bundle.js', + includeContent: true, + hires: true, +}); +``` + +As an alternative syntax, if you a) don't have `filename` or `indentExclusionRanges` options, or b) passed those in when you used `new MagicString(...)`, you can simply pass the `MagicString` instance itself: + +```js +const bundle = new MagicString.Bundle(); +const source = new MagicString(someCode, { + filename: 'foo.js', +}); + +bundle.addSource(source); +``` + +## License + +MIT diff --git a/node_modules/magic-string/dist/magic-string.cjs.d.ts b/node_modules/magic-string/dist/magic-string.cjs.d.ts new file mode 100644 index 0000000..76cc537 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.d.ts @@ -0,0 +1,289 @@ +export interface BundleOptions { + intro?: string; + separator?: string; +} + +export interface SourceMapOptions { + /** + * Whether the mapping should be high-resolution. + * Hi-res mappings map every single character, meaning (for example) your devtools will always + * be able to pinpoint the exact location of function calls and so on. + * With lo-res mappings, devtools may only be able to identify the correct + * line - but they're quicker to generate and less bulky. + * You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary + * instead of per character, suitable for string semantics that are separated by words. + * If sourcemap locations have been specified with s.addSourceMapLocation(), they will be used here. + */ + hires?: boolean | 'boundary'; + /** + * The filename where you plan to write the sourcemap. + */ + file?: string; + /** + * The filename of the file containing the original source. + */ + source?: string; + /** + * Whether to include the original content in the map's sourcesContent array. + */ + includeContent?: boolean; +} + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; + +export interface DecodedSourceMap { + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: SourceMapSegment[][]; + x_google_ignoreList?: number[]; +} + +export class SourceMap { + constructor(properties: DecodedSourceMap); + + version: number; + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: string; + x_google_ignoreList?: number[]; + debugId?: string; + + /** + * Returns the equivalent of `JSON.stringify(map)` + */ + toString(): string; + /** + * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + * `generateMap(options?: SourceMapOptions): SourceMap;` + */ + toUrl(): string; +} + +export class Bundle { + constructor(options?: BundleOptions); + /** + * Adds the specified source to the bundle, which can either be a `MagicString` object directly, + * or an options object that holds a magic string `content` property and optionally provides + * a `filename` for the source within the bundle, as well as an optional `ignoreList` hint + * (which defaults to `false`). The `filename` is used when constructing the source map for the + * bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint + * is used to populate the `x_google_ignoreList` extension field in the source map, which is a + * mechanism for tools to signal to debuggers that certain sources should be ignored by default + * (depending on user preferences). + */ + addSource( + source: MagicString | { filename?: string; content: MagicString; ignoreList?: boolean }, + ): this; + append(str: string, options?: BundleOptions): this; + clone(): this; + generateMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + generateDecodedMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + getIndentString(): string; + indent(indentStr?: string): this; + indentExclusionRanges: ExclusionRange | Array; + prepend(str: string): this; + toString(): string; + trimLines(): this; + trim(charType?: string): this; + trimStart(charType?: string): this; + trimEnd(charType?: string): this; + isEmpty(): boolean; + length(): number; +} + +export type ExclusionRange = [number, number]; + +export interface MagicStringOptions { + filename?: string; + indentExclusionRanges?: ExclusionRange | Array; + offset?: number; +} + +export interface IndentOptions { + exclude?: ExclusionRange | Array; + indentStart?: boolean; +} + +export interface OverwriteOptions { + storeName?: boolean; + contentOnly?: boolean; +} + +export interface UpdateOptions { + storeName?: boolean; + overwrite?: boolean; +} + +export default class MagicString { + constructor(str: string, options?: MagicStringOptions); + /** + * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false. + */ + addSourcemapLocation(char: number): void; + /** + * Appends the specified content to the end of the string. + */ + append(content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *ending* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependLeft(...)`. + */ + appendLeft(index: number, content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *starting* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependRight(...)`. + */ + appendRight(index: number, content: string): this; + /** + * Does what you'd expect. + */ + clone(): this; + /** + * Generates a version 3 sourcemap. + */ + generateMap(options?: SourceMapOptions): SourceMap; + /** + * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. + * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + */ + generateDecodedMap(options?: SourceMapOptions): DecodedSourceMap; + getIndentString(): string; + + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + */ + indent(options?: IndentOptions): this; + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + * + * The options argument can have an exclude property, which is an array of [start, end] character ranges. + * These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + */ + indent(indentStr?: string, options?: IndentOptions): this; + indentExclusionRanges: ExclusionRange | Array; + + /** + * Moves the characters from `start` and `end` to `index`. + */ + move(start: number, end: number, index: number): this; + /** + * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in + * that range. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and a contentOnly property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + * + * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + */ + overwrite( + start: number, + end: number, + content: string, + options?: boolean | OverwriteOptions, + ): this; + /** + * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and an overwrite property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + */ + update(start: number, end: number, content: string, options?: boolean | UpdateOptions): this; + /** + * Prepends the string with the specified content. + */ + prepend(content: string): this; + /** + * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index + */ + prependLeft(index: number, content: string): this; + /** + * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index` + */ + prependRight(index: number, content: string): this; + /** + * Removes the characters from `start` to `end` (of the original string, **not** the generated string). + * Removing the same content twice, or making removals that partially overlap, will cause an error. + */ + remove(start: number, end: number): this; + /** + * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string). + */ + reset(start: number, end: number): this; + /** + * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. + * Throws error if the indices are for characters that were already removed. + */ + slice(start: number, end: number): string; + /** + * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + */ + snip(start: number, end: number): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. + */ + trim(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. + */ + trimStart(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. + */ + trimEnd(charType?: string): this; + /** + * Removes empty lines from the start and end. + */ + trimLines(): this; + /** + * String replacement with RegExp or string. + */ + replace( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + /** + * Same as `s.replace`, but replace all matched strings instead of just one. + */ + replaceAll( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + + lastChar(): string; + lastLine(): string; + /** + * Returns true if the resulting source is empty (disregarding white space). + */ + isEmpty(): boolean; + length(): number; + + /** + * Indicates if the string has been changed. + */ + hasChanged(): boolean; + + original: string; + /** + * Returns the generated string. + */ + toString(): string; + + offset: number; +} diff --git a/node_modules/magic-string/dist/magic-string.cjs.js b/node_modules/magic-string/dist/magic-string.cjs.js new file mode 100644 index 0000000..bf3cd1d --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.js @@ -0,0 +1,1594 @@ +'use strict'; + +var sourcemapCodec = require('@jridgewell/sourcemap-codec'); + +class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } +} + +class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } +} + +function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } +} + +const btoa = /*#__PURE__*/ getBtoa(); + +class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = sourcemapCodec.encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } +} + +function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); +} + +function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); +} + +const toString = Object.prototype.toString; + +function isObject(thing) { + return toString.call(thing) === '[object Object]'; +} + +function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; +} + +const wordRegex = /\w/; + +class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } +} + +const n = '\n'; + +const warned = { + insertLeft: false, + insertRight: false, + storeName: false, +}; + +class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (this.outro) { + mappings.advance(this.outro); + } + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + if (typeof replacement === 'function') { + replacement = replacement(string, index, original); + } + if (string !== replacement) { + this.overwrite(index, index + string.length, replacement); + } + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + let _replacement = replacement; + if (typeof replacement === 'function') { + _replacement = replacement(previous, index, original); + } + if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } +} + +const hasOwnProp = Object.prototype.hasOwnProperty; + +class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } +} + +MagicString.Bundle = Bundle; +MagicString.SourceMap = SourceMap; +MagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121 + +module.exports = MagicString; +//# sourceMappingURL=magic-string.cjs.js.map diff --git a/node_modules/magic-string/dist/magic-string.cjs.js.map b/node_modules/magic-string/dist/magic-string.cjs.js.map new file mode 100644 index 0000000..685274f --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.cjs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.cjs.js","sources":["../src/BitSet.js","../src/Chunk.js","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js","../src/index-legacy.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\tif (this.outro) {\n\t\t\tmappings.advance(this.outro);\n\t\t}\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\treplacement = replacement(string, index, original);\n\t\t\t}\n\t\t\tif (string !== replacement) {\n\t\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tlet _replacement = replacement;\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\t_replacement = replacement(previous, index, original);\n\t\t\t}\n\t\t\tif (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n","import MagicString from './MagicString.js';\nimport Bundle from './Bundle.js';\nimport SourceMap from './SourceMap.js';\n\nMagicString.Bundle = Bundle;\nMagicString.SourceMap = SourceMap;\nMagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121\n\nexport default MagicString;\n"],"names":["encode"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/magic-string/dist/magic-string.es.d.mts b/node_modules/magic-string/dist/magic-string.es.d.mts new file mode 100644 index 0000000..76cc537 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.d.mts @@ -0,0 +1,289 @@ +export interface BundleOptions { + intro?: string; + separator?: string; +} + +export interface SourceMapOptions { + /** + * Whether the mapping should be high-resolution. + * Hi-res mappings map every single character, meaning (for example) your devtools will always + * be able to pinpoint the exact location of function calls and so on. + * With lo-res mappings, devtools may only be able to identify the correct + * line - but they're quicker to generate and less bulky. + * You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary + * instead of per character, suitable for string semantics that are separated by words. + * If sourcemap locations have been specified with s.addSourceMapLocation(), they will be used here. + */ + hires?: boolean | 'boundary'; + /** + * The filename where you plan to write the sourcemap. + */ + file?: string; + /** + * The filename of the file containing the original source. + */ + source?: string; + /** + * Whether to include the original content in the map's sourcesContent array. + */ + includeContent?: boolean; +} + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; + +export interface DecodedSourceMap { + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: SourceMapSegment[][]; + x_google_ignoreList?: number[]; +} + +export class SourceMap { + constructor(properties: DecodedSourceMap); + + version: number; + file: string; + sources: string[]; + sourcesContent?: string[]; + names: string[]; + mappings: string; + x_google_ignoreList?: number[]; + debugId?: string; + + /** + * Returns the equivalent of `JSON.stringify(map)` + */ + toString(): string; + /** + * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing: + * `generateMap(options?: SourceMapOptions): SourceMap;` + */ + toUrl(): string; +} + +export class Bundle { + constructor(options?: BundleOptions); + /** + * Adds the specified source to the bundle, which can either be a `MagicString` object directly, + * or an options object that holds a magic string `content` property and optionally provides + * a `filename` for the source within the bundle, as well as an optional `ignoreList` hint + * (which defaults to `false`). The `filename` is used when constructing the source map for the + * bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint + * is used to populate the `x_google_ignoreList` extension field in the source map, which is a + * mechanism for tools to signal to debuggers that certain sources should be ignored by default + * (depending on user preferences). + */ + addSource( + source: MagicString | { filename?: string; content: MagicString; ignoreList?: boolean }, + ): this; + append(str: string, options?: BundleOptions): this; + clone(): this; + generateMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + generateDecodedMap( + options?: SourceMapOptions, + ): Omit & { sourcesContent: Array }; + getIndentString(): string; + indent(indentStr?: string): this; + indentExclusionRanges: ExclusionRange | Array; + prepend(str: string): this; + toString(): string; + trimLines(): this; + trim(charType?: string): this; + trimStart(charType?: string): this; + trimEnd(charType?: string): this; + isEmpty(): boolean; + length(): number; +} + +export type ExclusionRange = [number, number]; + +export interface MagicStringOptions { + filename?: string; + indentExclusionRanges?: ExclusionRange | Array; + offset?: number; +} + +export interface IndentOptions { + exclude?: ExclusionRange | Array; + indentStart?: boolean; +} + +export interface OverwriteOptions { + storeName?: boolean; + contentOnly?: boolean; +} + +export interface UpdateOptions { + storeName?: boolean; + overwrite?: boolean; +} + +export default class MagicString { + constructor(str: string, options?: MagicStringOptions); + /** + * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false. + */ + addSourcemapLocation(char: number): void; + /** + * Appends the specified content to the end of the string. + */ + append(content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *ending* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependLeft(...)`. + */ + appendLeft(index: number, content: string): this; + /** + * Appends the specified content at the index in the original string. + * If a range *starting* with index is subsequently moved, the insert will be moved with it. + * See also `s.prependRight(...)`. + */ + appendRight(index: number, content: string): this; + /** + * Does what you'd expect. + */ + clone(): this; + /** + * Generates a version 3 sourcemap. + */ + generateMap(options?: SourceMapOptions): SourceMap; + /** + * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. + * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. + */ + generateDecodedMap(options?: SourceMapOptions): DecodedSourceMap; + getIndentString(): string; + + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + */ + indent(options?: IndentOptions): this; + /** + * Prefixes each line of the string with prefix. + * If prefix is not supplied, the indentation will be guessed from the original content, falling back to a single tab character. + * + * The options argument can have an exclude property, which is an array of [start, end] character ranges. + * These ranges will be excluded from the indentation - useful for (e.g.) multiline strings. + */ + indent(indentStr?: string, options?: IndentOptions): this; + indentExclusionRanges: ExclusionRange | Array; + + /** + * Moves the characters from `start` and `end` to `index`. + */ + move(start: number, end: number, index: number): this; + /** + * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in + * that range. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and a contentOnly property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + * + * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. + */ + overwrite( + start: number, + end: number, + content: string, + options?: boolean | OverwriteOptions, + ): this; + /** + * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. + * + * The fourth argument is optional. It can have a storeName property — if true, the original name will be stored + * for later inclusion in a sourcemap's names array — and an overwrite property which determines whether only + * the content is overwritten, or anything that was appended/prepended to the range as well. + */ + update(start: number, end: number, content: string, options?: boolean | UpdateOptions): this; + /** + * Prepends the string with the specified content. + */ + prepend(content: string): this; + /** + * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index + */ + prependLeft(index: number, content: string): this; + /** + * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index` + */ + prependRight(index: number, content: string): this; + /** + * Removes the characters from `start` to `end` (of the original string, **not** the generated string). + * Removing the same content twice, or making removals that partially overlap, will cause an error. + */ + remove(start: number, end: number): this; + /** + * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string). + */ + reset(start: number, end: number): this; + /** + * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. + * Throws error if the indices are for characters that were already removed. + */ + slice(start: number, end: number): string; + /** + * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. + */ + snip(start: number, end: number): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. + */ + trim(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. + */ + trimStart(charType?: string): this; + /** + * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. + */ + trimEnd(charType?: string): this; + /** + * Removes empty lines from the start and end. + */ + trimLines(): this; + /** + * String replacement with RegExp or string. + */ + replace( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + /** + * Same as `s.replace`, but replace all matched strings instead of just one. + */ + replaceAll( + regex: RegExp | string, + replacement: string | ((substring: string, ...args: any[]) => string), + ): this; + + lastChar(): string; + lastLine(): string; + /** + * Returns true if the resulting source is empty (disregarding white space). + */ + isEmpty(): boolean; + length(): number; + + /** + * Indicates if the string has been changed. + */ + hasChanged(): boolean; + + original: string; + /** + * Returns the generated string. + */ + toString(): string; + + offset: number; +} diff --git a/node_modules/magic-string/dist/magic-string.es.mjs b/node_modules/magic-string/dist/magic-string.es.mjs new file mode 100644 index 0000000..c7999fc --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.mjs @@ -0,0 +1,1588 @@ +import { encode } from '@jridgewell/sourcemap-codec'; + +class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } +} + +class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } +} + +function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } +} + +const btoa = /*#__PURE__*/ getBtoa(); + +class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } +} + +function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); +} + +function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); +} + +const toString = Object.prototype.toString; + +function isObject(thing) { + return toString.call(thing) === '[object Object]'; +} + +function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; +} + +const wordRegex = /\w/; + +class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } +} + +const n = '\n'; + +const warned = { + insertLeft: false, + insertRight: false, + storeName: false, +}; + +class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (this.outro) { + mappings.advance(this.outro); + } + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + if (typeof replacement === 'function') { + replacement = replacement(string, index, original); + } + if (string !== replacement) { + this.overwrite(index, index + string.length, replacement); + } + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + let _replacement = replacement; + if (typeof replacement === 'function') { + _replacement = replacement(previous, index, original); + } + if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } +} + +const hasOwnProp = Object.prototype.hasOwnProperty; + +class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } +} + +export { Bundle, SourceMap, MagicString as default }; +//# sourceMappingURL=magic-string.es.mjs.map diff --git a/node_modules/magic-string/dist/magic-string.es.mjs.map b/node_modules/magic-string/dist/magic-string.es.mjs.map new file mode 100644 index 0000000..a60bcc8 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.es.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.es.mjs","sources":["../src/BitSet.js","../src/Chunk.js","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\tif (this.outro) {\n\t\t\tmappings.advance(this.outro);\n\t\t}\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\treplacement = replacement(string, index, original);\n\t\t\t}\n\t\t\tif (string !== replacement) {\n\t\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tlet _replacement = replacement;\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\t_replacement = replacement(previous, index, original);\n\t\t\t}\n\t\t\tif (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/magic-string/dist/magic-string.umd.js b/node_modules/magic-string/dist/magic-string.umd.js new file mode 100644 index 0000000..0c399cd --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.umd.js @@ -0,0 +1,1682 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MagicString = factory()); +})(this, (function () { 'use strict'; + + class BitSet { + constructor(arg) { + this.bits = arg instanceof BitSet ? arg.bits.slice() : []; + } + + add(n) { + this.bits[n >> 5] |= 1 << (n & 31); + } + + has(n) { + return !!(this.bits[n >> 5] & (1 << (n & 31))); + } + } + + class Chunk { + constructor(start, end, content) { + this.start = start; + this.end = end; + this.original = content; + + this.intro = ''; + this.outro = ''; + + this.content = content; + this.storeName = false; + this.edited = false; + + { + this.previous = null; + this.next = null; + } + } + + appendLeft(content) { + this.outro += content; + } + + appendRight(content) { + this.intro = this.intro + content; + } + + clone() { + const chunk = new Chunk(this.start, this.end, this.original); + + chunk.intro = this.intro; + chunk.outro = this.outro; + chunk.content = this.content; + chunk.storeName = this.storeName; + chunk.edited = this.edited; + + return chunk; + } + + contains(index) { + return this.start < index && index < this.end; + } + + eachNext(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.next; + } + } + + eachPrevious(fn) { + let chunk = this; + while (chunk) { + fn(chunk); + chunk = chunk.previous; + } + } + + edit(content, storeName, contentOnly) { + this.content = content; + if (!contentOnly) { + this.intro = ''; + this.outro = ''; + } + this.storeName = storeName; + + this.edited = true; + + return this; + } + + prependLeft(content) { + this.outro = content + this.outro; + } + + prependRight(content) { + this.intro = content + this.intro; + } + + reset() { + this.intro = ''; + this.outro = ''; + if (this.edited) { + this.content = this.original; + this.storeName = false; + this.edited = false; + } + } + + split(index) { + const sliceIndex = index - this.start; + + const originalBefore = this.original.slice(0, sliceIndex); + const originalAfter = this.original.slice(sliceIndex); + + this.original = originalBefore; + + const newChunk = new Chunk(index, this.end, originalAfter); + newChunk.outro = this.outro; + this.outro = ''; + + this.end = index; + + if (this.edited) { + // after split we should save the edit content record into the correct chunk + // to make sure sourcemap correct + // For example: + // ' test'.trim() + // split -> ' ' + 'test' + // ✔️ edit -> '' + 'test' + // ✖️ edit -> 'test' + '' + // TODO is this block necessary?... + newChunk.edit('', false); + this.content = ''; + } else { + this.content = originalBefore; + } + + newChunk.next = this.next; + if (newChunk.next) newChunk.next.previous = newChunk; + newChunk.previous = this; + this.next = newChunk; + + return newChunk; + } + + toString() { + return this.intro + this.content + this.outro; + } + + trimEnd(rx) { + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + this.split(this.start + trimmed.length).edit('', undefined, true); + if (this.edited) { + // save the change, if it has been edited + this.edit(trimmed, this.storeName, true); + } + } + return true; + } else { + this.edit('', undefined, true); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + } + } + + trimStart(rx) { + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + const trimmed = this.content.replace(rx, ''); + + if (trimmed.length) { + if (trimmed !== this.content) { + const newChunk = this.split(this.end - trimmed.length); + if (this.edited) { + // save the change, if it has been edited + newChunk.edit(trimmed, this.storeName, true); + } + this.edit('', undefined, true); + } + return true; + } else { + this.edit('', undefined, true); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + } + } + } + + // src/vlq.ts + var comma = ",".charCodeAt(0); + var semicolon = ";".charCodeAt(0); + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var intToChar = new Uint8Array(64); + var charToInt = new Uint8Array(128); + for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; + } + function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; + } + + // src/strings.ts + var bufLength = 1024 * 16; + var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } + } : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } + }; + var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } + }; + function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); + } + + function getBtoa() { + if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') { + return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); + } else if (typeof Buffer === 'function') { + return (str) => Buffer.from(str, 'utf-8').toString('base64'); + } else { + return () => { + throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.'); + }; + } + } + + const btoa = /*#__PURE__*/ getBtoa(); + + class SourceMap { + constructor(properties) { + this.version = 3; + this.file = properties.file; + this.sources = properties.sources; + this.sourcesContent = properties.sourcesContent; + this.names = properties.names; + this.mappings = encode(properties.mappings); + if (typeof properties.x_google_ignoreList !== 'undefined') { + this.x_google_ignoreList = properties.x_google_ignoreList; + } + if (typeof properties.debugId !== 'undefined') { + this.debugId = properties.debugId; + } + } + + toString() { + return JSON.stringify(this); + } + + toUrl() { + return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()); + } + } + + function guessIndent(code) { + const lines = code.split('\n'); + + const tabbed = lines.filter((line) => /^\t+/.test(line)); + const spaced = lines.filter((line) => /^ {2,}/.test(line)); + + if (tabbed.length === 0 && spaced.length === 0) { + return null; + } + + // More lines tabbed than spaced? Assume tabs, and + // default to tabs in the case of a tie (or nothing + // to go on) + if (tabbed.length >= spaced.length) { + return '\t'; + } + + // Otherwise, we need to guess the multiple + const min = spaced.reduce((previous, current) => { + const numSpaces = /^ +/.exec(current)[0].length; + return Math.min(numSpaces, previous); + }, Infinity); + + return new Array(min + 1).join(' '); + } + + function getRelativePath(from, to) { + const fromParts = from.split(/[/\\]/); + const toParts = to.split(/[/\\]/); + + fromParts.pop(); // get dirname + + while (fromParts[0] === toParts[0]) { + fromParts.shift(); + toParts.shift(); + } + + if (fromParts.length) { + let i = fromParts.length; + while (i--) fromParts[i] = '..'; + } + + return fromParts.concat(toParts).join('/'); + } + + const toString = Object.prototype.toString; + + function isObject(thing) { + return toString.call(thing) === '[object Object]'; + } + + function getLocator(source) { + const originalLines = source.split('\n'); + const lineOffsets = []; + + for (let i = 0, pos = 0; i < originalLines.length; i++) { + lineOffsets.push(pos); + pos += originalLines[i].length + 1; + } + + return function locate(index) { + let i = 0; + let j = lineOffsets.length; + while (i < j) { + const m = (i + j) >> 1; + if (index < lineOffsets[m]) { + j = m; + } else { + i = m + 1; + } + } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; + }; + } + + const wordRegex = /\w/; + + class Mappings { + constructor(hires) { + this.hires = hires; + this.generatedCodeLine = 0; + this.generatedCodeColumn = 0; + this.raw = []; + this.rawSegments = this.raw[this.generatedCodeLine] = []; + this.pending = null; + } + + addEdit(sourceIndex, content, loc, nameIndex) { + if (content.length) { + const contentLengthMinusOne = content.length - 1; + let contentLineEnd = content.indexOf('\n', 0); + let previousContentLineEnd = -1; + // Loop through each line in the content and add a segment, but stop if the last line is empty, + // else code afterwards would fill one line too many + while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + + previousContentLineEnd = contentLineEnd; + contentLineEnd = content.indexOf('\n', contentLineEnd + 1); + } + + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + if (nameIndex >= 0) { + segment.push(nameIndex); + } + this.rawSegments.push(segment); + + this.advance(content.slice(previousContentLineEnd + 1)); + } else if (this.pending) { + this.rawSegments.push(this.pending); + this.advance(content); + } + + this.pending = null; + } + + addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { + let originalCharIndex = chunk.start; + let first = true; + // when iterating each char, check if it's in a word boundary + let charInHiresBoundary = false; + + while (originalCharIndex < chunk.end) { + if (original[originalCharIndex] === '\n') { + loc.line += 1; + loc.column = 0; + this.generatedCodeLine += 1; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + this.generatedCodeColumn = 0; + first = true; + charInHiresBoundary = false; + } else { + if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { + const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; + + if (this.hires === 'boundary') { + // in hires "boundary", group segments per word boundary than per char + if (wordRegex.test(original[originalCharIndex])) { + // for first char in the boundary found, start the boundary by pushing a segment + if (!charInHiresBoundary) { + this.rawSegments.push(segment); + charInHiresBoundary = true; + } + } else { + // for non-word char, end the boundary by pushing a segment + this.rawSegments.push(segment); + charInHiresBoundary = false; + } + } else { + this.rawSegments.push(segment); + } + } + + loc.column += 1; + this.generatedCodeColumn += 1; + first = false; + } + + originalCharIndex += 1; + } + + this.pending = null; + } + + advance(str) { + if (!str) return; + + const lines = str.split('\n'); + + if (lines.length > 1) { + for (let i = 0; i < lines.length - 1; i++) { + this.generatedCodeLine++; + this.raw[this.generatedCodeLine] = this.rawSegments = []; + } + this.generatedCodeColumn = 0; + } + + this.generatedCodeColumn += lines[lines.length - 1].length; + } + } + + const n = '\n'; + + const warned = { + insertLeft: false, + insertRight: false, + storeName: false, + }; + + class MagicString { + constructor(string, options = {}) { + const chunk = new Chunk(0, string.length, string); + + Object.defineProperties(this, { + original: { writable: true, value: string }, + outro: { writable: true, value: '' }, + intro: { writable: true, value: '' }, + firstChunk: { writable: true, value: chunk }, + lastChunk: { writable: true, value: chunk }, + lastSearchedChunk: { writable: true, value: chunk }, + byStart: { writable: true, value: {} }, + byEnd: { writable: true, value: {} }, + filename: { writable: true, value: options.filename }, + indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, + sourcemapLocations: { writable: true, value: new BitSet() }, + storedNames: { writable: true, value: {} }, + indentStr: { writable: true, value: undefined }, + ignoreList: { writable: true, value: options.ignoreList }, + offset: { writable: true, value: options.offset || 0 }, + }); + + this.byStart[0] = chunk; + this.byEnd[string.length] = chunk; + } + + addSourcemapLocation(char) { + this.sourcemapLocations.add(char); + } + + append(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.outro += content; + return this; + } + + appendLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.appendLeft(content); + } else { + this.intro += content; + } + return this; + } + + appendRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.appendRight(content); + } else { + this.outro += content; + } + return this; + } + + clone() { + const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset }); + + let originalChunk = this.firstChunk; + let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone()); + + while (originalChunk) { + cloned.byStart[clonedChunk.start] = clonedChunk; + cloned.byEnd[clonedChunk.end] = clonedChunk; + + const nextOriginalChunk = originalChunk.next; + const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); + + if (nextClonedChunk) { + clonedChunk.next = nextClonedChunk; + nextClonedChunk.previous = clonedChunk; + + clonedChunk = nextClonedChunk; + } + + originalChunk = nextOriginalChunk; + } + + cloned.lastChunk = clonedChunk; + + if (this.indentExclusionRanges) { + cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); + } + + cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); + + cloned.intro = this.intro; + cloned.outro = this.outro; + + return cloned; + } + + generateDecodedMap(options) { + options = options || {}; + + const sourceIndex = 0; + const names = Object.keys(this.storedNames); + const mappings = new Mappings(options.hires); + + const locate = getLocator(this.original); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (this.outro) { + mappings.advance(this.outro); + } + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: [ + options.source ? getRelativePath(options.file || '', options.source) : options.file || '', + ], + sourcesContent: options.includeContent ? [this.original] : undefined, + names, + mappings: mappings.raw, + x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + _ensureindentStr() { + if (this.indentStr === undefined) { + this.indentStr = guessIndent(this.original); + } + } + + _getRawIndentString() { + this._ensureindentStr(); + return this.indentStr; + } + + getIndentString() { + this._ensureindentStr(); + return this.indentStr === null ? '\t' : this.indentStr; + } + + indent(indentStr, options) { + const pattern = /^[^\r\n]/gm; + + if (isObject(indentStr)) { + options = indentStr; + indentStr = undefined; + } + + if (indentStr === undefined) { + this._ensureindentStr(); + indentStr = this.indentStr || '\t'; + } + + if (indentStr === '') return this; // noop + + options = options || {}; + + // Process exclusion ranges + const isExcluded = {}; + + if (options.exclude) { + const exclusions = + typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude; + exclusions.forEach((exclusion) => { + for (let i = exclusion[0]; i < exclusion[1]; i += 1) { + isExcluded[i] = true; + } + }); + } + + let shouldIndentNextCharacter = options.indentStart !== false; + const replacer = (match) => { + if (shouldIndentNextCharacter) return `${indentStr}${match}`; + shouldIndentNextCharacter = true; + return match; + }; + + this.intro = this.intro.replace(pattern, replacer); + + let charIndex = 0; + let chunk = this.firstChunk; + + while (chunk) { + const end = chunk.end; + + if (chunk.edited) { + if (!isExcluded[charIndex]) { + chunk.content = chunk.content.replace(pattern, replacer); + + if (chunk.content.length) { + shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n'; + } + } + } else { + charIndex = chunk.start; + + while (charIndex < end) { + if (!isExcluded[charIndex]) { + const char = this.original[charIndex]; + + if (char === '\n') { + shouldIndentNextCharacter = true; + } else if (char !== '\r' && shouldIndentNextCharacter) { + shouldIndentNextCharacter = false; + + if (charIndex === chunk.start) { + chunk.prependRight(indentStr); + } else { + this._splitChunk(chunk, charIndex); + chunk = chunk.next; + chunk.prependRight(indentStr); + } + } + } + + charIndex += 1; + } + } + + charIndex = chunk.end; + chunk = chunk.next; + } + + this.outro = this.outro.replace(pattern, replacer); + + return this; + } + + insert() { + throw new Error( + 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)', + ); + } + + insertLeft(index, content) { + if (!warned.insertLeft) { + console.warn( + 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead', + ); + warned.insertLeft = true; + } + + return this.appendLeft(index, content); + } + + insertRight(index, content) { + if (!warned.insertRight) { + console.warn( + 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead', + ); + warned.insertRight = true; + } + + return this.prependRight(index, content); + } + + move(start, end, index) { + start = start + this.offset; + end = end + this.offset; + index = index + this.offset; + + if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); + + this._split(start); + this._split(end); + this._split(index); + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + const oldLeft = first.previous; + const oldRight = last.next; + + const newRight = this.byStart[index]; + if (!newRight && last === this.lastChunk) return this; + const newLeft = newRight ? newRight.previous : this.lastChunk; + + if (oldLeft) oldLeft.next = oldRight; + if (oldRight) oldRight.previous = oldLeft; + + if (newLeft) newLeft.next = first; + if (newRight) newRight.previous = last; + + if (!first.previous) this.firstChunk = last.next; + if (!last.next) { + this.lastChunk = first.previous; + this.lastChunk.next = null; + } + + first.previous = newLeft; + last.next = newRight || null; + + if (!newLeft) this.firstChunk = first; + if (!newRight) this.lastChunk = last; + return this; + } + + overwrite(start, end, content, options) { + options = options || {}; + return this.update(start, end, content, { ...options, overwrite: !options.contentOnly }); + } + + update(start, end, content, options) { + start = start + this.offset; + end = end + this.offset; + + if (typeof content !== 'string') throw new TypeError('replacement content must be a string'); + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (end > this.original.length) throw new Error('end is out of bounds'); + if (start === end) + throw new Error( + 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead', + ); + + this._split(start); + this._split(end); + + if (options === true) { + if (!warned.storeName) { + console.warn( + 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string', + ); + warned.storeName = true; + } + + options = { storeName: true }; + } + const storeName = options !== undefined ? options.storeName : false; + const overwrite = options !== undefined ? options.overwrite : false; + + if (storeName) { + const original = this.original.slice(start, end); + Object.defineProperty(this.storedNames, original, { + writable: true, + value: true, + enumerable: true, + }); + } + + const first = this.byStart[start]; + const last = this.byEnd[end]; + + if (first) { + let chunk = first; + while (chunk !== last) { + if (chunk.next !== this.byStart[chunk.end]) { + throw new Error('Cannot overwrite across a split point'); + } + chunk = chunk.next; + chunk.edit('', false); + } + + first.edit(content, storeName, !overwrite); + } else { + // must be inserting at the end + const newChunk = new Chunk(start, end, '').edit(content, storeName); + + // TODO last chunk in the array may not be the last chunk, if it's moved... + last.next = newChunk; + newChunk.previous = last; + } + return this; + } + + prepend(content) { + if (typeof content !== 'string') throw new TypeError('outro content must be a string'); + + this.intro = content + this.intro; + return this; + } + + prependLeft(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byEnd[index]; + + if (chunk) { + chunk.prependLeft(content); + } else { + this.intro = content + this.intro; + } + return this; + } + + prependRight(index, content) { + index = index + this.offset; + + if (typeof content !== 'string') throw new TypeError('inserted content must be a string'); + + this._split(index); + + const chunk = this.byStart[index]; + + if (chunk) { + chunk.prependRight(content); + } else { + this.outro = content + this.outro; + } + return this; + } + + remove(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.intro = ''; + chunk.outro = ''; + chunk.edit(''); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + reset(start, end) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + if (start === end) return this; + + if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds'); + if (start > end) throw new Error('end must be greater than start'); + + this._split(start); + this._split(end); + + let chunk = this.byStart[start]; + + while (chunk) { + chunk.reset(); + + chunk = end > chunk.end ? this.byStart[chunk.end] : null; + } + return this; + } + + lastChar() { + if (this.outro.length) return this.outro[this.outro.length - 1]; + let chunk = this.lastChunk; + do { + if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; + if (chunk.content.length) return chunk.content[chunk.content.length - 1]; + if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; + } while ((chunk = chunk.previous)); + if (this.intro.length) return this.intro[this.intro.length - 1]; + return ''; + } + + lastLine() { + let lineIndex = this.outro.lastIndexOf(n); + if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); + let lineStr = this.outro; + let chunk = this.lastChunk; + do { + if (chunk.outro.length > 0) { + lineIndex = chunk.outro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.outro + lineStr; + } + + if (chunk.content.length > 0) { + lineIndex = chunk.content.lastIndexOf(n); + if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; + lineStr = chunk.content + lineStr; + } + + if (chunk.intro.length > 0) { + lineIndex = chunk.intro.lastIndexOf(n); + if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; + lineStr = chunk.intro + lineStr; + } + } while ((chunk = chunk.previous)); + lineIndex = this.intro.lastIndexOf(n); + if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; + return this.intro + lineStr; + } + + slice(start = 0, end = this.original.length - this.offset) { + start = start + this.offset; + end = end + this.offset; + + if (this.original.length !== 0) { + while (start < 0) start += this.original.length; + while (end < 0) end += this.original.length; + } + + let result = ''; + + // find start chunk + let chunk = this.firstChunk; + while (chunk && (chunk.start > start || chunk.end <= start)) { + // found end chunk before start + if (chunk.start < end && chunk.end >= end) { + return result; + } + + chunk = chunk.next; + } + + if (chunk && chunk.edited && chunk.start !== start) + throw new Error(`Cannot use replaced character ${start} as slice start anchor.`); + + const startChunk = chunk; + while (chunk) { + if (chunk.intro && (startChunk !== chunk || chunk.start === start)) { + result += chunk.intro; + } + + const containsEnd = chunk.start < end && chunk.end >= end; + if (containsEnd && chunk.edited && chunk.end !== end) + throw new Error(`Cannot use replaced character ${end} as slice end anchor.`); + + const sliceStart = startChunk === chunk ? start - chunk.start : 0; + const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; + + result += chunk.content.slice(sliceStart, sliceEnd); + + if (chunk.outro && (!containsEnd || chunk.end === end)) { + result += chunk.outro; + } + + if (containsEnd) { + break; + } + + chunk = chunk.next; + } + + return result; + } + + // TODO deprecate this? not really very useful + snip(start, end) { + const clone = this.clone(); + clone.remove(0, start); + clone.remove(end, clone.original.length); + + return clone; + } + + _split(index) { + if (this.byStart[index] || this.byEnd[index]) return; + + let chunk = this.lastSearchedChunk; + let previousChunk = chunk; + const searchForward = index > chunk.end; + + while (chunk) { + if (chunk.contains(index)) return this._splitChunk(chunk, index); + + chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start]; + + // Prevent infinite loop (e.g. via empty chunks, where start === end) + if (chunk === previousChunk) return; + + previousChunk = chunk; + } + } + + _splitChunk(chunk, index) { + if (chunk.edited && chunk.content.length) { + // zero-length edited chunks are a special case (overlapping replacements) + const loc = getLocator(this.original)(index); + throw new Error( + `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`, + ); + } + + const newChunk = chunk.split(index); + + this.byEnd[index] = chunk; + this.byStart[index] = newChunk; + this.byEnd[newChunk.end] = newChunk; + + if (chunk === this.lastChunk) this.lastChunk = newChunk; + + this.lastSearchedChunk = chunk; + return true; + } + + toString() { + let str = this.intro; + + let chunk = this.firstChunk; + while (chunk) { + str += chunk.toString(); + chunk = chunk.next; + } + + return str + this.outro; + } + + isEmpty() { + let chunk = this.firstChunk; + do { + if ( + (chunk.intro.length && chunk.intro.trim()) || + (chunk.content.length && chunk.content.trim()) || + (chunk.outro.length && chunk.outro.trim()) + ) + return false; + } while ((chunk = chunk.next)); + return true; + } + + length() { + let chunk = this.firstChunk; + let length = 0; + do { + length += chunk.intro.length + chunk.content.length + chunk.outro.length; + } while ((chunk = chunk.next)); + return length; + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimEndAborted(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + this.outro = this.outro.replace(rx, ''); + if (this.outro.length) return true; + + let chunk = this.lastChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimEnd(rx); + + // if chunk was trimmed, we have a new lastChunk + if (chunk.end !== end) { + if (this.lastChunk === chunk) { + this.lastChunk = chunk.next; + } + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.previous; + } while (chunk); + + return false; + } + + trimEnd(charType) { + this.trimEndAborted(charType); + return this; + } + trimStartAborted(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + + this.intro = this.intro.replace(rx, ''); + if (this.intro.length) return true; + + let chunk = this.firstChunk; + + do { + const end = chunk.end; + const aborted = chunk.trimStart(rx); + + if (chunk.end !== end) { + // special case... + if (chunk === this.lastChunk) this.lastChunk = chunk.next; + + this.byEnd[chunk.end] = chunk; + this.byStart[chunk.next.start] = chunk.next; + this.byEnd[chunk.next.end] = chunk.next; + } + + if (aborted) return true; + chunk = chunk.next; + } while (chunk); + + return false; + } + + trimStart(charType) { + this.trimStartAborted(charType); + return this; + } + + hasChanged() { + return this.original !== this.toString(); + } + + _replaceRegexp(searchValue, replacement) { + function getReplacement(match, str) { + if (typeof replacement === 'string') { + return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter + if (i === '$') return '$'; + if (i === '&') return match[0]; + const num = +i; + if (num < match.length) return match[+i]; + return `$${i}`; + }); + } else { + return replacement(...match, match.index, str, match.groups); + } + } + function matchAll(re, str) { + let match; + const matches = []; + while ((match = re.exec(str))) { + matches.push(match); + } + return matches; + } + if (searchValue.global) { + const matches = matchAll(searchValue, this.original); + matches.forEach((match) => { + if (match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + }); + } else { + const match = this.original.match(searchValue); + if (match && match.index != null) { + const replacement = getReplacement(match, this.original); + if (replacement !== match[0]) { + this.overwrite(match.index, match.index + match[0].length, replacement); + } + } + } + return this; + } + + _replaceString(string, replacement) { + const { original } = this; + const index = original.indexOf(string); + + if (index !== -1) { + if (typeof replacement === 'function') { + replacement = replacement(string, index, original); + } + if (string !== replacement) { + this.overwrite(index, index + string.length, replacement); + } + } + + return this; + } + + replace(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceString(searchValue, replacement); + } + + return this._replaceRegexp(searchValue, replacement); + } + + _replaceAllString(string, replacement) { + const { original } = this; + const stringLength = string.length; + for ( + let index = original.indexOf(string); + index !== -1; + index = original.indexOf(string, index + stringLength) + ) { + const previous = original.slice(index, index + stringLength); + let _replacement = replacement; + if (typeof replacement === 'function') { + _replacement = replacement(previous, index, original); + } + if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement); + } + + return this; + } + + replaceAll(searchValue, replacement) { + if (typeof searchValue === 'string') { + return this._replaceAllString(searchValue, replacement); + } + + if (!searchValue.global) { + throw new TypeError( + 'MagicString.prototype.replaceAll called with a non-global RegExp argument', + ); + } + + return this._replaceRegexp(searchValue, replacement); + } + } + + const hasOwnProp = Object.prototype.hasOwnProperty; + + class Bundle { + constructor(options = {}) { + this.intro = options.intro || ''; + this.separator = options.separator !== undefined ? options.separator : '\n'; + this.sources = []; + this.uniqueSources = []; + this.uniqueSourceIndexByFilename = {}; + } + + addSource(source) { + if (source instanceof MagicString) { + return this.addSource({ + content: source, + filename: source.filename, + separator: this.separator, + }); + } + + if (!isObject(source) || !source.content) { + throw new Error( + 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', + ); + } + + ['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => { + if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; + }); + + if (source.separator === undefined) { + // TODO there's a bunch of this sort of thing, needs cleaning up + source.separator = this.separator; + } + + if (source.filename) { + if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { + this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; + this.uniqueSources.push({ filename: source.filename, content: source.content.original }); + } else { + const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; + if (source.content.original !== uniqueSource.content) { + throw new Error(`Illegal source: same filename (${source.filename}), different contents`); + } + } + } + + this.sources.push(source); + return this; + } + + append(str, options) { + this.addSource({ + content: new MagicString(str), + separator: (options && options.separator) || '', + }); + + return this; + } + + clone() { + const bundle = new Bundle({ + intro: this.intro, + separator: this.separator, + }); + + this.sources.forEach((source) => { + bundle.addSource({ + filename: source.filename, + content: source.content.clone(), + separator: source.separator, + }); + }); + + return bundle; + } + + generateDecodedMap(options = {}) { + const names = []; + let x_google_ignoreList = undefined; + this.sources.forEach((source) => { + Object.keys(source.content.storedNames).forEach((name) => { + if (!~names.indexOf(name)) names.push(name); + }); + }); + + const mappings = new Mappings(options.hires); + + if (this.intro) { + mappings.advance(this.intro); + } + + this.sources.forEach((source, i) => { + if (i > 0) { + mappings.advance(this.separator); + } + + const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; + const magicString = source.content; + const locate = getLocator(magicString.original); + + if (magicString.intro) { + mappings.advance(magicString.intro); + } + + magicString.firstChunk.eachNext((chunk) => { + const loc = locate(chunk.start); + + if (chunk.intro.length) mappings.advance(chunk.intro); + + if (source.filename) { + if (chunk.edited) { + mappings.addEdit( + sourceIndex, + chunk.content, + loc, + chunk.storeName ? names.indexOf(chunk.original) : -1, + ); + } else { + mappings.addUneditedChunk( + sourceIndex, + chunk, + magicString.original, + loc, + magicString.sourcemapLocations, + ); + } + } else { + mappings.advance(chunk.content); + } + + if (chunk.outro.length) mappings.advance(chunk.outro); + }); + + if (magicString.outro) { + mappings.advance(magicString.outro); + } + + if (source.ignoreList && sourceIndex !== -1) { + if (x_google_ignoreList === undefined) { + x_google_ignoreList = []; + } + x_google_ignoreList.push(sourceIndex); + } + }); + + return { + file: options.file ? options.file.split(/[/\\]/).pop() : undefined, + sources: this.uniqueSources.map((source) => { + return options.file ? getRelativePath(options.file, source.filename) : source.filename; + }), + sourcesContent: this.uniqueSources.map((source) => { + return options.includeContent ? source.content : null; + }), + names, + mappings: mappings.raw, + x_google_ignoreList, + }; + } + + generateMap(options) { + return new SourceMap(this.generateDecodedMap(options)); + } + + getIndentString() { + const indentStringCounts = {}; + + this.sources.forEach((source) => { + const indentStr = source.content._getRawIndentString(); + + if (indentStr === null) return; + + if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; + indentStringCounts[indentStr] += 1; + }); + + return ( + Object.keys(indentStringCounts).sort((a, b) => { + return indentStringCounts[a] - indentStringCounts[b]; + })[0] || '\t' + ); + } + + indent(indentStr) { + if (!arguments.length) { + indentStr = this.getIndentString(); + } + + if (indentStr === '') return this; // noop + + let trailingNewline = !this.intro || this.intro.slice(-1) === '\n'; + + this.sources.forEach((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator)); + + source.content.indent(indentStr, { + exclude: source.indentExclusionRanges, + indentStart, //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator ) + }); + + trailingNewline = source.content.lastChar() === '\n'; + }); + + if (this.intro) { + this.intro = + indentStr + + this.intro.replace(/^[^\n]/gm, (match, index) => { + return index > 0 ? indentStr + match : match; + }); + } + + return this; + } + + prepend(str) { + this.intro = str + this.intro; + return this; + } + + toString() { + const body = this.sources + .map((source, i) => { + const separator = source.separator !== undefined ? source.separator : this.separator; + const str = (i > 0 ? separator : '') + source.content.toString(); + + return str; + }) + .join(''); + + return this.intro + body; + } + + isEmpty() { + if (this.intro.length && this.intro.trim()) return false; + if (this.sources.some((source) => !source.content.isEmpty())) return false; + return true; + } + + length() { + return this.sources.reduce( + (length, source) => length + source.content.length(), + this.intro.length, + ); + } + + trimLines() { + return this.trim('[\\r\\n]'); + } + + trim(charType) { + return this.trimStart(charType).trimEnd(charType); + } + + trimStart(charType) { + const rx = new RegExp('^' + (charType || '\\s') + '+'); + this.intro = this.intro.replace(rx, ''); + + if (!this.intro) { + let source; + let i = 0; + + do { + source = this.sources[i++]; + if (!source) { + break; + } + } while (!source.content.trimStartAborted(charType)); + } + + return this; + } + + trimEnd(charType) { + const rx = new RegExp((charType || '\\s') + '+$'); + + let source; + let i = this.sources.length - 1; + + do { + source = this.sources[i--]; + if (!source) { + this.intro = this.intro.replace(rx, ''); + break; + } + } while (!source.content.trimEndAborted(charType)); + + return this; + } + } + + MagicString.Bundle = Bundle; + MagicString.SourceMap = SourceMap; + MagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121 + + return MagicString; + +})); +//# sourceMappingURL=magic-string.umd.js.map diff --git a/node_modules/magic-string/dist/magic-string.umd.js.map b/node_modules/magic-string/dist/magic-string.umd.js.map new file mode 100644 index 0000000..43addb8 --- /dev/null +++ b/node_modules/magic-string/dist/magic-string.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"magic-string.umd.js","sources":["../src/BitSet.js","../src/Chunk.js","../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs","../src/SourceMap.js","../src/utils/guessIndent.js","../src/utils/getRelativePath.js","../src/utils/isObject.js","../src/utils/getLocator.js","../src/utils/Mappings.js","../src/MagicString.js","../src/Bundle.js","../src/index-legacy.js"],"sourcesContent":["export default class BitSet {\n\tconstructor(arg) {\n\t\tthis.bits = arg instanceof BitSet ? arg.bits.slice() : [];\n\t}\n\n\tadd(n) {\n\t\tthis.bits[n >> 5] |= 1 << (n & 31);\n\t}\n\n\thas(n) {\n\t\treturn !!(this.bits[n >> 5] & (1 << (n & 31)));\n\t}\n}\n","export default class Chunk {\n\tconstructor(start, end, content) {\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.original = content;\n\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\n\t\tthis.content = content;\n\t\tthis.storeName = false;\n\t\tthis.edited = false;\n\n\t\tif (DEBUG) {\n\t\t\t// we make these non-enumerable, for sanity while debugging\n\t\t\tObject.defineProperties(this, {\n\t\t\t\tprevious: { writable: true, value: null },\n\t\t\t\tnext: { writable: true, value: null },\n\t\t\t});\n\t\t} else {\n\t\t\tthis.previous = null;\n\t\t\tthis.next = null;\n\t\t}\n\t}\n\n\tappendLeft(content) {\n\t\tthis.outro += content;\n\t}\n\n\tappendRight(content) {\n\t\tthis.intro = this.intro + content;\n\t}\n\n\tclone() {\n\t\tconst chunk = new Chunk(this.start, this.end, this.original);\n\n\t\tchunk.intro = this.intro;\n\t\tchunk.outro = this.outro;\n\t\tchunk.content = this.content;\n\t\tchunk.storeName = this.storeName;\n\t\tchunk.edited = this.edited;\n\n\t\treturn chunk;\n\t}\n\n\tcontains(index) {\n\t\treturn this.start < index && index < this.end;\n\t}\n\n\teachNext(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.next;\n\t\t}\n\t}\n\n\teachPrevious(fn) {\n\t\tlet chunk = this;\n\t\twhile (chunk) {\n\t\t\tfn(chunk);\n\t\t\tchunk = chunk.previous;\n\t\t}\n\t}\n\n\tedit(content, storeName, contentOnly) {\n\t\tthis.content = content;\n\t\tif (!contentOnly) {\n\t\t\tthis.intro = '';\n\t\t\tthis.outro = '';\n\t\t}\n\t\tthis.storeName = storeName;\n\n\t\tthis.edited = true;\n\n\t\treturn this;\n\t}\n\n\tprependLeft(content) {\n\t\tthis.outro = content + this.outro;\n\t}\n\n\tprependRight(content) {\n\t\tthis.intro = content + this.intro;\n\t}\n\n\treset() {\n\t\tthis.intro = '';\n\t\tthis.outro = '';\n\t\tif (this.edited) {\n\t\t\tthis.content = this.original;\n\t\t\tthis.storeName = false;\n\t\t\tthis.edited = false;\n\t\t}\n\t}\n\n\tsplit(index) {\n\t\tconst sliceIndex = index - this.start;\n\n\t\tconst originalBefore = this.original.slice(0, sliceIndex);\n\t\tconst originalAfter = this.original.slice(sliceIndex);\n\n\t\tthis.original = originalBefore;\n\n\t\tconst newChunk = new Chunk(index, this.end, originalAfter);\n\t\tnewChunk.outro = this.outro;\n\t\tthis.outro = '';\n\n\t\tthis.end = index;\n\n\t\tif (this.edited) {\n\t\t\t// after split we should save the edit content record into the correct chunk\n\t\t\t// to make sure sourcemap correct\n\t\t\t// For example:\n\t\t\t// ' test'.trim()\n\t\t\t// split -> ' ' + 'test'\n\t\t\t// ✔️ edit -> '' + 'test'\n\t\t\t// ✖️ edit -> 'test' + ''\n\t\t\t// TODO is this block necessary?...\n\t\t\tnewChunk.edit('', false);\n\t\t\tthis.content = '';\n\t\t} else {\n\t\t\tthis.content = originalBefore;\n\t\t}\n\n\t\tnewChunk.next = this.next;\n\t\tif (newChunk.next) newChunk.next.previous = newChunk;\n\t\tnewChunk.previous = this;\n\t\tthis.next = newChunk;\n\n\t\treturn newChunk;\n\t}\n\n\ttoString() {\n\t\treturn this.intro + this.content + this.outro;\n\t}\n\n\ttrimEnd(rx) {\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tthis.split(this.start + trimmed.length).edit('', undefined, true);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tthis.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\tif (this.intro.length) return true;\n\t\t}\n\t}\n\n\ttrimStart(rx) {\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tconst trimmed = this.content.replace(rx, '');\n\n\t\tif (trimmed.length) {\n\t\t\tif (trimmed !== this.content) {\n\t\t\t\tconst newChunk = this.split(this.end - trimmed.length);\n\t\t\t\tif (this.edited) {\n\t\t\t\t\t// save the change, if it has been edited\n\t\t\t\t\tnewChunk.edit(trimmed, this.storeName, true);\n\t\t\t\t}\n\t\t\t\tthis.edit('', undefined, true);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthis.edit('', undefined, true);\n\n\t\t\tthis.outro = this.outro.replace(rx, '');\n\t\t\tif (this.outro.length) return true;\n\t\t}\n\t}\n}\n","// src/vlq.ts\nvar comma = \",\".charCodeAt(0);\nvar semicolon = \";\".charCodeAt(0);\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar intToChar = new Uint8Array(64);\nvar charToInt = new Uint8Array(128);\nfor (let i = 0; i < chars.length; i++) {\n const c = chars.charCodeAt(i);\n intToChar[i] = c;\n charToInt[c] = i;\n}\nfunction decodeInteger(reader, relative) {\n let value = 0;\n let shift = 0;\n let integer = 0;\n do {\n const c = reader.next();\n integer = charToInt[c];\n value |= (integer & 31) << shift;\n shift += 5;\n } while (integer & 32);\n const shouldNegate = value & 1;\n value >>>= 1;\n if (shouldNegate) {\n value = -2147483648 | -value;\n }\n return relative + value;\n}\nfunction encodeInteger(builder, num, relative) {\n let delta = num - relative;\n delta = delta < 0 ? -delta << 1 | 1 : delta << 1;\n do {\n let clamped = delta & 31;\n delta >>>= 5;\n if (delta > 0) clamped |= 32;\n builder.write(intToChar[clamped]);\n } while (delta > 0);\n return num;\n}\nfunction hasMoreVlq(reader, max) {\n if (reader.pos >= max) return false;\n return reader.peek() !== comma;\n}\n\n// src/strings.ts\nvar bufLength = 1024 * 16;\nvar td = typeof TextDecoder !== \"undefined\" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== \"undefined\" ? {\n decode(buf) {\n const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);\n return out.toString();\n }\n} : {\n decode(buf) {\n let out = \"\";\n for (let i = 0; i < buf.length; i++) {\n out += String.fromCharCode(buf[i]);\n }\n return out;\n }\n};\nvar StringWriter = class {\n constructor() {\n this.pos = 0;\n this.out = \"\";\n this.buffer = new Uint8Array(bufLength);\n }\n write(v) {\n const { buffer } = this;\n buffer[this.pos++] = v;\n if (this.pos === bufLength) {\n this.out += td.decode(buffer);\n this.pos = 0;\n }\n }\n flush() {\n const { buffer, out, pos } = this;\n return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;\n }\n};\nvar StringReader = class {\n constructor(buffer) {\n this.pos = 0;\n this.buffer = buffer;\n }\n next() {\n return this.buffer.charCodeAt(this.pos++);\n }\n peek() {\n return this.buffer.charCodeAt(this.pos);\n }\n indexOf(char) {\n const { buffer, pos } = this;\n const idx = buffer.indexOf(char, pos);\n return idx === -1 ? buffer.length : idx;\n }\n};\n\n// src/scopes.ts\nvar EMPTY = [];\nfunction decodeOriginalScopes(input) {\n const { length } = input;\n const reader = new StringReader(input);\n const scopes = [];\n const stack = [];\n let line = 0;\n for (; reader.pos < length; reader.pos++) {\n line = decodeInteger(reader, line);\n const column = decodeInteger(reader, 0);\n if (!hasMoreVlq(reader, length)) {\n const last = stack.pop();\n last[2] = line;\n last[3] = column;\n continue;\n }\n const kind = decodeInteger(reader, 0);\n const fields = decodeInteger(reader, 0);\n const hasName = fields & 1;\n const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind];\n let vars = EMPTY;\n if (hasMoreVlq(reader, length)) {\n vars = [];\n do {\n const varsIndex = decodeInteger(reader, 0);\n vars.push(varsIndex);\n } while (hasMoreVlq(reader, length));\n }\n scope.vars = vars;\n scopes.push(scope);\n stack.push(scope);\n }\n return scopes;\n}\nfunction encodeOriginalScopes(scopes) {\n const writer = new StringWriter();\n for (let i = 0; i < scopes.length; ) {\n i = _encodeOriginalScopes(scopes, i, writer, [0]);\n }\n return writer.flush();\n}\nfunction _encodeOriginalScopes(scopes, index, writer, state) {\n const scope = scopes[index];\n const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;\n if (index > 0) writer.write(comma);\n state[0] = encodeInteger(writer, startLine, state[0]);\n encodeInteger(writer, startColumn, 0);\n encodeInteger(writer, kind, 0);\n const fields = scope.length === 6 ? 1 : 0;\n encodeInteger(writer, fields, 0);\n if (scope.length === 6) encodeInteger(writer, scope[5], 0);\n for (const v of vars) {\n encodeInteger(writer, v, 0);\n }\n for (index++; index < scopes.length; ) {\n const next = scopes[index];\n const { 0: l, 1: c } = next;\n if (l > endLine || l === endLine && c >= endColumn) {\n break;\n }\n index = _encodeOriginalScopes(scopes, index, writer, state);\n }\n writer.write(comma);\n state[0] = encodeInteger(writer, endLine, state[0]);\n encodeInteger(writer, endColumn, 0);\n return index;\n}\nfunction decodeGeneratedRanges(input) {\n const { length } = input;\n const reader = new StringReader(input);\n const ranges = [];\n const stack = [];\n let genLine = 0;\n let definitionSourcesIndex = 0;\n let definitionScopeIndex = 0;\n let callsiteSourcesIndex = 0;\n let callsiteLine = 0;\n let callsiteColumn = 0;\n let bindingLine = 0;\n let bindingColumn = 0;\n do {\n const semi = reader.indexOf(\";\");\n let genColumn = 0;\n for (; reader.pos < semi; reader.pos++) {\n genColumn = decodeInteger(reader, genColumn);\n if (!hasMoreVlq(reader, semi)) {\n const last = stack.pop();\n last[2] = genLine;\n last[3] = genColumn;\n continue;\n }\n const fields = decodeInteger(reader, 0);\n const hasDefinition = fields & 1;\n const hasCallsite = fields & 2;\n const hasScope = fields & 4;\n let callsite = null;\n let bindings = EMPTY;\n let range;\n if (hasDefinition) {\n const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);\n definitionScopeIndex = decodeInteger(\n reader,\n definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0\n );\n definitionSourcesIndex = defSourcesIndex;\n range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];\n } else {\n range = [genLine, genColumn, 0, 0];\n }\n range.isScope = !!hasScope;\n if (hasCallsite) {\n const prevCsi = callsiteSourcesIndex;\n const prevLine = callsiteLine;\n callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);\n const sameSource = prevCsi === callsiteSourcesIndex;\n callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);\n callsiteColumn = decodeInteger(\n reader,\n sameSource && prevLine === callsiteLine ? callsiteColumn : 0\n );\n callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];\n }\n range.callsite = callsite;\n if (hasMoreVlq(reader, semi)) {\n bindings = [];\n do {\n bindingLine = genLine;\n bindingColumn = genColumn;\n const expressionsCount = decodeInteger(reader, 0);\n let expressionRanges;\n if (expressionsCount < -1) {\n expressionRanges = [[decodeInteger(reader, 0)]];\n for (let i = -1; i > expressionsCount; i--) {\n const prevBl = bindingLine;\n bindingLine = decodeInteger(reader, bindingLine);\n bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);\n const expression = decodeInteger(reader, 0);\n expressionRanges.push([expression, bindingLine, bindingColumn]);\n }\n } else {\n expressionRanges = [[expressionsCount]];\n }\n bindings.push(expressionRanges);\n } while (hasMoreVlq(reader, semi));\n }\n range.bindings = bindings;\n ranges.push(range);\n stack.push(range);\n }\n genLine++;\n reader.pos = semi + 1;\n } while (reader.pos < length);\n return ranges;\n}\nfunction encodeGeneratedRanges(ranges) {\n if (ranges.length === 0) return \"\";\n const writer = new StringWriter();\n for (let i = 0; i < ranges.length; ) {\n i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);\n }\n return writer.flush();\n}\nfunction _encodeGeneratedRanges(ranges, index, writer, state) {\n const range = ranges[index];\n const {\n 0: startLine,\n 1: startColumn,\n 2: endLine,\n 3: endColumn,\n isScope,\n callsite,\n bindings\n } = range;\n if (state[0] < startLine) {\n catchupLine(writer, state[0], startLine);\n state[0] = startLine;\n state[1] = 0;\n } else if (index > 0) {\n writer.write(comma);\n }\n state[1] = encodeInteger(writer, range[1], state[1]);\n const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0);\n encodeInteger(writer, fields, 0);\n if (range.length === 6) {\n const { 4: sourcesIndex, 5: scopesIndex } = range;\n if (sourcesIndex !== state[2]) {\n state[3] = 0;\n }\n state[2] = encodeInteger(writer, sourcesIndex, state[2]);\n state[3] = encodeInteger(writer, scopesIndex, state[3]);\n }\n if (callsite) {\n const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;\n if (sourcesIndex !== state[4]) {\n state[5] = 0;\n state[6] = 0;\n } else if (callLine !== state[5]) {\n state[6] = 0;\n }\n state[4] = encodeInteger(writer, sourcesIndex, state[4]);\n state[5] = encodeInteger(writer, callLine, state[5]);\n state[6] = encodeInteger(writer, callColumn, state[6]);\n }\n if (bindings) {\n for (const binding of bindings) {\n if (binding.length > 1) encodeInteger(writer, -binding.length, 0);\n const expression = binding[0][0];\n encodeInteger(writer, expression, 0);\n let bindingStartLine = startLine;\n let bindingStartColumn = startColumn;\n for (let i = 1; i < binding.length; i++) {\n const expRange = binding[i];\n bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);\n bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);\n encodeInteger(writer, expRange[0], 0);\n }\n }\n }\n for (index++; index < ranges.length; ) {\n const next = ranges[index];\n const { 0: l, 1: c } = next;\n if (l > endLine || l === endLine && c >= endColumn) {\n break;\n }\n index = _encodeGeneratedRanges(ranges, index, writer, state);\n }\n if (state[0] < endLine) {\n catchupLine(writer, state[0], endLine);\n state[0] = endLine;\n state[1] = 0;\n } else {\n writer.write(comma);\n }\n state[1] = encodeInteger(writer, endColumn, state[1]);\n return index;\n}\nfunction catchupLine(writer, lastLine, line) {\n do {\n writer.write(semicolon);\n } while (++lastLine < line);\n}\n\n// src/sourcemap-codec.ts\nfunction decode(mappings) {\n const { length } = mappings;\n const reader = new StringReader(mappings);\n const decoded = [];\n let genColumn = 0;\n let sourcesIndex = 0;\n let sourceLine = 0;\n let sourceColumn = 0;\n let namesIndex = 0;\n do {\n const semi = reader.indexOf(\";\");\n const line = [];\n let sorted = true;\n let lastCol = 0;\n genColumn = 0;\n while (reader.pos < semi) {\n let seg;\n genColumn = decodeInteger(reader, genColumn);\n if (genColumn < lastCol) sorted = false;\n lastCol = genColumn;\n if (hasMoreVlq(reader, semi)) {\n sourcesIndex = decodeInteger(reader, sourcesIndex);\n sourceLine = decodeInteger(reader, sourceLine);\n sourceColumn = decodeInteger(reader, sourceColumn);\n if (hasMoreVlq(reader, semi)) {\n namesIndex = decodeInteger(reader, namesIndex);\n seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];\n } else {\n seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];\n }\n } else {\n seg = [genColumn];\n }\n line.push(seg);\n reader.pos++;\n }\n if (!sorted) sort(line);\n decoded.push(line);\n reader.pos = semi + 1;\n } while (reader.pos <= length);\n return decoded;\n}\nfunction sort(line) {\n line.sort(sortComparator);\n}\nfunction sortComparator(a, b) {\n return a[0] - b[0];\n}\nfunction encode(decoded) {\n const writer = new StringWriter();\n let sourcesIndex = 0;\n let sourceLine = 0;\n let sourceColumn = 0;\n let namesIndex = 0;\n for (let i = 0; i < decoded.length; i++) {\n const line = decoded[i];\n if (i > 0) writer.write(semicolon);\n if (line.length === 0) continue;\n let genColumn = 0;\n for (let j = 0; j < line.length; j++) {\n const segment = line[j];\n if (j > 0) writer.write(comma);\n genColumn = encodeInteger(writer, segment[0], genColumn);\n if (segment.length === 1) continue;\n sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);\n sourceLine = encodeInteger(writer, segment[2], sourceLine);\n sourceColumn = encodeInteger(writer, segment[3], sourceColumn);\n if (segment.length === 4) continue;\n namesIndex = encodeInteger(writer, segment[4], namesIndex);\n }\n }\n return writer.flush();\n}\nexport {\n decode,\n decodeGeneratedRanges,\n decodeOriginalScopes,\n encode,\n encodeGeneratedRanges,\n encodeOriginalScopes\n};\n//# sourceMappingURL=sourcemap-codec.mjs.map\n","import { encode } from '@jridgewell/sourcemap-codec';\n\nfunction getBtoa() {\n\tif (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {\n\t\treturn (str) => globalThis.btoa(unescape(encodeURIComponent(str)));\n\t} else if (typeof Buffer === 'function') {\n\t\treturn (str) => Buffer.from(str, 'utf-8').toString('base64');\n\t} else {\n\t\treturn () => {\n\t\t\tthrow new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');\n\t\t};\n\t}\n}\n\nconst btoa = /*#__PURE__*/ getBtoa();\n\nexport default class SourceMap {\n\tconstructor(properties) {\n\t\tthis.version = 3;\n\t\tthis.file = properties.file;\n\t\tthis.sources = properties.sources;\n\t\tthis.sourcesContent = properties.sourcesContent;\n\t\tthis.names = properties.names;\n\t\tthis.mappings = encode(properties.mappings);\n\t\tif (typeof properties.x_google_ignoreList !== 'undefined') {\n\t\t\tthis.x_google_ignoreList = properties.x_google_ignoreList;\n\t\t}\n\t\tif (typeof properties.debugId !== 'undefined') {\n\t\t\tthis.debugId = properties.debugId;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this);\n\t}\n\n\ttoUrl() {\n\t\treturn 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());\n\t}\n}\n","export default function guessIndent(code) {\n\tconst lines = code.split('\\n');\n\n\tconst tabbed = lines.filter((line) => /^\\t+/.test(line));\n\tconst spaced = lines.filter((line) => /^ {2,}/.test(line));\n\n\tif (tabbed.length === 0 && spaced.length === 0) {\n\t\treturn null;\n\t}\n\n\t// More lines tabbed than spaced? Assume tabs, and\n\t// default to tabs in the case of a tie (or nothing\n\t// to go on)\n\tif (tabbed.length >= spaced.length) {\n\t\treturn '\\t';\n\t}\n\n\t// Otherwise, we need to guess the multiple\n\tconst min = spaced.reduce((previous, current) => {\n\t\tconst numSpaces = /^ +/.exec(current)[0].length;\n\t\treturn Math.min(numSpaces, previous);\n\t}, Infinity);\n\n\treturn new Array(min + 1).join(' ');\n}\n","export default function getRelativePath(from, to) {\n\tconst fromParts = from.split(/[/\\\\]/);\n\tconst toParts = to.split(/[/\\\\]/);\n\n\tfromParts.pop(); // get dirname\n\n\twhile (fromParts[0] === toParts[0]) {\n\t\tfromParts.shift();\n\t\ttoParts.shift();\n\t}\n\n\tif (fromParts.length) {\n\t\tlet i = fromParts.length;\n\t\twhile (i--) fromParts[i] = '..';\n\t}\n\n\treturn fromParts.concat(toParts).join('/');\n}\n","const toString = Object.prototype.toString;\n\nexport default function isObject(thing) {\n\treturn toString.call(thing) === '[object Object]';\n}\n","export default function getLocator(source) {\n\tconst originalLines = source.split('\\n');\n\tconst lineOffsets = [];\n\n\tfor (let i = 0, pos = 0; i < originalLines.length; i++) {\n\t\tlineOffsets.push(pos);\n\t\tpos += originalLines[i].length + 1;\n\t}\n\n\treturn function locate(index) {\n\t\tlet i = 0;\n\t\tlet j = lineOffsets.length;\n\t\twhile (i < j) {\n\t\t\tconst m = (i + j) >> 1;\n\t\t\tif (index < lineOffsets[m]) {\n\t\t\t\tj = m;\n\t\t\t} else {\n\t\t\t\ti = m + 1;\n\t\t\t}\n\t\t}\n\t\tconst line = i - 1;\n\t\tconst column = index - lineOffsets[line];\n\t\treturn { line, column };\n\t};\n}\n","const wordRegex = /\\w/;\n\nexport default class Mappings {\n\tconstructor(hires) {\n\t\tthis.hires = hires;\n\t\tthis.generatedCodeLine = 0;\n\t\tthis.generatedCodeColumn = 0;\n\t\tthis.raw = [];\n\t\tthis.rawSegments = this.raw[this.generatedCodeLine] = [];\n\t\tthis.pending = null;\n\t}\n\n\taddEdit(sourceIndex, content, loc, nameIndex) {\n\t\tif (content.length) {\n\t\t\tconst contentLengthMinusOne = content.length - 1;\n\t\t\tlet contentLineEnd = content.indexOf('\\n', 0);\n\t\t\tlet previousContentLineEnd = -1;\n\t\t\t// Loop through each line in the content and add a segment, but stop if the last line is empty,\n\t\t\t// else code afterwards would fill one line too many\n\t\t\twhile (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {\n\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\t\tif (nameIndex >= 0) {\n\t\t\t\t\tsegment.push(nameIndex);\n\t\t\t\t}\n\t\t\t\tthis.rawSegments.push(segment);\n\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\n\t\t\t\tpreviousContentLineEnd = contentLineEnd;\n\t\t\t\tcontentLineEnd = content.indexOf('\\n', contentLineEnd + 1);\n\t\t\t}\n\n\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\t\t\tif (nameIndex >= 0) {\n\t\t\t\tsegment.push(nameIndex);\n\t\t\t}\n\t\t\tthis.rawSegments.push(segment);\n\n\t\t\tthis.advance(content.slice(previousContentLineEnd + 1));\n\t\t} else if (this.pending) {\n\t\t\tthis.rawSegments.push(this.pending);\n\t\t\tthis.advance(content);\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\taddUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {\n\t\tlet originalCharIndex = chunk.start;\n\t\tlet first = true;\n\t\t// when iterating each char, check if it's in a word boundary\n\t\tlet charInHiresBoundary = false;\n\n\t\twhile (originalCharIndex < chunk.end) {\n\t\t\tif (original[originalCharIndex] === '\\n') {\n\t\t\t\tloc.line += 1;\n\t\t\t\tloc.column = 0;\n\t\t\t\tthis.generatedCodeLine += 1;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t\tthis.generatedCodeColumn = 0;\n\t\t\t\tfirst = true;\n\t\t\t\tcharInHiresBoundary = false;\n\t\t\t} else {\n\t\t\t\tif (this.hires || first || sourcemapLocations.has(originalCharIndex)) {\n\t\t\t\t\tconst segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];\n\n\t\t\t\t\tif (this.hires === 'boundary') {\n\t\t\t\t\t\t// in hires \"boundary\", group segments per word boundary than per char\n\t\t\t\t\t\tif (wordRegex.test(original[originalCharIndex])) {\n\t\t\t\t\t\t\t// for first char in the boundary found, start the boundary by pushing a segment\n\t\t\t\t\t\t\tif (!charInHiresBoundary) {\n\t\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\t\tcharInHiresBoundary = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// for non-word char, end the boundary by pushing a segment\n\t\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t\t\tcharInHiresBoundary = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.rawSegments.push(segment);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tloc.column += 1;\n\t\t\t\tthis.generatedCodeColumn += 1;\n\t\t\t\tfirst = false;\n\t\t\t}\n\n\t\t\toriginalCharIndex += 1;\n\t\t}\n\n\t\tthis.pending = null;\n\t}\n\n\tadvance(str) {\n\t\tif (!str) return;\n\n\t\tconst lines = str.split('\\n');\n\n\t\tif (lines.length > 1) {\n\t\t\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\t\t\tthis.generatedCodeLine++;\n\t\t\t\tthis.raw[this.generatedCodeLine] = this.rawSegments = [];\n\t\t\t}\n\t\t\tthis.generatedCodeColumn = 0;\n\t\t}\n\n\t\tthis.generatedCodeColumn += lines[lines.length - 1].length;\n\t}\n}\n","import BitSet from './BitSet.js';\nimport Chunk from './Chunk.js';\nimport SourceMap from './SourceMap.js';\nimport guessIndent from './utils/guessIndent.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\nimport Stats from './utils/Stats.js';\n\nconst n = '\\n';\n\nconst warned = {\n\tinsertLeft: false,\n\tinsertRight: false,\n\tstoreName: false,\n};\n\nexport default class MagicString {\n\tconstructor(string, options = {}) {\n\t\tconst chunk = new Chunk(0, string.length, string);\n\n\t\tObject.defineProperties(this, {\n\t\t\toriginal: { writable: true, value: string },\n\t\t\toutro: { writable: true, value: '' },\n\t\t\tintro: { writable: true, value: '' },\n\t\t\tfirstChunk: { writable: true, value: chunk },\n\t\t\tlastChunk: { writable: true, value: chunk },\n\t\t\tlastSearchedChunk: { writable: true, value: chunk },\n\t\t\tbyStart: { writable: true, value: {} },\n\t\t\tbyEnd: { writable: true, value: {} },\n\t\t\tfilename: { writable: true, value: options.filename },\n\t\t\tindentExclusionRanges: { writable: true, value: options.indentExclusionRanges },\n\t\t\tsourcemapLocations: { writable: true, value: new BitSet() },\n\t\t\tstoredNames: { writable: true, value: {} },\n\t\t\tindentStr: { writable: true, value: undefined },\n\t\t\tignoreList: { writable: true, value: options.ignoreList },\n\t\t\toffset: { writable: true, value: options.offset || 0 },\n\t\t});\n\n\t\tif (DEBUG) {\n\t\t\tObject.defineProperty(this, 'stats', { value: new Stats() });\n\t\t}\n\n\t\tthis.byStart[0] = chunk;\n\t\tthis.byEnd[string.length] = chunk;\n\t}\n\n\taddSourcemapLocation(char) {\n\t\tthis.sourcemapLocations.add(char);\n\t}\n\n\tappend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.outro += content;\n\t\treturn this;\n\t}\n\n\tappendLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendLeft');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendLeft(content);\n\t\t} else {\n\t\t\tthis.intro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendLeft');\n\t\treturn this;\n\t}\n\n\tappendRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('appendRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.appendRight(content);\n\t\t} else {\n\t\t\tthis.outro += content;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('appendRight');\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });\n\n\t\tlet originalChunk = this.firstChunk;\n\t\tlet clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());\n\n\t\twhile (originalChunk) {\n\t\t\tcloned.byStart[clonedChunk.start] = clonedChunk;\n\t\t\tcloned.byEnd[clonedChunk.end] = clonedChunk;\n\n\t\t\tconst nextOriginalChunk = originalChunk.next;\n\t\t\tconst nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();\n\n\t\t\tif (nextClonedChunk) {\n\t\t\t\tclonedChunk.next = nextClonedChunk;\n\t\t\t\tnextClonedChunk.previous = clonedChunk;\n\n\t\t\t\tclonedChunk = nextClonedChunk;\n\t\t\t}\n\n\t\t\toriginalChunk = nextOriginalChunk;\n\t\t}\n\n\t\tcloned.lastChunk = clonedChunk;\n\n\t\tif (this.indentExclusionRanges) {\n\t\t\tcloned.indentExclusionRanges = this.indentExclusionRanges.slice();\n\t\t}\n\n\t\tcloned.sourcemapLocations = new BitSet(this.sourcemapLocations);\n\n\t\tcloned.intro = this.intro;\n\t\tcloned.outro = this.outro;\n\n\t\treturn cloned;\n\t}\n\n\tgenerateDecodedMap(options) {\n\t\toptions = options || {};\n\n\t\tconst sourceIndex = 0;\n\t\tconst names = Object.keys(this.storedNames);\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tconst locate = getLocator(this.original);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.firstChunk.eachNext((chunk) => {\n\t\t\tconst loc = locate(chunk.start);\n\n\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tmappings.addEdit(\n\t\t\t\t\tsourceIndex,\n\t\t\t\t\tchunk.content,\n\t\t\t\t\tloc,\n\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);\n\t\t\t}\n\n\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t});\n\n\t\tif (this.outro) {\n\t\t\tmappings.advance(this.outro);\n\t\t}\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: [\n\t\t\t\toptions.source ? getRelativePath(options.file || '', options.source) : options.file || '',\n\t\t\t],\n\t\t\tsourcesContent: options.includeContent ? [this.original] : undefined,\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\t_ensureindentStr() {\n\t\tif (this.indentStr === undefined) {\n\t\t\tthis.indentStr = guessIndent(this.original);\n\t\t}\n\t}\n\n\t_getRawIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr;\n\t}\n\n\tgetIndentString() {\n\t\tthis._ensureindentStr();\n\t\treturn this.indentStr === null ? '\\t' : this.indentStr;\n\t}\n\n\tindent(indentStr, options) {\n\t\tconst pattern = /^[^\\r\\n]/gm;\n\n\t\tif (isObject(indentStr)) {\n\t\t\toptions = indentStr;\n\t\t\tindentStr = undefined;\n\t\t}\n\n\t\tif (indentStr === undefined) {\n\t\t\tthis._ensureindentStr();\n\t\t\tindentStr = this.indentStr || '\\t';\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\toptions = options || {};\n\n\t\t// Process exclusion ranges\n\t\tconst isExcluded = {};\n\n\t\tif (options.exclude) {\n\t\t\tconst exclusions =\n\t\t\t\ttypeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;\n\t\t\texclusions.forEach((exclusion) => {\n\t\t\t\tfor (let i = exclusion[0]; i < exclusion[1]; i += 1) {\n\t\t\t\t\tisExcluded[i] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet shouldIndentNextCharacter = options.indentStart !== false;\n\t\tconst replacer = (match) => {\n\t\t\tif (shouldIndentNextCharacter) return `${indentStr}${match}`;\n\t\t\tshouldIndentNextCharacter = true;\n\t\t\treturn match;\n\t\t};\n\n\t\tthis.intro = this.intro.replace(pattern, replacer);\n\n\t\tlet charIndex = 0;\n\t\tlet chunk = this.firstChunk;\n\n\t\twhile (chunk) {\n\t\t\tconst end = chunk.end;\n\n\t\t\tif (chunk.edited) {\n\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\tchunk.content = chunk.content.replace(pattern, replacer);\n\n\t\t\t\t\tif (chunk.content.length) {\n\t\t\t\t\t\tshouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\\n';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcharIndex = chunk.start;\n\n\t\t\t\twhile (charIndex < end) {\n\t\t\t\t\tif (!isExcluded[charIndex]) {\n\t\t\t\t\t\tconst char = this.original[charIndex];\n\n\t\t\t\t\t\tif (char === '\\n') {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = true;\n\t\t\t\t\t\t} else if (char !== '\\r' && shouldIndentNextCharacter) {\n\t\t\t\t\t\t\tshouldIndentNextCharacter = false;\n\n\t\t\t\t\t\t\tif (charIndex === chunk.start) {\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis._splitChunk(chunk, charIndex);\n\t\t\t\t\t\t\t\tchunk = chunk.next;\n\t\t\t\t\t\t\t\tchunk.prependRight(indentStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcharIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcharIndex = chunk.end;\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tthis.outro = this.outro.replace(pattern, replacer);\n\n\t\treturn this;\n\t}\n\n\tinsert() {\n\t\tthrow new Error(\n\t\t\t'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',\n\t\t);\n\t}\n\n\tinsertLeft(index, content) {\n\t\tif (!warned.insertLeft) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',\n\t\t\t);\n\t\t\twarned.insertLeft = true;\n\t\t}\n\n\t\treturn this.appendLeft(index, content);\n\t}\n\n\tinsertRight(index, content) {\n\t\tif (!warned.insertRight) {\n\t\t\tconsole.warn(\n\t\t\t\t'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',\n\t\t\t);\n\t\t\twarned.insertRight = true;\n\t\t}\n\n\t\treturn this.prependRight(index, content);\n\t}\n\n\tmove(start, end, index) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\t\tindex = index + this.offset;\n\n\t\tif (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');\n\n\t\tif (DEBUG) this.stats.time('move');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\t\tthis._split(index);\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tconst oldLeft = first.previous;\n\t\tconst oldRight = last.next;\n\n\t\tconst newRight = this.byStart[index];\n\t\tif (!newRight && last === this.lastChunk) return this;\n\t\tconst newLeft = newRight ? newRight.previous : this.lastChunk;\n\n\t\tif (oldLeft) oldLeft.next = oldRight;\n\t\tif (oldRight) oldRight.previous = oldLeft;\n\n\t\tif (newLeft) newLeft.next = first;\n\t\tif (newRight) newRight.previous = last;\n\n\t\tif (!first.previous) this.firstChunk = last.next;\n\t\tif (!last.next) {\n\t\t\tthis.lastChunk = first.previous;\n\t\t\tthis.lastChunk.next = null;\n\t\t}\n\n\t\tfirst.previous = newLeft;\n\t\tlast.next = newRight || null;\n\n\t\tif (!newLeft) this.firstChunk = first;\n\t\tif (!newRight) this.lastChunk = last;\n\n\t\tif (DEBUG) this.stats.timeEnd('move');\n\t\treturn this;\n\t}\n\n\toverwrite(start, end, content, options) {\n\t\toptions = options || {};\n\t\treturn this.update(start, end, content, { ...options, overwrite: !options.contentOnly });\n\t}\n\n\tupdate(start, end, content, options) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('replacement content must be a string');\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (end > this.original.length) throw new Error('end is out of bounds');\n\t\tif (start === end)\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',\n\t\t\t);\n\n\t\tif (DEBUG) this.stats.time('overwrite');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tif (options === true) {\n\t\t\tif (!warned.storeName) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',\n\t\t\t\t);\n\t\t\t\twarned.storeName = true;\n\t\t\t}\n\n\t\t\toptions = { storeName: true };\n\t\t}\n\t\tconst storeName = options !== undefined ? options.storeName : false;\n\t\tconst overwrite = options !== undefined ? options.overwrite : false;\n\n\t\tif (storeName) {\n\t\t\tconst original = this.original.slice(start, end);\n\t\t\tObject.defineProperty(this.storedNames, original, {\n\t\t\t\twritable: true,\n\t\t\t\tvalue: true,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\n\t\tconst first = this.byStart[start];\n\t\tconst last = this.byEnd[end];\n\n\t\tif (first) {\n\t\t\tlet chunk = first;\n\t\t\twhile (chunk !== last) {\n\t\t\t\tif (chunk.next !== this.byStart[chunk.end]) {\n\t\t\t\t\tthrow new Error('Cannot overwrite across a split point');\n\t\t\t\t}\n\t\t\t\tchunk = chunk.next;\n\t\t\t\tchunk.edit('', false);\n\t\t\t}\n\n\t\t\tfirst.edit(content, storeName, !overwrite);\n\t\t} else {\n\t\t\t// must be inserting at the end\n\t\t\tconst newChunk = new Chunk(start, end, '').edit(content, storeName);\n\n\t\t\t// TODO last chunk in the array may not be the last chunk, if it's moved...\n\t\t\tlast.next = newChunk;\n\t\t\tnewChunk.previous = last;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('overwrite');\n\t\treturn this;\n\t}\n\n\tprepend(content) {\n\t\tif (typeof content !== 'string') throw new TypeError('outro content must be a string');\n\n\t\tthis.intro = content + this.intro;\n\t\treturn this;\n\t}\n\n\tprependLeft(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byEnd[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependLeft(content);\n\t\t} else {\n\t\t\tthis.intro = content + this.intro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tprependRight(index, content) {\n\t\tindex = index + this.offset;\n\n\t\tif (typeof content !== 'string') throw new TypeError('inserted content must be a string');\n\n\t\tif (DEBUG) this.stats.time('insertRight');\n\n\t\tthis._split(index);\n\n\t\tconst chunk = this.byStart[index];\n\n\t\tif (chunk) {\n\t\t\tchunk.prependRight(content);\n\t\t} else {\n\t\t\tthis.outro = content + this.outro;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('insertRight');\n\t\treturn this;\n\t}\n\n\tremove(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('remove');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.intro = '';\n\t\t\tchunk.outro = '';\n\t\t\tchunk.edit('');\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('remove');\n\t\treturn this;\n\t}\n\n\treset(start, end) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tif (start === end) return this;\n\n\t\tif (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');\n\t\tif (start > end) throw new Error('end must be greater than start');\n\n\t\tif (DEBUG) this.stats.time('reset');\n\n\t\tthis._split(start);\n\t\tthis._split(end);\n\n\t\tlet chunk = this.byStart[start];\n\n\t\twhile (chunk) {\n\t\t\tchunk.reset();\n\n\t\t\tchunk = end > chunk.end ? this.byStart[chunk.end] : null;\n\t\t}\n\n\t\tif (DEBUG) this.stats.timeEnd('reset');\n\t\treturn this;\n\t}\n\n\tlastChar() {\n\t\tif (this.outro.length) return this.outro[this.outro.length - 1];\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];\n\t\t\tif (chunk.content.length) return chunk.content[chunk.content.length - 1];\n\t\t\tif (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];\n\t\t} while ((chunk = chunk.previous));\n\t\tif (this.intro.length) return this.intro[this.intro.length - 1];\n\t\treturn '';\n\t}\n\n\tlastLine() {\n\t\tlet lineIndex = this.outro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.outro.substr(lineIndex + 1);\n\t\tlet lineStr = this.outro;\n\t\tlet chunk = this.lastChunk;\n\t\tdo {\n\t\t\tif (chunk.outro.length > 0) {\n\t\t\t\tlineIndex = chunk.outro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.outro + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.content.length > 0) {\n\t\t\t\tlineIndex = chunk.content.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.content + lineStr;\n\t\t\t}\n\n\t\t\tif (chunk.intro.length > 0) {\n\t\t\t\tlineIndex = chunk.intro.lastIndexOf(n);\n\t\t\t\tif (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;\n\t\t\t\tlineStr = chunk.intro + lineStr;\n\t\t\t}\n\t\t} while ((chunk = chunk.previous));\n\t\tlineIndex = this.intro.lastIndexOf(n);\n\t\tif (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;\n\t\treturn this.intro + lineStr;\n\t}\n\n\tslice(start = 0, end = this.original.length - this.offset) {\n\t\tstart = start + this.offset;\n\t\tend = end + this.offset;\n\n\t\tif (this.original.length !== 0) {\n\t\t\twhile (start < 0) start += this.original.length;\n\t\t\twhile (end < 0) end += this.original.length;\n\t\t}\n\n\t\tlet result = '';\n\n\t\t// find start chunk\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk && (chunk.start > start || chunk.end <= start)) {\n\t\t\t// found end chunk before start\n\t\t\tif (chunk.start < end && chunk.end >= end) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\tif (chunk && chunk.edited && chunk.start !== start)\n\t\t\tthrow new Error(`Cannot use replaced character ${start} as slice start anchor.`);\n\n\t\tconst startChunk = chunk;\n\t\twhile (chunk) {\n\t\t\tif (chunk.intro && (startChunk !== chunk || chunk.start === start)) {\n\t\t\t\tresult += chunk.intro;\n\t\t\t}\n\n\t\t\tconst containsEnd = chunk.start < end && chunk.end >= end;\n\t\t\tif (containsEnd && chunk.edited && chunk.end !== end)\n\t\t\t\tthrow new Error(`Cannot use replaced character ${end} as slice end anchor.`);\n\n\t\t\tconst sliceStart = startChunk === chunk ? start - chunk.start : 0;\n\t\t\tconst sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;\n\n\t\t\tresult += chunk.content.slice(sliceStart, sliceEnd);\n\n\t\t\tif (chunk.outro && (!containsEnd || chunk.end === end)) {\n\t\t\t\tresult += chunk.outro;\n\t\t\t}\n\n\t\t\tif (containsEnd) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// TODO deprecate this? not really very useful\n\tsnip(start, end) {\n\t\tconst clone = this.clone();\n\t\tclone.remove(0, start);\n\t\tclone.remove(end, clone.original.length);\n\n\t\treturn clone;\n\t}\n\n\t_split(index) {\n\t\tif (this.byStart[index] || this.byEnd[index]) return;\n\n\t\tif (DEBUG) this.stats.time('_split');\n\n\t\tlet chunk = this.lastSearchedChunk;\n\t\tlet previousChunk = chunk;\n\t\tconst searchForward = index > chunk.end;\n\n\t\twhile (chunk) {\n\t\t\tif (chunk.contains(index)) return this._splitChunk(chunk, index);\n\n\t\t\tchunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];\n\n\t\t\t// Prevent infinite loop (e.g. via empty chunks, where start === end)\n\t\t\tif (chunk === previousChunk) return;\n\n\t\t\tpreviousChunk = chunk;\n\t\t}\n\t}\n\n\t_splitChunk(chunk, index) {\n\t\tif (chunk.edited && chunk.content.length) {\n\t\t\t// zero-length edited chunks are a special case (overlapping replacements)\n\t\t\tconst loc = getLocator(this.original)(index);\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – \"${chunk.original}\")`,\n\t\t\t);\n\t\t}\n\n\t\tconst newChunk = chunk.split(index);\n\n\t\tthis.byEnd[index] = chunk;\n\t\tthis.byStart[index] = newChunk;\n\t\tthis.byEnd[newChunk.end] = newChunk;\n\n\t\tif (chunk === this.lastChunk) this.lastChunk = newChunk;\n\n\t\tthis.lastSearchedChunk = chunk;\n\t\tif (DEBUG) this.stats.timeEnd('_split');\n\t\treturn true;\n\t}\n\n\ttoString() {\n\t\tlet str = this.intro;\n\n\t\tlet chunk = this.firstChunk;\n\t\twhile (chunk) {\n\t\t\tstr += chunk.toString();\n\t\t\tchunk = chunk.next;\n\t\t}\n\n\t\treturn str + this.outro;\n\t}\n\n\tisEmpty() {\n\t\tlet chunk = this.firstChunk;\n\t\tdo {\n\t\t\tif (\n\t\t\t\t(chunk.intro.length && chunk.intro.trim()) ||\n\t\t\t\t(chunk.content.length && chunk.content.trim()) ||\n\t\t\t\t(chunk.outro.length && chunk.outro.trim())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t} while ((chunk = chunk.next));\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\tlet chunk = this.firstChunk;\n\t\tlet length = 0;\n\t\tdo {\n\t\t\tlength += chunk.intro.length + chunk.content.length + chunk.outro.length;\n\t\t} while ((chunk = chunk.next));\n\t\treturn length;\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimEndAborted(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tthis.outro = this.outro.replace(rx, '');\n\t\tif (this.outro.length) return true;\n\n\t\tlet chunk = this.lastChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimEnd(rx);\n\n\t\t\t// if chunk was trimmed, we have a new lastChunk\n\t\t\tif (chunk.end !== end) {\n\t\t\t\tif (this.lastChunk === chunk) {\n\t\t\t\t\tthis.lastChunk = chunk.next;\n\t\t\t\t}\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.previous;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimEnd(charType) {\n\t\tthis.trimEndAborted(charType);\n\t\treturn this;\n\t}\n\ttrimStartAborted(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\n\t\tthis.intro = this.intro.replace(rx, '');\n\t\tif (this.intro.length) return true;\n\n\t\tlet chunk = this.firstChunk;\n\n\t\tdo {\n\t\t\tconst end = chunk.end;\n\t\t\tconst aborted = chunk.trimStart(rx);\n\n\t\t\tif (chunk.end !== end) {\n\t\t\t\t// special case...\n\t\t\t\tif (chunk === this.lastChunk) this.lastChunk = chunk.next;\n\n\t\t\t\tthis.byEnd[chunk.end] = chunk;\n\t\t\t\tthis.byStart[chunk.next.start] = chunk.next;\n\t\t\t\tthis.byEnd[chunk.next.end] = chunk.next;\n\t\t\t}\n\n\t\t\tif (aborted) return true;\n\t\t\tchunk = chunk.next;\n\t\t} while (chunk);\n\n\t\treturn false;\n\t}\n\n\ttrimStart(charType) {\n\t\tthis.trimStartAborted(charType);\n\t\treturn this;\n\t}\n\n\thasChanged() {\n\t\treturn this.original !== this.toString();\n\t}\n\n\t_replaceRegexp(searchValue, replacement) {\n\t\tfunction getReplacement(match, str) {\n\t\t\tif (typeof replacement === 'string') {\n\t\t\t\treturn replacement.replace(/\\$(\\$|&|\\d+)/g, (_, i) => {\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter\n\t\t\t\t\tif (i === '$') return '$';\n\t\t\t\t\tif (i === '&') return match[0];\n\t\t\t\t\tconst num = +i;\n\t\t\t\t\tif (num < match.length) return match[+i];\n\t\t\t\t\treturn `$${i}`;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn replacement(...match, match.index, str, match.groups);\n\t\t\t}\n\t\t}\n\t\tfunction matchAll(re, str) {\n\t\t\tlet match;\n\t\t\tconst matches = [];\n\t\t\twhile ((match = re.exec(str))) {\n\t\t\t\tmatches.push(match);\n\t\t\t}\n\t\t\treturn matches;\n\t\t}\n\t\tif (searchValue.global) {\n\t\t\tconst matches = matchAll(searchValue, this.original);\n\t\t\tmatches.forEach((match) => {\n\t\t\t\tif (match.index != null) {\n\t\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tconst match = this.original.match(searchValue);\n\t\t\tif (match && match.index != null) {\n\t\t\t\tconst replacement = getReplacement(match, this.original);\n\t\t\t\tif (replacement !== match[0]) {\n\t\t\t\t\tthis.overwrite(match.index, match.index + match[0].length, replacement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t_replaceString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst index = original.indexOf(string);\n\n\t\tif (index !== -1) {\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\treplacement = replacement(string, index, original);\n\t\t\t}\n\t\t\tif (string !== replacement) {\n\t\t\t\tthis.overwrite(index, index + string.length, replacement);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplace(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceString(searchValue, replacement);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n\n\t_replaceAllString(string, replacement) {\n\t\tconst { original } = this;\n\t\tconst stringLength = string.length;\n\t\tfor (\n\t\t\tlet index = original.indexOf(string);\n\t\t\tindex !== -1;\n\t\t\tindex = original.indexOf(string, index + stringLength)\n\t\t) {\n\t\t\tconst previous = original.slice(index, index + stringLength);\n\t\t\tlet _replacement = replacement;\n\t\t\tif (typeof replacement === 'function') {\n\t\t\t\t_replacement = replacement(previous, index, original);\n\t\t\t}\n\t\t\tif (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\treplaceAll(searchValue, replacement) {\n\t\tif (typeof searchValue === 'string') {\n\t\t\treturn this._replaceAllString(searchValue, replacement);\n\t\t}\n\n\t\tif (!searchValue.global) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'MagicString.prototype.replaceAll called with a non-global RegExp argument',\n\t\t\t);\n\t\t}\n\n\t\treturn this._replaceRegexp(searchValue, replacement);\n\t}\n}\n","import MagicString from './MagicString.js';\nimport SourceMap from './SourceMap.js';\nimport getRelativePath from './utils/getRelativePath.js';\nimport isObject from './utils/isObject.js';\nimport getLocator from './utils/getLocator.js';\nimport Mappings from './utils/Mappings.js';\n\nconst hasOwnProp = Object.prototype.hasOwnProperty;\n\nexport default class Bundle {\n\tconstructor(options = {}) {\n\t\tthis.intro = options.intro || '';\n\t\tthis.separator = options.separator !== undefined ? options.separator : '\\n';\n\t\tthis.sources = [];\n\t\tthis.uniqueSources = [];\n\t\tthis.uniqueSourceIndexByFilename = {};\n\t}\n\n\taddSource(source) {\n\t\tif (source instanceof MagicString) {\n\t\t\treturn this.addSource({\n\t\t\t\tcontent: source,\n\t\t\t\tfilename: source.filename,\n\t\t\t\tseparator: this.separator,\n\t\t\t});\n\t\t}\n\n\t\tif (!isObject(source) || !source.content) {\n\t\t\tthrow new Error(\n\t\t\t\t'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`',\n\t\t\t);\n\t\t}\n\n\t\t['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {\n\t\t\tif (!hasOwnProp.call(source, option)) source[option] = source.content[option];\n\t\t});\n\n\t\tif (source.separator === undefined) {\n\t\t\t// TODO there's a bunch of this sort of thing, needs cleaning up\n\t\t\tsource.separator = this.separator;\n\t\t}\n\n\t\tif (source.filename) {\n\t\t\tif (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {\n\t\t\t\tthis.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;\n\t\t\t\tthis.uniqueSources.push({ filename: source.filename, content: source.content.original });\n\t\t\t} else {\n\t\t\t\tconst uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];\n\t\t\t\tif (source.content.original !== uniqueSource.content) {\n\t\t\t\t\tthrow new Error(`Illegal source: same filename (${source.filename}), different contents`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.sources.push(source);\n\t\treturn this;\n\t}\n\n\tappend(str, options) {\n\t\tthis.addSource({\n\t\t\tcontent: new MagicString(str),\n\t\t\tseparator: (options && options.separator) || '',\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\tconst bundle = new Bundle({\n\t\t\tintro: this.intro,\n\t\t\tseparator: this.separator,\n\t\t});\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tbundle.addSource({\n\t\t\t\tfilename: source.filename,\n\t\t\t\tcontent: source.content.clone(),\n\t\t\t\tseparator: source.separator,\n\t\t\t});\n\t\t});\n\n\t\treturn bundle;\n\t}\n\n\tgenerateDecodedMap(options = {}) {\n\t\tconst names = [];\n\t\tlet x_google_ignoreList = undefined;\n\t\tthis.sources.forEach((source) => {\n\t\t\tObject.keys(source.content.storedNames).forEach((name) => {\n\t\t\t\tif (!~names.indexOf(name)) names.push(name);\n\t\t\t});\n\t\t});\n\n\t\tconst mappings = new Mappings(options.hires);\n\n\t\tif (this.intro) {\n\t\t\tmappings.advance(this.intro);\n\t\t}\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tif (i > 0) {\n\t\t\t\tmappings.advance(this.separator);\n\t\t\t}\n\n\t\t\tconst sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;\n\t\t\tconst magicString = source.content;\n\t\t\tconst locate = getLocator(magicString.original);\n\n\t\t\tif (magicString.intro) {\n\t\t\t\tmappings.advance(magicString.intro);\n\t\t\t}\n\n\t\t\tmagicString.firstChunk.eachNext((chunk) => {\n\t\t\t\tconst loc = locate(chunk.start);\n\n\t\t\t\tif (chunk.intro.length) mappings.advance(chunk.intro);\n\n\t\t\t\tif (source.filename) {\n\t\t\t\t\tif (chunk.edited) {\n\t\t\t\t\t\tmappings.addEdit(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk.content,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tchunk.storeName ? names.indexOf(chunk.original) : -1,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmappings.addUneditedChunk(\n\t\t\t\t\t\t\tsourceIndex,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tmagicString.original,\n\t\t\t\t\t\t\tloc,\n\t\t\t\t\t\t\tmagicString.sourcemapLocations,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmappings.advance(chunk.content);\n\t\t\t\t}\n\n\t\t\t\tif (chunk.outro.length) mappings.advance(chunk.outro);\n\t\t\t});\n\n\t\t\tif (magicString.outro) {\n\t\t\t\tmappings.advance(magicString.outro);\n\t\t\t}\n\n\t\t\tif (source.ignoreList && sourceIndex !== -1) {\n\t\t\t\tif (x_google_ignoreList === undefined) {\n\t\t\t\t\tx_google_ignoreList = [];\n\t\t\t\t}\n\t\t\t\tx_google_ignoreList.push(sourceIndex);\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tfile: options.file ? options.file.split(/[/\\\\]/).pop() : undefined,\n\t\t\tsources: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.file ? getRelativePath(options.file, source.filename) : source.filename;\n\t\t\t}),\n\t\t\tsourcesContent: this.uniqueSources.map((source) => {\n\t\t\t\treturn options.includeContent ? source.content : null;\n\t\t\t}),\n\t\t\tnames,\n\t\t\tmappings: mappings.raw,\n\t\t\tx_google_ignoreList,\n\t\t};\n\t}\n\n\tgenerateMap(options) {\n\t\treturn new SourceMap(this.generateDecodedMap(options));\n\t}\n\n\tgetIndentString() {\n\t\tconst indentStringCounts = {};\n\n\t\tthis.sources.forEach((source) => {\n\t\t\tconst indentStr = source.content._getRawIndentString();\n\n\t\t\tif (indentStr === null) return;\n\n\t\t\tif (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0;\n\t\t\tindentStringCounts[indentStr] += 1;\n\t\t});\n\n\t\treturn (\n\t\t\tObject.keys(indentStringCounts).sort((a, b) => {\n\t\t\t\treturn indentStringCounts[a] - indentStringCounts[b];\n\t\t\t})[0] || '\\t'\n\t\t);\n\t}\n\n\tindent(indentStr) {\n\t\tif (!arguments.length) {\n\t\t\tindentStr = this.getIndentString();\n\t\t}\n\n\t\tif (indentStr === '') return this; // noop\n\n\t\tlet trailingNewline = !this.intro || this.intro.slice(-1) === '\\n';\n\n\t\tthis.sources.forEach((source, i) => {\n\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\tconst indentStart = trailingNewline || (i > 0 && /\\r?\\n$/.test(separator));\n\n\t\t\tsource.content.indent(indentStr, {\n\t\t\t\texclude: source.indentExclusionRanges,\n\t\t\t\tindentStart, //: trailingNewline || /\\r?\\n$/.test( separator ) //true///\\r?\\n/.test( separator )\n\t\t\t});\n\n\t\t\ttrailingNewline = source.content.lastChar() === '\\n';\n\t\t});\n\n\t\tif (this.intro) {\n\t\t\tthis.intro =\n\t\t\t\tindentStr +\n\t\t\t\tthis.intro.replace(/^[^\\n]/gm, (match, index) => {\n\t\t\t\t\treturn index > 0 ? indentStr + match : match;\n\t\t\t\t});\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprepend(str) {\n\t\tthis.intro = str + this.intro;\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst body = this.sources\n\t\t\t.map((source, i) => {\n\t\t\t\tconst separator = source.separator !== undefined ? source.separator : this.separator;\n\t\t\t\tconst str = (i > 0 ? separator : '') + source.content.toString();\n\n\t\t\t\treturn str;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn this.intro + body;\n\t}\n\n\tisEmpty() {\n\t\tif (this.intro.length && this.intro.trim()) return false;\n\t\tif (this.sources.some((source) => !source.content.isEmpty())) return false;\n\t\treturn true;\n\t}\n\n\tlength() {\n\t\treturn this.sources.reduce(\n\t\t\t(length, source) => length + source.content.length(),\n\t\t\tthis.intro.length,\n\t\t);\n\t}\n\n\ttrimLines() {\n\t\treturn this.trim('[\\\\r\\\\n]');\n\t}\n\n\ttrim(charType) {\n\t\treturn this.trimStart(charType).trimEnd(charType);\n\t}\n\n\ttrimStart(charType) {\n\t\tconst rx = new RegExp('^' + (charType || '\\\\s') + '+');\n\t\tthis.intro = this.intro.replace(rx, '');\n\n\t\tif (!this.intro) {\n\t\t\tlet source;\n\t\t\tlet i = 0;\n\n\t\t\tdo {\n\t\t\t\tsource = this.sources[i++];\n\t\t\t\tif (!source) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (!source.content.trimStartAborted(charType));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttrimEnd(charType) {\n\t\tconst rx = new RegExp((charType || '\\\\s') + '+$');\n\n\t\tlet source;\n\t\tlet i = this.sources.length - 1;\n\n\t\tdo {\n\t\t\tsource = this.sources[i--];\n\t\t\tif (!source) {\n\t\t\t\tthis.intro = this.intro.replace(rx, '');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (!source.content.trimEndAborted(charType));\n\n\t\treturn this;\n\t}\n}\n","import MagicString from './MagicString.js';\nimport Bundle from './Bundle.js';\nimport SourceMap from './SourceMap.js';\n\nMagicString.Bundle = Bundle;\nMagicString.SourceMap = SourceMap;\nMagicString.default = MagicString; // work around TypeScript bug https://github.com/Rich-Harris/magic-string/pull/121\n\nexport default MagicString;\n"],"names":[],"mappings":"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","x_google_ignoreList":[2]} \ No newline at end of file diff --git a/node_modules/magic-string/package.json b/node_modules/magic-string/package.json new file mode 100644 index 0000000..5ba3ac6 --- /dev/null +++ b/node_modules/magic-string/package.json @@ -0,0 +1,67 @@ +{ + "name": "magic-string", + "version": "0.30.21", + "type": "commonjs", + "description": "Modify strings, generate sourcemaps", + "keywords": [ + "string", + "string manipulation", + "sourcemap", + "templating", + "transpilation" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Rich-Harris/magic-string.git" + }, + "license": "MIT", + "author": "Rich Harris", + "main": "./dist/magic-string.cjs.js", + "module": "./dist/magic-string.es.mjs", + "sideEffects": false, + "jsnext:main": "./dist/magic-string.es.mjs", + "types": "./dist/magic-string.cjs.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": "./dist/magic-string.es.mjs", + "require": "./dist/magic-string.cjs.js" + } + }, + "files": [ + "dist/*", + "index.d.ts", + "README.md" + ], + "devDependencies": { + "@eslint/js": "^9.38.0", + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-replace": "^6.0.2", + "benchmark": "^2.1.4", + "bumpp": "^10.3.1", + "conventional-changelog-cli": "^5.0.0", + "eslint": "^9.38.0", + "prettier": "^3.6.2", + "publint": "^0.3.15", + "rollup": "^4.52.5", + "source-map-js": "^1.2.1", + "source-map-support": "^0.5.21", + "vitest": "^4.0.2" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + }, + "scripts": { + "build": "rollup -c", + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", + "format": "prettier --single-quote --print-width 100 --use-tabs --write .", + "lint": "eslint src test && publint", + "lint:fix": "eslint src test --fix", + "release": "bumpp -x \"pnpm run changelog\" --all", + "pretest": "pnpm run build", + "test": "vitest run", + "test:dev": "vitest", + "bench": "pnpm run build && node benchmark/index.mjs", + "watch": "rollup -cw" + } +} \ No newline at end of file diff --git a/node_modules/merge-stream/LICENSE b/node_modules/merge-stream/LICENSE new file mode 100644 index 0000000..94a4c0a --- /dev/null +++ b/node_modules/merge-stream/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Stephen Sugden (stephensugden.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/merge-stream/README.md b/node_modules/merge-stream/README.md new file mode 100644 index 0000000..0d54841 --- /dev/null +++ b/node_modules/merge-stream/README.md @@ -0,0 +1,78 @@ +# merge-stream + +Merge (interleave) a bunch of streams. + +[![build status](https://secure.travis-ci.org/grncdr/merge-stream.svg?branch=master)](http://travis-ci.org/grncdr/merge-stream) + +## Synopsis + +```javascript +var stream1 = new Stream(); +var stream2 = new Stream(); + +var merged = mergeStream(stream1, stream2); + +var stream3 = new Stream(); +merged.add(stream3); +merged.isEmpty(); +//=> false +``` + +## Description + +This is adapted from [event-stream](https://github.com/dominictarr/event-stream) separated into a new module, using Streams3. + +## API + +### `mergeStream` + +Type: `function` + +Merges an arbitrary number of streams. Returns a merged stream. + +#### `merged.add` + +A method to dynamically add more sources to the stream. The argument supplied to `add` can be either a source or an array of sources. + +#### `merged.isEmpty` + +A method that tells you if the merged stream is empty. + +When a stream is "empty" (aka. no sources were added), it could not be returned to a gulp task. + +So, we could do something like this: + +```js +stream = require('merge-stream')(); +// Something like a loop to add some streams to the merge stream +// stream.add(streamA); +// stream.add(streamB); +return stream.isEmpty() ? null : stream; +``` + +## Gulp example + +An example use case for **merge-stream** is to combine parts of a task in a project's **gulpfile.js** like this: + +```js +const gulp = require('gulp'); +const htmlValidator = require('gulp-w3c-html-validator'); +const jsHint = require('gulp-jshint'); +const mergeStream = require('merge-stream'); + +function lint() { + return mergeStream( + gulp.src('src/*.html') + .pipe(htmlValidator()) + .pipe(htmlValidator.reporter()), + gulp.src('src/*.js') + .pipe(jsHint()) + .pipe(jsHint.reporter()) + ); +} +gulp.task('lint', lint); +``` + +## License + +MIT diff --git a/node_modules/merge-stream/index.js b/node_modules/merge-stream/index.js new file mode 100644 index 0000000..b1a9e1a --- /dev/null +++ b/node_modules/merge-stream/index.js @@ -0,0 +1,41 @@ +'use strict'; + +const { PassThrough } = require('stream'); + +module.exports = function (/*streams...*/) { + var sources = [] + var output = new PassThrough({objectMode: true}) + + output.setMaxListeners(0) + + output.add = add + output.isEmpty = isEmpty + + output.on('unpipe', remove) + + Array.prototype.slice.call(arguments).forEach(add) + + return output + + function add (source) { + if (Array.isArray(source)) { + source.forEach(add) + return this + } + + sources.push(source); + source.once('end', remove.bind(null, source)) + source.once('error', output.emit.bind(output, 'error')) + source.pipe(output, {end: false}) + return this + } + + function isEmpty () { + return sources.length == 0; + } + + function remove (source) { + sources = sources.filter(function (it) { return it !== source }) + if (!sources.length && output.readable) { output.end() } + } +} diff --git a/node_modules/merge-stream/package.json b/node_modules/merge-stream/package.json new file mode 100644 index 0000000..1a4c54c --- /dev/null +++ b/node_modules/merge-stream/package.json @@ -0,0 +1,19 @@ +{ + "name": "merge-stream", + "version": "2.0.0", + "description": "Create a stream that emits events from multiple other streams", + "files": [ + "index.js" + ], + "scripts": { + "test": "istanbul cover test.js && istanbul check-cover --statements 100 --branches 100" + }, + "repository": "grncdr/merge-stream", + "author": "Stephen Sugden ", + "license": "MIT", + "dependencies": {}, + "devDependencies": { + "from2": "^2.0.3", + "istanbul": "^0.4.5" + } +} diff --git a/node_modules/mimic-fn/index.d.ts b/node_modules/mimic-fn/index.d.ts new file mode 100644 index 0000000..2a72e0a --- /dev/null +++ b/node_modules/mimic-fn/index.d.ts @@ -0,0 +1,52 @@ +export interface Options { + /** + Skip modifying [non-configurable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description) instead of throwing an error. + + @default false + */ + readonly ignoreNonConfigurable?: boolean; +} + +/** +Modifies the `to` function to mimic the `from` function. Returns the `to` function. + +`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied. + +`to.toString()` will return the same as `from.toString()` but prepended with a `Wrapped with to()` comment. + +@param to - Mimicking function. +@param from - Function to mimic. +@returns The modified `to` function. + +@example +``` +import mimicFunction from 'mimic-fn'; + +function foo() {} +foo.unicorn = '🦄'; + +function wrapper() { + return foo(); +} + +console.log(wrapper.name); +//=> 'wrapper' + +mimicFunction(wrapper, foo); + +console.log(wrapper.name); +//=> 'foo' + +console.log(wrapper.unicorn); +//=> '🦄' +``` +*/ +export default function mimicFunction< + ArgumentsType extends unknown[], + ReturnType, + FunctionType extends (...arguments: ArgumentsType) => ReturnType +>( + to: (...arguments: ArgumentsType) => ReturnType, + from: FunctionType, + options?: Options, +): FunctionType; diff --git a/node_modules/mimic-fn/index.js b/node_modules/mimic-fn/index.js new file mode 100644 index 0000000..bc9ef7d --- /dev/null +++ b/node_modules/mimic-fn/index.js @@ -0,0 +1,71 @@ +const copyProperty = (to, from, property, ignoreNonConfigurable) => { + // `Function#length` should reflect the parameters of `to` not `from` since we keep its body. + // `Function#prototype` is non-writable and non-configurable so can never be modified. + if (property === 'length' || property === 'prototype') { + return; + } + + // `Function#arguments` and `Function#caller` should not be copied. They were reported to be present in `Reflect.ownKeys` for some devices in React Native (#41), so we explicitly ignore them here. + if (property === 'arguments' || property === 'caller') { + return; + } + + const toDescriptor = Object.getOwnPropertyDescriptor(to, property); + const fromDescriptor = Object.getOwnPropertyDescriptor(from, property); + + if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) { + return; + } + + Object.defineProperty(to, property, fromDescriptor); +}; + +// `Object.defineProperty()` throws if the property exists, is not configurable and either: +// - one its descriptors is changed +// - it is non-writable and its value is changed +const canCopyProperty = function (toDescriptor, fromDescriptor) { + return toDescriptor === undefined || toDescriptor.configurable || ( + toDescriptor.writable === fromDescriptor.writable && + toDescriptor.enumerable === fromDescriptor.enumerable && + toDescriptor.configurable === fromDescriptor.configurable && + (toDescriptor.writable || toDescriptor.value === fromDescriptor.value) + ); +}; + +const changePrototype = (to, from) => { + const fromPrototype = Object.getPrototypeOf(from); + if (fromPrototype === Object.getPrototypeOf(to)) { + return; + } + + Object.setPrototypeOf(to, fromPrototype); +}; + +const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`; + +const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString'); +const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name'); + +// We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected. +// We use `bind()` instead of a closure for the same reason. +// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times. +const changeToString = (to, from, name) => { + const withName = name === '' ? '' : `with ${name.trim()}() `; + const newToString = wrappedToString.bind(null, withName, from.toString()); + // Ensure `to.toString.toString` is non-enumerable and has the same `same` + Object.defineProperty(newToString, 'name', toStringName); + Object.defineProperty(to, 'toString', {...toStringDescriptor, value: newToString}); +}; + +export default function mimicFunction(to, from, {ignoreNonConfigurable = false} = {}) { + const {name} = to; + + for (const property of Reflect.ownKeys(from)) { + copyProperty(to, from, property, ignoreNonConfigurable); + } + + changePrototype(to, from); + changeToString(to, from, name); + + return to; +} diff --git a/node_modules/mimic-fn/license b/node_modules/mimic-fn/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/mimic-fn/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mimic-fn/package.json b/node_modules/mimic-fn/package.json new file mode 100644 index 0000000..d010cdd --- /dev/null +++ b/node_modules/mimic-fn/package.json @@ -0,0 +1,45 @@ +{ + "name": "mimic-fn", + "version": "4.0.0", + "description": "Make a function mimic another one", + "license": "MIT", + "repository": "sindresorhus/mimic-fn", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": "./index.js", + "engines": { + "node": ">=12" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "function", + "mimic", + "imitate", + "rename", + "copy", + "inherit", + "properties", + "name", + "func", + "fn", + "set", + "infer", + "change" + ], + "devDependencies": { + "ava": "^3.15.0", + "tsd": "^0.14.0", + "xo": "^0.38.2" + } +} diff --git a/node_modules/mimic-fn/readme.md b/node_modules/mimic-fn/readme.md new file mode 100644 index 0000000..9f571ce --- /dev/null +++ b/node_modules/mimic-fn/readme.md @@ -0,0 +1,90 @@ +mimic-fn +
+ +> Make a function mimic another one + +Useful when you wrap a function in another function and like to preserve the original name and other properties. + +## Install + +``` +$ npm install mimic-fn +``` + +## Usage + +```js +import mimicFunction from 'mimic-fn'; + +function foo() {} +foo.unicorn = '🦄'; + +function wrapper() { + return foo(); +} + +console.log(wrapper.name); +//=> 'wrapper' + +mimicFunction(wrapper, foo); + +console.log(wrapper.name); +//=> 'foo' + +console.log(wrapper.unicorn); +//=> '🦄' + +console.log(String(wrapper)); +//=> '/* Wrapped with wrapper() */\nfunction foo() {}' +``` + + +## API + +### mimicFunction(to, from, options?) + +Modifies the `to` function to mimic the `from` function. Returns the `to` function. + +`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied. + +`to.toString()` will return the same as `from.toString()` but prepended with a `Wrapped with to()` comment. + +#### to + +Type: `Function` + +Mimicking function. + +#### from + +Type: `Function` + +Function to mimic. + +#### options + +Type: `object` + +##### ignoreNonConfigurable + +Type: `boolean`\ +Default: `false` + +Skip modifying [non-configurable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description) instead of throwing an error. + +## Related + +- [rename-fn](https://github.com/sindresorhus/rename-fn) - Rename a function +- [keep-func-props](https://github.com/ehmicky/keep-func-props) - Wrap a function without changing its name and other properties + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/mlly/LICENSE b/node_modules/mlly/LICENSE new file mode 100644 index 0000000..e739abc --- /dev/null +++ b/node_modules/mlly/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Pooya Parsa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/mlly/README.md b/node_modules/mlly/README.md new file mode 100644 index 0000000..1a27fa9 --- /dev/null +++ b/node_modules/mlly/README.md @@ -0,0 +1,561 @@ +# mlly + +[![npm version][npm-version-src]][npm-version-href] +[![npm downloads][npm-downloads-src]][npm-downloads-href] +[![Codecov][codecov-src]][codecov-href] + +> Missing [ECMAScript module](https://nodejs.org/api/esm.html) utils for Node.js + +While ESM Modules are evolving in Node.js ecosystem, there are still +many required features that are still experimental or missing or needed to support ESM. This package tries to fill in the gap. + +## Usage + +Install npm package: + +```sh +# using yarn +yarn add mlly + +# using npm +npm install mlly +``` + +**Note:** Node.js 14+ is recommended. + +Import utils: + +```js +// ESM +import {} from "mlly"; + +// CommonJS +const {} = require("mlly"); +``` + +## Resolving ESM modules + +Several utilities to make ESM resolution easier: + +- Respecting [ECMAScript Resolver algorithm](https://nodejs.org/dist/latest-v14.x/docs/api/esm.html#esm_resolver_algorithm) +- Exposed from Node.js implementation +- Windows paths normalized +- Supporting custom `extensions` and `/index` resolution +- Supporting custom `conditions` +- Support resolving from multiple paths or urls + +### `resolve` / `resolveSync` + +Resolve a module by respecting [ECMAScript Resolver algorithm](https://nodejs.org/dist/latest-v14.x/docs/api/esm.html#esm_resolver_algorithm) +(using [wooorm/import-meta-resolve](https://github.com/wooorm/import-meta-resolve)). + +Additionally supports resolving without extension and `/index` similar to CommonJS. + +```js +import { resolve, resolveSync } from "mlly"; + +// file:///home/user/project/module.mjs +console.log(await resolve("./module.mjs", { url: import.meta.url })); +``` + +**Resolve options:** + +- `url`: URL or string to resolve from (default is `pwd()`) +- `conditions`: Array of conditions used for resolution algorithm (default is `['node', 'import']`) +- `extensions`: Array of additional extensions to check if import failed (default is `['.mjs', '.cjs', '.js', '.json']`) + +### `resolvePath` / `resolvePathSync` + +Similar to `resolve` but returns a path instead of URL using `fileURLToPath`. + +```js +import { resolvePath, resolveSync } from "mlly"; + +// /home/user/project/module.mjs +console.log(await resolvePath("./module.mjs", { url: import.meta.url })); +``` + +### `createResolve` + +Create a `resolve` function with defaults. + +```js +import { createResolve } from "mlly"; + +const _resolve = createResolve({ url: import.meta.url }); + +// file:///home/user/project/module.mjs +console.log(await _resolve("./module.mjs")); +``` + +**Example:** Ponyfill [import.meta.resolve](https://nodejs.org/api/esm.html#esm_import_meta_resolve_specifier_parent): + +```js +import { createResolve } from "mlly"; + +import.meta.resolve = createResolve({ url: import.meta.url }); +``` + +### `resolveImports` + +Resolve all static and dynamic imports with relative paths to full resolved path. + +```js +import { resolveImports } from "mlly"; + +// import foo from 'file:///home/user/project/bar.mjs' +console.log( + await resolveImports(`import foo from './bar.mjs'`, { url: import.meta.url }), +); +``` + +## Syntax Analyzes + +### `isValidNodeImport` + +Using various syntax detection and heuristics, this method can determine if import is a valid import or not to be imported using dynamic `import()` before hitting an error! + +When result is `false`, we usually need a to create a CommonJS require context or add specific rules to the bundler to transform dependency. + +```js +import { isValidNodeImport } from "mlly"; + +// If returns true, we are safe to use `import('some-lib')` +await isValidNodeImport("some-lib", {}); +``` + +**Algorithm:** + +- Check import protocol - If is `data:` return `true` (✅ valid) - If is not `node:`, `file:` or `data:`, return `false` ( + ❌ invalid) +- Resolve full path of import using Node.js [Resolution algorithm](https://nodejs.org/api/esm.html#resolution-algorithm) +- Check full path extension + - If is `.mjs`, `.cjs`, `.node` or `.wasm`, return `true` (✅ valid) + - If is not `.js`, return `false` (❌ invalid) + - If is matching known mixed syntax (`.esm.js`, `.es.js`, etc) return `false` ( + ❌ invalid) +- Read closest `package.json` file to resolve path +- If `type: 'module'` field is set, return `true` (✅ valid) +- Read source code of resolved path +- Try to detect CommonJS syntax usage + - If yes, return `true` (✅ valid) +- Try to detect ESM syntax usage + - if yes, return `false` ( + ❌ invalid) + +**Notes:** + +- There might be still edge cases algorithm cannot cover. It is designed with best-efforts. +- This method also allows using dynamic import of CommonJS libraries considering + Node.js has [Interoperability with CommonJS](https://nodejs.org/api/esm.html#interoperability-with-commonjs). + +### `hasESMSyntax` + +Detect if code, has usage of ESM syntax (Static `import`, ESM `export` and `import.meta` usage) + +```js +import { hasESMSyntax } from "mlly"; + +hasESMSyntax("export default foo = 123"); // true +``` + +### `hasCJSSyntax` + +Detect if code, has usage of CommonJS syntax (`exports`, `module.exports`, `require` and `global` usage) + +```js +import { hasCJSSyntax } from "mlly"; + +hasCJSSyntax("export default foo = 123"); // false +``` + +### `detectSyntax` + +Tests code against both CJS and ESM. + +`isMixed` indicates if both are detected! This is a common case with legacy packages exporting semi-compatible ESM syntax meant to be used by bundlers. + +```js +import { detectSyntax } from "mlly"; + +// { hasESM: true, hasCJS: true, isMixed: true } +detectSyntax('export default require("lodash")'); +``` + +## CommonJS Context + +### `createCommonJS` + +This utility creates a compatible CommonJS context that is missing in ECMAScript modules. + +```js +import { createCommonJS } from "mlly"; + +const { __dirname, __filename, require } = createCommonJS(import.meta.url); +``` + +Note: `require` and `require.resolve` implementation are lazy functions. [`createRequire`](https://nodejs.org/api/module.html#module_module_createrequire_filename) will be called on first usage. + +## Import/Export Analyzes + +Tools to quickly analyze ESM syntax and extract static `import`/`export` + +- Super fast Regex based implementation +- Handle most edge cases +- Find all static ESM imports +- Find all dynamic ESM imports +- Parse static import statement +- Find all named, declared and default exports + +### `findStaticImports` + +Find all static ESM imports. + +Example: + +```js +import { findStaticImports } from "mlly"; + +console.log( + findStaticImports(` +// Empty line +import foo, { bar /* foo */ } from 'baz' +`), +); +``` + +Outputs: + +```js +[ + { + type: "static", + imports: "foo, { bar /* foo */ } ", + specifier: "baz", + code: "import foo, { bar /* foo */ } from 'baz'", + start: 15, + end: 55, + }, +]; +``` + +### `parseStaticImport` + +Parse a dynamic ESM import statement previously matched by `findStaticImports`. + +Example: + +```js +import { findStaticImports, parseStaticImport } from "mlly"; + +const [match0] = findStaticImports(`import baz, { x, y as z } from 'baz'`); +console.log(parseStaticImport(match0)); +``` + +Outputs: + +```js +{ + type: 'static', + imports: 'baz, { x, y as z } ', + specifier: 'baz', + code: "import baz, { x, y as z } from 'baz'", + start: 0, + end: 36, + defaultImport: 'baz', + namespacedImport: undefined, + namedImports: { x: 'x', y: 'z' } +} +``` + +### `findDynamicImports` + +Find all dynamic ESM imports. + +Example: + +```js +import { findDynamicImports } from "mlly"; + +console.log( + findDynamicImports(` +const foo = await import('bar') +`), +); +``` + +### `findExports` + +```js +import { findExports } from "mlly"; + +console.log( + findExports(` +export const foo = 'bar' +export { bar, baz } +export default something +`), +); +``` + +Outputs: + +```js +[ + { + type: "declaration", + declaration: "const", + name: "foo", + code: "export const foo", + start: 1, + end: 17, + }, + { + type: "named", + exports: " bar, baz ", + code: "export { bar, baz }", + start: 26, + end: 45, + names: ["bar", "baz"], + }, + { type: "default", code: "export default ", start: 46, end: 61 }, +]; +``` + +### `findExportNames` + +Same as `findExports` but returns array of export names. + +```js +import { findExportNames } from "mlly"; + +// [ "foo", "bar", "baz", "default" ] +console.log( + findExportNames(` +export const foo = 'bar' +export { bar, baz } +export default something +`), +); +``` + +## `resolveModuleExportNames` + +Resolves module and reads its contents to extract possible export names using static analyzes. + +```js +import { resolveModuleExportNames } from "mlly"; + +// ["basename", "dirname", ... ] +console.log(await resolveModuleExportNames("mlly")); +``` + +## Evaluating Modules + +Set of utilities to evaluate ESM modules using `data:` imports + +- Automatic import rewrite to resolved path using static analyzes +- Allow bypass ESM Cache +- Stack-trace support +- `.json` loader + +### `evalModule` + +Transform and evaluates module code using dynamic imports. + +```js +import { evalModule } from "mlly"; + +await evalModule(`console.log("Hello World!")`); + +await evalModule( + ` + import { reverse } from './utils.mjs' + console.log(reverse('!emosewa si sj')) +`, + { url: import.meta.url }, +); +``` + +**Options:** + +- all `resolve` options +- `url`: File URL + +### `loadModule` + +Dynamically loads a module by evaluating source code. + +```js +import { loadModule } from "mlly"; + +await loadModule("./hello.mjs", { url: import.meta.url }); +``` + +Options are same as `evalModule`. + +### `transformModule` + +- Resolves all relative imports will be resolved +- All usages of `import.meta.url` will be replaced with `url` or `from` option + +```js +import { transformModule } from "mlly"; +console.log(transformModule(`console.log(import.meta.url)`), { + url: "test.mjs", +}); +``` + +Options are same as `evalModule`. + +## Other Utils + +### `fileURLToPath` + +Similar to [url.fileURLToPath](https://nodejs.org/api/url.html#url_url_fileurltopath_url) but also converts windows backslash `\` to unix slash `/` and handles if input is already a path. + +```js +import { fileURLToPath } from "mlly"; + +// /foo/bar.js +console.log(fileURLToPath("file:///foo/bar.js")); + +// C:/path +console.log(fileURLToPath("file:///C:/path/")); +``` + +### `pathToFileURL` + +Similar to [url.pathToFileURL](https://nodejs.org/api/url.html#urlpathtofileurlpath) but also handles `URL` input and returns a **string** with `file://` protocol. + +```js +import { pathToFileURL } from "mlly"; + +// /foo/bar.js +console.log(pathToFileURL("foo/bar.js")); + +// C:/path +console.log(pathToFileURL("C:\\path")); +``` + +### `normalizeid` + +Ensures id has either of `node:`, `data:`, `http:`, `https:` or `file:` protocols. + +```js +import { normalizeid } from "mlly"; + +// file:///foo/bar.js +console.log(normalizeid("/foo/bar.js")); +``` + +### `loadURL` + +Read source contents of a URL. (currently only file protocol supported) + +```js +import { resolve, loadURL } from "mlly"; + +const url = await resolve("./index.mjs", { url: import.meta.url }); +console.log(await loadURL(url)); +``` + +### `toDataURL` + +Convert code to [`data:`](https://nodejs.org/api/esm.html#esm_data_imports) URL using base64 encoding. + +```js +import { toDataURL } from "mlly"; + +console.log( + toDataURL(` + // This is an example + console.log('Hello world') +`), +); +``` + +### `interopDefault` + +Return the default export of a module at the top-level, alongside any other named exports. + +```js +// Assuming the shape { default: { foo: 'bar' }, baz: 'qux' } +import myModule from "my-module"; + +// Returns { foo: 'bar', baz: 'qux' } +console.log(interopDefault(myModule)); +``` + +**Options:** + +- `preferNamespace`: In case that `default` value exists but is not extendable (when is string for example), return input as-is (default is `false`, meaning `default`'s value is prefered even if cannot be extended) + +### `sanitizeURIComponent` + +Replace reserved characters from a segment of URI to make it compatible with [rfc2396](https://datatracker.ietf.org/doc/html/rfc2396). + +```js +import { sanitizeURIComponent } from "mlly"; + +// foo_bar +console.log(sanitizeURIComponent(`foo:bar`)); +``` + +### `sanitizeFilePath` + +Sanitize each path of a file name or path with `sanitizeURIComponent` for URI compatibility. + +```js +import { sanitizeFilePath } from "mlly"; + +// C:/te_st/_...slug_.jsx' +console.log(sanitizeFilePath("C:\\te#st\\[...slug].jsx")); +``` + +### `parseNodeModulePath` + +Parses an absolute file path in `node_modules` to three segments: + +- `dir`: Path to main directory of package +- `name`: Package name +- `subpath`: The optional package subpath + +It returns an empty object (with partial keys) if parsing fails. + +```js +import { parseNodeModulePath } from "mlly"; + +// dir: "/src/a/node_modules/" +// name: "lib" +// subpath: "./dist/index.mjs" +const { dir, name, subpath } = parseNodeModulePath( + "/src/a/node_modules/lib/dist/index.mjs", +); +``` + +### `lookupNodeModuleSubpath` + +Parses an absolute file path in `node_modules` and tries to reverse lookup (or guess) the original package exports subpath for it. + +```js +import { lookupNodeModuleSubpath } from "mlly"; + +// subpath: "./utils" +const subpath = lookupNodeModuleSubpath( + "/src/a/node_modules/lib/dist/utils.mjs", +); +``` + +## License + +[MIT](./LICENSE) - Made with 💛 + + + +[npm-version-src]: https://img.shields.io/npm/v/mlly?style=flat&colorA=18181B&colorB=F0DB4F +[npm-version-href]: https://npmjs.com/package/mlly +[npm-downloads-src]: https://img.shields.io/npm/dm/mlly?style=flat&colorA=18181B&colorB=F0DB4F +[npm-downloads-href]: https://npmjs.com/package/mlly +[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/mlly/main?style=flat&colorA=18181B&colorB=F0DB4F +[codecov-href]: https://codecov.io/gh/unjs/mlly diff --git a/node_modules/mlly/dist/index.cjs b/node_modules/mlly/dist/index.cjs new file mode 100644 index 0000000..8adc2c2 --- /dev/null +++ b/node_modules/mlly/dist/index.cjs @@ -0,0 +1,2756 @@ +'use strict'; + +const acorn = require('acorn'); +const node_module = require('node:module'); +const fs = require('node:fs'); +const ufo = require('ufo'); +const pathe = require('pathe'); +const pkgTypes = require('pkg-types'); +const node_url = require('node:url'); +const assert = require('node:assert'); +const process$1 = require('node:process'); +const path = require('node:path'); +const v8 = require('node:v8'); +const node_util = require('node:util'); + +function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } + +const fs__default = /*#__PURE__*/_interopDefaultCompat(fs); +const assert__default = /*#__PURE__*/_interopDefaultCompat(assert); +const process__default = /*#__PURE__*/_interopDefaultCompat(process$1); +const path__default = /*#__PURE__*/_interopDefaultCompat(path); +const v8__default = /*#__PURE__*/_interopDefaultCompat(v8); + +const BUILTIN_MODULES = new Set(node_module.builtinModules); +function normalizeSlash(path) { + return path.replace(/\\/g, "/"); +} +function isObject(value) { + return value !== null && typeof value === "object"; +} +function matchAll(regex, string, addition) { + const matches = []; + for (const match of string.matchAll(regex)) { + matches.push({ + ...addition, + ...match.groups, + code: match[0], + start: match.index, + end: (match.index || 0) + match[0].length + }); + } + return matches; +} +function clearImports(imports) { + return (imports || "").replace(/\/\/[^\n]*\n|\/\*.*\*\//g, "").replace(/\s+/g, " "); +} +function getImportNames(cleanedImports) { + const topLevelImports = cleanedImports.replace(/{[^}]*}/, ""); + const namespacedImport = topLevelImports.match(/\* as \s*(\S*)/)?.[1]; + const defaultImport = topLevelImports.split(",").find((index) => !/[*{}]/.test(index))?.trim() || void 0; + return { + namespacedImport, + defaultImport + }; +} + +/** + * @typedef ErrnoExceptionFields + * @property {number | undefined} [errnode] + * @property {string | undefined} [code] + * @property {string | undefined} [path] + * @property {string | undefined} [syscall] + * @property {string | undefined} [url] + * + * @typedef {Error & ErrnoExceptionFields} ErrnoException + */ + + +const own$1 = {}.hasOwnProperty; + +const classRegExp = /^([A-Z][a-z\d]*)+$/; +// Sorted by a rough estimate on most frequently used entries. +const kTypes = new Set([ + 'string', + 'function', + 'number', + 'object', + // Accept 'Function' and 'Object' as alternative to the lower cased version. + 'Function', + 'Object', + 'boolean', + 'bigint', + 'symbol' +]); + +const codes = {}; + +/** + * Create a list string in the form like 'A and B' or 'A, B, ..., and Z'. + * We cannot use Intl.ListFormat because it's not available in + * --without-intl builds. + * + * @param {Array} array + * An array of strings. + * @param {string} [type] + * The list type to be inserted before the last element. + * @returns {string} + */ +function formatList(array, type = 'and') { + return array.length < 3 + ? array.join(` ${type} `) + : `${array.slice(0, -1).join(', ')}, ${type} ${array[array.length - 1]}` +} + +/** @type {Map} */ +const messages = new Map(); +const nodeInternalPrefix = '__node_internal_'; +/** @type {number} */ +let userStackTraceLimit; + +codes.ERR_INVALID_ARG_TYPE = createError( + 'ERR_INVALID_ARG_TYPE', + /** + * @param {string} name + * @param {Array | string} expected + * @param {unknown} actual + */ + (name, expected, actual) => { + assert__default.ok(typeof name === 'string', "'name' must be a string"); + if (!Array.isArray(expected)) { + expected = [expected]; + } + + let message = 'The '; + if (name.endsWith(' argument')) { + // For cases like 'first argument' + message += `${name} `; + } else { + const type = name.includes('.') ? 'property' : 'argument'; + message += `"${name}" ${type} `; + } + + message += 'must be '; + + /** @type {Array} */ + const types = []; + /** @type {Array} */ + const instances = []; + /** @type {Array} */ + const other = []; + + for (const value of expected) { + assert__default.ok( + typeof value === 'string', + 'All expected entries have to be of type string' + ); + + if (kTypes.has(value)) { + types.push(value.toLowerCase()); + } else if (classRegExp.exec(value) === null) { + assert__default.ok( + value !== 'object', + 'The value "object" should be written as "Object"' + ); + other.push(value); + } else { + instances.push(value); + } + } + + // Special handle `object` in case other instances are allowed to outline + // the differences between each other. + if (instances.length > 0) { + const pos = types.indexOf('object'); + if (pos !== -1) { + types.slice(pos, 1); + instances.push('Object'); + } + } + + if (types.length > 0) { + message += `${types.length > 1 ? 'one of type' : 'of type'} ${formatList( + types, + 'or' + )}`; + if (instances.length > 0 || other.length > 0) message += ' or '; + } + + if (instances.length > 0) { + message += `an instance of ${formatList(instances, 'or')}`; + if (other.length > 0) message += ' or '; + } + + if (other.length > 0) { + if (other.length > 1) { + message += `one of ${formatList(other, 'or')}`; + } else { + if (other[0].toLowerCase() !== other[0]) message += 'an '; + message += `${other[0]}`; + } + } + + message += `. Received ${determineSpecificType(actual)}`; + + return message + }, + TypeError +); + +codes.ERR_INVALID_MODULE_SPECIFIER = createError( + 'ERR_INVALID_MODULE_SPECIFIER', + /** + * @param {string} request + * @param {string} reason + * @param {string} [base] + */ + (request, reason, base = undefined) => { + return `Invalid module "${request}" ${reason}${ + base ? ` imported from ${base}` : '' + }` + }, + TypeError +); + +codes.ERR_INVALID_PACKAGE_CONFIG = createError( + 'ERR_INVALID_PACKAGE_CONFIG', + /** + * @param {string} path + * @param {string} [base] + * @param {string} [message] + */ + (path, base, message) => { + return `Invalid package config ${path}${ + base ? ` while importing ${base}` : '' + }${message ? `. ${message}` : ''}` + }, + Error +); + +codes.ERR_INVALID_PACKAGE_TARGET = createError( + 'ERR_INVALID_PACKAGE_TARGET', + /** + * @param {string} packagePath + * @param {string} key + * @param {unknown} target + * @param {boolean} [isImport=false] + * @param {string} [base] + */ + (packagePath, key, target, isImport = false, base = undefined) => { + const relatedError = + typeof target === 'string' && + !isImport && + target.length > 0 && + !target.startsWith('./'); + if (key === '.') { + assert__default.ok(isImport === false); + return ( + `Invalid "exports" main target ${JSON.stringify(target)} defined ` + + `in the package config ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }${relatedError ? '; targets must start with "./"' : ''}` + ) + } + + return `Invalid "${ + isImport ? 'imports' : 'exports' + }" target ${JSON.stringify( + target + )} defined for '${key}' in the package config ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }${relatedError ? '; targets must start with "./"' : ''}` + }, + Error +); + +codes.ERR_MODULE_NOT_FOUND = createError( + 'ERR_MODULE_NOT_FOUND', + /** + * @param {string} path + * @param {string} base + * @param {boolean} [exactUrl] + */ + (path, base, exactUrl = false) => { + return `Cannot find ${ + exactUrl ? 'module' : 'package' + } '${path}' imported from ${base}` + }, + Error +); + +codes.ERR_NETWORK_IMPORT_DISALLOWED = createError( + 'ERR_NETWORK_IMPORT_DISALLOWED', + "import of '%s' by %s is not supported: %s", + Error +); + +codes.ERR_PACKAGE_IMPORT_NOT_DEFINED = createError( + 'ERR_PACKAGE_IMPORT_NOT_DEFINED', + /** + * @param {string} specifier + * @param {string} packagePath + * @param {string} base + */ + (specifier, packagePath, base) => { + return `Package import specifier "${specifier}" is not defined${ + packagePath ? ` in package ${packagePath}package.json` : '' + } imported from ${base}` + }, + TypeError +); + +codes.ERR_PACKAGE_PATH_NOT_EXPORTED = createError( + 'ERR_PACKAGE_PATH_NOT_EXPORTED', + /** + * @param {string} packagePath + * @param {string} subpath + * @param {string} [base] + */ + (packagePath, subpath, base = undefined) => { + if (subpath === '.') + return `No "exports" main defined in ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }` + return `Package subpath '${subpath}' is not defined by "exports" in ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }` + }, + Error +); + +codes.ERR_UNSUPPORTED_DIR_IMPORT = createError( + 'ERR_UNSUPPORTED_DIR_IMPORT', + "Directory import '%s' is not supported " + + 'resolving ES modules imported from %s', + Error +); + +codes.ERR_UNSUPPORTED_RESOLVE_REQUEST = createError( + 'ERR_UNSUPPORTED_RESOLVE_REQUEST', + 'Failed to resolve module specifier "%s" from "%s": Invalid relative URL or base scheme is not hierarchical.', + TypeError +); + +codes.ERR_UNKNOWN_FILE_EXTENSION = createError( + 'ERR_UNKNOWN_FILE_EXTENSION', + /** + * @param {string} extension + * @param {string} path + */ + (extension, path) => { + return `Unknown file extension "${extension}" for ${path}` + }, + TypeError +); + +codes.ERR_INVALID_ARG_VALUE = createError( + 'ERR_INVALID_ARG_VALUE', + /** + * @param {string} name + * @param {unknown} value + * @param {string} [reason='is invalid'] + */ + (name, value, reason = 'is invalid') => { + let inspected = node_util.inspect(value); + + if (inspected.length > 128) { + inspected = `${inspected.slice(0, 128)}...`; + } + + const type = name.includes('.') ? 'property' : 'argument'; + + return `The ${type} '${name}' ${reason}. Received ${inspected}` + }, + TypeError + // Note: extra classes have been shaken out. + // , RangeError +); + +/** + * Utility function for registering the error codes. Only used here. Exported + * *only* to allow for testing. + * @param {string} sym + * @param {MessageFunction | string} value + * @param {ErrorConstructor} constructor + * @returns {new (...parameters: Array) => Error} + */ +function createError(sym, value, constructor) { + // Special case for SystemError that formats the error message differently + // The SystemErrors only have SystemError as their base classes. + messages.set(sym, value); + + return makeNodeErrorWithCode(constructor, sym) +} + +/** + * @param {ErrorConstructor} Base + * @param {string} key + * @returns {ErrorConstructor} + */ +function makeNodeErrorWithCode(Base, key) { + // @ts-expect-error It’s a Node error. + return NodeError + /** + * @param {Array} parameters + */ + function NodeError(...parameters) { + const limit = Error.stackTraceLimit; + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const error = new Base(); + // Reset the limit and setting the name property. + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; + const message = getMessage(key, parameters, error); + Object.defineProperties(error, { + // Note: no need to implement `kIsNodeError` symbol, would be hard, + // probably. + message: { + value: message, + enumerable: false, + writable: true, + configurable: true + }, + toString: { + /** @this {Error} */ + value() { + return `${this.name} [${key}]: ${this.message}` + }, + enumerable: false, + writable: true, + configurable: true + } + }); + + captureLargerStackTrace(error); + // @ts-expect-error It’s a Node error. + error.code = key; + return error + } +} + +/** + * @returns {boolean} + */ +function isErrorStackTraceLimitWritable() { + // Do no touch Error.stackTraceLimit as V8 would attempt to install + // it again during deserialization. + try { + if (v8__default.startupSnapshot.isBuildingSnapshot()) { + return false + } + } catch {} + + const desc = Object.getOwnPropertyDescriptor(Error, 'stackTraceLimit'); + if (desc === undefined) { + return Object.isExtensible(Error) + } + + return own$1.call(desc, 'writable') && desc.writable !== undefined + ? desc.writable + : desc.set !== undefined +} + +/** + * This function removes unnecessary frames from Node.js core errors. + * @template {(...parameters: unknown[]) => unknown} T + * @param {T} wrappedFunction + * @returns {T} + */ +function hideStackFrames(wrappedFunction) { + // We rename the functions that will be hidden to cut off the stacktrace + // at the outermost one + const hidden = nodeInternalPrefix + wrappedFunction.name; + Object.defineProperty(wrappedFunction, 'name', {value: hidden}); + return wrappedFunction +} + +const captureLargerStackTrace = hideStackFrames( + /** + * @param {Error} error + * @returns {Error} + */ + // @ts-expect-error: fine + function (error) { + const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); + if (stackTraceLimitIsWritable) { + userStackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = Number.POSITIVE_INFINITY; + } + + Error.captureStackTrace(error); + + // Reset the limit + if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; + + return error + } +); + +/** + * @param {string} key + * @param {Array} parameters + * @param {Error} self + * @returns {string} + */ +function getMessage(key, parameters, self) { + const message = messages.get(key); + assert__default.ok(message !== undefined, 'expected `message` to be found'); + + if (typeof message === 'function') { + assert__default.ok( + message.length <= parameters.length, // Default options do not count. + `Code: ${key}; The provided arguments length (${parameters.length}) does not ` + + `match the required ones (${message.length}).` + ); + return Reflect.apply(message, self, parameters) + } + + const regex = /%[dfijoOs]/g; + let expectedLength = 0; + while (regex.exec(message) !== null) expectedLength++; + assert__default.ok( + expectedLength === parameters.length, + `Code: ${key}; The provided arguments length (${parameters.length}) does not ` + + `match the required ones (${expectedLength}).` + ); + if (parameters.length === 0) return message + + parameters.unshift(message); + return Reflect.apply(node_util.format, null, parameters) +} + +/** + * Determine the specific type of a value for type-mismatch errors. + * @param {unknown} value + * @returns {string} + */ +function determineSpecificType(value) { + if (value === null || value === undefined) { + return String(value) + } + + if (typeof value === 'function' && value.name) { + return `function ${value.name}` + } + + if (typeof value === 'object') { + if (value.constructor && value.constructor.name) { + return `an instance of ${value.constructor.name}` + } + + return `${node_util.inspect(value, {depth: -1})}` + } + + let inspected = node_util.inspect(value, {colors: false}); + + if (inspected.length > 28) { + inspected = `${inspected.slice(0, 25)}...`; + } + + return `type ${typeof value} (${inspected})` +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. +// Removed the native dependency. +// Also: no need to cache, we do that in resolve already. + + +const hasOwnProperty$1 = {}.hasOwnProperty; + +const {ERR_INVALID_PACKAGE_CONFIG: ERR_INVALID_PACKAGE_CONFIG$1} = codes; + +/** @type {Map} */ +const cache = new Map(); + +/** + * @param {string} jsonPath + * @param {{specifier: URL | string, base?: URL}} options + * @returns {PackageConfig} + */ +function read(jsonPath, {base, specifier}) { + const existing = cache.get(jsonPath); + + if (existing) { + return existing + } + + /** @type {string | undefined} */ + let string; + + try { + string = fs__default.readFileSync(path__default.toNamespacedPath(jsonPath), 'utf8'); + } catch (error) { + const exception = /** @type {ErrnoException} */ (error); + + if (exception.code !== 'ENOENT') { + throw exception + } + } + + /** @type {PackageConfig} */ + const result = { + exists: false, + pjsonPath: jsonPath, + main: undefined, + name: undefined, + type: 'none', // Ignore unknown types for forwards compatibility + exports: undefined, + imports: undefined + }; + + if (string !== undefined) { + /** @type {Record} */ + let parsed; + + try { + parsed = JSON.parse(string); + } catch (error_) { + const cause = /** @type {ErrnoException} */ (error_); + const error = new ERR_INVALID_PACKAGE_CONFIG$1( + jsonPath, + (base ? `"${specifier}" from ` : '') + node_url.fileURLToPath(base || specifier), + cause.message + ); + error.cause = cause; + throw error + } + + result.exists = true; + + if ( + hasOwnProperty$1.call(parsed, 'name') && + typeof parsed.name === 'string' + ) { + result.name = parsed.name; + } + + if ( + hasOwnProperty$1.call(parsed, 'main') && + typeof parsed.main === 'string' + ) { + result.main = parsed.main; + } + + if (hasOwnProperty$1.call(parsed, 'exports')) { + // @ts-expect-error: assume valid. + result.exports = parsed.exports; + } + + if (hasOwnProperty$1.call(parsed, 'imports')) { + // @ts-expect-error: assume valid. + result.imports = parsed.imports; + } + + // Ignore unknown types for forwards compatibility + if ( + hasOwnProperty$1.call(parsed, 'type') && + (parsed.type === 'commonjs' || parsed.type === 'module') + ) { + result.type = parsed.type; + } + } + + cache.set(jsonPath, result); + + return result +} + +/** + * @param {URL | string} resolved + * @returns {PackageConfig} + */ +function getPackageScopeConfig(resolved) { + // Note: in Node, this is now a native module. + let packageJSONUrl = new URL('package.json', resolved); + + while (true) { + const packageJSONPath = packageJSONUrl.pathname; + if (packageJSONPath.endsWith('node_modules/package.json')) { + break + } + + const packageConfig = read(node_url.fileURLToPath(packageJSONUrl), { + specifier: resolved + }); + + if (packageConfig.exists) { + return packageConfig + } + + const lastPackageJSONUrl = packageJSONUrl; + packageJSONUrl = new URL('../package.json', packageJSONUrl); + + // Terminates at root where ../package.json equals ../../package.json + // (can't just check "/package.json" for Windows support). + if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) { + break + } + } + + const packageJSONPath = node_url.fileURLToPath(packageJSONUrl); + // ^^ Note: in Node, this is now a native module. + + return { + pjsonPath: packageJSONPath, + exists: false, + type: 'none' + } +} + +/** + * Returns the package type for a given URL. + * @param {URL} url - The URL to get the package type for. + * @returns {PackageType} + */ +function getPackageType(url) { + // To do @anonrig: Write a C++ function that returns only "type". + return getPackageScopeConfig(url).type +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +const {ERR_UNKNOWN_FILE_EXTENSION} = codes; + +const hasOwnProperty = {}.hasOwnProperty; + +/** @type {Record} */ +const extensionFormatMap = { + // @ts-expect-error: hush. + __proto__: null, + '.cjs': 'commonjs', + '.js': 'module', + '.json': 'json', + '.mjs': 'module' +}; + +/** + * @param {string | null} mime + * @returns {string | null} + */ +function mimeToFormat(mime) { + if ( + mime && + /\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?/i.test(mime) + ) + return 'module' + if (mime === 'application/json') return 'json' + return null +} + +/** + * @callback ProtocolHandler + * @param {URL} parsed + * @param {{parentURL: string, source?: Buffer}} context + * @param {boolean} ignoreErrors + * @returns {string | null | void} + */ + +/** + * @type {Record} + */ +const protocolHandlers = { + // @ts-expect-error: hush. + __proto__: null, + 'data:': getDataProtocolModuleFormat, + 'file:': getFileProtocolModuleFormat, + 'http:': getHttpProtocolModuleFormat, + 'https:': getHttpProtocolModuleFormat, + 'node:'() { + return 'builtin' + } +}; + +/** + * @param {URL} parsed + */ +function getDataProtocolModuleFormat(parsed) { + const {1: mime} = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec( + parsed.pathname + ) || [null, null, null]; + return mimeToFormat(mime) +} + +/** + * Returns the file extension from a URL. + * + * Should give similar result to + * `require('node:path').extname(require('node:url').fileURLToPath(url))` + * when used with a `file:` URL. + * + * @param {URL} url + * @returns {string} + */ +function extname(url) { + const pathname = url.pathname; + let index = pathname.length; + + while (index--) { + const code = pathname.codePointAt(index); + + if (code === 47 /* `/` */) { + return '' + } + + if (code === 46 /* `.` */) { + return pathname.codePointAt(index - 1) === 47 /* `/` */ + ? '' + : pathname.slice(index) + } + } + + return '' +} + +/** + * @type {ProtocolHandler} + */ +function getFileProtocolModuleFormat(url, _context, ignoreErrors) { + const value = extname(url); + + if (value === '.js') { + const packageType = getPackageType(url); + + if (packageType !== 'none') { + return packageType + } + + return 'commonjs' + } + + if (value === '') { + const packageType = getPackageType(url); + + // Legacy behavior + if (packageType === 'none' || packageType === 'commonjs') { + return 'commonjs' + } + + // Note: we don’t implement WASM, so we don’t need + // `getFormatOfExtensionlessFile` from `formats`. + return 'module' + } + + const format = extensionFormatMap[value]; + if (format) return format + + // Explicit undefined return indicates load hook should rerun format check + if (ignoreErrors) { + return undefined + } + + const filepath = node_url.fileURLToPath(url); + throw new ERR_UNKNOWN_FILE_EXTENSION(value, filepath) +} + +function getHttpProtocolModuleFormat() { + // To do: HTTPS imports. +} + +/** + * @param {URL} url + * @param {{parentURL: string}} context + * @returns {string | null} + */ +function defaultGetFormatWithoutErrors(url, context) { + const protocol = url.protocol; + + if (!hasOwnProperty.call(protocolHandlers, protocol)) { + return null + } + + return protocolHandlers[protocol](url, context, true) || null +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +// In Node itself these values are populated from CLI arguments, before any +// user code runs. +// Here we just define the defaults. +const DEFAULT_CONDITIONS = Object.freeze(['node', 'import']); +const DEFAULT_CONDITIONS_SET$1 = new Set(DEFAULT_CONDITIONS); + +/** + * Returns the default conditions for ES module loading, as a Set. + */ +function getDefaultConditionsSet() { + return DEFAULT_CONDITIONS_SET$1 +} + +/** + * @param {Array} [conditions] + * @returns {Set} + */ +function getConditionsSet(conditions) { + + return getDefaultConditionsSet() +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +const RegExpPrototypeSymbolReplace = RegExp.prototype[Symbol.replace]; + +const { + ERR_INVALID_MODULE_SPECIFIER, + ERR_INVALID_PACKAGE_CONFIG, + ERR_INVALID_PACKAGE_TARGET, + ERR_MODULE_NOT_FOUND, + ERR_PACKAGE_IMPORT_NOT_DEFINED, + ERR_PACKAGE_PATH_NOT_EXPORTED, + ERR_UNSUPPORTED_DIR_IMPORT, + ERR_UNSUPPORTED_RESOLVE_REQUEST +} = codes; + +const own = {}.hasOwnProperty; + +const invalidSegmentRegEx = + /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))?(\\|\/|$)/i; +const deprecatedInvalidSegmentRegEx = + /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i; +const invalidPackageNameRegEx = /^\.|%|\\/; +const patternRegEx = /\*/g; +const encodedSeparatorRegEx = /%2f|%5c/i; +/** @type {Set} */ +const emittedPackageWarnings = new Set(); + +const doubleSlashRegEx = /[/\\]{2}/; + +/** + * + * @param {string} target + * @param {string} request + * @param {string} match + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} base + * @param {boolean} isTarget + */ +function emitInvalidSegmentDeprecation( + target, + request, + match, + packageJsonUrl, + internal, + base, + isTarget +) { + // @ts-expect-error: apparently it does exist, TS. + if (process__default.noDeprecation) { + return + } + + const pjsonPath = node_url.fileURLToPath(packageJsonUrl); + const double = doubleSlashRegEx.exec(isTarget ? target : request) !== null; + process__default.emitWarning( + `Use of deprecated ${ + double ? 'double slash' : 'leading or trailing slash matching' + } resolving "${target}" for module ` + + `request "${request}" ${ + request === match ? '' : `matched to "${match}" ` + }in the "${ + internal ? 'imports' : 'exports' + }" field module resolution of the package at ${pjsonPath}${ + base ? ` imported from ${node_url.fileURLToPath(base)}` : '' + }.`, + 'DeprecationWarning', + 'DEP0166' + ); +} + +/** + * @param {URL} url + * @param {URL} packageJsonUrl + * @param {URL} base + * @param {string} [main] + * @returns {void} + */ +function emitLegacyIndexDeprecation(url, packageJsonUrl, base, main) { + // @ts-expect-error: apparently it does exist, TS. + if (process__default.noDeprecation) { + return + } + + const format = defaultGetFormatWithoutErrors(url, {parentURL: base.href}); + if (format !== 'module') return + const urlPath = node_url.fileURLToPath(url.href); + const packagePath = node_url.fileURLToPath(new URL('.', packageJsonUrl)); + const basePath = node_url.fileURLToPath(base); + if (!main) { + process__default.emitWarning( + `No "main" or "exports" field defined in the package.json for ${packagePath} resolving the main entry point "${urlPath.slice( + packagePath.length + )}", imported from ${basePath}.\nDefault "index" lookups for the main are deprecated for ES modules.`, + 'DeprecationWarning', + 'DEP0151' + ); + } else if (path__default.resolve(packagePath, main) !== urlPath) { + process__default.emitWarning( + `Package ${packagePath} has a "main" field set to "${main}", ` + + `excluding the full filename and extension to the resolved file at "${urlPath.slice( + packagePath.length + )}", imported from ${basePath}.\n Automatic extension resolution of the "main" field is ` + + 'deprecated for ES modules.', + 'DeprecationWarning', + 'DEP0151' + ); + } +} + +/** + * @param {string} path + * @returns {Stats | undefined} + */ +function tryStatSync(path) { + // Note: from Node 15 onwards we can use `throwIfNoEntry: false` instead. + try { + return fs.statSync(path) + } catch { + // Note: in Node code this returns `new Stats`, + // but in Node 22 that’s marked as a deprecated internal API. + // Which, well, we kinda are, but still to prevent that warning, + // just yield `undefined`. + } +} + +/** + * Legacy CommonJS main resolution: + * 1. let M = pkg_url + (json main field) + * 2. TRY(M, M.js, M.json, M.node) + * 3. TRY(M/index.js, M/index.json, M/index.node) + * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) + * 5. NOT_FOUND + * + * @param {URL} url + * @returns {boolean} + */ +function fileExists(url) { + const stats = fs.statSync(url, {throwIfNoEntry: false}); + const isFile = stats ? stats.isFile() : undefined; + return isFile === null || isFile === undefined ? false : isFile +} + +/** + * @param {URL} packageJsonUrl + * @param {PackageConfig} packageConfig + * @param {URL} base + * @returns {URL} + */ +function legacyMainResolve(packageJsonUrl, packageConfig, base) { + /** @type {URL | undefined} */ + let guess; + if (packageConfig.main !== undefined) { + guess = new URL(packageConfig.main, packageJsonUrl); + // Note: fs check redundances will be handled by Descriptor cache here. + if (fileExists(guess)) return guess + + const tries = [ + `./${packageConfig.main}.js`, + `./${packageConfig.main}.json`, + `./${packageConfig.main}.node`, + `./${packageConfig.main}/index.js`, + `./${packageConfig.main}/index.json`, + `./${packageConfig.main}/index.node` + ]; + let i = -1; + + while (++i < tries.length) { + guess = new URL(tries[i], packageJsonUrl); + if (fileExists(guess)) break + guess = undefined; + } + + if (guess) { + emitLegacyIndexDeprecation( + guess, + packageJsonUrl, + base, + packageConfig.main + ); + return guess + } + // Fallthrough. + } + + const tries = ['./index.js', './index.json', './index.node']; + let i = -1; + + while (++i < tries.length) { + guess = new URL(tries[i], packageJsonUrl); + if (fileExists(guess)) break + guess = undefined; + } + + if (guess) { + emitLegacyIndexDeprecation(guess, packageJsonUrl, base, packageConfig.main); + return guess + } + + // Not found. + throw new ERR_MODULE_NOT_FOUND( + node_url.fileURLToPath(new URL('.', packageJsonUrl)), + node_url.fileURLToPath(base) + ) +} + +/** + * @param {URL} resolved + * @param {URL} base + * @param {boolean} [preserveSymlinks] + * @returns {URL} + */ +function finalizeResolution(resolved, base, preserveSymlinks) { + if (encodedSeparatorRegEx.exec(resolved.pathname) !== null) { + throw new ERR_INVALID_MODULE_SPECIFIER( + resolved.pathname, + 'must not include encoded "/" or "\\" characters', + node_url.fileURLToPath(base) + ) + } + + /** @type {string} */ + let filePath; + + try { + filePath = node_url.fileURLToPath(resolved); + } catch (error) { + const cause = /** @type {ErrnoException} */ (error); + Object.defineProperty(cause, 'input', {value: String(resolved)}); + Object.defineProperty(cause, 'module', {value: String(base)}); + throw cause + } + + const stats = tryStatSync( + filePath.endsWith('/') ? filePath.slice(-1) : filePath + ); + + if (stats && stats.isDirectory()) { + const error = new ERR_UNSUPPORTED_DIR_IMPORT(filePath, node_url.fileURLToPath(base)); + // @ts-expect-error Add this for `import.meta.resolve`. + error.url = String(resolved); + throw error + } + + if (!stats || !stats.isFile()) { + const error = new ERR_MODULE_NOT_FOUND( + filePath || resolved.pathname, + base && node_url.fileURLToPath(base), + true + ); + // @ts-expect-error Add this for `import.meta.resolve`. + error.url = String(resolved); + throw error + } + + { + const real = fs.realpathSync(filePath); + const {search, hash} = resolved; + resolved = node_url.pathToFileURL(real + (filePath.endsWith(path__default.sep) ? '/' : '')); + resolved.search = search; + resolved.hash = hash; + } + + return resolved +} + +/** + * @param {string} specifier + * @param {URL | undefined} packageJsonUrl + * @param {URL} base + * @returns {Error} + */ +function importNotDefined(specifier, packageJsonUrl, base) { + return new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, + packageJsonUrl && node_url.fileURLToPath(new URL('.', packageJsonUrl)), + node_url.fileURLToPath(base) + ) +} + +/** + * @param {string} subpath + * @param {URL} packageJsonUrl + * @param {URL} base + * @returns {Error} + */ +function exportsNotFound(subpath, packageJsonUrl, base) { + return new ERR_PACKAGE_PATH_NOT_EXPORTED( + node_url.fileURLToPath(new URL('.', packageJsonUrl)), + subpath, + base && node_url.fileURLToPath(base) + ) +} + +/** + * @param {string} request + * @param {string} match + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} [base] + * @returns {never} + */ +function throwInvalidSubpath(request, match, packageJsonUrl, internal, base) { + const reason = `request is not a valid match in pattern "${match}" for the "${ + internal ? 'imports' : 'exports' + }" resolution of ${node_url.fileURLToPath(packageJsonUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER( + request, + reason, + base && node_url.fileURLToPath(base) + ) +} + +/** + * @param {string} subpath + * @param {unknown} target + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} [base] + * @returns {Error} + */ +function invalidPackageTarget(subpath, target, packageJsonUrl, internal, base) { + target = + typeof target === 'object' && target !== null + ? JSON.stringify(target, null, '') + : `${target}`; + + return new ERR_INVALID_PACKAGE_TARGET( + node_url.fileURLToPath(new URL('.', packageJsonUrl)), + subpath, + target, + internal, + base && node_url.fileURLToPath(base) + ) +} + +/** + * @param {string} target + * @param {string} subpath + * @param {string} match + * @param {URL} packageJsonUrl + * @param {URL} base + * @param {boolean} pattern + * @param {boolean} internal + * @param {boolean} isPathMap + * @param {Set | undefined} conditions + * @returns {URL} + */ +function resolvePackageTargetString( + target, + subpath, + match, + packageJsonUrl, + base, + pattern, + internal, + isPathMap, + conditions +) { + if (subpath !== '' && !pattern && target[target.length - 1] !== '/') + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + + if (!target.startsWith('./')) { + if (internal && !target.startsWith('../') && !target.startsWith('/')) { + let isURL = false; + + try { + new URL(target); + isURL = true; + } catch { + // Continue regardless of error. + } + + if (!isURL) { + const exportTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target + subpath; + + return packageResolve(exportTarget, packageJsonUrl, conditions) + } + } + + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + } + + if (invalidSegmentRegEx.exec(target.slice(2)) !== null) { + if (deprecatedInvalidSegmentRegEx.exec(target.slice(2)) === null) { + if (!isPathMap) { + const request = pattern + ? match.replace('*', () => subpath) + : match + subpath; + const resolvedTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target; + emitInvalidSegmentDeprecation( + resolvedTarget, + request, + match, + packageJsonUrl, + internal, + base, + true + ); + } + } else { + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + } + } + + const resolved = new URL(target, packageJsonUrl); + const resolvedPath = resolved.pathname; + const packagePath = new URL('.', packageJsonUrl).pathname; + + if (!resolvedPath.startsWith(packagePath)) + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + + if (subpath === '') return resolved + + if (invalidSegmentRegEx.exec(subpath) !== null) { + const request = pattern + ? match.replace('*', () => subpath) + : match + subpath; + if (deprecatedInvalidSegmentRegEx.exec(subpath) === null) { + if (!isPathMap) { + const resolvedTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target; + emitInvalidSegmentDeprecation( + resolvedTarget, + request, + match, + packageJsonUrl, + internal, + base, + false + ); + } + } else { + throwInvalidSubpath(request, match, packageJsonUrl, internal, base); + } + } + + if (pattern) { + return new URL( + RegExpPrototypeSymbolReplace.call( + patternRegEx, + resolved.href, + () => subpath + ) + ) + } + + return new URL(subpath, resolved) +} + +/** + * @param {string} key + * @returns {boolean} + */ +function isArrayIndex(key) { + const keyNumber = Number(key); + if (`${keyNumber}` !== key) return false + return keyNumber >= 0 && keyNumber < 0xff_ff_ff_ff +} + +/** + * @param {URL} packageJsonUrl + * @param {unknown} target + * @param {string} subpath + * @param {string} packageSubpath + * @param {URL} base + * @param {boolean} pattern + * @param {boolean} internal + * @param {boolean} isPathMap + * @param {Set | undefined} conditions + * @returns {URL | null} + */ +function resolvePackageTarget( + packageJsonUrl, + target, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions +) { + if (typeof target === 'string') { + return resolvePackageTargetString( + target, + subpath, + packageSubpath, + packageJsonUrl, + base, + pattern, + internal, + isPathMap, + conditions + ) + } + + if (Array.isArray(target)) { + /** @type {Array} */ + const targetList = target; + if (targetList.length === 0) return null + + /** @type {ErrnoException | null | undefined} */ + let lastException; + let i = -1; + + while (++i < targetList.length) { + const targetItem = targetList[i]; + /** @type {URL | null} */ + let resolveResult; + try { + resolveResult = resolvePackageTarget( + packageJsonUrl, + targetItem, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions + ); + } catch (error) { + const exception = /** @type {ErrnoException} */ (error); + lastException = exception; + if (exception.code === 'ERR_INVALID_PACKAGE_TARGET') continue + throw error + } + + if (resolveResult === undefined) continue + + if (resolveResult === null) { + lastException = null; + continue + } + + return resolveResult + } + + if (lastException === undefined || lastException === null) { + return null + } + + throw lastException + } + + if (typeof target === 'object' && target !== null) { + const keys = Object.getOwnPropertyNames(target); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + if (isArrayIndex(key)) { + throw new ERR_INVALID_PACKAGE_CONFIG( + node_url.fileURLToPath(packageJsonUrl), + base, + '"exports" cannot contain numeric property keys.' + ) + } + } + + i = -1; + + while (++i < keys.length) { + const key = keys[i]; + if (key === 'default' || (conditions && conditions.has(key))) { + // @ts-expect-error: indexable. + const conditionalTarget = /** @type {unknown} */ (target[key]); + const resolveResult = resolvePackageTarget( + packageJsonUrl, + conditionalTarget, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions + ); + if (resolveResult === undefined) continue + return resolveResult + } + } + + return null + } + + if (target === null) { + return null + } + + throw invalidPackageTarget( + packageSubpath, + target, + packageJsonUrl, + internal, + base + ) +} + +/** + * @param {unknown} exports + * @param {URL} packageJsonUrl + * @param {URL} base + * @returns {boolean} + */ +function isConditionalExportsMainSugar(exports$1, packageJsonUrl, base) { + if (typeof exports$1 === 'string' || Array.isArray(exports$1)) return true + if (typeof exports$1 !== 'object' || exports$1 === null) return false + + const keys = Object.getOwnPropertyNames(exports$1); + let isConditionalSugar = false; + let i = 0; + let keyIndex = -1; + while (++keyIndex < keys.length) { + const key = keys[keyIndex]; + const currentIsConditionalSugar = key === '' || key[0] !== '.'; + if (i++ === 0) { + isConditionalSugar = currentIsConditionalSugar; + } else if (isConditionalSugar !== currentIsConditionalSugar) { + throw new ERR_INVALID_PACKAGE_CONFIG( + node_url.fileURLToPath(packageJsonUrl), + base, + '"exports" cannot contain some keys starting with \'.\' and some not.' + + ' The exports object must either be an object of package subpath keys' + + ' or an object of main entry condition name keys only.' + ) + } + } + + return isConditionalSugar +} + +/** + * @param {string} match + * @param {URL} pjsonUrl + * @param {URL} base + */ +function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { + // @ts-expect-error: apparently it does exist, TS. + if (process__default.noDeprecation) { + return + } + + const pjsonPath = node_url.fileURLToPath(pjsonUrl); + if (emittedPackageWarnings.has(pjsonPath + '|' + match)) return + emittedPackageWarnings.add(pjsonPath + '|' + match); + process__default.emitWarning( + `Use of deprecated trailing slash pattern mapping "${match}" in the ` + + `"exports" field module resolution of the package at ${pjsonPath}${ + base ? ` imported from ${node_url.fileURLToPath(base)}` : '' + }. Mapping specifiers ending in "/" is no longer supported.`, + 'DeprecationWarning', + 'DEP0155' + ); +} + +/** + * @param {URL} packageJsonUrl + * @param {string} packageSubpath + * @param {Record} packageConfig + * @param {URL} base + * @param {Set | undefined} conditions + * @returns {URL} + */ +function packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions +) { + let exports$1 = packageConfig.exports; + + if (isConditionalExportsMainSugar(exports$1, packageJsonUrl, base)) { + exports$1 = {'.': exports$1}; + } + + if ( + own.call(exports$1, packageSubpath) && + !packageSubpath.includes('*') && + !packageSubpath.endsWith('/') + ) { + // @ts-expect-error: indexable. + const target = exports$1[packageSubpath]; + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + '', + packageSubpath, + base, + false, + false, + false, + conditions + ); + if (resolveResult === null || resolveResult === undefined) { + throw exportsNotFound(packageSubpath, packageJsonUrl, base) + } + + return resolveResult + } + + let bestMatch = ''; + let bestMatchSubpath = ''; + const keys = Object.getOwnPropertyNames(exports$1); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + const patternIndex = key.indexOf('*'); + + if ( + patternIndex !== -1 && + packageSubpath.startsWith(key.slice(0, patternIndex)) + ) { + // When this reaches EOL, this can throw at the top of the whole function: + // + // if (StringPrototypeEndsWith(packageSubpath, '/')) + // throwInvalidSubpath(packageSubpath) + // + // To match "imports" and the spec. + if (packageSubpath.endsWith('/')) { + emitTrailingSlashPatternDeprecation( + packageSubpath, + packageJsonUrl, + base + ); + } + + const patternTrailer = key.slice(patternIndex + 1); + + if ( + packageSubpath.length >= key.length && + packageSubpath.endsWith(patternTrailer) && + patternKeyCompare(bestMatch, key) === 1 && + key.lastIndexOf('*') === patternIndex + ) { + bestMatch = key; + bestMatchSubpath = packageSubpath.slice( + patternIndex, + packageSubpath.length - patternTrailer.length + ); + } + } + } + + if (bestMatch) { + // @ts-expect-error: indexable. + const target = /** @type {unknown} */ (exports$1[bestMatch]); + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + false, + packageSubpath.endsWith('/'), + conditions + ); + + if (resolveResult === null || resolveResult === undefined) { + throw exportsNotFound(packageSubpath, packageJsonUrl, base) + } + + return resolveResult + } + + throw exportsNotFound(packageSubpath, packageJsonUrl, base) +} + +/** + * @param {string} a + * @param {string} b + */ +function patternKeyCompare(a, b) { + const aPatternIndex = a.indexOf('*'); + const bPatternIndex = b.indexOf('*'); + const baseLengthA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; + const baseLengthB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; + if (baseLengthA > baseLengthB) return -1 + if (baseLengthB > baseLengthA) return 1 + if (aPatternIndex === -1) return 1 + if (bPatternIndex === -1) return -1 + if (a.length > b.length) return -1 + if (b.length > a.length) return 1 + return 0 +} + +/** + * @param {string} name + * @param {URL} base + * @param {Set} [conditions] + * @returns {URL} + */ +function packageImportsResolve(name, base, conditions) { + if (name === '#' || name.startsWith('#/') || name.endsWith('/')) { + const reason = 'is not a valid internal imports specifier name'; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, node_url.fileURLToPath(base)) + } + + /** @type {URL | undefined} */ + let packageJsonUrl; + + const packageConfig = getPackageScopeConfig(base); + + if (packageConfig.exists) { + packageJsonUrl = node_url.pathToFileURL(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (own.call(imports, name) && !name.includes('*')) { + const resolveResult = resolvePackageTarget( + packageJsonUrl, + imports[name], + '', + name, + base, + false, + true, + false, + conditions + ); + if (resolveResult !== null && resolveResult !== undefined) { + return resolveResult + } + } else { + let bestMatch = ''; + let bestMatchSubpath = ''; + const keys = Object.getOwnPropertyNames(imports); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + const patternIndex = key.indexOf('*'); + + if (patternIndex !== -1 && name.startsWith(key.slice(0, -1))) { + const patternTrailer = key.slice(patternIndex + 1); + if ( + name.length >= key.length && + name.endsWith(patternTrailer) && + patternKeyCompare(bestMatch, key) === 1 && + key.lastIndexOf('*') === patternIndex + ) { + bestMatch = key; + bestMatchSubpath = name.slice( + patternIndex, + name.length - patternTrailer.length + ); + } + } + } + + if (bestMatch) { + const target = imports[bestMatch]; + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + true, + false, + conditions + ); + + if (resolveResult !== null && resolveResult !== undefined) { + return resolveResult + } + } + } + } + } + + throw importNotDefined(name, packageJsonUrl, base) +} + +/** + * @param {string} specifier + * @param {URL} base + */ +function parsePackageName(specifier, base) { + let separatorIndex = specifier.indexOf('/'); + let validPackageName = true; + let isScoped = false; + if (specifier[0] === '@') { + isScoped = true; + if (separatorIndex === -1 || specifier.length === 0) { + validPackageName = false; + } else { + separatorIndex = specifier.indexOf('/', separatorIndex + 1); + } + } + + const packageName = + separatorIndex === -1 ? specifier : specifier.slice(0, separatorIndex); + + // Package name cannot have leading . and cannot have percent-encoding or + // \\ separators. + if (invalidPackageNameRegEx.exec(packageName) !== null) { + validPackageName = false; + } + + if (!validPackageName) { + throw new ERR_INVALID_MODULE_SPECIFIER( + specifier, + 'is not a valid package name', + node_url.fileURLToPath(base) + ) + } + + const packageSubpath = + '.' + (separatorIndex === -1 ? '' : specifier.slice(separatorIndex)); + + return {packageName, packageSubpath, isScoped} +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set | undefined} conditions + * @returns {URL} + */ +function packageResolve(specifier, base, conditions) { + if (node_module.builtinModules.includes(specifier)) { + return new URL('node:' + specifier) + } + + const {packageName, packageSubpath, isScoped} = parsePackageName( + specifier, + base + ); + + // ResolveSelf + const packageConfig = getPackageScopeConfig(base); + + // Can’t test. + /* c8 ignore next 16 */ + if (packageConfig.exists) { + const packageJsonUrl = node_url.pathToFileURL(packageConfig.pjsonPath); + if ( + packageConfig.name === packageName && + packageConfig.exports !== undefined && + packageConfig.exports !== null + ) { + return packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions + ) + } + } + + let packageJsonUrl = new URL( + './node_modules/' + packageName + '/package.json', + base + ); + let packageJsonPath = node_url.fileURLToPath(packageJsonUrl); + /** @type {string} */ + let lastPath; + do { + const stat = tryStatSync(packageJsonPath.slice(0, -13)); + if (!stat || !stat.isDirectory()) { + lastPath = packageJsonPath; + packageJsonUrl = new URL( + (isScoped ? '../../../../node_modules/' : '../../../node_modules/') + + packageName + + '/package.json', + packageJsonUrl + ); + packageJsonPath = node_url.fileURLToPath(packageJsonUrl); + continue + } + + // Package match. + const packageConfig = read(packageJsonPath, {base, specifier}); + if (packageConfig.exports !== undefined && packageConfig.exports !== null) { + return packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions + ) + } + + if (packageSubpath === '.') { + return legacyMainResolve(packageJsonUrl, packageConfig, base) + } + + return new URL(packageSubpath, packageJsonUrl) + // Cross-platform root check. + } while (packageJsonPath.length !== lastPath.length) + + throw new ERR_MODULE_NOT_FOUND(packageName, node_url.fileURLToPath(base), false) +} + +/** + * @param {string} specifier + * @returns {boolean} + */ +function isRelativeSpecifier(specifier) { + if (specifier[0] === '.') { + if (specifier.length === 1 || specifier[1] === '/') return true + if ( + specifier[1] === '.' && + (specifier.length === 2 || specifier[2] === '/') + ) { + return true + } + } + + return false +} + +/** + * @param {string} specifier + * @returns {boolean} + */ +function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { + if (specifier === '') return false + if (specifier[0] === '/') return true + return isRelativeSpecifier(specifier) +} + +/** + * The “Resolver Algorithm Specification” as detailed in the Node docs (which is + * sync and slightly lower-level than `resolve`). + * + * @param {string} specifier + * `/example.js`, `./example.js`, `../example.js`, `some-package`, `fs`, etc. + * @param {URL} base + * Full URL (to a file) that `specifier` is resolved relative from. + * @param {Set} [conditions] + * Conditions. + * @param {boolean} [preserveSymlinks] + * Keep symlinks instead of resolving them. + * @returns {URL} + * A URL object to the found thing. + */ +function moduleResolve(specifier, base, conditions, preserveSymlinks) { + // Note: The Node code supports `base` as a string (in this internal API) too, + // we don’t. + if (conditions === undefined) { + conditions = getConditionsSet(); + } + + const protocol = base.protocol; + const isData = protocol === 'data:'; + const isRemote = isData || protocol === 'http:' || protocol === 'https:'; + // Order swapped from spec for minor perf gain. + // Ok since relative URLs cannot parse as URLs. + /** @type {URL | undefined} */ + let resolved; + + if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { + try { + resolved = new URL(specifier, base); + } catch (error_) { + const error = new ERR_UNSUPPORTED_RESOLVE_REQUEST(specifier, base); + error.cause = error_; + throw error + } + } else if (protocol === 'file:' && specifier[0] === '#') { + resolved = packageImportsResolve(specifier, base, conditions); + } else { + try { + resolved = new URL(specifier); + } catch (error_) { + // Note: actual code uses `canBeRequiredWithoutScheme`. + if (isRemote && !node_module.builtinModules.includes(specifier)) { + const error = new ERR_UNSUPPORTED_RESOLVE_REQUEST(specifier, base); + error.cause = error_; + throw error + } + + resolved = packageResolve(specifier, base, conditions); + } + } + + assert__default.ok(resolved !== undefined, 'expected to be defined'); + + if (resolved.protocol !== 'file:') { + return resolved + } + + return finalizeResolution(resolved, base) +} + +function fileURLToPath(id) { + if (typeof id === "string" && !id.startsWith("file://")) { + return normalizeSlash(id); + } + return normalizeSlash(node_url.fileURLToPath(id)); +} +function pathToFileURL(id) { + return node_url.pathToFileURL(fileURLToPath(id)).toString(); +} +const INVALID_CHAR_RE = /[\u0000-\u001F"#$&*+,/:;<=>?@[\]^`{|}\u007F]+/g; +function sanitizeURIComponent(name = "", replacement = "_") { + return name.replace(INVALID_CHAR_RE, replacement).replace(/%../g, replacement); +} +function sanitizeFilePath(filePath = "") { + return filePath.replace(/\?.*$/, "").split(/[/\\]/g).map((p) => sanitizeURIComponent(p)).join("/").replace(/^([A-Za-z])_\//, "$1:/"); +} +function normalizeid(id) { + if (typeof id !== "string") { + id = id.toString(); + } + if (/(?:node|data|http|https|file):/.test(id)) { + return id; + } + if (BUILTIN_MODULES.has(id)) { + return "node:" + id; + } + return "file://" + encodeURI(normalizeSlash(id)); +} +async function loadURL(url) { + const code = await fs.promises.readFile(fileURLToPath(url), "utf8"); + return code; +} +function toDataURL(code) { + const base64 = Buffer.from(code).toString("base64"); + return `data:text/javascript;base64,${base64}`; +} +function isNodeBuiltin(id = "") { + id = id.replace(/^node:/, "").split("/", 1)[0]; + return BUILTIN_MODULES.has(id); +} +const ProtocolRegex = /^(?.{2,}?):.+$/; +function getProtocol(id) { + const proto = id.match(ProtocolRegex); + return proto ? proto.groups?.proto : void 0; +} + +const DEFAULT_CONDITIONS_SET = /* @__PURE__ */ new Set(["node", "import"]); +const DEFAULT_EXTENSIONS = [".mjs", ".cjs", ".js", ".json"]; +const NOT_FOUND_ERRORS = /* @__PURE__ */ new Set([ + "ERR_MODULE_NOT_FOUND", + "ERR_UNSUPPORTED_DIR_IMPORT", + "MODULE_NOT_FOUND", + "ERR_PACKAGE_PATH_NOT_EXPORTED" +]); +function _tryModuleResolve(id, url, conditions) { + try { + return moduleResolve(id, url, conditions); + } catch (error) { + if (!NOT_FOUND_ERRORS.has(error?.code)) { + throw error; + } + } +} +function _resolve(id, options = {}) { + if (typeof id !== "string") { + if (id instanceof URL) { + id = fileURLToPath(id); + } else { + throw new TypeError("input must be a `string` or `URL`"); + } + } + if (/(?:node|data|http|https):/.test(id)) { + return id; + } + if (BUILTIN_MODULES.has(id)) { + return "node:" + id; + } + if (id.startsWith("file://")) { + id = fileURLToPath(id); + } + if (pathe.isAbsolute(id)) { + try { + const stat = fs.statSync(id); + if (stat.isFile()) { + return pathToFileURL(id); + } + } catch (error) { + if (error?.code !== "ENOENT") { + throw error; + } + } + } + const conditionsSet = options.conditions ? new Set(options.conditions) : DEFAULT_CONDITIONS_SET; + const _urls = (Array.isArray(options.url) ? options.url : [options.url]).filter(Boolean).map((url) => new URL(normalizeid(url.toString()))); + if (_urls.length === 0) { + _urls.push(new URL(pathToFileURL(process.cwd()))); + } + const urls = [..._urls]; + for (const url of _urls) { + if (url.protocol === "file:") { + urls.push( + new URL("./", url), + // If url is directory + new URL(ufo.joinURL(url.pathname, "_index.js"), url), + // TODO: Remove in next major version? + new URL("node_modules", url) + ); + } + } + let resolved; + for (const url of urls) { + resolved = _tryModuleResolve(id, url, conditionsSet); + if (resolved) { + break; + } + for (const prefix of ["", "/index"]) { + for (const extension of options.extensions || DEFAULT_EXTENSIONS) { + resolved = _tryModuleResolve( + ufo.joinURL(id, prefix) + extension, + url, + conditionsSet + ); + if (resolved) { + break; + } + } + if (resolved) { + break; + } + } + if (resolved) { + break; + } + } + if (!resolved) { + const error = new Error( + `Cannot find module ${id} imported from ${urls.join(", ")}` + ); + error.code = "ERR_MODULE_NOT_FOUND"; + throw error; + } + return pathToFileURL(resolved); +} +function resolveSync(id, options) { + return _resolve(id, options); +} +function resolve(id, options) { + try { + return Promise.resolve(resolveSync(id, options)); + } catch (error) { + return Promise.reject(error); + } +} +function resolvePathSync(id, options) { + return fileURLToPath(resolveSync(id, options)); +} +function resolvePath(id, options) { + try { + return Promise.resolve(resolvePathSync(id, options)); + } catch (error) { + return Promise.reject(error); + } +} +function createResolve(defaults) { + return (id, url) => { + return resolve(id, { url, ...defaults }); + }; +} +const NODE_MODULES_RE = /^(.+\/node_modules\/)([^/@]+|@[^/]+\/[^/]+)(\/?.*?)?$/; +function parseNodeModulePath(path) { + if (!path) { + return {}; + } + path = pathe.normalize(fileURLToPath(path)); + const match = NODE_MODULES_RE.exec(path); + if (!match) { + return {}; + } + const [, dir, name, subpath] = match; + return { + dir, + name, + subpath: subpath ? `.${subpath}` : void 0 + }; +} +async function lookupNodeModuleSubpath(path) { + path = pathe.normalize(fileURLToPath(path)); + const { name, subpath } = parseNodeModulePath(path); + if (!name || !subpath) { + return subpath; + } + const { exports: exports$1 } = await pkgTypes.readPackageJSON(path).catch(() => { + }) || {}; + if (exports$1) { + const resolvedSubpath = _findSubpath(subpath, exports$1); + if (resolvedSubpath) { + return resolvedSubpath; + } + } + return subpath; +} +function _findSubpath(subpath, exports$1) { + if (typeof exports$1 === "string") { + exports$1 = { ".": exports$1 }; + } + if (!subpath.startsWith(".")) { + subpath = subpath.startsWith("/") ? `.${subpath}` : `./${subpath}`; + } + if (subpath in (exports$1 || {})) { + return subpath; + } + return _flattenExports(exports$1).find((p) => p.fsPath === subpath)?.subpath; +} +function _flattenExports(exports$1 = {}, parentSubpath = "./") { + return Object.entries(exports$1).flatMap(([key, value]) => { + const [subpath, condition] = key.startsWith(".") ? [key.slice(1), void 0] : ["", key]; + const _subPath = ufo.joinURL(parentSubpath, subpath); + if (typeof value === "string") { + return [{ subpath: _subPath, fsPath: value, condition }]; + } else { + return _flattenExports(value, _subPath); + } + }); +} + +const ESM_STATIC_IMPORT_RE = /(?<=\s|^|;|\})import\s*(?:[\s"']*(?[\p{L}\p{M}\w\t\n\r $*,/{}@.]+)from\s*)?["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][\s;]*/gmu; +const DYNAMIC_IMPORT_RE = /import\s*\((?(?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*)\)/gm; +const IMPORT_NAMED_TYPE_RE = /(?<=\s|^|;|})import\s*type\s+(?:[\s"']*(?[\w\t\n\r $*,/{}]+)from\s*)?["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][\s;]*/gm; +const EXPORT_DECAL_RE = /\bexport\s+(?(?:async function\s*\*?|function\s*\*?|let|const enum|const|enum|var|class))\s+\*?(?[\w$]+)(?.*,\s*[\s\w:[\]{}]*[\w$\]}]+)*/g; +const EXPORT_DECAL_TYPE_RE = /\bexport\s+(?(?:interface|type|declare (?:async function|function|let|const enum|const|enum|var|class)))\s+(?[\w$]+)/g; +const EXPORT_NAMED_RE = /\bexport\s*{(?[^}]+?)[\s,]*}(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_NAMED_TYPE_RE = /\bexport\s+type\s*{(?[^}]+?)[\s,]*}(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_NAMED_DESTRUCT = /\bexport\s+(?:let|var|const)\s+(?:{(?[^}]+?)[\s,]*}|\[(?[^\]]+?)[\s,]*])\s+=/gm; +const EXPORT_STAR_RE = /\bexport\s*\*(?:\s*as\s+(?[\w$]+)\s+)?\s*(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_DEFAULT_RE = /\bexport\s+default\s+(async function|function|class|true|false|\W|\d)|\bexport\s+default\s+(?.*)/g; +const EXPORT_DEFAULT_CLASS_RE = /\bexport\s+default\s+(?class)\s+(?[\w$]+)/g; +const TYPE_RE = /^\s*?type\s/; +function findStaticImports(code) { + return _filterStatement( + _tryGetLocations(code, "import"), + matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" }) + ); +} +function findDynamicImports(code) { + return _filterStatement( + _tryGetLocations(code, "import"), + matchAll(DYNAMIC_IMPORT_RE, code, { type: "dynamic" }) + ); +} +function findTypeImports(code) { + return [ + ...matchAll(IMPORT_NAMED_TYPE_RE, code, { type: "type" }), + ...matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" }).filter( + (match) => /[^A-Za-z]type\s/.test(match.imports) + ) + ]; +} +function parseStaticImport(matched) { + const cleanedImports = clearImports(matched.imports); + const namedImports = {}; + const _matches = cleanedImports.match(/{([^}]*)}/)?.[1]?.split(",") || []; + for (const namedImport of _matches) { + const _match = namedImport.match(/^\s*(\S*) as (\S*)\s*$/); + const source = _match?.[1] || namedImport.trim(); + const importName = _match?.[2] || source; + if (source && !TYPE_RE.test(source)) { + namedImports[source] = importName; + } + } + const { namespacedImport, defaultImport } = getImportNames(cleanedImports); + return { + ...matched, + defaultImport, + namespacedImport, + namedImports + }; +} +function parseTypeImport(matched) { + if (matched.type === "type") { + return parseStaticImport(matched); + } + const cleanedImports = clearImports(matched.imports); + const namedImports = {}; + const _matches = cleanedImports.match(/{([^}]*)}/)?.[1]?.split(",") || []; + for (const namedImport of _matches) { + const _match = /\s+as\s+/.test(namedImport) ? namedImport.match(/^\s*type\s+(\S*) as (\S*)\s*$/) : namedImport.match(/^\s*type\s+(\S*)\s*$/); + const source = _match?.[1] || namedImport.trim(); + const importName = _match?.[2] || source; + if (source && TYPE_RE.test(namedImport)) { + namedImports[source] = importName; + } + } + const { namespacedImport, defaultImport } = getImportNames(cleanedImports); + return { + ...matched, + defaultImport, + namespacedImport, + namedImports + }; +} +function _extractExtraNames(extraNamesStr) { + const names = []; + let depth = 0; + let angleDepth = 0; + let inString = false; + let inTypeAnnotation = false; + for (let i = 0; i < extraNamesStr.length; i++) { + const char = extraNamesStr[i]; + if (inString) { + if (char === inString) { + let backslashCount = 0; + for (let j = i - 1; j >= 0 && extraNamesStr[j] === "\\"; j--) { + backslashCount++; + } + if (backslashCount % 2 === 0) { + inString = false; + } + } + continue; + } + if (char === '"' || char === "'" || char === "`") { + inString = char; + continue; + } + if (char === ":" && depth === 0 && angleDepth === 0) { + inTypeAnnotation = true; + continue; + } + if (char === "=" && extraNamesStr[i + 1] !== ">" && depth === 0 && angleDepth === 0) { + inTypeAnnotation = false; + } + if (inTypeAnnotation && char === "<") { + angleDepth++; + continue; + } + if (!inTypeAnnotation && char === "<" && depth === 0 && i > 0 && _isIdentifierBeforeAngleBracket(extraNamesStr, i)) { + angleDepth++; + continue; + } + if (char === ">" && angleDepth > 0 && extraNamesStr[i - 1] !== "=") { + angleDepth--; + continue; + } + if (char === "(" || char === "[" || char === "{") { + depth++; + } else if (char === ")" || char === "]" || char === "}") { + depth--; + } + if (char === "," && depth === 0 && angleDepth === 0) { + const rest = extraNamesStr.slice(i + 1); + const match = rest.match(/^\s*([\w$]+)/); + if (match) { + names.push(match[1]); + } + } + } + return names; +} +function findExports(code) { + const declaredExports = matchAll(EXPORT_DECAL_RE, code, { + type: "declaration" + }); + for (const declaredExport of declaredExports) { + if (/^export\s+(?:async\s+)?function/.test(declaredExport.code)) { + continue; + } + const extraNamesStr = declaredExport.extraNames; + if (extraNamesStr) { + const extraNames = _extractExtraNames(extraNamesStr); + if (extraNames.length > 0) { + declaredExport.names = [declaredExport.name, ...extraNames]; + } + } + delete declaredExport.extraNames; + } + const namedExports = normalizeNamedExports( + matchAll(EXPORT_NAMED_RE, code, { + type: "named" + }) + ); + const destructuredExports = matchAll( + EXPORT_NAMED_DESTRUCT, + code, + { type: "named" } + ); + for (const namedExport of destructuredExports) { + namedExport.exports = namedExport.exports1 || namedExport.exports2; + namedExport.names = namedExport.exports.replace(/^\r?\n?/, "").split(/\s*,\s*/g).filter((name) => !TYPE_RE.test(name)).map( + (name) => name.replace(/^.*?\s*:\s*/, "").replace(/\s*=\s*.*$/, "").trim() + ); + } + const defaultExport = matchAll(EXPORT_DEFAULT_RE, code, { + type: "default", + name: "default" + }); + const defaultClassExports = matchAll(EXPORT_DEFAULT_CLASS_RE, code, { + type: "declaration" + }); + const starExports = matchAll(EXPORT_STAR_RE, code, { + type: "star" + }); + const exports$1 = normalizeExports([ + ...declaredExports, + ...namedExports, + ...destructuredExports, + ...defaultExport, + ...defaultClassExports, + ...starExports + ]); + if (exports$1.length === 0) { + return []; + } + const exportLocations = _tryGetLocations(code, "export"); + if (exportLocations && exportLocations.length === 0) { + return []; + } + return ( + // Filter false positive export matches + _filterStatement(exportLocations, exports$1).filter((exp, index, exports2) => { + const nextExport = exports2[index + 1]; + return !nextExport || exp.type !== nextExport.type || !exp.name || exp.name !== nextExport.name; + }) + ); +} +function findTypeExports(code) { + const declaredExports = matchAll( + EXPORT_DECAL_TYPE_RE, + code, + { type: "declaration" } + ); + const namedExports = normalizeNamedExports( + matchAll(EXPORT_NAMED_TYPE_RE, code, { + type: "named" + }) + ); + const exports$1 = normalizeExports([ + ...declaredExports, + ...namedExports + ]); + if (exports$1.length === 0) { + return []; + } + const exportLocations = _tryGetLocations(code, "export"); + if (exportLocations && exportLocations.length === 0) { + return []; + } + return ( + // Filter false positive export matches + _filterStatement(exportLocations, exports$1).filter((exp, index, exports2) => { + const nextExport = exports2[index + 1]; + return !nextExport || exp.type !== nextExport.type || !exp.name || exp.name !== nextExport.name; + }) + ); +} +function normalizeExports(exports$1) { + for (const exp of exports$1) { + if (!exp.name && exp.names && exp.names.length === 1) { + exp.name = exp.names[0]; + } + if (exp.name === "default" && exp.type !== "default") { + exp._type = exp.type; + exp.type = "default"; + } + if (!exp.names && exp.name) { + exp.names = [exp.name]; + } + if (exp.type === "declaration" && exp.declaration) { + exp.declarationType = exp.declaration.replace( + /^declare\s*/, + "" + ); + } + } + return exports$1; +} +function normalizeNamedExports(namedExports) { + for (const namedExport of namedExports) { + namedExport.names = namedExport.exports.replace(/^\r?\n?/, "").split(/\s*,\s*/g).filter((name) => !TYPE_RE.test(name)).map((name) => name.replace(/^.*?\sas\s/, "").trim()); + } + return namedExports; +} +function findExportNames(code) { + return findExports(code).flatMap((exp) => exp.names).filter(Boolean); +} +async function resolveModuleExportNames(id, options) { + const url = await resolvePath(id, options); + const code = await loadURL(url); + const exports$1 = findExports(code); + const exportNames = new Set( + exports$1.flatMap((exp) => exp.names).filter(Boolean) + ); + for (const exp of exports$1) { + if (exp.type !== "star" || !exp.specifier) { + continue; + } + const subExports = await resolveModuleExportNames(exp.specifier, { + ...options, + url + }); + for (const subExport of subExports) { + exportNames.add(subExport); + } + } + return [...exportNames]; +} +function _filterStatement(locations, statements) { + return statements.filter((exp) => { + return !locations || locations.some((location) => { + return exp.start <= location.start && exp.end >= location.end; + }); + }); +} +function _tryGetLocations(code, label) { + try { + return _getLocations(code, label); + } catch { + } +} +function _getLocations(code, label) { + const tokens = acorn.tokenizer(code, { + ecmaVersion: "latest", + sourceType: "module", + allowHashBang: true, + allowAwaitOutsideFunction: true, + allowImportExportEverywhere: true + }); + const locations = []; + for (const token of tokens) { + if (token.type.label === label) { + locations.push({ + start: token.start, + end: token.end + }); + } + } + return locations; +} +function _isIdentifierBeforeAngleBracket(str, i) { + let j = i - 1; + while (j >= 0 && /[A-Za-z0-9_$]/.test(str[j])) { + j--; + } + const wordStart = j + 1; + return wordStart < i && /[A-Za-z_$]/.test(str[wordStart]); +} + +function createCommonJS(url) { + const __filename = fileURLToPath(url); + const __dirname = path.dirname(__filename); + let _nativeRequire; + const getNativeRequire = () => { + if (!_nativeRequire) { + _nativeRequire = node_module.createRequire(url); + } + return _nativeRequire; + }; + function require(id) { + return getNativeRequire()(id); + } + require.resolve = function requireResolve(id, options) { + return getNativeRequire().resolve(id, options); + }; + return { + __filename, + __dirname, + require + }; +} +function interopDefault(sourceModule, opts = {}) { + if (!isObject(sourceModule) || !("default" in sourceModule)) { + return sourceModule; + } + const defaultValue = sourceModule.default; + if (defaultValue === void 0 || defaultValue === null) { + return sourceModule; + } + const _defaultType = typeof defaultValue; + if (_defaultType !== "object" && !(_defaultType === "function" && !opts.preferNamespace)) { + return opts.preferNamespace ? sourceModule : defaultValue; + } + for (const key in sourceModule) { + try { + if (!(key in defaultValue)) { + Object.defineProperty(defaultValue, key, { + enumerable: key !== "default", + configurable: key !== "default", + get() { + return sourceModule[key]; + } + }); + } + } catch { + } + } + return defaultValue; +} + +const EVAL_ESM_IMPORT_RE = /(?<=import .* from ["'])[^"']+(?=["'])|(?<=export .* from ["'])[^"']+(?=["'])|(?<=import\s*["'])[^"']+(?=["'])|(?<=import\s*\(["'])[^"']+(?=["']\))/g; +async function loadModule(id, options = {}) { + const url = await resolve(id, options); + const code = await loadURL(url); + return evalModule(code, { ...options, url }); +} +async function evalModule(code, options = {}) { + const transformed = await transformModule(code, options); + const dataURL = toDataURL(transformed); + return import(dataURL).catch((error) => { + error.stack = error.stack.replace( + new RegExp(dataURL, "g"), + options.url || "_mlly_eval_" + ); + throw error; + }); +} +function transformModule(code, options = {}) { + if (options.url && options.url.endsWith(".json")) { + return Promise.resolve("export default " + code); + } + if (options.url) { + code = code.replace(/import\.meta\.url/g, `'${options.url}'`); + } + return Promise.resolve(code); +} +async function resolveImports(code, options) { + const imports = [...code.matchAll(EVAL_ESM_IMPORT_RE)].map((m) => m[0]); + if (imports.length === 0) { + return code; + } + const uniqueImports = [...new Set(imports)]; + const resolved = /* @__PURE__ */ new Map(); + await Promise.all( + uniqueImports.map(async (id) => { + let url = await resolve(id, options); + if (url.endsWith(".json")) { + const code2 = await loadURL(url); + url = toDataURL(await transformModule(code2, { url })); + } + resolved.set(id, url); + }) + ); + const re = new RegExp( + uniqueImports.map((index) => `(?:${index})`).join("|"), + "g" + ); + return code.replace(re, (id) => resolved.get(id)); +} + +const ESM_RE = /(?:[\s;]|^)(?:import[\s\w*,{}]*from|import\s*["'*{]|export\b\s*(?:[*{]|default|class|type|function|const|var|let|async function)|import\.meta\b)/m; +const CJS_RE = /(?:[\s;]|^)(?:module\.exports\b|exports\.\w|require\s*\(|global\.\w)/m; +const COMMENT_RE = /\/\*.+?\*\/|\/\/.*(?=[nr])/g; +const BUILTIN_EXTENSIONS = /* @__PURE__ */ new Set([".mjs", ".cjs", ".node", ".wasm"]); +function hasESMSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + return ESM_RE.test(code); +} +function hasCJSSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + return CJS_RE.test(code); +} +function detectSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + const hasESM = hasESMSyntax(code, {}); + const hasCJS = hasCJSSyntax(code, {}); + return { + hasESM, + hasCJS, + isMixed: hasESM && hasCJS + }; +} +const validNodeImportDefaults = { + allowedProtocols: ["node", "file", "data"] +}; +async function isValidNodeImport(id, _options = {}) { + if (isNodeBuiltin(id)) { + return true; + } + const options = { ...validNodeImportDefaults, ..._options }; + const proto = getProtocol(id); + if (proto && !options.allowedProtocols?.includes(proto)) { + return false; + } + if (proto === "data") { + return true; + } + const resolvedPath = await resolvePath(id, options); + const extension = pathe.extname(resolvedPath); + if (BUILTIN_EXTENSIONS.has(extension)) { + return true; + } + if (extension !== ".js") { + return false; + } + const package_ = await pkgTypes.readPackageJSON(resolvedPath).catch(() => { + }); + if (package_?.type === "module") { + return true; + } + if (/\.(?:\w+-)?esm?(?:-\w+)?\.js$|\/esm?\//.test(resolvedPath)) { + return false; + } + const code = options.code || await fs.promises.readFile(resolvedPath, "utf8").catch(() => { + }) || ""; + return !hasESMSyntax(code, { stripComments: options.stripComments }); +} + +exports.DYNAMIC_IMPORT_RE = DYNAMIC_IMPORT_RE; +exports.ESM_STATIC_IMPORT_RE = ESM_STATIC_IMPORT_RE; +exports.EXPORT_DECAL_RE = EXPORT_DECAL_RE; +exports.EXPORT_DECAL_TYPE_RE = EXPORT_DECAL_TYPE_RE; +exports.createCommonJS = createCommonJS; +exports.createResolve = createResolve; +exports.detectSyntax = detectSyntax; +exports.evalModule = evalModule; +exports.fileURLToPath = fileURLToPath; +exports.findDynamicImports = findDynamicImports; +exports.findExportNames = findExportNames; +exports.findExports = findExports; +exports.findStaticImports = findStaticImports; +exports.findTypeExports = findTypeExports; +exports.findTypeImports = findTypeImports; +exports.getProtocol = getProtocol; +exports.hasCJSSyntax = hasCJSSyntax; +exports.hasESMSyntax = hasESMSyntax; +exports.interopDefault = interopDefault; +exports.isNodeBuiltin = isNodeBuiltin; +exports.isValidNodeImport = isValidNodeImport; +exports.loadModule = loadModule; +exports.loadURL = loadURL; +exports.lookupNodeModuleSubpath = lookupNodeModuleSubpath; +exports.normalizeid = normalizeid; +exports.parseNodeModulePath = parseNodeModulePath; +exports.parseStaticImport = parseStaticImport; +exports.parseTypeImport = parseTypeImport; +exports.pathToFileURL = pathToFileURL; +exports.resolve = resolve; +exports.resolveImports = resolveImports; +exports.resolveModuleExportNames = resolveModuleExportNames; +exports.resolvePath = resolvePath; +exports.resolvePathSync = resolvePathSync; +exports.resolveSync = resolveSync; +exports.sanitizeFilePath = sanitizeFilePath; +exports.sanitizeURIComponent = sanitizeURIComponent; +exports.toDataURL = toDataURL; +exports.transformModule = transformModule; diff --git a/node_modules/mlly/dist/index.d.cts b/node_modules/mlly/dist/index.d.cts new file mode 100644 index 0000000..a9029bd --- /dev/null +++ b/node_modules/mlly/dist/index.d.cts @@ -0,0 +1,564 @@ +interface ResolveOptions { + /** + * A URL, path or array of URLs/paths to resolve against. + */ + url?: string | URL | (string | URL)[]; + /** + * File extensions to consider when resolving modules. + */ + extensions?: string[]; + /** + * Conditions to consider when resolving package exports. + */ + conditions?: string[]; +} +/** + * Synchronously resolves a module path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved URL as a string. + */ +declare function resolveSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve the URL as a string. + */ +declare function resolve(id: string, options?: ResolveOptions): Promise; +/** + * Synchronously resolves a module path to a local file path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved file path. + */ +declare function resolvePathSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path to a local file path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve to the file path. + */ +declare function resolvePath(id: string, options?: ResolveOptions): Promise; +/** + * Creates a resolver function with default options that can be used to resolve module identifiers. + * + * @param {ResolveOptions} [defaults] - Default options to use for all resolutions. See {@link ResolveOptions}. + * @returns {Function} A resolver function that takes an identifier and an optional URL, and resolves the identifier using the default options and the given URL. + */ +declare function createResolve(defaults?: ResolveOptions): (id: string, url?: ResolveOptions["url"]) => Promise; +/** + * Parses a node module path to extract the directory, name, and subpath. + * + * @param {string} path - The path to parse. + * @returns {Object} An object containing the directory, module name, and subpath of the node module. + */ +declare function parseNodeModulePath(path: string): { + dir?: undefined; + name?: undefined; + subpath?: undefined; +} | { + dir: string; + name: string; + subpath: string | undefined; +}; +/** + * Attempts to reverse engineer a subpath export within a node module. + * + * @param {string} path - The path within the node module. + * @returns {Promise} A promise that resolves to the detected subpath or undefined if not found. + */ +declare function lookupNodeModuleSubpath(path: string): Promise; + +/** + * Represents a general structure for ECMAScript module imports. + */ +interface ESMImport { + /** + * Specifies the type of import: "static" for static imports and "dynamic" for dynamic imports. + */ + type: "static" | "dynamic"; + /** + * The full import declaration code snippet as a string. + */ + code: string; + /** + * The starting position (index) of the import declaration in the source code. + */ + start: number; + /** + * The end position (index) of the import declaration in the source code. + */ + end: number; +} +/** + * Represents a static import declaration in an ECMAScript module. + * Extends {@link ESMImport}. + */ +interface StaticImport extends ESMImport { + /** + * Indicates the type of import, specifically a static import. + */ + type: "static"; + /** + * Contains the entire import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which imports are being brought in. + */ + specifier: string; +} +/** + * Represents a parsed static import declaration with detailed components of the import. + * Extends {@link StaticImport}. + */ +interface ParsedStaticImport extends StaticImport { + /** + * The default import name, if any. + * @optional + */ + defaultImport?: string; + /** + * The namespace import name, if any, using the `* as` syntax. + * @optional + */ + namespacedImport?: string; + /** + * An object representing named imports, with their local aliases if specified. + * Each property key is the original name and its value is the alias. + * @optional + */ + namedImports?: { + [name: string]: string; + }; +} +/** + * Represents a dynamic import declaration that is loaded at runtime. + * Extends {@link ESMImport}. + */ +interface DynamicImport extends ESMImport { + /** + * Indicates that this is a dynamic import. + */ + type: "dynamic"; + /** + * The expression or path to be dynamically imported, typically a module path or URL. + */ + expression: string; +} +/** + * Represents a type-specific import, primarily used for importing types in TypeScript. + * Extends {@link ESMImport} but omits the 'type' to redefine it specifically for type imports. + */ +interface TypeImport extends Omit { + /** + * Specifies that this is a type import. + */ + type: "type"; + /** + * Contains the entire type import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which to import types. + */ + specifier: string; +} +/** + * Represents a general structure for ECMAScript module exports. + */ +interface ESMExport { + /** + * Optional explicit type for complex scenarios, often used internally. + * @optional + */ + _type?: "declaration" | "named" | "default" | "star"; + /** + * The type of export (declaration, named, default or star). + */ + type: "declaration" | "named" | "default" | "star"; + /** + * The specific type of declaration being exported, if applicable. + * @optional + */ + declarationType?: "let" | "var" | "const" | "enum" | "const enum" | "class" | "function" | "async function"; + /** + * The full code snippet of the export statement. + */ + code: string; + /** + * The starting position (index) of the export declaration in the source code. + */ + start: number; + /** + * The end position (index) of the export declaration in the source code. + */ + end: number; + /** + * The name of the variable, function or class being exported, if given explicitly. + * @optional + */ + name?: string; + /** + * The name used for default exports when a specific identifier isn't given. + * @optional + */ + defaultName?: string; + /** + * An array of names to export, applicable to named and destructured exports. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a declaration export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DeclarationExport extends ESMExport { + /** + * Indicates that this export is a declaration export. + */ + type: "declaration"; + /** + * The declaration string, such as 'let', 'const', 'class', etc., describing what is being exported. + */ + declaration: string; + /** + * The name of the declaration to be exported. + */ + name: string; +} +/** + * Represents a named export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface NamedExport extends ESMExport { + /** + * Specifies that this export is a named export. + */ + type: "named"; + /** + * The export string, containing all exported identifiers. + */ + exports: string; + /** + * An array of names to export. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a standard export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DefaultExport extends ESMExport { + /** + * Specifies that this export is a standard export. + */ + type: "default"; +} +/** + * Regular expression to match static import statements in JavaScript/TypeScript code. + * @example `import { foo, bar as baz } from 'module'` + */ +declare const ESM_STATIC_IMPORT_RE: RegExp; +/** + * Regular expression to match dynamic import statements in JavaScript/TypeScript code. + * @example `import('module')` + */ +declare const DYNAMIC_IMPORT_RE: RegExp; +/** + * Regular expression to match various types of export declarations including variables, functions, and classes. + * @example `export const num = 1, str = 'hello'; export class Example {}` + */ +declare const EXPORT_DECAL_RE: RegExp; +/** + * Regular expression to match export declarations specifically for types, interfaces, and type aliases in TypeScript. + * @example `export type Result = { success: boolean; }; export interface User { name: string; age: number; };` + */ +declare const EXPORT_DECAL_TYPE_RE: RegExp; +/** + * Finds all static import statements within the given code string. + * @param {string} code - The source code to search for static imports. + * @returns {StaticImport[]} An array of {@link StaticImport} objects representing each static import found. + */ +declare function findStaticImports(code: string): StaticImport[]; +/** + * Searches for dynamic import statements in the given source code. + * @param {string} code - The source to search for dynamic imports in. + * @returns {DynamicImport[]} An array of {@link DynamicImport} objects representing each dynamic import found. + */ +declare function findDynamicImports(code: string): DynamicImport[]; +/** + * Identifies and returns all type import statements in the given source code. + * This function is specifically targeted at type imports used in TypeScript. + * @param {string} code - The source code to search for type imports. + * @returns {TypeImport[]} An array of {@link TypeImport} objects representing each type import found. + */ +declare function findTypeImports(code: string): TypeImport[]; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseStaticImport(matched: StaticImport | TypeImport): ParsedStaticImport; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseTypeImport(matched: TypeImport | StaticImport): ParsedStaticImport; +/** + * Identifies all export statements in the supplied source code and categorises them into different types such as declarations, named, default and star exports. + * This function processes the code to capture different forms of export statements and normalise their representation for further processing. + * + * @param {string} code - The source code containing the export statements to be analysed. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each export found, properly categorised and structured. + */ +declare function findExports(code: string): ESMExport[]; +/** + * Searches specifically for type-related exports in TypeScript code, such as exported interfaces, types, and declarations prefixed with 'declare'. + * This function uses specialised regular expressions to identify type exports and normalises them for consistency. + * + * @param {string} code - The TypeScript source code to search for type exports. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each type export found. + */ +declare function findTypeExports(code: string): ESMExport[]; +/** + * Extracts and returns a list of all export names from the given source. + * This function uses {@link findExports} to retrieve all types of exports and consolidates their names into a single array. + * + * @param {string} code - The source code to search for export names. + * @returns {string[]} An array containing the names of all exports found in the code. + */ +declare function findExportNames(code: string): string[]; +/** + * Asynchronously resolves and returns all export names from a module specified by its module identifier. + * This function recursively resolves all explicitly named and asterisked (* as) exports to fully enumerate the exported identifiers. + * + * @param {string} id - The module identifier to resolve. + * @param {ResolveOptions} [options] - Optional settings for resolving the module path, such as the base URL. + * @returns {Promise} A promise that resolves to an array of export names from the module. + */ +declare function resolveModuleExportNames(id: string, options?: ResolveOptions): Promise; + +/** + * Represents the context of a CommonJS environment, providing node-like module resolution capabilities within a module. + */ +interface CommonjsContext { + /** + * The absolute path to the current module file. + */ + __filename: string; + /** + * The directory name of the current module. + */ + __dirname: string; + /** + * A function to require modules as in CommonJS. + */ + require: NodeRequire; +} +/** + * Creates a CommonJS context for a given module URL, enabling `require`, `__filename` and `__dirname` support similar to Node.js. + * This function dynamically generates a `require` function that is context-aware and bound to the location of the given module URL. + * + * @param {string} url - The URL of the module file to create a context for. + * @returns {CommonjsContext} A context object containing `__filename`, `__dirname` and a custom `require` function. See {@link CommonjsContext}. + */ +declare function createCommonJS(url: string): CommonjsContext; +declare function interopDefault(sourceModule: any, opts?: { + preferNamespace?: boolean; +}): any; + +/** + * Options for evaluating or transforming modules, extending resolution options with optional URL specifications. + */ +interface EvaluateOptions extends ResolveOptions { + /** + * The URL of the module, which can be specified to override the URL resolved from the module identifier. + * @optional + */ + url?: string; +} +/** + * Loads a module by resolving its identifier to a URL, fetching the module's code and evaluating it. + * + * @param {string} id - The identifier of the module to load. + * @param {EvaluateOptions} options - Optional parameters to resolve and load the module. See {@link EvaluateOptions}. + * @returns {Promise} A promise to resolve to the evaluated module. + * }); + */ +declare function loadModule(id: string, options?: EvaluateOptions): Promise; +/** + * Evaluates JavaScript code as a module using a dynamic import from a data URL. + * + * @param {string} code - The code of the module to evaluate. + * @param {EvaluateOptions} options - Includes the original URL of the module for better error mapping. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the evaluated module or throws an error if the evaluation fails. + */ +declare function evalModule(code: string, options?: EvaluateOptions): Promise; +/** + * Transform module code to handle specific scenarios, such as converting JSON to a module or rewriting import.meta.url. + * + * @param {string} code - The code of the module to transform. + * @param {EvaluateOptions} options - Options to control how the code is transformed. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the transformed code. + */ +declare function transformModule(code: string, options?: EvaluateOptions): Promise; +/** + * Resolves all import URLs found within the provided code to their absolute URLs, based on the given options. + * + * @param {string} code - The code containing the import directives to resolve. + * @param {EvaluateOptions} [options] - Options to use for resolving imports. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the code, replacing import URLs with resolved URLs. + */ +declare function resolveImports(code: string, options?: EvaluateOptions): Promise; + +/** + * Options for detecting syntax within a code string. + */ +type DetectSyntaxOptions = { + /** + * Indicates whether comments should be stripped from the code before syntax checking. + * @default false + */ + stripComments?: boolean; +}; +/** + * Determines if a given code string contains ECMAScript module syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains ESM syntax, otherwise `false`. + */ +declare function hasESMSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Determines if a given string of code contains CommonJS syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains CommonJS syntax, `false` otherwise. + */ +declare function hasCJSSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Analyses the supplied code to determine if it contains ECMAScript module syntax, CommonJS syntax, or both. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {object} An object indicating the presence of ESM syntax (`hasESM`), CJS syntax (`hasCJS`) and whether both syntaxes are present (`isMixed`). + */ +declare function detectSyntax(code: string, opts?: DetectSyntaxOptions): { + hasESM: boolean; + hasCJS: boolean; + isMixed: boolean; +}; +interface ValidNodeImportOptions extends ResolveOptions { + /** + * The contents of the import, which may be analyzed to see if it contains + * CJS or ESM syntax as a last step in checking whether it is a valid import. + */ + code?: string; + /** + * Protocols that are allowed as valid node imports. + * + * @default ['node', 'file', 'data'] + * + */ + allowedProtocols?: Array; + /** + * Whether to strip comments from the code before checking for ESM syntax. + * + * @default false + */ + stripComments?: boolean; +} +/** + * Validates whether a given identifier represents a valid node import, based on its protocol, file extension, and optionally its contents. + * + * @param {string} id - The identifier or URL of the import to validate. + * @param {ValidNodeImportOptions} _options - Options for resolving and validating the import. See {@link ValidNodeImportOptions}. + * @returns {Promise} A promise that resolves to `true` if the import is valid, otherwise `false`. + */ +declare function isValidNodeImport(id: string, _options?: ValidNodeImportOptions): Promise; + +/** + * Converts a file URL to a local file system path with normalized slashes. + * + * @param {string | URL} id - The file URL or local path to convert. + * @returns {string} A normalized file system path. + */ +declare function fileURLToPath(id: string | URL): string; +/** + * Converts a local file system path to a file URL. + * + * @param {string | URL} id - The file system path to convert. + * @returns {string} The resulting file URL as a string. + */ +declare function pathToFileURL(id: string | URL): string; +/** + * Sanitises a component of a URI by replacing invalid characters. + * + * @param {string} name - The URI component to sanitise. + * @param {string} [replacement="_"] - The string to replace invalid characters with. + * @returns {string} The sanitised URI component. + */ +declare function sanitizeURIComponent(name?: string, replacement?: string): string; +/** + * Cleans a file path string by sanitising each component of the path. + * + * @param {string} filePath - The file path to sanitise. + * @returns {string} The sanitised file path. + */ +declare function sanitizeFilePath(filePath?: string): string; +/** + * Normalises a module identifier to ensure it has a protocol if missing, handling built-in modules and file paths. + * + * @param {string} id - The identifier to normalise. + * @returns {string} The normalised identifier with the appropriate protocol. + */ +declare function normalizeid(id: string): string; +/** + * Loads the contents of a file from a URL into a string. + * + * @param {string} url - The URL of the file to load. + * @returns {Promise} A promise that resolves to the content of the file. + */ +declare function loadURL(url: string): Promise; +/** + * Converts a string of code into a data URL that can be used for dynamic imports. + * + * @param {string} code - The string of code to convert. + * @returns {string} The data URL containing the encoded code. + */ +declare function toDataURL(code: string): string; +/** + * Checks if a module identifier matches a Node.js built-in module. + * + * @param {string} id - The identifier to check. + * @returns {boolean} `true` if the identifier is a built-in module, otherwise `false`. + */ +declare function isNodeBuiltin(id?: string): boolean; +/** + * Extracts the protocol portion of a given identifier string. + * + * @param {string} id - The identifier from which to extract the log. + * @returns {string | undefined} The protocol part of the identifier, or undefined if no protocol is present. + */ +declare function getProtocol(id: string): string | undefined; + +export { DYNAMIC_IMPORT_RE, ESM_STATIC_IMPORT_RE, EXPORT_DECAL_RE, EXPORT_DECAL_TYPE_RE, createCommonJS, createResolve, detectSyntax, evalModule, fileURLToPath, findDynamicImports, findExportNames, findExports, findStaticImports, findTypeExports, findTypeImports, getProtocol, hasCJSSyntax, hasESMSyntax, interopDefault, isNodeBuiltin, isValidNodeImport, loadModule, loadURL, lookupNodeModuleSubpath, normalizeid, parseNodeModulePath, parseStaticImport, parseTypeImport, pathToFileURL, resolve, resolveImports, resolveModuleExportNames, resolvePath, resolvePathSync, resolveSync, sanitizeFilePath, sanitizeURIComponent, toDataURL, transformModule }; +export type { CommonjsContext, DeclarationExport, DefaultExport, DetectSyntaxOptions, DynamicImport, ESMExport, ESMImport, EvaluateOptions, NamedExport, ParsedStaticImport, ResolveOptions, StaticImport, TypeImport, ValidNodeImportOptions }; diff --git a/node_modules/mlly/dist/index.d.mts b/node_modules/mlly/dist/index.d.mts new file mode 100644 index 0000000..a9029bd --- /dev/null +++ b/node_modules/mlly/dist/index.d.mts @@ -0,0 +1,564 @@ +interface ResolveOptions { + /** + * A URL, path or array of URLs/paths to resolve against. + */ + url?: string | URL | (string | URL)[]; + /** + * File extensions to consider when resolving modules. + */ + extensions?: string[]; + /** + * Conditions to consider when resolving package exports. + */ + conditions?: string[]; +} +/** + * Synchronously resolves a module path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved URL as a string. + */ +declare function resolveSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve the URL as a string. + */ +declare function resolve(id: string, options?: ResolveOptions): Promise; +/** + * Synchronously resolves a module path to a local file path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved file path. + */ +declare function resolvePathSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path to a local file path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve to the file path. + */ +declare function resolvePath(id: string, options?: ResolveOptions): Promise; +/** + * Creates a resolver function with default options that can be used to resolve module identifiers. + * + * @param {ResolveOptions} [defaults] - Default options to use for all resolutions. See {@link ResolveOptions}. + * @returns {Function} A resolver function that takes an identifier and an optional URL, and resolves the identifier using the default options and the given URL. + */ +declare function createResolve(defaults?: ResolveOptions): (id: string, url?: ResolveOptions["url"]) => Promise; +/** + * Parses a node module path to extract the directory, name, and subpath. + * + * @param {string} path - The path to parse. + * @returns {Object} An object containing the directory, module name, and subpath of the node module. + */ +declare function parseNodeModulePath(path: string): { + dir?: undefined; + name?: undefined; + subpath?: undefined; +} | { + dir: string; + name: string; + subpath: string | undefined; +}; +/** + * Attempts to reverse engineer a subpath export within a node module. + * + * @param {string} path - The path within the node module. + * @returns {Promise} A promise that resolves to the detected subpath or undefined if not found. + */ +declare function lookupNodeModuleSubpath(path: string): Promise; + +/** + * Represents a general structure for ECMAScript module imports. + */ +interface ESMImport { + /** + * Specifies the type of import: "static" for static imports and "dynamic" for dynamic imports. + */ + type: "static" | "dynamic"; + /** + * The full import declaration code snippet as a string. + */ + code: string; + /** + * The starting position (index) of the import declaration in the source code. + */ + start: number; + /** + * The end position (index) of the import declaration in the source code. + */ + end: number; +} +/** + * Represents a static import declaration in an ECMAScript module. + * Extends {@link ESMImport}. + */ +interface StaticImport extends ESMImport { + /** + * Indicates the type of import, specifically a static import. + */ + type: "static"; + /** + * Contains the entire import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which imports are being brought in. + */ + specifier: string; +} +/** + * Represents a parsed static import declaration with detailed components of the import. + * Extends {@link StaticImport}. + */ +interface ParsedStaticImport extends StaticImport { + /** + * The default import name, if any. + * @optional + */ + defaultImport?: string; + /** + * The namespace import name, if any, using the `* as` syntax. + * @optional + */ + namespacedImport?: string; + /** + * An object representing named imports, with their local aliases if specified. + * Each property key is the original name and its value is the alias. + * @optional + */ + namedImports?: { + [name: string]: string; + }; +} +/** + * Represents a dynamic import declaration that is loaded at runtime. + * Extends {@link ESMImport}. + */ +interface DynamicImport extends ESMImport { + /** + * Indicates that this is a dynamic import. + */ + type: "dynamic"; + /** + * The expression or path to be dynamically imported, typically a module path or URL. + */ + expression: string; +} +/** + * Represents a type-specific import, primarily used for importing types in TypeScript. + * Extends {@link ESMImport} but omits the 'type' to redefine it specifically for type imports. + */ +interface TypeImport extends Omit { + /** + * Specifies that this is a type import. + */ + type: "type"; + /** + * Contains the entire type import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which to import types. + */ + specifier: string; +} +/** + * Represents a general structure for ECMAScript module exports. + */ +interface ESMExport { + /** + * Optional explicit type for complex scenarios, often used internally. + * @optional + */ + _type?: "declaration" | "named" | "default" | "star"; + /** + * The type of export (declaration, named, default or star). + */ + type: "declaration" | "named" | "default" | "star"; + /** + * The specific type of declaration being exported, if applicable. + * @optional + */ + declarationType?: "let" | "var" | "const" | "enum" | "const enum" | "class" | "function" | "async function"; + /** + * The full code snippet of the export statement. + */ + code: string; + /** + * The starting position (index) of the export declaration in the source code. + */ + start: number; + /** + * The end position (index) of the export declaration in the source code. + */ + end: number; + /** + * The name of the variable, function or class being exported, if given explicitly. + * @optional + */ + name?: string; + /** + * The name used for default exports when a specific identifier isn't given. + * @optional + */ + defaultName?: string; + /** + * An array of names to export, applicable to named and destructured exports. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a declaration export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DeclarationExport extends ESMExport { + /** + * Indicates that this export is a declaration export. + */ + type: "declaration"; + /** + * The declaration string, such as 'let', 'const', 'class', etc., describing what is being exported. + */ + declaration: string; + /** + * The name of the declaration to be exported. + */ + name: string; +} +/** + * Represents a named export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface NamedExport extends ESMExport { + /** + * Specifies that this export is a named export. + */ + type: "named"; + /** + * The export string, containing all exported identifiers. + */ + exports: string; + /** + * An array of names to export. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a standard export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DefaultExport extends ESMExport { + /** + * Specifies that this export is a standard export. + */ + type: "default"; +} +/** + * Regular expression to match static import statements in JavaScript/TypeScript code. + * @example `import { foo, bar as baz } from 'module'` + */ +declare const ESM_STATIC_IMPORT_RE: RegExp; +/** + * Regular expression to match dynamic import statements in JavaScript/TypeScript code. + * @example `import('module')` + */ +declare const DYNAMIC_IMPORT_RE: RegExp; +/** + * Regular expression to match various types of export declarations including variables, functions, and classes. + * @example `export const num = 1, str = 'hello'; export class Example {}` + */ +declare const EXPORT_DECAL_RE: RegExp; +/** + * Regular expression to match export declarations specifically for types, interfaces, and type aliases in TypeScript. + * @example `export type Result = { success: boolean; }; export interface User { name: string; age: number; };` + */ +declare const EXPORT_DECAL_TYPE_RE: RegExp; +/** + * Finds all static import statements within the given code string. + * @param {string} code - The source code to search for static imports. + * @returns {StaticImport[]} An array of {@link StaticImport} objects representing each static import found. + */ +declare function findStaticImports(code: string): StaticImport[]; +/** + * Searches for dynamic import statements in the given source code. + * @param {string} code - The source to search for dynamic imports in. + * @returns {DynamicImport[]} An array of {@link DynamicImport} objects representing each dynamic import found. + */ +declare function findDynamicImports(code: string): DynamicImport[]; +/** + * Identifies and returns all type import statements in the given source code. + * This function is specifically targeted at type imports used in TypeScript. + * @param {string} code - The source code to search for type imports. + * @returns {TypeImport[]} An array of {@link TypeImport} objects representing each type import found. + */ +declare function findTypeImports(code: string): TypeImport[]; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseStaticImport(matched: StaticImport | TypeImport): ParsedStaticImport; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseTypeImport(matched: TypeImport | StaticImport): ParsedStaticImport; +/** + * Identifies all export statements in the supplied source code and categorises them into different types such as declarations, named, default and star exports. + * This function processes the code to capture different forms of export statements and normalise their representation for further processing. + * + * @param {string} code - The source code containing the export statements to be analysed. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each export found, properly categorised and structured. + */ +declare function findExports(code: string): ESMExport[]; +/** + * Searches specifically for type-related exports in TypeScript code, such as exported interfaces, types, and declarations prefixed with 'declare'. + * This function uses specialised regular expressions to identify type exports and normalises them for consistency. + * + * @param {string} code - The TypeScript source code to search for type exports. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each type export found. + */ +declare function findTypeExports(code: string): ESMExport[]; +/** + * Extracts and returns a list of all export names from the given source. + * This function uses {@link findExports} to retrieve all types of exports and consolidates their names into a single array. + * + * @param {string} code - The source code to search for export names. + * @returns {string[]} An array containing the names of all exports found in the code. + */ +declare function findExportNames(code: string): string[]; +/** + * Asynchronously resolves and returns all export names from a module specified by its module identifier. + * This function recursively resolves all explicitly named and asterisked (* as) exports to fully enumerate the exported identifiers. + * + * @param {string} id - The module identifier to resolve. + * @param {ResolveOptions} [options] - Optional settings for resolving the module path, such as the base URL. + * @returns {Promise} A promise that resolves to an array of export names from the module. + */ +declare function resolveModuleExportNames(id: string, options?: ResolveOptions): Promise; + +/** + * Represents the context of a CommonJS environment, providing node-like module resolution capabilities within a module. + */ +interface CommonjsContext { + /** + * The absolute path to the current module file. + */ + __filename: string; + /** + * The directory name of the current module. + */ + __dirname: string; + /** + * A function to require modules as in CommonJS. + */ + require: NodeRequire; +} +/** + * Creates a CommonJS context for a given module URL, enabling `require`, `__filename` and `__dirname` support similar to Node.js. + * This function dynamically generates a `require` function that is context-aware and bound to the location of the given module URL. + * + * @param {string} url - The URL of the module file to create a context for. + * @returns {CommonjsContext} A context object containing `__filename`, `__dirname` and a custom `require` function. See {@link CommonjsContext}. + */ +declare function createCommonJS(url: string): CommonjsContext; +declare function interopDefault(sourceModule: any, opts?: { + preferNamespace?: boolean; +}): any; + +/** + * Options for evaluating or transforming modules, extending resolution options with optional URL specifications. + */ +interface EvaluateOptions extends ResolveOptions { + /** + * The URL of the module, which can be specified to override the URL resolved from the module identifier. + * @optional + */ + url?: string; +} +/** + * Loads a module by resolving its identifier to a URL, fetching the module's code and evaluating it. + * + * @param {string} id - The identifier of the module to load. + * @param {EvaluateOptions} options - Optional parameters to resolve and load the module. See {@link EvaluateOptions}. + * @returns {Promise} A promise to resolve to the evaluated module. + * }); + */ +declare function loadModule(id: string, options?: EvaluateOptions): Promise; +/** + * Evaluates JavaScript code as a module using a dynamic import from a data URL. + * + * @param {string} code - The code of the module to evaluate. + * @param {EvaluateOptions} options - Includes the original URL of the module for better error mapping. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the evaluated module or throws an error if the evaluation fails. + */ +declare function evalModule(code: string, options?: EvaluateOptions): Promise; +/** + * Transform module code to handle specific scenarios, such as converting JSON to a module or rewriting import.meta.url. + * + * @param {string} code - The code of the module to transform. + * @param {EvaluateOptions} options - Options to control how the code is transformed. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the transformed code. + */ +declare function transformModule(code: string, options?: EvaluateOptions): Promise; +/** + * Resolves all import URLs found within the provided code to their absolute URLs, based on the given options. + * + * @param {string} code - The code containing the import directives to resolve. + * @param {EvaluateOptions} [options] - Options to use for resolving imports. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the code, replacing import URLs with resolved URLs. + */ +declare function resolveImports(code: string, options?: EvaluateOptions): Promise; + +/** + * Options for detecting syntax within a code string. + */ +type DetectSyntaxOptions = { + /** + * Indicates whether comments should be stripped from the code before syntax checking. + * @default false + */ + stripComments?: boolean; +}; +/** + * Determines if a given code string contains ECMAScript module syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains ESM syntax, otherwise `false`. + */ +declare function hasESMSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Determines if a given string of code contains CommonJS syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains CommonJS syntax, `false` otherwise. + */ +declare function hasCJSSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Analyses the supplied code to determine if it contains ECMAScript module syntax, CommonJS syntax, or both. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {object} An object indicating the presence of ESM syntax (`hasESM`), CJS syntax (`hasCJS`) and whether both syntaxes are present (`isMixed`). + */ +declare function detectSyntax(code: string, opts?: DetectSyntaxOptions): { + hasESM: boolean; + hasCJS: boolean; + isMixed: boolean; +}; +interface ValidNodeImportOptions extends ResolveOptions { + /** + * The contents of the import, which may be analyzed to see if it contains + * CJS or ESM syntax as a last step in checking whether it is a valid import. + */ + code?: string; + /** + * Protocols that are allowed as valid node imports. + * + * @default ['node', 'file', 'data'] + * + */ + allowedProtocols?: Array; + /** + * Whether to strip comments from the code before checking for ESM syntax. + * + * @default false + */ + stripComments?: boolean; +} +/** + * Validates whether a given identifier represents a valid node import, based on its protocol, file extension, and optionally its contents. + * + * @param {string} id - The identifier or URL of the import to validate. + * @param {ValidNodeImportOptions} _options - Options for resolving and validating the import. See {@link ValidNodeImportOptions}. + * @returns {Promise} A promise that resolves to `true` if the import is valid, otherwise `false`. + */ +declare function isValidNodeImport(id: string, _options?: ValidNodeImportOptions): Promise; + +/** + * Converts a file URL to a local file system path with normalized slashes. + * + * @param {string | URL} id - The file URL or local path to convert. + * @returns {string} A normalized file system path. + */ +declare function fileURLToPath(id: string | URL): string; +/** + * Converts a local file system path to a file URL. + * + * @param {string | URL} id - The file system path to convert. + * @returns {string} The resulting file URL as a string. + */ +declare function pathToFileURL(id: string | URL): string; +/** + * Sanitises a component of a URI by replacing invalid characters. + * + * @param {string} name - The URI component to sanitise. + * @param {string} [replacement="_"] - The string to replace invalid characters with. + * @returns {string} The sanitised URI component. + */ +declare function sanitizeURIComponent(name?: string, replacement?: string): string; +/** + * Cleans a file path string by sanitising each component of the path. + * + * @param {string} filePath - The file path to sanitise. + * @returns {string} The sanitised file path. + */ +declare function sanitizeFilePath(filePath?: string): string; +/** + * Normalises a module identifier to ensure it has a protocol if missing, handling built-in modules and file paths. + * + * @param {string} id - The identifier to normalise. + * @returns {string} The normalised identifier with the appropriate protocol. + */ +declare function normalizeid(id: string): string; +/** + * Loads the contents of a file from a URL into a string. + * + * @param {string} url - The URL of the file to load. + * @returns {Promise} A promise that resolves to the content of the file. + */ +declare function loadURL(url: string): Promise; +/** + * Converts a string of code into a data URL that can be used for dynamic imports. + * + * @param {string} code - The string of code to convert. + * @returns {string} The data URL containing the encoded code. + */ +declare function toDataURL(code: string): string; +/** + * Checks if a module identifier matches a Node.js built-in module. + * + * @param {string} id - The identifier to check. + * @returns {boolean} `true` if the identifier is a built-in module, otherwise `false`. + */ +declare function isNodeBuiltin(id?: string): boolean; +/** + * Extracts the protocol portion of a given identifier string. + * + * @param {string} id - The identifier from which to extract the log. + * @returns {string | undefined} The protocol part of the identifier, or undefined if no protocol is present. + */ +declare function getProtocol(id: string): string | undefined; + +export { DYNAMIC_IMPORT_RE, ESM_STATIC_IMPORT_RE, EXPORT_DECAL_RE, EXPORT_DECAL_TYPE_RE, createCommonJS, createResolve, detectSyntax, evalModule, fileURLToPath, findDynamicImports, findExportNames, findExports, findStaticImports, findTypeExports, findTypeImports, getProtocol, hasCJSSyntax, hasESMSyntax, interopDefault, isNodeBuiltin, isValidNodeImport, loadModule, loadURL, lookupNodeModuleSubpath, normalizeid, parseNodeModulePath, parseStaticImport, parseTypeImport, pathToFileURL, resolve, resolveImports, resolveModuleExportNames, resolvePath, resolvePathSync, resolveSync, sanitizeFilePath, sanitizeURIComponent, toDataURL, transformModule }; +export type { CommonjsContext, DeclarationExport, DefaultExport, DetectSyntaxOptions, DynamicImport, ESMExport, ESMImport, EvaluateOptions, NamedExport, ParsedStaticImport, ResolveOptions, StaticImport, TypeImport, ValidNodeImportOptions }; diff --git a/node_modules/mlly/dist/index.d.ts b/node_modules/mlly/dist/index.d.ts new file mode 100644 index 0000000..a9029bd --- /dev/null +++ b/node_modules/mlly/dist/index.d.ts @@ -0,0 +1,564 @@ +interface ResolveOptions { + /** + * A URL, path or array of URLs/paths to resolve against. + */ + url?: string | URL | (string | URL)[]; + /** + * File extensions to consider when resolving modules. + */ + extensions?: string[]; + /** + * Conditions to consider when resolving package exports. + */ + conditions?: string[]; +} +/** + * Synchronously resolves a module path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved URL as a string. + */ +declare function resolveSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve the URL as a string. + */ +declare function resolve(id: string, options?: ResolveOptions): Promise; +/** + * Synchronously resolves a module path to a local file path based on the given options. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}. + * @returns {string} The resolved file path. + */ +declare function resolvePathSync(id: string, options?: ResolveOptions): string; +/** + * Asynchronously resolves a module path to a local file path based on the options provided. + * + * @param {string} id - The identifier or path of the module to resolve. + * @param {ResolveOptions} [options] - Options for resolving the module. See {@link ResolveOptions}. + * @returns {Promise} A promise to resolve to the file path. + */ +declare function resolvePath(id: string, options?: ResolveOptions): Promise; +/** + * Creates a resolver function with default options that can be used to resolve module identifiers. + * + * @param {ResolveOptions} [defaults] - Default options to use for all resolutions. See {@link ResolveOptions}. + * @returns {Function} A resolver function that takes an identifier and an optional URL, and resolves the identifier using the default options and the given URL. + */ +declare function createResolve(defaults?: ResolveOptions): (id: string, url?: ResolveOptions["url"]) => Promise; +/** + * Parses a node module path to extract the directory, name, and subpath. + * + * @param {string} path - The path to parse. + * @returns {Object} An object containing the directory, module name, and subpath of the node module. + */ +declare function parseNodeModulePath(path: string): { + dir?: undefined; + name?: undefined; + subpath?: undefined; +} | { + dir: string; + name: string; + subpath: string | undefined; +}; +/** + * Attempts to reverse engineer a subpath export within a node module. + * + * @param {string} path - The path within the node module. + * @returns {Promise} A promise that resolves to the detected subpath or undefined if not found. + */ +declare function lookupNodeModuleSubpath(path: string): Promise; + +/** + * Represents a general structure for ECMAScript module imports. + */ +interface ESMImport { + /** + * Specifies the type of import: "static" for static imports and "dynamic" for dynamic imports. + */ + type: "static" | "dynamic"; + /** + * The full import declaration code snippet as a string. + */ + code: string; + /** + * The starting position (index) of the import declaration in the source code. + */ + start: number; + /** + * The end position (index) of the import declaration in the source code. + */ + end: number; +} +/** + * Represents a static import declaration in an ECMAScript module. + * Extends {@link ESMImport}. + */ +interface StaticImport extends ESMImport { + /** + * Indicates the type of import, specifically a static import. + */ + type: "static"; + /** + * Contains the entire import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which imports are being brought in. + */ + specifier: string; +} +/** + * Represents a parsed static import declaration with detailed components of the import. + * Extends {@link StaticImport}. + */ +interface ParsedStaticImport extends StaticImport { + /** + * The default import name, if any. + * @optional + */ + defaultImport?: string; + /** + * The namespace import name, if any, using the `* as` syntax. + * @optional + */ + namespacedImport?: string; + /** + * An object representing named imports, with their local aliases if specified. + * Each property key is the original name and its value is the alias. + * @optional + */ + namedImports?: { + [name: string]: string; + }; +} +/** + * Represents a dynamic import declaration that is loaded at runtime. + * Extends {@link ESMImport}. + */ +interface DynamicImport extends ESMImport { + /** + * Indicates that this is a dynamic import. + */ + type: "dynamic"; + /** + * The expression or path to be dynamically imported, typically a module path or URL. + */ + expression: string; +} +/** + * Represents a type-specific import, primarily used for importing types in TypeScript. + * Extends {@link ESMImport} but omits the 'type' to redefine it specifically for type imports. + */ +interface TypeImport extends Omit { + /** + * Specifies that this is a type import. + */ + type: "type"; + /** + * Contains the entire type import statement as a string, excluding the module specifier. + */ + imports: string; + /** + * The module specifier from which to import types. + */ + specifier: string; +} +/** + * Represents a general structure for ECMAScript module exports. + */ +interface ESMExport { + /** + * Optional explicit type for complex scenarios, often used internally. + * @optional + */ + _type?: "declaration" | "named" | "default" | "star"; + /** + * The type of export (declaration, named, default or star). + */ + type: "declaration" | "named" | "default" | "star"; + /** + * The specific type of declaration being exported, if applicable. + * @optional + */ + declarationType?: "let" | "var" | "const" | "enum" | "const enum" | "class" | "function" | "async function"; + /** + * The full code snippet of the export statement. + */ + code: string; + /** + * The starting position (index) of the export declaration in the source code. + */ + start: number; + /** + * The end position (index) of the export declaration in the source code. + */ + end: number; + /** + * The name of the variable, function or class being exported, if given explicitly. + * @optional + */ + name?: string; + /** + * The name used for default exports when a specific identifier isn't given. + * @optional + */ + defaultName?: string; + /** + * An array of names to export, applicable to named and destructured exports. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a declaration export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DeclarationExport extends ESMExport { + /** + * Indicates that this export is a declaration export. + */ + type: "declaration"; + /** + * The declaration string, such as 'let', 'const', 'class', etc., describing what is being exported. + */ + declaration: string; + /** + * The name of the declaration to be exported. + */ + name: string; +} +/** + * Represents a named export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface NamedExport extends ESMExport { + /** + * Specifies that this export is a named export. + */ + type: "named"; + /** + * The export string, containing all exported identifiers. + */ + exports: string; + /** + * An array of names to export. + */ + names: string[]; + /** + * The module specifier, if any, from which exports are being re-exported. + * @optional + */ + specifier?: string; +} +/** + * Represents a standard export within an ECMAScript module. + * Extends {@link ESMExport}. + */ +interface DefaultExport extends ESMExport { + /** + * Specifies that this export is a standard export. + */ + type: "default"; +} +/** + * Regular expression to match static import statements in JavaScript/TypeScript code. + * @example `import { foo, bar as baz } from 'module'` + */ +declare const ESM_STATIC_IMPORT_RE: RegExp; +/** + * Regular expression to match dynamic import statements in JavaScript/TypeScript code. + * @example `import('module')` + */ +declare const DYNAMIC_IMPORT_RE: RegExp; +/** + * Regular expression to match various types of export declarations including variables, functions, and classes. + * @example `export const num = 1, str = 'hello'; export class Example {}` + */ +declare const EXPORT_DECAL_RE: RegExp; +/** + * Regular expression to match export declarations specifically for types, interfaces, and type aliases in TypeScript. + * @example `export type Result = { success: boolean; }; export interface User { name: string; age: number; };` + */ +declare const EXPORT_DECAL_TYPE_RE: RegExp; +/** + * Finds all static import statements within the given code string. + * @param {string} code - The source code to search for static imports. + * @returns {StaticImport[]} An array of {@link StaticImport} objects representing each static import found. + */ +declare function findStaticImports(code: string): StaticImport[]; +/** + * Searches for dynamic import statements in the given source code. + * @param {string} code - The source to search for dynamic imports in. + * @returns {DynamicImport[]} An array of {@link DynamicImport} objects representing each dynamic import found. + */ +declare function findDynamicImports(code: string): DynamicImport[]; +/** + * Identifies and returns all type import statements in the given source code. + * This function is specifically targeted at type imports used in TypeScript. + * @param {string} code - The source code to search for type imports. + * @returns {TypeImport[]} An array of {@link TypeImport} objects representing each type import found. + */ +declare function findTypeImports(code: string): TypeImport[]; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseStaticImport(matched: StaticImport | TypeImport): ParsedStaticImport; +/** + * Parses a static import or type import to extract detailed import elements such as default, namespace and named imports. + * @param {StaticImport | TypeImport} matched - The matched import statement to parse. See {@link StaticImport} and {@link TypeImport}. + * @returns {ParsedStaticImport} A structured object representing the parsed static import. See {@link ParsedStaticImport}. + */ +declare function parseTypeImport(matched: TypeImport | StaticImport): ParsedStaticImport; +/** + * Identifies all export statements in the supplied source code and categorises them into different types such as declarations, named, default and star exports. + * This function processes the code to capture different forms of export statements and normalise their representation for further processing. + * + * @param {string} code - The source code containing the export statements to be analysed. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each export found, properly categorised and structured. + */ +declare function findExports(code: string): ESMExport[]; +/** + * Searches specifically for type-related exports in TypeScript code, such as exported interfaces, types, and declarations prefixed with 'declare'. + * This function uses specialised regular expressions to identify type exports and normalises them for consistency. + * + * @param {string} code - The TypeScript source code to search for type exports. + * @returns {ESMExport[]} An array of {@link ESMExport} objects representing each type export found. + */ +declare function findTypeExports(code: string): ESMExport[]; +/** + * Extracts and returns a list of all export names from the given source. + * This function uses {@link findExports} to retrieve all types of exports and consolidates their names into a single array. + * + * @param {string} code - The source code to search for export names. + * @returns {string[]} An array containing the names of all exports found in the code. + */ +declare function findExportNames(code: string): string[]; +/** + * Asynchronously resolves and returns all export names from a module specified by its module identifier. + * This function recursively resolves all explicitly named and asterisked (* as) exports to fully enumerate the exported identifiers. + * + * @param {string} id - The module identifier to resolve. + * @param {ResolveOptions} [options] - Optional settings for resolving the module path, such as the base URL. + * @returns {Promise} A promise that resolves to an array of export names from the module. + */ +declare function resolveModuleExportNames(id: string, options?: ResolveOptions): Promise; + +/** + * Represents the context of a CommonJS environment, providing node-like module resolution capabilities within a module. + */ +interface CommonjsContext { + /** + * The absolute path to the current module file. + */ + __filename: string; + /** + * The directory name of the current module. + */ + __dirname: string; + /** + * A function to require modules as in CommonJS. + */ + require: NodeRequire; +} +/** + * Creates a CommonJS context for a given module URL, enabling `require`, `__filename` and `__dirname` support similar to Node.js. + * This function dynamically generates a `require` function that is context-aware and bound to the location of the given module URL. + * + * @param {string} url - The URL of the module file to create a context for. + * @returns {CommonjsContext} A context object containing `__filename`, `__dirname` and a custom `require` function. See {@link CommonjsContext}. + */ +declare function createCommonJS(url: string): CommonjsContext; +declare function interopDefault(sourceModule: any, opts?: { + preferNamespace?: boolean; +}): any; + +/** + * Options for evaluating or transforming modules, extending resolution options with optional URL specifications. + */ +interface EvaluateOptions extends ResolveOptions { + /** + * The URL of the module, which can be specified to override the URL resolved from the module identifier. + * @optional + */ + url?: string; +} +/** + * Loads a module by resolving its identifier to a URL, fetching the module's code and evaluating it. + * + * @param {string} id - The identifier of the module to load. + * @param {EvaluateOptions} options - Optional parameters to resolve and load the module. See {@link EvaluateOptions}. + * @returns {Promise} A promise to resolve to the evaluated module. + * }); + */ +declare function loadModule(id: string, options?: EvaluateOptions): Promise; +/** + * Evaluates JavaScript code as a module using a dynamic import from a data URL. + * + * @param {string} code - The code of the module to evaluate. + * @param {EvaluateOptions} options - Includes the original URL of the module for better error mapping. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the evaluated module or throws an error if the evaluation fails. + */ +declare function evalModule(code: string, options?: EvaluateOptions): Promise; +/** + * Transform module code to handle specific scenarios, such as converting JSON to a module or rewriting import.meta.url. + * + * @param {string} code - The code of the module to transform. + * @param {EvaluateOptions} options - Options to control how the code is transformed. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the transformed code. + */ +declare function transformModule(code: string, options?: EvaluateOptions): Promise; +/** + * Resolves all import URLs found within the provided code to their absolute URLs, based on the given options. + * + * @param {string} code - The code containing the import directives to resolve. + * @param {EvaluateOptions} [options] - Options to use for resolving imports. See {@link EvaluateOptions}. + * @returns {Promise} A promise that resolves to the code, replacing import URLs with resolved URLs. + */ +declare function resolveImports(code: string, options?: EvaluateOptions): Promise; + +/** + * Options for detecting syntax within a code string. + */ +type DetectSyntaxOptions = { + /** + * Indicates whether comments should be stripped from the code before syntax checking. + * @default false + */ + stripComments?: boolean; +}; +/** + * Determines if a given code string contains ECMAScript module syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains ESM syntax, otherwise `false`. + */ +declare function hasESMSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Determines if a given string of code contains CommonJS syntax. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {boolean} `true` if the code contains CommonJS syntax, `false` otherwise. + */ +declare function hasCJSSyntax(code: string, opts?: DetectSyntaxOptions): boolean; +/** + * Analyses the supplied code to determine if it contains ECMAScript module syntax, CommonJS syntax, or both. + * + * @param {string} code - The source code to analyse. + * @param {DetectSyntaxOptions} opts - See {@link DetectSyntaxOptions}. + * @returns {object} An object indicating the presence of ESM syntax (`hasESM`), CJS syntax (`hasCJS`) and whether both syntaxes are present (`isMixed`). + */ +declare function detectSyntax(code: string, opts?: DetectSyntaxOptions): { + hasESM: boolean; + hasCJS: boolean; + isMixed: boolean; +}; +interface ValidNodeImportOptions extends ResolveOptions { + /** + * The contents of the import, which may be analyzed to see if it contains + * CJS or ESM syntax as a last step in checking whether it is a valid import. + */ + code?: string; + /** + * Protocols that are allowed as valid node imports. + * + * @default ['node', 'file', 'data'] + * + */ + allowedProtocols?: Array; + /** + * Whether to strip comments from the code before checking for ESM syntax. + * + * @default false + */ + stripComments?: boolean; +} +/** + * Validates whether a given identifier represents a valid node import, based on its protocol, file extension, and optionally its contents. + * + * @param {string} id - The identifier or URL of the import to validate. + * @param {ValidNodeImportOptions} _options - Options for resolving and validating the import. See {@link ValidNodeImportOptions}. + * @returns {Promise} A promise that resolves to `true` if the import is valid, otherwise `false`. + */ +declare function isValidNodeImport(id: string, _options?: ValidNodeImportOptions): Promise; + +/** + * Converts a file URL to a local file system path with normalized slashes. + * + * @param {string | URL} id - The file URL or local path to convert. + * @returns {string} A normalized file system path. + */ +declare function fileURLToPath(id: string | URL): string; +/** + * Converts a local file system path to a file URL. + * + * @param {string | URL} id - The file system path to convert. + * @returns {string} The resulting file URL as a string. + */ +declare function pathToFileURL(id: string | URL): string; +/** + * Sanitises a component of a URI by replacing invalid characters. + * + * @param {string} name - The URI component to sanitise. + * @param {string} [replacement="_"] - The string to replace invalid characters with. + * @returns {string} The sanitised URI component. + */ +declare function sanitizeURIComponent(name?: string, replacement?: string): string; +/** + * Cleans a file path string by sanitising each component of the path. + * + * @param {string} filePath - The file path to sanitise. + * @returns {string} The sanitised file path. + */ +declare function sanitizeFilePath(filePath?: string): string; +/** + * Normalises a module identifier to ensure it has a protocol if missing, handling built-in modules and file paths. + * + * @param {string} id - The identifier to normalise. + * @returns {string} The normalised identifier with the appropriate protocol. + */ +declare function normalizeid(id: string): string; +/** + * Loads the contents of a file from a URL into a string. + * + * @param {string} url - The URL of the file to load. + * @returns {Promise} A promise that resolves to the content of the file. + */ +declare function loadURL(url: string): Promise; +/** + * Converts a string of code into a data URL that can be used for dynamic imports. + * + * @param {string} code - The string of code to convert. + * @returns {string} The data URL containing the encoded code. + */ +declare function toDataURL(code: string): string; +/** + * Checks if a module identifier matches a Node.js built-in module. + * + * @param {string} id - The identifier to check. + * @returns {boolean} `true` if the identifier is a built-in module, otherwise `false`. + */ +declare function isNodeBuiltin(id?: string): boolean; +/** + * Extracts the protocol portion of a given identifier string. + * + * @param {string} id - The identifier from which to extract the log. + * @returns {string | undefined} The protocol part of the identifier, or undefined if no protocol is present. + */ +declare function getProtocol(id: string): string | undefined; + +export { DYNAMIC_IMPORT_RE, ESM_STATIC_IMPORT_RE, EXPORT_DECAL_RE, EXPORT_DECAL_TYPE_RE, createCommonJS, createResolve, detectSyntax, evalModule, fileURLToPath, findDynamicImports, findExportNames, findExports, findStaticImports, findTypeExports, findTypeImports, getProtocol, hasCJSSyntax, hasESMSyntax, interopDefault, isNodeBuiltin, isValidNodeImport, loadModule, loadURL, lookupNodeModuleSubpath, normalizeid, parseNodeModulePath, parseStaticImport, parseTypeImport, pathToFileURL, resolve, resolveImports, resolveModuleExportNames, resolvePath, resolvePathSync, resolveSync, sanitizeFilePath, sanitizeURIComponent, toDataURL, transformModule }; +export type { CommonjsContext, DeclarationExport, DefaultExport, DetectSyntaxOptions, DynamicImport, ESMExport, ESMImport, EvaluateOptions, NamedExport, ParsedStaticImport, ResolveOptions, StaticImport, TypeImport, ValidNodeImportOptions }; diff --git a/node_modules/mlly/dist/index.mjs b/node_modules/mlly/dist/index.mjs new file mode 100644 index 0000000..38561d3 --- /dev/null +++ b/node_modules/mlly/dist/index.mjs @@ -0,0 +1,2708 @@ +import { tokenizer } from 'acorn'; +import { builtinModules, createRequire } from 'node:module'; +import fs, { realpathSync, statSync, promises } from 'node:fs'; +import { joinURL } from 'ufo'; +import { normalize, isAbsolute, extname as extname$1 } from 'pathe'; +import { readPackageJSON } from 'pkg-types'; +import { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1 } from 'node:url'; +import assert from 'node:assert'; +import process$1 from 'node:process'; +import path, { dirname } from 'node:path'; +import v8 from 'node:v8'; +import { format, inspect } from 'node:util'; + +const BUILTIN_MODULES = new Set(builtinModules); +function normalizeSlash(path) { + return path.replace(/\\/g, "/"); +} +function isObject(value) { + return value !== null && typeof value === "object"; +} +function matchAll(regex, string, addition) { + const matches = []; + for (const match of string.matchAll(regex)) { + matches.push({ + ...addition, + ...match.groups, + code: match[0], + start: match.index, + end: (match.index || 0) + match[0].length + }); + } + return matches; +} +function clearImports(imports) { + return (imports || "").replace(/\/\/[^\n]*\n|\/\*.*\*\//g, "").replace(/\s+/g, " "); +} +function getImportNames(cleanedImports) { + const topLevelImports = cleanedImports.replace(/{[^}]*}/, ""); + const namespacedImport = topLevelImports.match(/\* as \s*(\S*)/)?.[1]; + const defaultImport = topLevelImports.split(",").find((index) => !/[*{}]/.test(index))?.trim() || void 0; + return { + namespacedImport, + defaultImport + }; +} + +/** + * @typedef ErrnoExceptionFields + * @property {number | undefined} [errnode] + * @property {string | undefined} [code] + * @property {string | undefined} [path] + * @property {string | undefined} [syscall] + * @property {string | undefined} [url] + * + * @typedef {Error & ErrnoExceptionFields} ErrnoException + */ + + +const own$1 = {}.hasOwnProperty; + +const classRegExp = /^([A-Z][a-z\d]*)+$/; +// Sorted by a rough estimate on most frequently used entries. +const kTypes = new Set([ + 'string', + 'function', + 'number', + 'object', + // Accept 'Function' and 'Object' as alternative to the lower cased version. + 'Function', + 'Object', + 'boolean', + 'bigint', + 'symbol' +]); + +const codes = {}; + +/** + * Create a list string in the form like 'A and B' or 'A, B, ..., and Z'. + * We cannot use Intl.ListFormat because it's not available in + * --without-intl builds. + * + * @param {Array} array + * An array of strings. + * @param {string} [type] + * The list type to be inserted before the last element. + * @returns {string} + */ +function formatList(array, type = 'and') { + return array.length < 3 + ? array.join(` ${type} `) + : `${array.slice(0, -1).join(', ')}, ${type} ${array[array.length - 1]}` +} + +/** @type {Map} */ +const messages = new Map(); +const nodeInternalPrefix = '__node_internal_'; +/** @type {number} */ +let userStackTraceLimit; + +codes.ERR_INVALID_ARG_TYPE = createError( + 'ERR_INVALID_ARG_TYPE', + /** + * @param {string} name + * @param {Array | string} expected + * @param {unknown} actual + */ + (name, expected, actual) => { + assert.ok(typeof name === 'string', "'name' must be a string"); + if (!Array.isArray(expected)) { + expected = [expected]; + } + + let message = 'The '; + if (name.endsWith(' argument')) { + // For cases like 'first argument' + message += `${name} `; + } else { + const type = name.includes('.') ? 'property' : 'argument'; + message += `"${name}" ${type} `; + } + + message += 'must be '; + + /** @type {Array} */ + const types = []; + /** @type {Array} */ + const instances = []; + /** @type {Array} */ + const other = []; + + for (const value of expected) { + assert.ok( + typeof value === 'string', + 'All expected entries have to be of type string' + ); + + if (kTypes.has(value)) { + types.push(value.toLowerCase()); + } else if (classRegExp.exec(value) === null) { + assert.ok( + value !== 'object', + 'The value "object" should be written as "Object"' + ); + other.push(value); + } else { + instances.push(value); + } + } + + // Special handle `object` in case other instances are allowed to outline + // the differences between each other. + if (instances.length > 0) { + const pos = types.indexOf('object'); + if (pos !== -1) { + types.slice(pos, 1); + instances.push('Object'); + } + } + + if (types.length > 0) { + message += `${types.length > 1 ? 'one of type' : 'of type'} ${formatList( + types, + 'or' + )}`; + if (instances.length > 0 || other.length > 0) message += ' or '; + } + + if (instances.length > 0) { + message += `an instance of ${formatList(instances, 'or')}`; + if (other.length > 0) message += ' or '; + } + + if (other.length > 0) { + if (other.length > 1) { + message += `one of ${formatList(other, 'or')}`; + } else { + if (other[0].toLowerCase() !== other[0]) message += 'an '; + message += `${other[0]}`; + } + } + + message += `. Received ${determineSpecificType(actual)}`; + + return message + }, + TypeError +); + +codes.ERR_INVALID_MODULE_SPECIFIER = createError( + 'ERR_INVALID_MODULE_SPECIFIER', + /** + * @param {string} request + * @param {string} reason + * @param {string} [base] + */ + (request, reason, base = undefined) => { + return `Invalid module "${request}" ${reason}${ + base ? ` imported from ${base}` : '' + }` + }, + TypeError +); + +codes.ERR_INVALID_PACKAGE_CONFIG = createError( + 'ERR_INVALID_PACKAGE_CONFIG', + /** + * @param {string} path + * @param {string} [base] + * @param {string} [message] + */ + (path, base, message) => { + return `Invalid package config ${path}${ + base ? ` while importing ${base}` : '' + }${message ? `. ${message}` : ''}` + }, + Error +); + +codes.ERR_INVALID_PACKAGE_TARGET = createError( + 'ERR_INVALID_PACKAGE_TARGET', + /** + * @param {string} packagePath + * @param {string} key + * @param {unknown} target + * @param {boolean} [isImport=false] + * @param {string} [base] + */ + (packagePath, key, target, isImport = false, base = undefined) => { + const relatedError = + typeof target === 'string' && + !isImport && + target.length > 0 && + !target.startsWith('./'); + if (key === '.') { + assert.ok(isImport === false); + return ( + `Invalid "exports" main target ${JSON.stringify(target)} defined ` + + `in the package config ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }${relatedError ? '; targets must start with "./"' : ''}` + ) + } + + return `Invalid "${ + isImport ? 'imports' : 'exports' + }" target ${JSON.stringify( + target + )} defined for '${key}' in the package config ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }${relatedError ? '; targets must start with "./"' : ''}` + }, + Error +); + +codes.ERR_MODULE_NOT_FOUND = createError( + 'ERR_MODULE_NOT_FOUND', + /** + * @param {string} path + * @param {string} base + * @param {boolean} [exactUrl] + */ + (path, base, exactUrl = false) => { + return `Cannot find ${ + exactUrl ? 'module' : 'package' + } '${path}' imported from ${base}` + }, + Error +); + +codes.ERR_NETWORK_IMPORT_DISALLOWED = createError( + 'ERR_NETWORK_IMPORT_DISALLOWED', + "import of '%s' by %s is not supported: %s", + Error +); + +codes.ERR_PACKAGE_IMPORT_NOT_DEFINED = createError( + 'ERR_PACKAGE_IMPORT_NOT_DEFINED', + /** + * @param {string} specifier + * @param {string} packagePath + * @param {string} base + */ + (specifier, packagePath, base) => { + return `Package import specifier "${specifier}" is not defined${ + packagePath ? ` in package ${packagePath}package.json` : '' + } imported from ${base}` + }, + TypeError +); + +codes.ERR_PACKAGE_PATH_NOT_EXPORTED = createError( + 'ERR_PACKAGE_PATH_NOT_EXPORTED', + /** + * @param {string} packagePath + * @param {string} subpath + * @param {string} [base] + */ + (packagePath, subpath, base = undefined) => { + if (subpath === '.') + return `No "exports" main defined in ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }` + return `Package subpath '${subpath}' is not defined by "exports" in ${packagePath}package.json${ + base ? ` imported from ${base}` : '' + }` + }, + Error +); + +codes.ERR_UNSUPPORTED_DIR_IMPORT = createError( + 'ERR_UNSUPPORTED_DIR_IMPORT', + "Directory import '%s' is not supported " + + 'resolving ES modules imported from %s', + Error +); + +codes.ERR_UNSUPPORTED_RESOLVE_REQUEST = createError( + 'ERR_UNSUPPORTED_RESOLVE_REQUEST', + 'Failed to resolve module specifier "%s" from "%s": Invalid relative URL or base scheme is not hierarchical.', + TypeError +); + +codes.ERR_UNKNOWN_FILE_EXTENSION = createError( + 'ERR_UNKNOWN_FILE_EXTENSION', + /** + * @param {string} extension + * @param {string} path + */ + (extension, path) => { + return `Unknown file extension "${extension}" for ${path}` + }, + TypeError +); + +codes.ERR_INVALID_ARG_VALUE = createError( + 'ERR_INVALID_ARG_VALUE', + /** + * @param {string} name + * @param {unknown} value + * @param {string} [reason='is invalid'] + */ + (name, value, reason = 'is invalid') => { + let inspected = inspect(value); + + if (inspected.length > 128) { + inspected = `${inspected.slice(0, 128)}...`; + } + + const type = name.includes('.') ? 'property' : 'argument'; + + return `The ${type} '${name}' ${reason}. Received ${inspected}` + }, + TypeError + // Note: extra classes have been shaken out. + // , RangeError +); + +/** + * Utility function for registering the error codes. Only used here. Exported + * *only* to allow for testing. + * @param {string} sym + * @param {MessageFunction | string} value + * @param {ErrorConstructor} constructor + * @returns {new (...parameters: Array) => Error} + */ +function createError(sym, value, constructor) { + // Special case for SystemError that formats the error message differently + // The SystemErrors only have SystemError as their base classes. + messages.set(sym, value); + + return makeNodeErrorWithCode(constructor, sym) +} + +/** + * @param {ErrorConstructor} Base + * @param {string} key + * @returns {ErrorConstructor} + */ +function makeNodeErrorWithCode(Base, key) { + // @ts-expect-error It’s a Node error. + return NodeError + /** + * @param {Array} parameters + */ + function NodeError(...parameters) { + const limit = Error.stackTraceLimit; + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const error = new Base(); + // Reset the limit and setting the name property. + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; + const message = getMessage(key, parameters, error); + Object.defineProperties(error, { + // Note: no need to implement `kIsNodeError` symbol, would be hard, + // probably. + message: { + value: message, + enumerable: false, + writable: true, + configurable: true + }, + toString: { + /** @this {Error} */ + value() { + return `${this.name} [${key}]: ${this.message}` + }, + enumerable: false, + writable: true, + configurable: true + } + }); + + captureLargerStackTrace(error); + // @ts-expect-error It’s a Node error. + error.code = key; + return error + } +} + +/** + * @returns {boolean} + */ +function isErrorStackTraceLimitWritable() { + // Do no touch Error.stackTraceLimit as V8 would attempt to install + // it again during deserialization. + try { + if (v8.startupSnapshot.isBuildingSnapshot()) { + return false + } + } catch {} + + const desc = Object.getOwnPropertyDescriptor(Error, 'stackTraceLimit'); + if (desc === undefined) { + return Object.isExtensible(Error) + } + + return own$1.call(desc, 'writable') && desc.writable !== undefined + ? desc.writable + : desc.set !== undefined +} + +/** + * This function removes unnecessary frames from Node.js core errors. + * @template {(...parameters: unknown[]) => unknown} T + * @param {T} wrappedFunction + * @returns {T} + */ +function hideStackFrames(wrappedFunction) { + // We rename the functions that will be hidden to cut off the stacktrace + // at the outermost one + const hidden = nodeInternalPrefix + wrappedFunction.name; + Object.defineProperty(wrappedFunction, 'name', {value: hidden}); + return wrappedFunction +} + +const captureLargerStackTrace = hideStackFrames( + /** + * @param {Error} error + * @returns {Error} + */ + // @ts-expect-error: fine + function (error) { + const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); + if (stackTraceLimitIsWritable) { + userStackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = Number.POSITIVE_INFINITY; + } + + Error.captureStackTrace(error); + + // Reset the limit + if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; + + return error + } +); + +/** + * @param {string} key + * @param {Array} parameters + * @param {Error} self + * @returns {string} + */ +function getMessage(key, parameters, self) { + const message = messages.get(key); + assert.ok(message !== undefined, 'expected `message` to be found'); + + if (typeof message === 'function') { + assert.ok( + message.length <= parameters.length, // Default options do not count. + `Code: ${key}; The provided arguments length (${parameters.length}) does not ` + + `match the required ones (${message.length}).` + ); + return Reflect.apply(message, self, parameters) + } + + const regex = /%[dfijoOs]/g; + let expectedLength = 0; + while (regex.exec(message) !== null) expectedLength++; + assert.ok( + expectedLength === parameters.length, + `Code: ${key}; The provided arguments length (${parameters.length}) does not ` + + `match the required ones (${expectedLength}).` + ); + if (parameters.length === 0) return message + + parameters.unshift(message); + return Reflect.apply(format, null, parameters) +} + +/** + * Determine the specific type of a value for type-mismatch errors. + * @param {unknown} value + * @returns {string} + */ +function determineSpecificType(value) { + if (value === null || value === undefined) { + return String(value) + } + + if (typeof value === 'function' && value.name) { + return `function ${value.name}` + } + + if (typeof value === 'object') { + if (value.constructor && value.constructor.name) { + return `an instance of ${value.constructor.name}` + } + + return `${inspect(value, {depth: -1})}` + } + + let inspected = inspect(value, {colors: false}); + + if (inspected.length > 28) { + inspected = `${inspected.slice(0, 25)}...`; + } + + return `type ${typeof value} (${inspected})` +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. +// Removed the native dependency. +// Also: no need to cache, we do that in resolve already. + + +const hasOwnProperty$1 = {}.hasOwnProperty; + +const {ERR_INVALID_PACKAGE_CONFIG: ERR_INVALID_PACKAGE_CONFIG$1} = codes; + +/** @type {Map} */ +const cache = new Map(); + +/** + * @param {string} jsonPath + * @param {{specifier: URL | string, base?: URL}} options + * @returns {PackageConfig} + */ +function read(jsonPath, {base, specifier}) { + const existing = cache.get(jsonPath); + + if (existing) { + return existing + } + + /** @type {string | undefined} */ + let string; + + try { + string = fs.readFileSync(path.toNamespacedPath(jsonPath), 'utf8'); + } catch (error) { + const exception = /** @type {ErrnoException} */ (error); + + if (exception.code !== 'ENOENT') { + throw exception + } + } + + /** @type {PackageConfig} */ + const result = { + exists: false, + pjsonPath: jsonPath, + main: undefined, + name: undefined, + type: 'none', // Ignore unknown types for forwards compatibility + exports: undefined, + imports: undefined + }; + + if (string !== undefined) { + /** @type {Record} */ + let parsed; + + try { + parsed = JSON.parse(string); + } catch (error_) { + const cause = /** @type {ErrnoException} */ (error_); + const error = new ERR_INVALID_PACKAGE_CONFIG$1( + jsonPath, + (base ? `"${specifier}" from ` : '') + fileURLToPath$1(base || specifier), + cause.message + ); + error.cause = cause; + throw error + } + + result.exists = true; + + if ( + hasOwnProperty$1.call(parsed, 'name') && + typeof parsed.name === 'string' + ) { + result.name = parsed.name; + } + + if ( + hasOwnProperty$1.call(parsed, 'main') && + typeof parsed.main === 'string' + ) { + result.main = parsed.main; + } + + if (hasOwnProperty$1.call(parsed, 'exports')) { + // @ts-expect-error: assume valid. + result.exports = parsed.exports; + } + + if (hasOwnProperty$1.call(parsed, 'imports')) { + // @ts-expect-error: assume valid. + result.imports = parsed.imports; + } + + // Ignore unknown types for forwards compatibility + if ( + hasOwnProperty$1.call(parsed, 'type') && + (parsed.type === 'commonjs' || parsed.type === 'module') + ) { + result.type = parsed.type; + } + } + + cache.set(jsonPath, result); + + return result +} + +/** + * @param {URL | string} resolved + * @returns {PackageConfig} + */ +function getPackageScopeConfig(resolved) { + // Note: in Node, this is now a native module. + let packageJSONUrl = new URL('package.json', resolved); + + while (true) { + const packageJSONPath = packageJSONUrl.pathname; + if (packageJSONPath.endsWith('node_modules/package.json')) { + break + } + + const packageConfig = read(fileURLToPath$1(packageJSONUrl), { + specifier: resolved + }); + + if (packageConfig.exists) { + return packageConfig + } + + const lastPackageJSONUrl = packageJSONUrl; + packageJSONUrl = new URL('../package.json', packageJSONUrl); + + // Terminates at root where ../package.json equals ../../package.json + // (can't just check "/package.json" for Windows support). + if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) { + break + } + } + + const packageJSONPath = fileURLToPath$1(packageJSONUrl); + // ^^ Note: in Node, this is now a native module. + + return { + pjsonPath: packageJSONPath, + exists: false, + type: 'none' + } +} + +/** + * Returns the package type for a given URL. + * @param {URL} url - The URL to get the package type for. + * @returns {PackageType} + */ +function getPackageType(url) { + // To do @anonrig: Write a C++ function that returns only "type". + return getPackageScopeConfig(url).type +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +const {ERR_UNKNOWN_FILE_EXTENSION} = codes; + +const hasOwnProperty = {}.hasOwnProperty; + +/** @type {Record} */ +const extensionFormatMap = { + // @ts-expect-error: hush. + __proto__: null, + '.cjs': 'commonjs', + '.js': 'module', + '.json': 'json', + '.mjs': 'module' +}; + +/** + * @param {string | null} mime + * @returns {string | null} + */ +function mimeToFormat(mime) { + if ( + mime && + /\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?/i.test(mime) + ) + return 'module' + if (mime === 'application/json') return 'json' + return null +} + +/** + * @callback ProtocolHandler + * @param {URL} parsed + * @param {{parentURL: string, source?: Buffer}} context + * @param {boolean} ignoreErrors + * @returns {string | null | void} + */ + +/** + * @type {Record} + */ +const protocolHandlers = { + // @ts-expect-error: hush. + __proto__: null, + 'data:': getDataProtocolModuleFormat, + 'file:': getFileProtocolModuleFormat, + 'http:': getHttpProtocolModuleFormat, + 'https:': getHttpProtocolModuleFormat, + 'node:'() { + return 'builtin' + } +}; + +/** + * @param {URL} parsed + */ +function getDataProtocolModuleFormat(parsed) { + const {1: mime} = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec( + parsed.pathname + ) || [null, null, null]; + return mimeToFormat(mime) +} + +/** + * Returns the file extension from a URL. + * + * Should give similar result to + * `require('node:path').extname(require('node:url').fileURLToPath(url))` + * when used with a `file:` URL. + * + * @param {URL} url + * @returns {string} + */ +function extname(url) { + const pathname = url.pathname; + let index = pathname.length; + + while (index--) { + const code = pathname.codePointAt(index); + + if (code === 47 /* `/` */) { + return '' + } + + if (code === 46 /* `.` */) { + return pathname.codePointAt(index - 1) === 47 /* `/` */ + ? '' + : pathname.slice(index) + } + } + + return '' +} + +/** + * @type {ProtocolHandler} + */ +function getFileProtocolModuleFormat(url, _context, ignoreErrors) { + const value = extname(url); + + if (value === '.js') { + const packageType = getPackageType(url); + + if (packageType !== 'none') { + return packageType + } + + return 'commonjs' + } + + if (value === '') { + const packageType = getPackageType(url); + + // Legacy behavior + if (packageType === 'none' || packageType === 'commonjs') { + return 'commonjs' + } + + // Note: we don’t implement WASM, so we don’t need + // `getFormatOfExtensionlessFile` from `formats`. + return 'module' + } + + const format = extensionFormatMap[value]; + if (format) return format + + // Explicit undefined return indicates load hook should rerun format check + if (ignoreErrors) { + return undefined + } + + const filepath = fileURLToPath$1(url); + throw new ERR_UNKNOWN_FILE_EXTENSION(value, filepath) +} + +function getHttpProtocolModuleFormat() { + // To do: HTTPS imports. +} + +/** + * @param {URL} url + * @param {{parentURL: string}} context + * @returns {string | null} + */ +function defaultGetFormatWithoutErrors(url, context) { + const protocol = url.protocol; + + if (!hasOwnProperty.call(protocolHandlers, protocol)) { + return null + } + + return protocolHandlers[protocol](url, context, true) || null +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +// In Node itself these values are populated from CLI arguments, before any +// user code runs. +// Here we just define the defaults. +const DEFAULT_CONDITIONS = Object.freeze(['node', 'import']); +const DEFAULT_CONDITIONS_SET$1 = new Set(DEFAULT_CONDITIONS); + +/** + * Returns the default conditions for ES module loading, as a Set. + */ +function getDefaultConditionsSet() { + return DEFAULT_CONDITIONS_SET$1 +} + +/** + * @param {Array} [conditions] + * @returns {Set} + */ +function getConditionsSet(conditions) { + + return getDefaultConditionsSet() +} + +// Manually “tree shaken” from: +// +// Last checked on: Apr 29, 2024. + + +const RegExpPrototypeSymbolReplace = RegExp.prototype[Symbol.replace]; + +const { + ERR_INVALID_MODULE_SPECIFIER, + ERR_INVALID_PACKAGE_CONFIG, + ERR_INVALID_PACKAGE_TARGET, + ERR_MODULE_NOT_FOUND, + ERR_PACKAGE_IMPORT_NOT_DEFINED, + ERR_PACKAGE_PATH_NOT_EXPORTED, + ERR_UNSUPPORTED_DIR_IMPORT, + ERR_UNSUPPORTED_RESOLVE_REQUEST +} = codes; + +const own = {}.hasOwnProperty; + +const invalidSegmentRegEx = + /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))?(\\|\/|$)/i; +const deprecatedInvalidSegmentRegEx = + /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i; +const invalidPackageNameRegEx = /^\.|%|\\/; +const patternRegEx = /\*/g; +const encodedSeparatorRegEx = /%2f|%5c/i; +/** @type {Set} */ +const emittedPackageWarnings = new Set(); + +const doubleSlashRegEx = /[/\\]{2}/; + +/** + * + * @param {string} target + * @param {string} request + * @param {string} match + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} base + * @param {boolean} isTarget + */ +function emitInvalidSegmentDeprecation( + target, + request, + match, + packageJsonUrl, + internal, + base, + isTarget +) { + // @ts-expect-error: apparently it does exist, TS. + if (process$1.noDeprecation) { + return + } + + const pjsonPath = fileURLToPath$1(packageJsonUrl); + const double = doubleSlashRegEx.exec(isTarget ? target : request) !== null; + process$1.emitWarning( + `Use of deprecated ${ + double ? 'double slash' : 'leading or trailing slash matching' + } resolving "${target}" for module ` + + `request "${request}" ${ + request === match ? '' : `matched to "${match}" ` + }in the "${ + internal ? 'imports' : 'exports' + }" field module resolution of the package at ${pjsonPath}${ + base ? ` imported from ${fileURLToPath$1(base)}` : '' + }.`, + 'DeprecationWarning', + 'DEP0166' + ); +} + +/** + * @param {URL} url + * @param {URL} packageJsonUrl + * @param {URL} base + * @param {string} [main] + * @returns {void} + */ +function emitLegacyIndexDeprecation(url, packageJsonUrl, base, main) { + // @ts-expect-error: apparently it does exist, TS. + if (process$1.noDeprecation) { + return + } + + const format = defaultGetFormatWithoutErrors(url, {parentURL: base.href}); + if (format !== 'module') return + const urlPath = fileURLToPath$1(url.href); + const packagePath = fileURLToPath$1(new URL('.', packageJsonUrl)); + const basePath = fileURLToPath$1(base); + if (!main) { + process$1.emitWarning( + `No "main" or "exports" field defined in the package.json for ${packagePath} resolving the main entry point "${urlPath.slice( + packagePath.length + )}", imported from ${basePath}.\nDefault "index" lookups for the main are deprecated for ES modules.`, + 'DeprecationWarning', + 'DEP0151' + ); + } else if (path.resolve(packagePath, main) !== urlPath) { + process$1.emitWarning( + `Package ${packagePath} has a "main" field set to "${main}", ` + + `excluding the full filename and extension to the resolved file at "${urlPath.slice( + packagePath.length + )}", imported from ${basePath}.\n Automatic extension resolution of the "main" field is ` + + 'deprecated for ES modules.', + 'DeprecationWarning', + 'DEP0151' + ); + } +} + +/** + * @param {string} path + * @returns {Stats | undefined} + */ +function tryStatSync(path) { + // Note: from Node 15 onwards we can use `throwIfNoEntry: false` instead. + try { + return statSync(path) + } catch { + // Note: in Node code this returns `new Stats`, + // but in Node 22 that’s marked as a deprecated internal API. + // Which, well, we kinda are, but still to prevent that warning, + // just yield `undefined`. + } +} + +/** + * Legacy CommonJS main resolution: + * 1. let M = pkg_url + (json main field) + * 2. TRY(M, M.js, M.json, M.node) + * 3. TRY(M/index.js, M/index.json, M/index.node) + * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) + * 5. NOT_FOUND + * + * @param {URL} url + * @returns {boolean} + */ +function fileExists(url) { + const stats = statSync(url, {throwIfNoEntry: false}); + const isFile = stats ? stats.isFile() : undefined; + return isFile === null || isFile === undefined ? false : isFile +} + +/** + * @param {URL} packageJsonUrl + * @param {PackageConfig} packageConfig + * @param {URL} base + * @returns {URL} + */ +function legacyMainResolve(packageJsonUrl, packageConfig, base) { + /** @type {URL | undefined} */ + let guess; + if (packageConfig.main !== undefined) { + guess = new URL(packageConfig.main, packageJsonUrl); + // Note: fs check redundances will be handled by Descriptor cache here. + if (fileExists(guess)) return guess + + const tries = [ + `./${packageConfig.main}.js`, + `./${packageConfig.main}.json`, + `./${packageConfig.main}.node`, + `./${packageConfig.main}/index.js`, + `./${packageConfig.main}/index.json`, + `./${packageConfig.main}/index.node` + ]; + let i = -1; + + while (++i < tries.length) { + guess = new URL(tries[i], packageJsonUrl); + if (fileExists(guess)) break + guess = undefined; + } + + if (guess) { + emitLegacyIndexDeprecation( + guess, + packageJsonUrl, + base, + packageConfig.main + ); + return guess + } + // Fallthrough. + } + + const tries = ['./index.js', './index.json', './index.node']; + let i = -1; + + while (++i < tries.length) { + guess = new URL(tries[i], packageJsonUrl); + if (fileExists(guess)) break + guess = undefined; + } + + if (guess) { + emitLegacyIndexDeprecation(guess, packageJsonUrl, base, packageConfig.main); + return guess + } + + // Not found. + throw new ERR_MODULE_NOT_FOUND( + fileURLToPath$1(new URL('.', packageJsonUrl)), + fileURLToPath$1(base) + ) +} + +/** + * @param {URL} resolved + * @param {URL} base + * @param {boolean} [preserveSymlinks] + * @returns {URL} + */ +function finalizeResolution(resolved, base, preserveSymlinks) { + if (encodedSeparatorRegEx.exec(resolved.pathname) !== null) { + throw new ERR_INVALID_MODULE_SPECIFIER( + resolved.pathname, + 'must not include encoded "/" or "\\" characters', + fileURLToPath$1(base) + ) + } + + /** @type {string} */ + let filePath; + + try { + filePath = fileURLToPath$1(resolved); + } catch (error) { + const cause = /** @type {ErrnoException} */ (error); + Object.defineProperty(cause, 'input', {value: String(resolved)}); + Object.defineProperty(cause, 'module', {value: String(base)}); + throw cause + } + + const stats = tryStatSync( + filePath.endsWith('/') ? filePath.slice(-1) : filePath + ); + + if (stats && stats.isDirectory()) { + const error = new ERR_UNSUPPORTED_DIR_IMPORT(filePath, fileURLToPath$1(base)); + // @ts-expect-error Add this for `import.meta.resolve`. + error.url = String(resolved); + throw error + } + + if (!stats || !stats.isFile()) { + const error = new ERR_MODULE_NOT_FOUND( + filePath || resolved.pathname, + base && fileURLToPath$1(base), + true + ); + // @ts-expect-error Add this for `import.meta.resolve`. + error.url = String(resolved); + throw error + } + + { + const real = realpathSync(filePath); + const {search, hash} = resolved; + resolved = pathToFileURL$1(real + (filePath.endsWith(path.sep) ? '/' : '')); + resolved.search = search; + resolved.hash = hash; + } + + return resolved +} + +/** + * @param {string} specifier + * @param {URL | undefined} packageJsonUrl + * @param {URL} base + * @returns {Error} + */ +function importNotDefined(specifier, packageJsonUrl, base) { + return new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, + packageJsonUrl && fileURLToPath$1(new URL('.', packageJsonUrl)), + fileURLToPath$1(base) + ) +} + +/** + * @param {string} subpath + * @param {URL} packageJsonUrl + * @param {URL} base + * @returns {Error} + */ +function exportsNotFound(subpath, packageJsonUrl, base) { + return new ERR_PACKAGE_PATH_NOT_EXPORTED( + fileURLToPath$1(new URL('.', packageJsonUrl)), + subpath, + base && fileURLToPath$1(base) + ) +} + +/** + * @param {string} request + * @param {string} match + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} [base] + * @returns {never} + */ +function throwInvalidSubpath(request, match, packageJsonUrl, internal, base) { + const reason = `request is not a valid match in pattern "${match}" for the "${ + internal ? 'imports' : 'exports' + }" resolution of ${fileURLToPath$1(packageJsonUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER( + request, + reason, + base && fileURLToPath$1(base) + ) +} + +/** + * @param {string} subpath + * @param {unknown} target + * @param {URL} packageJsonUrl + * @param {boolean} internal + * @param {URL} [base] + * @returns {Error} + */ +function invalidPackageTarget(subpath, target, packageJsonUrl, internal, base) { + target = + typeof target === 'object' && target !== null + ? JSON.stringify(target, null, '') + : `${target}`; + + return new ERR_INVALID_PACKAGE_TARGET( + fileURLToPath$1(new URL('.', packageJsonUrl)), + subpath, + target, + internal, + base && fileURLToPath$1(base) + ) +} + +/** + * @param {string} target + * @param {string} subpath + * @param {string} match + * @param {URL} packageJsonUrl + * @param {URL} base + * @param {boolean} pattern + * @param {boolean} internal + * @param {boolean} isPathMap + * @param {Set | undefined} conditions + * @returns {URL} + */ +function resolvePackageTargetString( + target, + subpath, + match, + packageJsonUrl, + base, + pattern, + internal, + isPathMap, + conditions +) { + if (subpath !== '' && !pattern && target[target.length - 1] !== '/') + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + + if (!target.startsWith('./')) { + if (internal && !target.startsWith('../') && !target.startsWith('/')) { + let isURL = false; + + try { + new URL(target); + isURL = true; + } catch { + // Continue regardless of error. + } + + if (!isURL) { + const exportTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target + subpath; + + return packageResolve(exportTarget, packageJsonUrl, conditions) + } + } + + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + } + + if (invalidSegmentRegEx.exec(target.slice(2)) !== null) { + if (deprecatedInvalidSegmentRegEx.exec(target.slice(2)) === null) { + if (!isPathMap) { + const request = pattern + ? match.replace('*', () => subpath) + : match + subpath; + const resolvedTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target; + emitInvalidSegmentDeprecation( + resolvedTarget, + request, + match, + packageJsonUrl, + internal, + base, + true + ); + } + } else { + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + } + } + + const resolved = new URL(target, packageJsonUrl); + const resolvedPath = resolved.pathname; + const packagePath = new URL('.', packageJsonUrl).pathname; + + if (!resolvedPath.startsWith(packagePath)) + throw invalidPackageTarget(match, target, packageJsonUrl, internal, base) + + if (subpath === '') return resolved + + if (invalidSegmentRegEx.exec(subpath) !== null) { + const request = pattern + ? match.replace('*', () => subpath) + : match + subpath; + if (deprecatedInvalidSegmentRegEx.exec(subpath) === null) { + if (!isPathMap) { + const resolvedTarget = pattern + ? RegExpPrototypeSymbolReplace.call( + patternRegEx, + target, + () => subpath + ) + : target; + emitInvalidSegmentDeprecation( + resolvedTarget, + request, + match, + packageJsonUrl, + internal, + base, + false + ); + } + } else { + throwInvalidSubpath(request, match, packageJsonUrl, internal, base); + } + } + + if (pattern) { + return new URL( + RegExpPrototypeSymbolReplace.call( + patternRegEx, + resolved.href, + () => subpath + ) + ) + } + + return new URL(subpath, resolved) +} + +/** + * @param {string} key + * @returns {boolean} + */ +function isArrayIndex(key) { + const keyNumber = Number(key); + if (`${keyNumber}` !== key) return false + return keyNumber >= 0 && keyNumber < 0xff_ff_ff_ff +} + +/** + * @param {URL} packageJsonUrl + * @param {unknown} target + * @param {string} subpath + * @param {string} packageSubpath + * @param {URL} base + * @param {boolean} pattern + * @param {boolean} internal + * @param {boolean} isPathMap + * @param {Set | undefined} conditions + * @returns {URL | null} + */ +function resolvePackageTarget( + packageJsonUrl, + target, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions +) { + if (typeof target === 'string') { + return resolvePackageTargetString( + target, + subpath, + packageSubpath, + packageJsonUrl, + base, + pattern, + internal, + isPathMap, + conditions + ) + } + + if (Array.isArray(target)) { + /** @type {Array} */ + const targetList = target; + if (targetList.length === 0) return null + + /** @type {ErrnoException | null | undefined} */ + let lastException; + let i = -1; + + while (++i < targetList.length) { + const targetItem = targetList[i]; + /** @type {URL | null} */ + let resolveResult; + try { + resolveResult = resolvePackageTarget( + packageJsonUrl, + targetItem, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions + ); + } catch (error) { + const exception = /** @type {ErrnoException} */ (error); + lastException = exception; + if (exception.code === 'ERR_INVALID_PACKAGE_TARGET') continue + throw error + } + + if (resolveResult === undefined) continue + + if (resolveResult === null) { + lastException = null; + continue + } + + return resolveResult + } + + if (lastException === undefined || lastException === null) { + return null + } + + throw lastException + } + + if (typeof target === 'object' && target !== null) { + const keys = Object.getOwnPropertyNames(target); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + if (isArrayIndex(key)) { + throw new ERR_INVALID_PACKAGE_CONFIG( + fileURLToPath$1(packageJsonUrl), + base, + '"exports" cannot contain numeric property keys.' + ) + } + } + + i = -1; + + while (++i < keys.length) { + const key = keys[i]; + if (key === 'default' || (conditions && conditions.has(key))) { + // @ts-expect-error: indexable. + const conditionalTarget = /** @type {unknown} */ (target[key]); + const resolveResult = resolvePackageTarget( + packageJsonUrl, + conditionalTarget, + subpath, + packageSubpath, + base, + pattern, + internal, + isPathMap, + conditions + ); + if (resolveResult === undefined) continue + return resolveResult + } + } + + return null + } + + if (target === null) { + return null + } + + throw invalidPackageTarget( + packageSubpath, + target, + packageJsonUrl, + internal, + base + ) +} + +/** + * @param {unknown} exports + * @param {URL} packageJsonUrl + * @param {URL} base + * @returns {boolean} + */ +function isConditionalExportsMainSugar(exports$1, packageJsonUrl, base) { + if (typeof exports$1 === 'string' || Array.isArray(exports$1)) return true + if (typeof exports$1 !== 'object' || exports$1 === null) return false + + const keys = Object.getOwnPropertyNames(exports$1); + let isConditionalSugar = false; + let i = 0; + let keyIndex = -1; + while (++keyIndex < keys.length) { + const key = keys[keyIndex]; + const currentIsConditionalSugar = key === '' || key[0] !== '.'; + if (i++ === 0) { + isConditionalSugar = currentIsConditionalSugar; + } else if (isConditionalSugar !== currentIsConditionalSugar) { + throw new ERR_INVALID_PACKAGE_CONFIG( + fileURLToPath$1(packageJsonUrl), + base, + '"exports" cannot contain some keys starting with \'.\' and some not.' + + ' The exports object must either be an object of package subpath keys' + + ' or an object of main entry condition name keys only.' + ) + } + } + + return isConditionalSugar +} + +/** + * @param {string} match + * @param {URL} pjsonUrl + * @param {URL} base + */ +function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { + // @ts-expect-error: apparently it does exist, TS. + if (process$1.noDeprecation) { + return + } + + const pjsonPath = fileURLToPath$1(pjsonUrl); + if (emittedPackageWarnings.has(pjsonPath + '|' + match)) return + emittedPackageWarnings.add(pjsonPath + '|' + match); + process$1.emitWarning( + `Use of deprecated trailing slash pattern mapping "${match}" in the ` + + `"exports" field module resolution of the package at ${pjsonPath}${ + base ? ` imported from ${fileURLToPath$1(base)}` : '' + }. Mapping specifiers ending in "/" is no longer supported.`, + 'DeprecationWarning', + 'DEP0155' + ); +} + +/** + * @param {URL} packageJsonUrl + * @param {string} packageSubpath + * @param {Record} packageConfig + * @param {URL} base + * @param {Set | undefined} conditions + * @returns {URL} + */ +function packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions +) { + let exports$1 = packageConfig.exports; + + if (isConditionalExportsMainSugar(exports$1, packageJsonUrl, base)) { + exports$1 = {'.': exports$1}; + } + + if ( + own.call(exports$1, packageSubpath) && + !packageSubpath.includes('*') && + !packageSubpath.endsWith('/') + ) { + // @ts-expect-error: indexable. + const target = exports$1[packageSubpath]; + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + '', + packageSubpath, + base, + false, + false, + false, + conditions + ); + if (resolveResult === null || resolveResult === undefined) { + throw exportsNotFound(packageSubpath, packageJsonUrl, base) + } + + return resolveResult + } + + let bestMatch = ''; + let bestMatchSubpath = ''; + const keys = Object.getOwnPropertyNames(exports$1); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + const patternIndex = key.indexOf('*'); + + if ( + patternIndex !== -1 && + packageSubpath.startsWith(key.slice(0, patternIndex)) + ) { + // When this reaches EOL, this can throw at the top of the whole function: + // + // if (StringPrototypeEndsWith(packageSubpath, '/')) + // throwInvalidSubpath(packageSubpath) + // + // To match "imports" and the spec. + if (packageSubpath.endsWith('/')) { + emitTrailingSlashPatternDeprecation( + packageSubpath, + packageJsonUrl, + base + ); + } + + const patternTrailer = key.slice(patternIndex + 1); + + if ( + packageSubpath.length >= key.length && + packageSubpath.endsWith(patternTrailer) && + patternKeyCompare(bestMatch, key) === 1 && + key.lastIndexOf('*') === patternIndex + ) { + bestMatch = key; + bestMatchSubpath = packageSubpath.slice( + patternIndex, + packageSubpath.length - patternTrailer.length + ); + } + } + } + + if (bestMatch) { + // @ts-expect-error: indexable. + const target = /** @type {unknown} */ (exports$1[bestMatch]); + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + false, + packageSubpath.endsWith('/'), + conditions + ); + + if (resolveResult === null || resolveResult === undefined) { + throw exportsNotFound(packageSubpath, packageJsonUrl, base) + } + + return resolveResult + } + + throw exportsNotFound(packageSubpath, packageJsonUrl, base) +} + +/** + * @param {string} a + * @param {string} b + */ +function patternKeyCompare(a, b) { + const aPatternIndex = a.indexOf('*'); + const bPatternIndex = b.indexOf('*'); + const baseLengthA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; + const baseLengthB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; + if (baseLengthA > baseLengthB) return -1 + if (baseLengthB > baseLengthA) return 1 + if (aPatternIndex === -1) return 1 + if (bPatternIndex === -1) return -1 + if (a.length > b.length) return -1 + if (b.length > a.length) return 1 + return 0 +} + +/** + * @param {string} name + * @param {URL} base + * @param {Set} [conditions] + * @returns {URL} + */ +function packageImportsResolve(name, base, conditions) { + if (name === '#' || name.startsWith('#/') || name.endsWith('/')) { + const reason = 'is not a valid internal imports specifier name'; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath$1(base)) + } + + /** @type {URL | undefined} */ + let packageJsonUrl; + + const packageConfig = getPackageScopeConfig(base); + + if (packageConfig.exists) { + packageJsonUrl = pathToFileURL$1(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (own.call(imports, name) && !name.includes('*')) { + const resolveResult = resolvePackageTarget( + packageJsonUrl, + imports[name], + '', + name, + base, + false, + true, + false, + conditions + ); + if (resolveResult !== null && resolveResult !== undefined) { + return resolveResult + } + } else { + let bestMatch = ''; + let bestMatchSubpath = ''; + const keys = Object.getOwnPropertyNames(imports); + let i = -1; + + while (++i < keys.length) { + const key = keys[i]; + const patternIndex = key.indexOf('*'); + + if (patternIndex !== -1 && name.startsWith(key.slice(0, -1))) { + const patternTrailer = key.slice(patternIndex + 1); + if ( + name.length >= key.length && + name.endsWith(patternTrailer) && + patternKeyCompare(bestMatch, key) === 1 && + key.lastIndexOf('*') === patternIndex + ) { + bestMatch = key; + bestMatchSubpath = name.slice( + patternIndex, + name.length - patternTrailer.length + ); + } + } + } + + if (bestMatch) { + const target = imports[bestMatch]; + const resolveResult = resolvePackageTarget( + packageJsonUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + true, + false, + conditions + ); + + if (resolveResult !== null && resolveResult !== undefined) { + return resolveResult + } + } + } + } + } + + throw importNotDefined(name, packageJsonUrl, base) +} + +/** + * @param {string} specifier + * @param {URL} base + */ +function parsePackageName(specifier, base) { + let separatorIndex = specifier.indexOf('/'); + let validPackageName = true; + let isScoped = false; + if (specifier[0] === '@') { + isScoped = true; + if (separatorIndex === -1 || specifier.length === 0) { + validPackageName = false; + } else { + separatorIndex = specifier.indexOf('/', separatorIndex + 1); + } + } + + const packageName = + separatorIndex === -1 ? specifier : specifier.slice(0, separatorIndex); + + // Package name cannot have leading . and cannot have percent-encoding or + // \\ separators. + if (invalidPackageNameRegEx.exec(packageName) !== null) { + validPackageName = false; + } + + if (!validPackageName) { + throw new ERR_INVALID_MODULE_SPECIFIER( + specifier, + 'is not a valid package name', + fileURLToPath$1(base) + ) + } + + const packageSubpath = + '.' + (separatorIndex === -1 ? '' : specifier.slice(separatorIndex)); + + return {packageName, packageSubpath, isScoped} +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set | undefined} conditions + * @returns {URL} + */ +function packageResolve(specifier, base, conditions) { + if (builtinModules.includes(specifier)) { + return new URL('node:' + specifier) + } + + const {packageName, packageSubpath, isScoped} = parsePackageName( + specifier, + base + ); + + // ResolveSelf + const packageConfig = getPackageScopeConfig(base); + + // Can’t test. + /* c8 ignore next 16 */ + if (packageConfig.exists) { + const packageJsonUrl = pathToFileURL$1(packageConfig.pjsonPath); + if ( + packageConfig.name === packageName && + packageConfig.exports !== undefined && + packageConfig.exports !== null + ) { + return packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions + ) + } + } + + let packageJsonUrl = new URL( + './node_modules/' + packageName + '/package.json', + base + ); + let packageJsonPath = fileURLToPath$1(packageJsonUrl); + /** @type {string} */ + let lastPath; + do { + const stat = tryStatSync(packageJsonPath.slice(0, -13)); + if (!stat || !stat.isDirectory()) { + lastPath = packageJsonPath; + packageJsonUrl = new URL( + (isScoped ? '../../../../node_modules/' : '../../../node_modules/') + + packageName + + '/package.json', + packageJsonUrl + ); + packageJsonPath = fileURLToPath$1(packageJsonUrl); + continue + } + + // Package match. + const packageConfig = read(packageJsonPath, {base, specifier}); + if (packageConfig.exports !== undefined && packageConfig.exports !== null) { + return packageExportsResolve( + packageJsonUrl, + packageSubpath, + packageConfig, + base, + conditions + ) + } + + if (packageSubpath === '.') { + return legacyMainResolve(packageJsonUrl, packageConfig, base) + } + + return new URL(packageSubpath, packageJsonUrl) + // Cross-platform root check. + } while (packageJsonPath.length !== lastPath.length) + + throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath$1(base), false) +} + +/** + * @param {string} specifier + * @returns {boolean} + */ +function isRelativeSpecifier(specifier) { + if (specifier[0] === '.') { + if (specifier.length === 1 || specifier[1] === '/') return true + if ( + specifier[1] === '.' && + (specifier.length === 2 || specifier[2] === '/') + ) { + return true + } + } + + return false +} + +/** + * @param {string} specifier + * @returns {boolean} + */ +function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { + if (specifier === '') return false + if (specifier[0] === '/') return true + return isRelativeSpecifier(specifier) +} + +/** + * The “Resolver Algorithm Specification” as detailed in the Node docs (which is + * sync and slightly lower-level than `resolve`). + * + * @param {string} specifier + * `/example.js`, `./example.js`, `../example.js`, `some-package`, `fs`, etc. + * @param {URL} base + * Full URL (to a file) that `specifier` is resolved relative from. + * @param {Set} [conditions] + * Conditions. + * @param {boolean} [preserveSymlinks] + * Keep symlinks instead of resolving them. + * @returns {URL} + * A URL object to the found thing. + */ +function moduleResolve(specifier, base, conditions, preserveSymlinks) { + // Note: The Node code supports `base` as a string (in this internal API) too, + // we don’t. + if (conditions === undefined) { + conditions = getConditionsSet(); + } + + const protocol = base.protocol; + const isData = protocol === 'data:'; + const isRemote = isData || protocol === 'http:' || protocol === 'https:'; + // Order swapped from spec for minor perf gain. + // Ok since relative URLs cannot parse as URLs. + /** @type {URL | undefined} */ + let resolved; + + if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { + try { + resolved = new URL(specifier, base); + } catch (error_) { + const error = new ERR_UNSUPPORTED_RESOLVE_REQUEST(specifier, base); + error.cause = error_; + throw error + } + } else if (protocol === 'file:' && specifier[0] === '#') { + resolved = packageImportsResolve(specifier, base, conditions); + } else { + try { + resolved = new URL(specifier); + } catch (error_) { + // Note: actual code uses `canBeRequiredWithoutScheme`. + if (isRemote && !builtinModules.includes(specifier)) { + const error = new ERR_UNSUPPORTED_RESOLVE_REQUEST(specifier, base); + error.cause = error_; + throw error + } + + resolved = packageResolve(specifier, base, conditions); + } + } + + assert.ok(resolved !== undefined, 'expected to be defined'); + + if (resolved.protocol !== 'file:') { + return resolved + } + + return finalizeResolution(resolved, base) +} + +function fileURLToPath(id) { + if (typeof id === "string" && !id.startsWith("file://")) { + return normalizeSlash(id); + } + return normalizeSlash(fileURLToPath$1(id)); +} +function pathToFileURL(id) { + return pathToFileURL$1(fileURLToPath(id)).toString(); +} +const INVALID_CHAR_RE = /[\u0000-\u001F"#$&*+,/:;<=>?@[\]^`{|}\u007F]+/g; +function sanitizeURIComponent(name = "", replacement = "_") { + return name.replace(INVALID_CHAR_RE, replacement).replace(/%../g, replacement); +} +function sanitizeFilePath(filePath = "") { + return filePath.replace(/\?.*$/, "").split(/[/\\]/g).map((p) => sanitizeURIComponent(p)).join("/").replace(/^([A-Za-z])_\//, "$1:/"); +} +function normalizeid(id) { + if (typeof id !== "string") { + id = id.toString(); + } + if (/(?:node|data|http|https|file):/.test(id)) { + return id; + } + if (BUILTIN_MODULES.has(id)) { + return "node:" + id; + } + return "file://" + encodeURI(normalizeSlash(id)); +} +async function loadURL(url) { + const code = await promises.readFile(fileURLToPath(url), "utf8"); + return code; +} +function toDataURL(code) { + const base64 = Buffer.from(code).toString("base64"); + return `data:text/javascript;base64,${base64}`; +} +function isNodeBuiltin(id = "") { + id = id.replace(/^node:/, "").split("/", 1)[0]; + return BUILTIN_MODULES.has(id); +} +const ProtocolRegex = /^(?.{2,}?):.+$/; +function getProtocol(id) { + const proto = id.match(ProtocolRegex); + return proto ? proto.groups?.proto : void 0; +} + +const DEFAULT_CONDITIONS_SET = /* @__PURE__ */ new Set(["node", "import"]); +const DEFAULT_EXTENSIONS = [".mjs", ".cjs", ".js", ".json"]; +const NOT_FOUND_ERRORS = /* @__PURE__ */ new Set([ + "ERR_MODULE_NOT_FOUND", + "ERR_UNSUPPORTED_DIR_IMPORT", + "MODULE_NOT_FOUND", + "ERR_PACKAGE_PATH_NOT_EXPORTED" +]); +function _tryModuleResolve(id, url, conditions) { + try { + return moduleResolve(id, url, conditions); + } catch (error) { + if (!NOT_FOUND_ERRORS.has(error?.code)) { + throw error; + } + } +} +function _resolve(id, options = {}) { + if (typeof id !== "string") { + if (id instanceof URL) { + id = fileURLToPath(id); + } else { + throw new TypeError("input must be a `string` or `URL`"); + } + } + if (/(?:node|data|http|https):/.test(id)) { + return id; + } + if (BUILTIN_MODULES.has(id)) { + return "node:" + id; + } + if (id.startsWith("file://")) { + id = fileURLToPath(id); + } + if (isAbsolute(id)) { + try { + const stat = statSync(id); + if (stat.isFile()) { + return pathToFileURL(id); + } + } catch (error) { + if (error?.code !== "ENOENT") { + throw error; + } + } + } + const conditionsSet = options.conditions ? new Set(options.conditions) : DEFAULT_CONDITIONS_SET; + const _urls = (Array.isArray(options.url) ? options.url : [options.url]).filter(Boolean).map((url) => new URL(normalizeid(url.toString()))); + if (_urls.length === 0) { + _urls.push(new URL(pathToFileURL(process.cwd()))); + } + const urls = [..._urls]; + for (const url of _urls) { + if (url.protocol === "file:") { + urls.push( + new URL("./", url), + // If url is directory + new URL(joinURL(url.pathname, "_index.js"), url), + // TODO: Remove in next major version? + new URL("node_modules", url) + ); + } + } + let resolved; + for (const url of urls) { + resolved = _tryModuleResolve(id, url, conditionsSet); + if (resolved) { + break; + } + for (const prefix of ["", "/index"]) { + for (const extension of options.extensions || DEFAULT_EXTENSIONS) { + resolved = _tryModuleResolve( + joinURL(id, prefix) + extension, + url, + conditionsSet + ); + if (resolved) { + break; + } + } + if (resolved) { + break; + } + } + if (resolved) { + break; + } + } + if (!resolved) { + const error = new Error( + `Cannot find module ${id} imported from ${urls.join(", ")}` + ); + error.code = "ERR_MODULE_NOT_FOUND"; + throw error; + } + return pathToFileURL(resolved); +} +function resolveSync(id, options) { + return _resolve(id, options); +} +function resolve(id, options) { + try { + return Promise.resolve(resolveSync(id, options)); + } catch (error) { + return Promise.reject(error); + } +} +function resolvePathSync(id, options) { + return fileURLToPath(resolveSync(id, options)); +} +function resolvePath(id, options) { + try { + return Promise.resolve(resolvePathSync(id, options)); + } catch (error) { + return Promise.reject(error); + } +} +function createResolve(defaults) { + return (id, url) => { + return resolve(id, { url, ...defaults }); + }; +} +const NODE_MODULES_RE = /^(.+\/node_modules\/)([^/@]+|@[^/]+\/[^/]+)(\/?.*?)?$/; +function parseNodeModulePath(path) { + if (!path) { + return {}; + } + path = normalize(fileURLToPath(path)); + const match = NODE_MODULES_RE.exec(path); + if (!match) { + return {}; + } + const [, dir, name, subpath] = match; + return { + dir, + name, + subpath: subpath ? `.${subpath}` : void 0 + }; +} +async function lookupNodeModuleSubpath(path) { + path = normalize(fileURLToPath(path)); + const { name, subpath } = parseNodeModulePath(path); + if (!name || !subpath) { + return subpath; + } + const { exports: exports$1 } = await readPackageJSON(path).catch(() => { + }) || {}; + if (exports$1) { + const resolvedSubpath = _findSubpath(subpath, exports$1); + if (resolvedSubpath) { + return resolvedSubpath; + } + } + return subpath; +} +function _findSubpath(subpath, exports$1) { + if (typeof exports$1 === "string") { + exports$1 = { ".": exports$1 }; + } + if (!subpath.startsWith(".")) { + subpath = subpath.startsWith("/") ? `.${subpath}` : `./${subpath}`; + } + if (subpath in (exports$1 || {})) { + return subpath; + } + return _flattenExports(exports$1).find((p) => p.fsPath === subpath)?.subpath; +} +function _flattenExports(exports$1 = {}, parentSubpath = "./") { + return Object.entries(exports$1).flatMap(([key, value]) => { + const [subpath, condition] = key.startsWith(".") ? [key.slice(1), void 0] : ["", key]; + const _subPath = joinURL(parentSubpath, subpath); + if (typeof value === "string") { + return [{ subpath: _subPath, fsPath: value, condition }]; + } else { + return _flattenExports(value, _subPath); + } + }); +} + +const ESM_STATIC_IMPORT_RE = /(?<=\s|^|;|\})import\s*(?:[\s"']*(?[\p{L}\p{M}\w\t\n\r $*,/{}@.]+)from\s*)?["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][\s;]*/gmu; +const DYNAMIC_IMPORT_RE = /import\s*\((?(?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*)\)/gm; +const IMPORT_NAMED_TYPE_RE = /(?<=\s|^|;|})import\s*type\s+(?:[\s"']*(?[\w\t\n\r $*,/{}]+)from\s*)?["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][\s;]*/gm; +const EXPORT_DECAL_RE = /\bexport\s+(?(?:async function\s*\*?|function\s*\*?|let|const enum|const|enum|var|class))\s+\*?(?[\w$]+)(?.*,\s*[\s\w:[\]{}]*[\w$\]}]+)*/g; +const EXPORT_DECAL_TYPE_RE = /\bexport\s+(?(?:interface|type|declare (?:async function|function|let|const enum|const|enum|var|class)))\s+(?[\w$]+)/g; +const EXPORT_NAMED_RE = /\bexport\s*{(?[^}]+?)[\s,]*}(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_NAMED_TYPE_RE = /\bexport\s+type\s*{(?[^}]+?)[\s,]*}(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_NAMED_DESTRUCT = /\bexport\s+(?:let|var|const)\s+(?:{(?[^}]+?)[\s,]*}|\[(?[^\]]+?)[\s,]*])\s+=/gm; +const EXPORT_STAR_RE = /\bexport\s*\*(?:\s*as\s+(?[\w$]+)\s+)?\s*(?:\s*from\s*["']\s*(?(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][^\n;]*)?/g; +const EXPORT_DEFAULT_RE = /\bexport\s+default\s+(async function|function|class|true|false|\W|\d)|\bexport\s+default\s+(?.*)/g; +const EXPORT_DEFAULT_CLASS_RE = /\bexport\s+default\s+(?class)\s+(?[\w$]+)/g; +const TYPE_RE = /^\s*?type\s/; +function findStaticImports(code) { + return _filterStatement( + _tryGetLocations(code, "import"), + matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" }) + ); +} +function findDynamicImports(code) { + return _filterStatement( + _tryGetLocations(code, "import"), + matchAll(DYNAMIC_IMPORT_RE, code, { type: "dynamic" }) + ); +} +function findTypeImports(code) { + return [ + ...matchAll(IMPORT_NAMED_TYPE_RE, code, { type: "type" }), + ...matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" }).filter( + (match) => /[^A-Za-z]type\s/.test(match.imports) + ) + ]; +} +function parseStaticImport(matched) { + const cleanedImports = clearImports(matched.imports); + const namedImports = {}; + const _matches = cleanedImports.match(/{([^}]*)}/)?.[1]?.split(",") || []; + for (const namedImport of _matches) { + const _match = namedImport.match(/^\s*(\S*) as (\S*)\s*$/); + const source = _match?.[1] || namedImport.trim(); + const importName = _match?.[2] || source; + if (source && !TYPE_RE.test(source)) { + namedImports[source] = importName; + } + } + const { namespacedImport, defaultImport } = getImportNames(cleanedImports); + return { + ...matched, + defaultImport, + namespacedImport, + namedImports + }; +} +function parseTypeImport(matched) { + if (matched.type === "type") { + return parseStaticImport(matched); + } + const cleanedImports = clearImports(matched.imports); + const namedImports = {}; + const _matches = cleanedImports.match(/{([^}]*)}/)?.[1]?.split(",") || []; + for (const namedImport of _matches) { + const _match = /\s+as\s+/.test(namedImport) ? namedImport.match(/^\s*type\s+(\S*) as (\S*)\s*$/) : namedImport.match(/^\s*type\s+(\S*)\s*$/); + const source = _match?.[1] || namedImport.trim(); + const importName = _match?.[2] || source; + if (source && TYPE_RE.test(namedImport)) { + namedImports[source] = importName; + } + } + const { namespacedImport, defaultImport } = getImportNames(cleanedImports); + return { + ...matched, + defaultImport, + namespacedImport, + namedImports + }; +} +function _extractExtraNames(extraNamesStr) { + const names = []; + let depth = 0; + let angleDepth = 0; + let inString = false; + let inTypeAnnotation = false; + for (let i = 0; i < extraNamesStr.length; i++) { + const char = extraNamesStr[i]; + if (inString) { + if (char === inString) { + let backslashCount = 0; + for (let j = i - 1; j >= 0 && extraNamesStr[j] === "\\"; j--) { + backslashCount++; + } + if (backslashCount % 2 === 0) { + inString = false; + } + } + continue; + } + if (char === '"' || char === "'" || char === "`") { + inString = char; + continue; + } + if (char === ":" && depth === 0 && angleDepth === 0) { + inTypeAnnotation = true; + continue; + } + if (char === "=" && extraNamesStr[i + 1] !== ">" && depth === 0 && angleDepth === 0) { + inTypeAnnotation = false; + } + if (inTypeAnnotation && char === "<") { + angleDepth++; + continue; + } + if (!inTypeAnnotation && char === "<" && depth === 0 && i > 0 && _isIdentifierBeforeAngleBracket(extraNamesStr, i)) { + angleDepth++; + continue; + } + if (char === ">" && angleDepth > 0 && extraNamesStr[i - 1] !== "=") { + angleDepth--; + continue; + } + if (char === "(" || char === "[" || char === "{") { + depth++; + } else if (char === ")" || char === "]" || char === "}") { + depth--; + } + if (char === "," && depth === 0 && angleDepth === 0) { + const rest = extraNamesStr.slice(i + 1); + const match = rest.match(/^\s*([\w$]+)/); + if (match) { + names.push(match[1]); + } + } + } + return names; +} +function findExports(code) { + const declaredExports = matchAll(EXPORT_DECAL_RE, code, { + type: "declaration" + }); + for (const declaredExport of declaredExports) { + if (/^export\s+(?:async\s+)?function/.test(declaredExport.code)) { + continue; + } + const extraNamesStr = declaredExport.extraNames; + if (extraNamesStr) { + const extraNames = _extractExtraNames(extraNamesStr); + if (extraNames.length > 0) { + declaredExport.names = [declaredExport.name, ...extraNames]; + } + } + delete declaredExport.extraNames; + } + const namedExports = normalizeNamedExports( + matchAll(EXPORT_NAMED_RE, code, { + type: "named" + }) + ); + const destructuredExports = matchAll( + EXPORT_NAMED_DESTRUCT, + code, + { type: "named" } + ); + for (const namedExport of destructuredExports) { + namedExport.exports = namedExport.exports1 || namedExport.exports2; + namedExport.names = namedExport.exports.replace(/^\r?\n?/, "").split(/\s*,\s*/g).filter((name) => !TYPE_RE.test(name)).map( + (name) => name.replace(/^.*?\s*:\s*/, "").replace(/\s*=\s*.*$/, "").trim() + ); + } + const defaultExport = matchAll(EXPORT_DEFAULT_RE, code, { + type: "default", + name: "default" + }); + const defaultClassExports = matchAll(EXPORT_DEFAULT_CLASS_RE, code, { + type: "declaration" + }); + const starExports = matchAll(EXPORT_STAR_RE, code, { + type: "star" + }); + const exports$1 = normalizeExports([ + ...declaredExports, + ...namedExports, + ...destructuredExports, + ...defaultExport, + ...defaultClassExports, + ...starExports + ]); + if (exports$1.length === 0) { + return []; + } + const exportLocations = _tryGetLocations(code, "export"); + if (exportLocations && exportLocations.length === 0) { + return []; + } + return ( + // Filter false positive export matches + _filterStatement(exportLocations, exports$1).filter((exp, index, exports2) => { + const nextExport = exports2[index + 1]; + return !nextExport || exp.type !== nextExport.type || !exp.name || exp.name !== nextExport.name; + }) + ); +} +function findTypeExports(code) { + const declaredExports = matchAll( + EXPORT_DECAL_TYPE_RE, + code, + { type: "declaration" } + ); + const namedExports = normalizeNamedExports( + matchAll(EXPORT_NAMED_TYPE_RE, code, { + type: "named" + }) + ); + const exports$1 = normalizeExports([ + ...declaredExports, + ...namedExports + ]); + if (exports$1.length === 0) { + return []; + } + const exportLocations = _tryGetLocations(code, "export"); + if (exportLocations && exportLocations.length === 0) { + return []; + } + return ( + // Filter false positive export matches + _filterStatement(exportLocations, exports$1).filter((exp, index, exports2) => { + const nextExport = exports2[index + 1]; + return !nextExport || exp.type !== nextExport.type || !exp.name || exp.name !== nextExport.name; + }) + ); +} +function normalizeExports(exports$1) { + for (const exp of exports$1) { + if (!exp.name && exp.names && exp.names.length === 1) { + exp.name = exp.names[0]; + } + if (exp.name === "default" && exp.type !== "default") { + exp._type = exp.type; + exp.type = "default"; + } + if (!exp.names && exp.name) { + exp.names = [exp.name]; + } + if (exp.type === "declaration" && exp.declaration) { + exp.declarationType = exp.declaration.replace( + /^declare\s*/, + "" + ); + } + } + return exports$1; +} +function normalizeNamedExports(namedExports) { + for (const namedExport of namedExports) { + namedExport.names = namedExport.exports.replace(/^\r?\n?/, "").split(/\s*,\s*/g).filter((name) => !TYPE_RE.test(name)).map((name) => name.replace(/^.*?\sas\s/, "").trim()); + } + return namedExports; +} +function findExportNames(code) { + return findExports(code).flatMap((exp) => exp.names).filter(Boolean); +} +async function resolveModuleExportNames(id, options) { + const url = await resolvePath(id, options); + const code = await loadURL(url); + const exports$1 = findExports(code); + const exportNames = new Set( + exports$1.flatMap((exp) => exp.names).filter(Boolean) + ); + for (const exp of exports$1) { + if (exp.type !== "star" || !exp.specifier) { + continue; + } + const subExports = await resolveModuleExportNames(exp.specifier, { + ...options, + url + }); + for (const subExport of subExports) { + exportNames.add(subExport); + } + } + return [...exportNames]; +} +function _filterStatement(locations, statements) { + return statements.filter((exp) => { + return !locations || locations.some((location) => { + return exp.start <= location.start && exp.end >= location.end; + }); + }); +} +function _tryGetLocations(code, label) { + try { + return _getLocations(code, label); + } catch { + } +} +function _getLocations(code, label) { + const tokens = tokenizer(code, { + ecmaVersion: "latest", + sourceType: "module", + allowHashBang: true, + allowAwaitOutsideFunction: true, + allowImportExportEverywhere: true + }); + const locations = []; + for (const token of tokens) { + if (token.type.label === label) { + locations.push({ + start: token.start, + end: token.end + }); + } + } + return locations; +} +function _isIdentifierBeforeAngleBracket(str, i) { + let j = i - 1; + while (j >= 0 && /[A-Za-z0-9_$]/.test(str[j])) { + j--; + } + const wordStart = j + 1; + return wordStart < i && /[A-Za-z_$]/.test(str[wordStart]); +} + +function createCommonJS(url) { + const __filename = fileURLToPath(url); + const __dirname = dirname(__filename); + let _nativeRequire; + const getNativeRequire = () => { + if (!_nativeRequire) { + _nativeRequire = createRequire(url); + } + return _nativeRequire; + }; + function require(id) { + return getNativeRequire()(id); + } + require.resolve = function requireResolve(id, options) { + return getNativeRequire().resolve(id, options); + }; + return { + __filename, + __dirname, + require + }; +} +function interopDefault(sourceModule, opts = {}) { + if (!isObject(sourceModule) || !("default" in sourceModule)) { + return sourceModule; + } + const defaultValue = sourceModule.default; + if (defaultValue === void 0 || defaultValue === null) { + return sourceModule; + } + const _defaultType = typeof defaultValue; + if (_defaultType !== "object" && !(_defaultType === "function" && !opts.preferNamespace)) { + return opts.preferNamespace ? sourceModule : defaultValue; + } + for (const key in sourceModule) { + try { + if (!(key in defaultValue)) { + Object.defineProperty(defaultValue, key, { + enumerable: key !== "default", + configurable: key !== "default", + get() { + return sourceModule[key]; + } + }); + } + } catch { + } + } + return defaultValue; +} + +const EVAL_ESM_IMPORT_RE = /(?<=import .* from ["'])[^"']+(?=["'])|(?<=export .* from ["'])[^"']+(?=["'])|(?<=import\s*["'])[^"']+(?=["'])|(?<=import\s*\(["'])[^"']+(?=["']\))/g; +async function loadModule(id, options = {}) { + const url = await resolve(id, options); + const code = await loadURL(url); + return evalModule(code, { ...options, url }); +} +async function evalModule(code, options = {}) { + const transformed = await transformModule(code, options); + const dataURL = toDataURL(transformed); + return import(dataURL).catch((error) => { + error.stack = error.stack.replace( + new RegExp(dataURL, "g"), + options.url || "_mlly_eval_" + ); + throw error; + }); +} +function transformModule(code, options = {}) { + if (options.url && options.url.endsWith(".json")) { + return Promise.resolve("export default " + code); + } + if (options.url) { + code = code.replace(/import\.meta\.url/g, `'${options.url}'`); + } + return Promise.resolve(code); +} +async function resolveImports(code, options) { + const imports = [...code.matchAll(EVAL_ESM_IMPORT_RE)].map((m) => m[0]); + if (imports.length === 0) { + return code; + } + const uniqueImports = [...new Set(imports)]; + const resolved = /* @__PURE__ */ new Map(); + await Promise.all( + uniqueImports.map(async (id) => { + let url = await resolve(id, options); + if (url.endsWith(".json")) { + const code2 = await loadURL(url); + url = toDataURL(await transformModule(code2, { url })); + } + resolved.set(id, url); + }) + ); + const re = new RegExp( + uniqueImports.map((index) => `(?:${index})`).join("|"), + "g" + ); + return code.replace(re, (id) => resolved.get(id)); +} + +const ESM_RE = /(?:[\s;]|^)(?:import[\s\w*,{}]*from|import\s*["'*{]|export\b\s*(?:[*{]|default|class|type|function|const|var|let|async function)|import\.meta\b)/m; +const CJS_RE = /(?:[\s;]|^)(?:module\.exports\b|exports\.\w|require\s*\(|global\.\w)/m; +const COMMENT_RE = /\/\*.+?\*\/|\/\/.*(?=[nr])/g; +const BUILTIN_EXTENSIONS = /* @__PURE__ */ new Set([".mjs", ".cjs", ".node", ".wasm"]); +function hasESMSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + return ESM_RE.test(code); +} +function hasCJSSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + return CJS_RE.test(code); +} +function detectSyntax(code, opts = {}) { + if (opts.stripComments) { + code = code.replace(COMMENT_RE, ""); + } + const hasESM = hasESMSyntax(code, {}); + const hasCJS = hasCJSSyntax(code, {}); + return { + hasESM, + hasCJS, + isMixed: hasESM && hasCJS + }; +} +const validNodeImportDefaults = { + allowedProtocols: ["node", "file", "data"] +}; +async function isValidNodeImport(id, _options = {}) { + if (isNodeBuiltin(id)) { + return true; + } + const options = { ...validNodeImportDefaults, ..._options }; + const proto = getProtocol(id); + if (proto && !options.allowedProtocols?.includes(proto)) { + return false; + } + if (proto === "data") { + return true; + } + const resolvedPath = await resolvePath(id, options); + const extension = extname$1(resolvedPath); + if (BUILTIN_EXTENSIONS.has(extension)) { + return true; + } + if (extension !== ".js") { + return false; + } + const package_ = await readPackageJSON(resolvedPath).catch(() => { + }); + if (package_?.type === "module") { + return true; + } + if (/\.(?:\w+-)?esm?(?:-\w+)?\.js$|\/esm?\//.test(resolvedPath)) { + return false; + } + const code = options.code || await promises.readFile(resolvedPath, "utf8").catch(() => { + }) || ""; + return !hasESMSyntax(code, { stripComments: options.stripComments }); +} + +export { DYNAMIC_IMPORT_RE, ESM_STATIC_IMPORT_RE, EXPORT_DECAL_RE, EXPORT_DECAL_TYPE_RE, createCommonJS, createResolve, detectSyntax, evalModule, fileURLToPath, findDynamicImports, findExportNames, findExports, findStaticImports, findTypeExports, findTypeImports, getProtocol, hasCJSSyntax, hasESMSyntax, interopDefault, isNodeBuiltin, isValidNodeImport, loadModule, loadURL, lookupNodeModuleSubpath, normalizeid, parseNodeModulePath, parseStaticImport, parseTypeImport, pathToFileURL, resolve, resolveImports, resolveModuleExportNames, resolvePath, resolvePathSync, resolveSync, sanitizeFilePath, sanitizeURIComponent, toDataURL, transformModule }; diff --git a/node_modules/mlly/node_modules/pathe/LICENSE b/node_modules/mlly/node_modules/pathe/LICENSE new file mode 100644 index 0000000..8eb90c4 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/LICENSE @@ -0,0 +1,70 @@ +MIT License + +Copyright (c) Pooya Parsa - Daniel Roe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +Bundled zeptomatch (https://github.com/fabiospampinato/zeptomatch) + +The MIT License (MIT) + +Copyright (c) 2023-present Fabio Spampinato + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mlly/node_modules/pathe/README.md b/node_modules/mlly/node_modules/pathe/README.md new file mode 100644 index 0000000..8eddf93 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/README.md @@ -0,0 +1,73 @@ +# 🛣️ pathe + +> Universal filesystem path utils + +[![version][npm-v-src]][npm-v-href] +[![downloads][npm-d-src]][npm-d-href] +[![size][size-src]][size-href] + +## ❓ Why + +For [historical reasons](https://docs.microsoft.com/en-us/archive/blogs/larryosterman/why-is-the-dos-path-character), windows followed MS-DOS and used backslash for separating paths rather than slash used for macOS, Linux, and other Posix operating systems. Nowadays, [Windows](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN) supports both Slash and Backslash for paths. [Node.js's built-in `path` module](https://nodejs.org/api/path.html) in the default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used. **This makes inconsistent code behavior between Windows and POSIX.** + +Compared to popular [upath](https://github.com/anodynos/upath), pathe provides **identical exports** of Node.js with normalization on **all operations** and is written in modern **ESM/TypeScript** and has **no dependency on Node.js**! + +This package is a drop-in replacement of the Node.js's [path module](https://nodejs.org/api/path.html) module and ensures paths are normalized with slash `/` and work in environments including Node.js. + +## 💿 Usage + +Install using npm or yarn: + +```bash +# npm +npm i pathe + +# yarn +yarn add pathe + +# pnpm +pnpm i pathe +``` + +Import: + +```js +// ESM / Typescript +import { resolve, matchesGlob } from "pathe"; + +// CommonJS +const { resolve, matchesGlob } = require("pathe"); +``` + +Read more about path utils from [Node.js documentation](https://nodejs.org/api/path.html) and rest assured behavior is consistently like POSIX regardless of your input paths format and running platform (the only exception is `delimiter` constant export, it will be set to `;` on windows platform). + +### Extra utilities + +Pathe exports some extra utilities that do not exist in standard Node.js [path module](https://nodejs.org/api/path.html). +In order to use them, you can import from `pathe/utils` subpath: + +```js +import { + filename, + normalizeAliases, + resolveAlias, + reverseResolveAlias, +} from "pathe/utils"; +``` + +## License + +Made with 💛 Published under the [MIT](./LICENSE) license. + +Some code was used from the Node.js project. Glob supported is powered by [zeptomatch](https://github.com/fabiospampinato/zeptomatch). + + + +[npm-v-src]: https://img.shields.io/npm/v/pathe?style=flat-square +[npm-v-href]: https://npmjs.com/package/pathe +[npm-d-src]: https://img.shields.io/npm/dm/pathe?style=flat-square +[npm-d-href]: https://npmjs.com/package/pathe +[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/pathe/ci/main?style=flat-square +[github-actions-href]: https://github.com/unjs/pathe/actions?query=workflow%3Aci +[size-src]: https://packagephobia.now.sh/badge?p=pathe +[size-href]: https://packagephobia.now.sh/result?p=pathe diff --git a/node_modules/mlly/node_modules/pathe/dist/index.cjs b/node_modules/mlly/node_modules/pathe/dist/index.cjs new file mode 100644 index 0000000..d64a6d2 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/index.cjs @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path._path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path._path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +exports.basename = _path.basename; +exports.dirname = _path.dirname; +exports.extname = _path.extname; +exports.format = _path.format; +exports.isAbsolute = _path.isAbsolute; +exports.join = _path.join; +exports.matchesGlob = _path.matchesGlob; +exports.normalize = _path.normalize; +exports.normalizeString = _path.normalizeString; +exports.parse = _path.parse; +exports.relative = _path.relative; +exports.resolve = _path.resolve; +exports.sep = _path.sep; +exports.toNamespacedPath = _path.toNamespacedPath; +exports.default = posix; +exports.delimiter = delimiter; +exports.posix = posix; +exports.win32 = win32; diff --git a/node_modules/mlly/node_modules/pathe/dist/index.d.cts b/node_modules/mlly/node_modules/pathe/dist/index.d.cts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/index.d.cts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/mlly/node_modules/pathe/dist/index.d.mts b/node_modules/mlly/node_modules/pathe/dist/index.d.mts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/index.d.mts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/mlly/node_modules/pathe/dist/index.d.ts b/node_modules/mlly/node_modules/pathe/dist/index.d.ts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/index.d.ts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/mlly/node_modules/pathe/dist/index.mjs b/node_modules/mlly/node_modules/pathe/dist/index.mjs new file mode 100644 index 0000000..0582c1f --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/index.mjs @@ -0,0 +1,19 @@ +import { _ as _path } from './shared/pathe.M-eThtNZ.mjs'; +export { c as basename, d as dirname, e as extname, f as format, i as isAbsolute, j as join, m as matchesGlob, n as normalize, a as normalizeString, p as parse, b as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.M-eThtNZ.mjs'; + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +export { posix as default, delimiter, posix, win32 }; diff --git a/node_modules/mlly/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs b/node_modules/mlly/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs new file mode 100644 index 0000000..f4a62e3 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs @@ -0,0 +1,266 @@ +'use strict'; + +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +exports._path = _path; +exports.basename = basename; +exports.dirname = dirname; +exports.extname = extname; +exports.format = format; +exports.isAbsolute = isAbsolute; +exports.join = join; +exports.matchesGlob = matchesGlob; +exports.normalize = normalize; +exports.normalizeString = normalizeString; +exports.normalizeWindowsPath = normalizeWindowsPath; +exports.parse = parse; +exports.relative = relative; +exports.resolve = resolve; +exports.sep = sep; +exports.toNamespacedPath = toNamespacedPath; diff --git a/node_modules/mlly/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs b/node_modules/mlly/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs new file mode 100644 index 0000000..81d714d --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs @@ -0,0 +1,249 @@ +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +export { _path as _, normalizeString as a, relative as b, basename as c, dirname as d, extname as e, format as f, normalizeWindowsPath as g, isAbsolute as i, join as j, matchesGlob as m, normalize as n, parse as p, resolve as r, sep as s, toNamespacedPath as t }; diff --git a/node_modules/mlly/node_modules/pathe/dist/utils.cjs b/node_modules/mlly/node_modules/pathe/dist/utils.cjs new file mode 100644 index 0000000..03c7ff3 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/utils.cjs @@ -0,0 +1,82 @@ +'use strict'; + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + return _path.join(to, _path$1.slice(alias.length)); + } + } + return _path$1; +} +function reverseResolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + matches.push(_path.join(to, _path$1.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +exports.filename = filename; +exports.normalizeAliases = normalizeAliases; +exports.resolveAlias = resolveAlias; +exports.reverseResolveAlias = reverseResolveAlias; diff --git a/node_modules/mlly/node_modules/pathe/dist/utils.d.cts b/node_modules/mlly/node_modules/pathe/dist/utils.d.cts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/utils.d.cts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/mlly/node_modules/pathe/dist/utils.d.mts b/node_modules/mlly/node_modules/pathe/dist/utils.d.mts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/utils.d.mts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/mlly/node_modules/pathe/dist/utils.d.ts b/node_modules/mlly/node_modules/pathe/dist/utils.d.ts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/utils.d.ts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/mlly/node_modules/pathe/dist/utils.mjs b/node_modules/mlly/node_modules/pathe/dist/utils.mjs new file mode 100644 index 0000000..748072e --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/dist/utils.mjs @@ -0,0 +1,77 @@ +import { g as normalizeWindowsPath, j as join } from './shared/pathe.M-eThtNZ.mjs'; + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + return join(to, _path.slice(alias.length)); + } + } + return _path; +} +function reverseResolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + matches.push(join(to, _path.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/mlly/node_modules/pathe/package.json b/node_modules/mlly/node_modules/pathe/package.json new file mode 100644 index 0000000..5522b28 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/package.json @@ -0,0 +1,61 @@ +{ + "name": "pathe", + "version": "2.0.3", + "description": "Universal filesystem path utils", + "repository": "unjs/pathe", + "license": "MIT", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./utils": { + "import": { + "types": "./dist/utils.d.mts", + "default": "./dist/utils.mjs" + }, + "require": { + "types": "./dist/utils.d.cts", + "default": "./dist/utils.cjs" + } + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "utils.d.ts" + ], + "devDependencies": { + "@types/node": "^22.13.1", + "@vitest/coverage-v8": "^3.0.5", + "changelogen": "^0.5.7", + "esbuild": "^0.25.0", + "eslint": "^9.20.1", + "eslint-config-unjs": "^0.4.2", + "jiti": "^2.4.2", + "prettier": "^3.5.0", + "typescript": "^5.7.3", + "unbuild": "^3.3.1", + "vitest": "^3.0.5", + "zeptomatch": "^2.0.0" + }, + "scripts": { + "build": "unbuild", + "dev": "vitest", + "lint": "eslint . && prettier -c src test", + "lint:fix": "eslint . --fix && prettier -w src test", + "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags", + "test": "pnpm lint && vitest run --coverage", + "test:types": "tsc --noEmit" + } +} \ No newline at end of file diff --git a/node_modules/mlly/node_modules/pathe/utils.d.ts b/node_modules/mlly/node_modules/pathe/utils.d.ts new file mode 100644 index 0000000..59cabd3 --- /dev/null +++ b/node_modules/mlly/node_modules/pathe/utils.d.ts @@ -0,0 +1 @@ +export * from "./dist/utils"; diff --git a/node_modules/mlly/package.json b/node_modules/mlly/package.json new file mode 100644 index 0000000..006d787 --- /dev/null +++ b/node_modules/mlly/package.json @@ -0,0 +1,55 @@ +{ + "name": "mlly", + "version": "1.8.2", + "description": "Missing ECMAScript module utils for Node.js", + "repository": "unjs/mlly", + "license": "MIT", + "sideEffects": false, + "type": "module", + "exports": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "unbuild", + "dev": "vitest", + "lint": "eslint src test && prettier -c src test", + "lint:fix": "eslint src test --fix && prettier -w src test", + "release": "pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags", + "test": "pnpm lint && pnpm test:types && vitest run", + "test:types": "tsc --noEmit" + }, + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "@vitest/coverage-v8": "^4.1.0", + "changelogen": "^0.6.2", + "eslint": "^10.0.3", + "eslint-config-unjs": "^0.6.2", + "import-meta-resolve": "^4.2.0", + "jiti": "^2.6.1", + "prettier": "^3.8.1", + "std-env": "^4.0.0", + "typescript": "^5.9.3", + "unbuild": "^3.6.1", + "vitest": "^4.1.0" + }, + "packageManager": "pnpm@10.20.0", + "pnpm": { + "onlyBuiltDependencies": [ + "esbuild" + ] + } +} diff --git a/node_modules/ms/index.js b/node_modules/ms/index.js new file mode 100644 index 0000000..ea734fb --- /dev/null +++ b/node_modules/ms/index.js @@ -0,0 +1,162 @@ +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; +} + +/** + * Pluralization helper. + */ + +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} diff --git a/node_modules/ms/license.md b/node_modules/ms/license.md new file mode 100644 index 0000000..fa5d39b --- /dev/null +++ b/node_modules/ms/license.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/ms/package.json b/node_modules/ms/package.json new file mode 100644 index 0000000..4997189 --- /dev/null +++ b/node_modules/ms/package.json @@ -0,0 +1,38 @@ +{ + "name": "ms", + "version": "2.1.3", + "description": "Tiny millisecond conversion utility", + "repository": "vercel/ms", + "main": "./index", + "files": [ + "index.js" + ], + "scripts": { + "precommit": "lint-staged", + "lint": "eslint lib/* bin/*", + "test": "mocha tests.js" + }, + "eslintConfig": { + "extends": "eslint:recommended", + "env": { + "node": true, + "es6": true + } + }, + "lint-staged": { + "*.js": [ + "npm run lint", + "prettier --single-quote --write", + "git add" + ] + }, + "license": "MIT", + "devDependencies": { + "eslint": "4.18.2", + "expect.js": "0.3.1", + "husky": "0.14.3", + "lint-staged": "5.0.0", + "mocha": "4.0.1", + "prettier": "2.0.5" + } +} diff --git a/node_modules/ms/readme.md b/node_modules/ms/readme.md new file mode 100644 index 0000000..0fc1abb --- /dev/null +++ b/node_modules/ms/readme.md @@ -0,0 +1,59 @@ +# ms + +![CI](https://github.com/vercel/ms/workflows/CI/badge.svg) + +Use this package to easily convert various time formats to milliseconds. + +## Examples + +```js +ms('2 days') // 172800000 +ms('1d') // 86400000 +ms('10h') // 36000000 +ms('2.5 hrs') // 9000000 +ms('2h') // 7200000 +ms('1m') // 60000 +ms('5s') // 5000 +ms('1y') // 31557600000 +ms('100') // 100 +ms('-3 days') // -259200000 +ms('-1h') // -3600000 +ms('-200') // -200 +``` + +### Convert from Milliseconds + +```js +ms(60000) // "1m" +ms(2 * 60000) // "2m" +ms(-3 * 60000) // "-3m" +ms(ms('10 hours')) // "10h" +``` + +### Time Format Written-Out + +```js +ms(60000, { long: true }) // "1 minute" +ms(2 * 60000, { long: true }) // "2 minutes" +ms(-3 * 60000, { long: true }) // "-3 minutes" +ms(ms('10 hours'), { long: true }) // "10 hours" +``` + +## Features + +- Works both in [Node.js](https://nodejs.org) and in the browser +- If a number is supplied to `ms`, a string with a unit is returned +- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) +- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned + +## Related Packages + +- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. + +## Caught a Bug? + +1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device +2. Link the package to the global module directory: `npm link` +3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! + +As always, you can run the tests using: `npm test` diff --git a/node_modules/nanoid/.claude/settings.local.json b/node_modules/nanoid/.claude/settings.local.json new file mode 100644 index 0000000..7ee57f3 --- /dev/null +++ b/node_modules/nanoid/.claude/settings.local.json @@ -0,0 +1,14 @@ +{ + "permissions": { + "allow": [ + "Bash(node /workspaces/nanoid/test/check-versions.js)", + "Bash(echo \"Exit: $?\")", + "Bash(node --version)", + "Bash(node --experimental-strip-types test/check-prebuild.js)", + "Bash(node --experimental-strip-types test/update-prebuild.js)", + "Bash(node test/check-versions.js)", + "Bash(node bin/nanoid.js --version)", + "Bash(node bin/nanoid.js -s 10)" + ] + } +} diff --git a/node_modules/nanoid/LICENSE b/node_modules/nanoid/LICENSE new file mode 100644 index 0000000..37f56aa --- /dev/null +++ b/node_modules/nanoid/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2017 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/nanoid/README.md b/node_modules/nanoid/README.md new file mode 100644 index 0000000..35abb57 --- /dev/null +++ b/node_modules/nanoid/README.md @@ -0,0 +1,39 @@ +# Nano ID + +Nano ID logo by Anton Lovchikov + +**English** | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md) | [Bahasa Indonesia](./README.id-ID.md) + +A tiny, secure, URL-friendly, unique string ID generator for JavaScript. + +> “An amazing level of senseless perfectionism, +> which is simply impossible not to respect.” + +* **Small.** 130 bytes (minified and gzipped). No dependencies. + [Size Limit] controls the size. +* **Fast.** It is 2 times faster than UUID. +* **Safe.** It uses hardware random generator. Can be used in clusters. +* **Short IDs.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`). + So ID size was reduced from 36 to 21 symbols. +* **Portable.** Nano ID was ported + to [20 programming languages](#other-programming-languages). + +```js +import { nanoid } from 'nanoid' +model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" +``` + +Supports modern browsers, IE [with Babel], Node.js and React Native. + +[online tool]: https://gitpod.io/#https://github.com/ai/nanoid/ +[with Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ +[Size Limit]: https://github.com/ai/size-limit + + + Sponsored by Evil Martians + + +## Docs +Read full docs **[here](https://github.com/ai/nanoid#readme)**. diff --git a/node_modules/nanoid/async/index.browser.cjs b/node_modules/nanoid/async/index.browser.cjs new file mode 100644 index 0000000..80d1871 --- /dev/null +++ b/node_modules/nanoid/async/index.browser.cjs @@ -0,0 +1,69 @@ +let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes)) + +let customAlphabet = (alphabet, defaultSize = 21) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + // `Math.clz32` is not used, because it is not available in browsers. + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + + // `-~f => Math.ceil(f)` if f is a float + // `-~i => i + 1` if i is an integer + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + + return async (size = defaultSize) => { + let id = '' + while (true) { + let bytes = crypto.getRandomValues(new Uint8Array(step)) + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = step | 0 + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let nanoid = async (size = 21) => { + let id = '' + let bytes = crypto.getRandomValues(new Uint8Array((size |= 0))) + + // A compact alternative for `for (var i = 0; i < step; i++)`. + while (size--) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + let byte = bytes[size] & 63 + if (byte < 36) { + // `0-9a-z` + id += byte.toString(36) + } else if (byte < 62) { + // `A-Z` + id += (byte - 26).toString(36).toUpperCase() + } else if (byte < 63) { + id += '_' + } else { + id += '-' + } + } + return id +} + +module.exports = { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.browser.js b/node_modules/nanoid/async/index.browser.js new file mode 100644 index 0000000..fbaa230 --- /dev/null +++ b/node_modules/nanoid/async/index.browser.js @@ -0,0 +1,34 @@ +let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes)) +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + return async (size = defaultSize) => { + let id = '' + while (true) { + let bytes = crypto.getRandomValues(new Uint8Array(step)) + let i = step | 0 + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} +let nanoid = async (size = 21) => { + let id = '' + let bytes = crypto.getRandomValues(new Uint8Array((size |= 0))) + while (size--) { + let byte = bytes[size] & 63 + if (byte < 36) { + id += byte.toString(36) + } else if (byte < 62) { + id += (byte - 26).toString(36).toUpperCase() + } else if (byte < 63) { + id += '_' + } else { + id += '-' + } + } + return id +} +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.cjs b/node_modules/nanoid/async/index.cjs new file mode 100644 index 0000000..f1b0ad0 --- /dev/null +++ b/node_modules/nanoid/async/index.cjs @@ -0,0 +1,71 @@ +let crypto = require('crypto') + +let { urlAlphabet } = require('../url-alphabet/index.cjs') + +// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`, +// because it is possible to use in combination with `Buffer.allocUnsafe()`. +let random = bytes => + new Promise((resolve, reject) => { + // `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory. + // Memory flushing is unnecessary since the buffer allocation itself resets + // the memory with the new bytes. + crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => { + if (err) { + reject(err) + } else { + resolve(buf) + } + }) + }) + +let customAlphabet = (alphabet, defaultSize = 21) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = step + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + + return size => tick('', size) +} + +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + while (size--) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + id += urlAlphabet[bytes[size] & 63] + } + return id + }) + +module.exports = { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.d.ts b/node_modules/nanoid/async/index.d.ts new file mode 100644 index 0000000..9e91965 --- /dev/null +++ b/node_modules/nanoid/async/index.d.ts @@ -0,0 +1,56 @@ +/** + * Generate secure URL-friendly unique ID. The non-blocking version. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid/async' + * nanoid().then(id => { + * model.id = id + * }) + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A promise with a random string. + */ +export function nanoid(size?: number): Promise + +/** + * A low-level function. + * Generate secure unique ID with custom alphabet. The non-blocking version. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A function that returns a promise with a random string. + * + * ```js + * import { customAlphabet } from 'nanoid/async' + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid().then(id => { + * model.id = id //=> "8ё56а" + * }) + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => Promise + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { random } from 'nanoid/async' + * random(5).then(bytes => { + * bytes //=> [10, 67, 212, 67, 89] + * }) + * ``` + * + * @param bytes Size of the array. + * @returns A promise with a random bytes array. + */ +export function random(bytes: number): Promise diff --git a/node_modules/nanoid/async/index.js b/node_modules/nanoid/async/index.js new file mode 100644 index 0000000..cec454a --- /dev/null +++ b/node_modules/nanoid/async/index.js @@ -0,0 +1,35 @@ +import crypto from 'crypto' +import { urlAlphabet } from '../url-alphabet/index.js' +let random = bytes => + new Promise((resolve, reject) => { + crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => { + if (err) { + reject(err) + } else { + resolve(buf) + } + }) + }) +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + return size => tick('', size) +} +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + while (size--) { + id += urlAlphabet[bytes[size] & 63] + } + return id + }) +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/index.native.js b/node_modules/nanoid/async/index.native.js new file mode 100644 index 0000000..7c1d6f3 --- /dev/null +++ b/node_modules/nanoid/async/index.native.js @@ -0,0 +1,26 @@ +import { getRandomBytesAsync } from 'expo-random' +import { urlAlphabet } from '../url-alphabet/index.js' +let random = getRandomBytesAsync +let customAlphabet = (alphabet, defaultSize = 21) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + let tick = (id, size = defaultSize) => + random(step).then(bytes => { + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length >= size) return id + } + return tick(id, size) + }) + return size => tick('', size) +} +let nanoid = (size = 21) => + random((size |= 0)).then(bytes => { + let id = '' + while (size--) { + id += urlAlphabet[bytes[size] & 63] + } + return id + }) +export { nanoid, customAlphabet, random } diff --git a/node_modules/nanoid/async/package.json b/node_modules/nanoid/async/package.json new file mode 100644 index 0000000..578cdb4 --- /dev/null +++ b/node_modules/nanoid/async/package.json @@ -0,0 +1,12 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": { + "./index.js": "./index.native.js" + }, + "browser": { + "./index.js": "./index.browser.js", + "./index.cjs": "./index.browser.cjs" + } +} \ No newline at end of file diff --git a/node_modules/nanoid/bin/nanoid.cjs b/node_modules/nanoid/bin/nanoid.cjs new file mode 100755 index 0000000..c76db0f --- /dev/null +++ b/node_modules/nanoid/bin/nanoid.cjs @@ -0,0 +1,55 @@ +#!/usr/bin/env node + +let { nanoid, customAlphabet } = require('..') + +function print(msg) { + process.stdout.write(msg + '\n') +} + +function error(msg) { + process.stderr.write(msg + '\n') + process.exit(1) +} + +if (process.argv.includes('--help') || process.argv.includes('-h')) { + print(` + Usage + $ nanoid [options] + + Options + -s, --size Generated ID size + -a, --alphabet Alphabet to use + -h, --help Show this help + + Examples + $ nanoid --s 15 + S9sBF77U6sDB8Yg + + $ nanoid --size 10 --alphabet abc + bcabababca`) + process.exit() +} + +let alphabet, size +for (let i = 2; i < process.argv.length; i++) { + let arg = process.argv[i] + if (arg === '--size' || arg === '-s') { + size = Number(process.argv[i + 1]) + i += 1 + if (Number.isNaN(size) || size <= 0) { + error('Size must be positive integer') + } + } else if (arg === '--alphabet' || arg === '-a') { + alphabet = process.argv[i + 1] + i += 1 + } else { + error('Unknown argument ' + arg) + } +} + +if (alphabet) { + let customNanoid = customAlphabet(alphabet, size) + print(customNanoid()) +} else { + print(nanoid(size)) +} diff --git a/node_modules/nanoid/index.browser.cjs b/node_modules/nanoid/index.browser.cjs new file mode 100644 index 0000000..d21a91f --- /dev/null +++ b/node_modules/nanoid/index.browser.cjs @@ -0,0 +1,72 @@ +// This file replaces `index.js` in bundlers like webpack or Rollup, +// according to `browser` config in `package.json`. + +let { urlAlphabet } = require('./url-alphabet/index.cjs') + +let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)) + +let customRandom = (alphabet, defaultSize, getRandom) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + // `Math.clz32` is not used, because it is not available in browsers. + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + + // `-~f => Math.ceil(f)` if f is a float + // `-~i => i + 1` if i is an integer + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + // A compact alternative for `for (var i = 0; i < step; i++)`. + let j = step | 0 + while (j--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[j] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) + +let nanoid = (size = 21) => + crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + byte &= 63 + if (byte < 36) { + // `0-9a-z` + id += byte.toString(36) + } else if (byte < 62) { + // `A-Z` + id += (byte - 26).toString(36).toUpperCase() + } else if (byte > 62) { + id += '-' + } else { + id += '_' + } + return id + }, '') + +module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.browser.js b/node_modules/nanoid/index.browser.js new file mode 100644 index 0000000..7d3b876 --- /dev/null +++ b/node_modules/nanoid/index.browser.js @@ -0,0 +1,34 @@ +import { urlAlphabet } from './url-alphabet/index.js' +let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)) +let customRandom = (alphabet, defaultSize, getRandom) => { + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 + let step = -~((1.6 * mask * defaultSize) / alphabet.length) + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + let j = step | 0 + while (j--) { + id += alphabet[bytes[j] & mask] || '' + if (id.length === size) return id + } + } + } +} +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) +let nanoid = (size = 21) => + crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => { + byte &= 63 + if (byte < 36) { + id += byte.toString(36) + } else if (byte < 62) { + id += (byte - 26).toString(36).toUpperCase() + } else if (byte > 62) { + id += '-' + } else { + id += '_' + } + return id + }, '') +export { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.cjs b/node_modules/nanoid/index.cjs new file mode 100644 index 0000000..0623c66 --- /dev/null +++ b/node_modules/nanoid/index.cjs @@ -0,0 +1,86 @@ +let crypto = require('crypto') + +let { urlAlphabet } = require('./url-alphabet/index.cjs') + +// It is best to make fewer, larger requests to the crypto module to +// avoid system call overhead. So, random numbers are generated in a +// pool. The pool is a Buffer that is larger than the initial random +// request size by this multiplier. The pool is enlarged if subsequent +// requests exceed the maximum buffer size. +const POOL_SIZE_MULTIPLIER = 128 +let pool, poolOffset + +let fillPool = bytes => { + if (bytes < 0 || bytes > 1024) throw new RangeError('Wrong ID size') + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) + crypto.randomFillSync(pool) + poolOffset = 0 + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool) + poolOffset = 0 + } + poolOffset += bytes +} + +let random = bytes => { + // `|=` convert `bytes` to number to prevent `valueOf` abusing and pool pollution + fillPool((bytes |= 0)) + return pool.subarray(poolOffset - bytes, poolOffset) +} + +let customRandom = (alphabet, defaultSize, getRandom) => { + // First, a bitmask is necessary to generate the ID. The bitmask makes bytes + // values closer to the alphabet size. The bitmask calculates the closest + // `2^31 - 1` number, which exceeds the alphabet size. + // For example, the bitmask for the alphabet size 30 is 31 (00011111). + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + // Though, the bitmask solution is not perfect since the bytes exceeding + // the alphabet size are refused. Therefore, to reliably generate the ID, + // the random bytes redundancy has to be satisfied. + + // Note: every hardware random generator call is performance expensive, + // because the system call for entropy collection takes a lot of time. + // So, to avoid additional system calls, extra bytes are requested in advance. + + // Next, a step determines how many random bytes to generate. + // The number of random bytes gets decided upon the ID size, mask, + // alphabet size, and magic number 1.6 (using 1.6 peaks at performance + // according to benchmarks). + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + // A compact alternative for `for (let i = 0; i < step; i++)`. + let i = step + while (i--) { + // Adding `|| ''` refuses a random byte that exceeds the alphabet size. + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} + +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) + +let nanoid = (size = 21) => { + // `|=` convert `size` to number to prevent `valueOf` abusing and pool pollution + fillPool((size |= 0)) + let id = '' + // We are reading directly from the random pool to avoid creating new array + for (let i = poolOffset - size; i < poolOffset; i++) { + // It is incorrect to use bytes exceeding the alphabet size. + // The following mask reduces the random byte in the 0-255 value + // range to the 0-63 value range. Therefore, adding hacks, such + // as empty string fallback or magic numbers, is unneccessary because + // the bitmask trims bytes down to the alphabet size. + id += urlAlphabet[pool[i] & 63] + } + return id +} + +module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/index.d.cts b/node_modules/nanoid/index.d.cts new file mode 100644 index 0000000..3e111a3 --- /dev/null +++ b/node_modules/nanoid/index.d.cts @@ -0,0 +1,91 @@ +/** + * Generate secure URL-friendly unique ID. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate secure unique ID with custom alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * const { customAlphabet } = require('nanoid') + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid() //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string + +/** + * Generate unique ID with custom random generator and alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * ```js + * import { customRandom } from 'nanoid/format' + * + * const nanoid = customRandom('abcdef', 5, size => { + * const random = [] + * for (let i = 0; i < size; i++) { + * random.push(randomByte()) + * } + * return random + * }) + * + * nanoid() //=> "fbaef" + * ``` + * + * @param alphabet Alphabet used to generate a random string. + * @param size Size of the random string. + * @param random A random bytes generator. + * @returns A random string generator. + */ +export function customRandom( + alphabet: string, + size: number, + random: (bytes: number) => Uint8Array +): () => string + +/** + * URL safe symbols. + * + * ```js + * import { urlAlphabet } from 'nanoid' + * const nanoid = customAlphabet(urlAlphabet, 10) + * nanoid() //=> "Uakgb_J5m9" + * ``` + */ +export const urlAlphabet: string + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { customRandom, random } from 'nanoid' + * const nanoid = customRandom("abcdef", 5, random) + * ``` + * + * @param bytes Size of the array. + * @returns An array of random bytes. + */ +export function random(bytes: number): Uint8Array diff --git a/node_modules/nanoid/index.d.ts b/node_modules/nanoid/index.d.ts new file mode 100644 index 0000000..3e111a3 --- /dev/null +++ b/node_modules/nanoid/index.d.ts @@ -0,0 +1,91 @@ +/** + * Generate secure URL-friendly unique ID. + * + * By default, the ID will have 21 symbols to have a collision probability + * similar to UUID v4. + * + * ```js + * import { nanoid } from 'nanoid' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate secure unique ID with custom alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * const { customAlphabet } = require('nanoid') + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * nanoid() //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string + +/** + * Generate unique ID with custom random generator and alphabet. + * + * Alphabet must contain 256 symbols or less. Otherwise, the generator + * will not be secure. + * + * ```js + * import { customRandom } from 'nanoid/format' + * + * const nanoid = customRandom('abcdef', 5, size => { + * const random = [] + * for (let i = 0; i < size; i++) { + * random.push(randomByte()) + * } + * return random + * }) + * + * nanoid() //=> "fbaef" + * ``` + * + * @param alphabet Alphabet used to generate a random string. + * @param size Size of the random string. + * @param random A random bytes generator. + * @returns A random string generator. + */ +export function customRandom( + alphabet: string, + size: number, + random: (bytes: number) => Uint8Array +): () => string + +/** + * URL safe symbols. + * + * ```js + * import { urlAlphabet } from 'nanoid' + * const nanoid = customAlphabet(urlAlphabet, 10) + * nanoid() //=> "Uakgb_J5m9" + * ``` + */ +export const urlAlphabet: string + +/** + * Generate an array of random bytes collected from hardware noise. + * + * ```js + * import { customRandom, random } from 'nanoid' + * const nanoid = customRandom("abcdef", 5, random) + * ``` + * + * @param bytes Size of the array. + * @returns An array of random bytes. + */ +export function random(bytes: number): Uint8Array diff --git a/node_modules/nanoid/index.js b/node_modules/nanoid/index.js new file mode 100644 index 0000000..186d339 --- /dev/null +++ b/node_modules/nanoid/index.js @@ -0,0 +1,46 @@ +import crypto from 'crypto' +import { urlAlphabet } from './url-alphabet/index.js' +const POOL_SIZE_MULTIPLIER = 128 +let pool, poolOffset +let fillPool = bytes => { + if (bytes < 0 || bytes > 1024) throw new RangeError('Wrong ID size') + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) + crypto.randomFillSync(pool) + poolOffset = 0 + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool) + poolOffset = 0 + } + poolOffset += bytes +} +let random = bytes => { + fillPool((bytes |= 0)) + return pool.subarray(poolOffset - bytes, poolOffset) +} +let customRandom = (alphabet, defaultSize, getRandom) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) + return (size = defaultSize) => { + let id = '' + while (true) { + let bytes = getRandom(step) + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} +let customAlphabet = (alphabet, size = 21) => + customRandom(alphabet, size, random) +let nanoid = (size = 21) => { + fillPool((size |= 0)) + let id = '' + for (let i = poolOffset - size; i < poolOffset; i++) { + id += urlAlphabet[pool[i] & 63] + } + return id +} +export { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/node_modules/nanoid/nanoid.js b/node_modules/nanoid/nanoid.js new file mode 100644 index 0000000..ec242ea --- /dev/null +++ b/node_modules/nanoid/nanoid.js @@ -0,0 +1 @@ +export let nanoid=(t=21)=>crypto.getRandomValues(new Uint8Array(t)).reduce(((t,e)=>t+=(e&=63)<36?e.toString(36):e<62?(e-26).toString(36).toUpperCase():e<63?"_":"-"),""); \ No newline at end of file diff --git a/node_modules/nanoid/non-secure/index.cjs b/node_modules/nanoid/non-secure/index.cjs new file mode 100644 index 0000000..d51fcb6 --- /dev/null +++ b/node_modules/nanoid/non-secure/index.cjs @@ -0,0 +1,34 @@ +// This alphabet uses `A-Za-z0-9_-` symbols. +// The order of characters is optimized for better gzip and brotli compression. +// References to the same file (works both for gzip and brotli): +// `'use`, `andom`, and `rict'` +// References to the brotli default dictionary: +// `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf` +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' + +let customAlphabet = (alphabet, defaultSize = 21) => { + return (size = defaultSize) => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = size | 0 + while (i--) { + // `| 0` is more compact and faster than `Math.floor()`. + id += alphabet[(Math.random() * alphabet.length) | 0] + } + return id + } +} + +let nanoid = (size = 21) => { + let id = '' + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = size | 0 + while (i--) { + // `| 0` is more compact and faster than `Math.floor()`. + id += urlAlphabet[(Math.random() * 64) | 0] + } + return id +} + +module.exports = { nanoid, customAlphabet } diff --git a/node_modules/nanoid/non-secure/index.d.ts b/node_modules/nanoid/non-secure/index.d.ts new file mode 100644 index 0000000..4965322 --- /dev/null +++ b/node_modules/nanoid/non-secure/index.d.ts @@ -0,0 +1,33 @@ +/** + * Generate URL-friendly unique ID. This method uses the non-secure + * predictable random generator with bigger collision probability. + * + * ```js + * import { nanoid } from 'nanoid/non-secure' + * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" + * ``` + * + * @param size Size of the ID. The default size is 21. + * @returns A random string. + */ +export function nanoid(size?: number): string + +/** + * Generate a unique ID based on a custom alphabet. + * This method uses the non-secure predictable random generator + * with bigger collision probability. + * + * @param alphabet Alphabet used to generate the ID. + * @param defaultSize Size of the ID. The default size is 21. + * @returns A random string generator. + * + * ```js + * import { customAlphabet } from 'nanoid/non-secure' + * const nanoid = customAlphabet('0123456789абвгдеё', 5) + * model.id = //=> "8ё56а" + * ``` + */ +export function customAlphabet( + alphabet: string, + defaultSize?: number +): (size?: number) => string diff --git a/node_modules/nanoid/non-secure/index.js b/node_modules/nanoid/non-secure/index.js new file mode 100644 index 0000000..2ea5827 --- /dev/null +++ b/node_modules/nanoid/non-secure/index.js @@ -0,0 +1,21 @@ +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' +let customAlphabet = (alphabet, defaultSize = 21) => { + return (size = defaultSize) => { + let id = '' + let i = size | 0 + while (i--) { + id += alphabet[(Math.random() * alphabet.length) | 0] + } + return id + } +} +let nanoid = (size = 21) => { + let id = '' + let i = size | 0 + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0] + } + return id +} +export { nanoid, customAlphabet } diff --git a/node_modules/nanoid/non-secure/package.json b/node_modules/nanoid/non-secure/package.json new file mode 100644 index 0000000..9930d6a --- /dev/null +++ b/node_modules/nanoid/non-secure/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": "index.js" +} \ No newline at end of file diff --git a/node_modules/nanoid/package.json b/node_modules/nanoid/package.json new file mode 100644 index 0000000..416c53f --- /dev/null +++ b/node_modules/nanoid/package.json @@ -0,0 +1,89 @@ +{ + "name": "nanoid", + "version": "3.3.12", + "description": "A tiny (116 bytes), secure URL-friendly unique string ID generator", + "keywords": [ + "uuid", + "random", + "id", + "url" + ], + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "author": "Andrey Sitnik ", + "license": "MIT", + "repository": "ai/nanoid", + "browser": { + "./index.js": "./index.browser.js", + "./async/index.js": "./async/index.browser.js", + "./async/index.cjs": "./async/index.browser.cjs", + "./index.cjs": "./index.browser.cjs" + }, + "react-native": "index.js", + "bin": "./bin/nanoid.cjs", + "sideEffects": false, + "types": "./index.d.ts", + "type": "module", + "main": "index.cjs", + "module": "index.js", + "exports": { + ".": { + "react-native": "./index.browser.js", + "browser": "./index.browser.js", + "require": { + "types": "./index.d.cts", + "default": "./index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "default": "./index.js" + }, + "./package.json": "./package.json", + "./async/package.json": "./async/package.json", + "./async": { + "browser": "./async/index.browser.js", + "require": { + "types": "./index.d.cts", + "default": "./async/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./async/index.js" + }, + "default": "./async/index.js" + }, + "./non-secure/package.json": "./non-secure/package.json", + "./non-secure": { + "require": { + "types": "./index.d.cts", + "default": "./non-secure/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./non-secure/index.js" + }, + "default": "./non-secure/index.js" + }, + "./url-alphabet/package.json": "./url-alphabet/package.json", + "./url-alphabet": { + "require": { + "types": "./index.d.cts", + "default": "./url-alphabet/index.cjs" + }, + "import": { + "types": "./index.d.ts", + "default": "./url-alphabet/index.js" + }, + "default": "./url-alphabet/index.js" + } + } +} diff --git a/node_modules/nanoid/url-alphabet/index.cjs b/node_modules/nanoid/url-alphabet/index.cjs new file mode 100644 index 0000000..a332f0b --- /dev/null +++ b/node_modules/nanoid/url-alphabet/index.cjs @@ -0,0 +1,7 @@ +// This alphabet uses `A-Za-z0-9_-` symbols. +// The order of characters is optimized for better gzip and brotli compression. +// Same as in non-secure/index.js +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' + +module.exports = { urlAlphabet } diff --git a/node_modules/nanoid/url-alphabet/index.js b/node_modules/nanoid/url-alphabet/index.js new file mode 100644 index 0000000..c2782e5 --- /dev/null +++ b/node_modules/nanoid/url-alphabet/index.js @@ -0,0 +1,3 @@ +let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' +export { urlAlphabet } diff --git a/node_modules/nanoid/url-alphabet/package.json b/node_modules/nanoid/url-alphabet/package.json new file mode 100644 index 0000000..9930d6a --- /dev/null +++ b/node_modules/nanoid/url-alphabet/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "index.cjs", + "module": "index.js", + "react-native": "index.js" +} \ No newline at end of file diff --git a/node_modules/npm-run-path/index.d.ts b/node_modules/npm-run-path/index.d.ts new file mode 100644 index 0000000..25eca12 --- /dev/null +++ b/node_modules/npm-run-path/index.d.ts @@ -0,0 +1,90 @@ +type CommonOptions = { + /** + Working directory. + + @default process.cwd() + */ + readonly cwd?: string | URL; + + /** + The path to the current Node.js executable. + + This can be either an absolute path or a path relative to the `cwd` option. + + @default [process.execPath](https://nodejs.org/api/process.html#processexecpath) + */ + readonly execPath?: string | URL; + + /** + Whether to push the current Node.js executable's directory (`execPath` option) to the front of PATH. + + @default true + */ + readonly addExecPath?: boolean; + + /** + Whether to push the locally installed binaries' directory to the front of PATH. + + @default true + */ + readonly preferLocal?: boolean; +}; + +export type RunPathOptions = CommonOptions & { + /** + PATH to be appended. + + Set it to an empty string to exclude the default PATH. + + @default [`PATH`](https://github.com/sindresorhus/path-key) + */ + readonly path?: string; +}; + +export type ProcessEnv = Record; + +export type EnvOptions = CommonOptions & { + /** + Accepts an object of environment variables, like `process.env`, and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key). Use this if you're modifying the PATH for use in the `child_process` options. + + @default [process.env](https://nodejs.org/api/process.html#processenv) + */ + readonly env?: ProcessEnv; +}; + +/** +Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries. + +@returns The augmented path string. + +@example +``` +import childProcess from 'node:child_process'; +import {npmRunPath} from 'npm-run-path'; + +console.log(process.env.PATH); +//=> '/usr/local/bin' + +console.log(npmRunPath()); +//=> '/Users/sindresorhus/dev/foo/node_modules/.bin:/Users/sindresorhus/dev/node_modules/.bin:/Users/sindresorhus/node_modules/.bin:/Users/node_modules/.bin:/node_modules/.bin:/usr/local/bin' +``` +*/ +export function npmRunPath(options?: RunPathOptions): string; + +/** +Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries. + +@returns The augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object. + +@example +``` +import childProcess from 'node:child_process'; +import {npmRunPathEnv} from 'npm-run-path'; + +// `foo` is a locally installed binary +childProcess.execFileSync('foo', { + env: npmRunPathEnv() +}); +``` +*/ +export function npmRunPathEnv(options?: EnvOptions): ProcessEnv; diff --git a/node_modules/npm-run-path/index.js b/node_modules/npm-run-path/index.js new file mode 100644 index 0000000..9d6c637 --- /dev/null +++ b/node_modules/npm-run-path/index.js @@ -0,0 +1,52 @@ +import process from 'node:process'; +import path from 'node:path'; +import {fileURLToPath} from 'node:url'; +import pathKey from 'path-key'; + +export const npmRunPath = ({ + cwd = process.cwd(), + path: pathOption = process.env[pathKey()], + preferLocal = true, + execPath = process.execPath, + addExecPath = true, +} = {}) => { + const cwdString = cwd instanceof URL ? fileURLToPath(cwd) : cwd; + const cwdPath = path.resolve(cwdString); + const result = []; + + if (preferLocal) { + applyPreferLocal(result, cwdPath); + } + + if (addExecPath) { + applyExecPath(result, execPath, cwdPath); + } + + return [...result, pathOption].join(path.delimiter); +}; + +const applyPreferLocal = (result, cwdPath) => { + let previous; + + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); + } +}; + +// Ensure the running `node` binary is used +const applyExecPath = (result, execPath, cwdPath) => { + const execPathString = execPath instanceof URL ? fileURLToPath(execPath) : execPath; + result.push(path.resolve(cwdPath, execPathString, '..')); +}; + +export const npmRunPathEnv = ({env = process.env, ...options} = {}) => { + env = {...env}; + + const pathName = pathKey({env}); + options.path = env[pathName]; + env[pathName] = npmRunPath(options); + + return env; +}; diff --git a/node_modules/npm-run-path/license b/node_modules/npm-run-path/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/npm-run-path/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/npm-run-path/node_modules/path-key/index.d.ts b/node_modules/npm-run-path/node_modules/path-key/index.d.ts new file mode 100644 index 0000000..f411d62 --- /dev/null +++ b/node_modules/npm-run-path/node_modules/path-key/index.d.ts @@ -0,0 +1,31 @@ +export interface Options { + /** + Use a custom environment variables object. + + Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env). + */ + readonly env?: Record; + + /** + Get the PATH key for a specific platform. + + Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform). + */ + readonly platform?: NodeJS.Platform; +} + +/** +Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform. + +@example +``` +import pathKey from 'path-key'; + +const key = pathKey(); +//=> 'PATH' + +const PATH = process.env[key]; +//=> '/usr/local/bin:/usr/bin:/bin' +``` +*/ +export default function pathKey(options?: Options): string; diff --git a/node_modules/npm-run-path/node_modules/path-key/index.js b/node_modules/npm-run-path/node_modules/path-key/index.js new file mode 100644 index 0000000..2c02914 --- /dev/null +++ b/node_modules/npm-run-path/node_modules/path-key/index.js @@ -0,0 +1,12 @@ +export default function pathKey(options = {}) { + const { + env = process.env, + platform = process.platform + } = options; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(env).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +} diff --git a/node_modules/npm-run-path/node_modules/path-key/license b/node_modules/npm-run-path/node_modules/path-key/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/npm-run-path/node_modules/path-key/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/npm-run-path/node_modules/path-key/package.json b/node_modules/npm-run-path/node_modules/path-key/package.json new file mode 100644 index 0000000..609070d --- /dev/null +++ b/node_modules/npm-run-path/node_modules/path-key/package.json @@ -0,0 +1,41 @@ +{ + "name": "path-key", + "version": "4.0.0", + "description": "Get the PATH environment variable key cross-platform", + "license": "MIT", + "repository": "sindresorhus/path-key", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": "./index.js", + "engines": { + "node": ">=12" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "path", + "key", + "environment", + "env", + "variable", + "get", + "cross-platform", + "windows" + ], + "devDependencies": { + "@types/node": "^14.14.37", + "ava": "^3.15.0", + "tsd": "^0.14.0", + "xo": "^0.38.2" + } +} diff --git a/node_modules/npm-run-path/node_modules/path-key/readme.md b/node_modules/npm-run-path/node_modules/path-key/readme.md new file mode 100644 index 0000000..aa22506 --- /dev/null +++ b/node_modules/npm-run-path/node_modules/path-key/readme.md @@ -0,0 +1,57 @@ +# path-key + +> Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform + +It's usually `PATH` but on Windows it can be any casing like `Path`... + +## Install + +``` +$ npm install path-key +``` + +## Usage + +```js +import pathKey from 'path-key'; + +const key = pathKey(); +//=> 'PATH' + +const PATH = process.env[key]; +//=> '/usr/local/bin:/usr/bin:/bin' +``` + +## API + +### pathKey(options?) + +#### options + +Type: `object` + +##### env + +Type: `object`\ +Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env) + +Use a custom environment variables object. + +#### platform + +Type: `string`\ +Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform) + +Get the PATH key for a specific platform. + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/npm-run-path/package.json b/node_modules/npm-run-path/package.json new file mode 100644 index 0000000..dd6a4ae --- /dev/null +++ b/node_modules/npm-run-path/package.json @@ -0,0 +1,49 @@ +{ + "name": "npm-run-path", + "version": "5.3.0", + "description": "Get your PATH prepended with locally installed binaries", + "license": "MIT", + "repository": "sindresorhus/npm-run-path", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": "./index.js", + "types": "./index.d.ts", + "sideEffects": false, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "npm", + "run", + "path", + "package", + "bin", + "binary", + "binaries", + "script", + "cli", + "command-line", + "execute", + "executable" + ], + "dependencies": { + "path-key": "^4.0.0" + }, + "devDependencies": { + "ava": "^3.15.0", + "tsd": "^0.17.0", + "xo": "^0.45.0" + } +} diff --git a/node_modules/npm-run-path/readme.md b/node_modules/npm-run-path/readme.md new file mode 100644 index 0000000..bec78f9 --- /dev/null +++ b/node_modules/npm-run-path/readme.md @@ -0,0 +1,104 @@ +# npm-run-path + +> Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries + +In [npm run scripts](https://docs.npmjs.com/cli/run-script) you can execute locally installed binaries by name. This enables the same outside npm. + +## Install + +```sh +npm install npm-run-path +``` + +## Usage + +```js +import childProcess from 'node:child_process'; +import {npmRunPath, npmRunPathEnv} from 'npm-run-path'; + +console.log(process.env.PATH); +//=> '/usr/local/bin' + +console.log(npmRunPath()); +//=> '/Users/sindresorhus/dev/foo/node_modules/.bin:/Users/sindresorhus/dev/node_modules/.bin:/Users/sindresorhus/node_modules/.bin:/Users/node_modules/.bin:/node_modules/.bin:/usr/local/bin' + +// `foo` is a locally installed binary +childProcess.execFileSync('foo', { + env: npmRunPathEnv() +}); +``` + +## API + +### npmRunPath(options?) + +`options`: [`Options`](#options)\ +_Returns_: `string` + +Returns the augmented PATH string. + +### npmRunPathEnv(options?) + +`options`: [`Options`](#options)\ +_Returns_: `object` + +Returns the augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object. + +### options + +Type: `object` + +#### cwd + +Type: `string | URL`\ +Default: `process.cwd()` + +The working directory. + +#### execPath + +Type: `string | URL`\ +Default: [`process.execPath`](https://nodejs.org/api/process.html#processexecpath) + +The path to the current Node.js executable. + +This can be either an absolute path or a path relative to the [`cwd` option](#cwd). + +#### addExecPath + +Type: `boolean`\ +Default: `true` + +Whether to push the current Node.js executable's directory ([`execPath`](#execpath) option) to the front of PATH. + +#### preferLocal + +Type: `boolean`\ +Default: `true` + +Whether to push the locally installed binaries' directory to the front of PATH. + +#### path + +Type: `string`\ +Default: [`PATH`](https://github.com/sindresorhus/path-key) + +The PATH to be appended. + +Set it to an empty string to exclude the default PATH. + +Only available with [`npmRunPath()`](#npmrunpathoptions), not [`npmRunPathEnv()`](#npmrunpathenvoptions). + +#### env + +Type: `object`\ +Default: [`process.env`](https://nodejs.org/api/process.html#processenv) + +Accepts an object of environment variables, like `process.env`, and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key). Use this if you're modifying the PATH for use in the `child_process` options. + +Only available with [`npmRunPathEnv()`](#npmrunpathenvoptions), not [`npmRunPath()`](#npmrunpathoptions). + +## Related + +- [npm-run-path-cli](https://github.com/sindresorhus/npm-run-path-cli) - CLI for this module +- [execa](https://github.com/sindresorhus/execa) - Execute a locally installed binary diff --git a/node_modules/onetime/index.d.ts b/node_modules/onetime/index.d.ts new file mode 100644 index 0000000..3c80803 --- /dev/null +++ b/node_modules/onetime/index.d.ts @@ -0,0 +1,59 @@ +export interface Options { + /** + Throw an error when called more than once. + + @default false + */ + readonly throw?: boolean; +} + +declare const onetime: { + /** + Ensure a function is only called once. When called multiple times it will return the return value from the first call. + + @param fn - Function that should only be called once. + @returns A function that only calls `fn` once. + + @example + ``` + import onetime from 'onetime'; + + let index = 0; + + const foo = onetime(() => ++index); + + foo(); //=> 1 + foo(); //=> 1 + foo(); //=> 1 + + onetime.callCount(foo); //=> 3 + ``` + */ + ( + fn: (...arguments: ArgumentsType) => ReturnType, + options?: Options + ): (...arguments: ArgumentsType) => ReturnType; + + /** + Get the number of times `fn` has been called. + + @param fn - Function to get call count from. + @returns A number representing how many times `fn` has been called. + + @example + ``` + import onetime from 'onetime'; + + const foo = onetime(() => {}); + foo(); + foo(); + foo(); + + console.log(onetime.callCount(foo)); + //=> 3 + ``` + */ + callCount(fn: (...arguments: any[]) => unknown): number; +}; + +export default onetime; diff --git a/node_modules/onetime/index.js b/node_modules/onetime/index.js new file mode 100644 index 0000000..eae4f33 --- /dev/null +++ b/node_modules/onetime/index.js @@ -0,0 +1,41 @@ +import mimicFunction from 'mimic-fn'; + +const calledFunctions = new WeakMap(); + +const onetime = (function_, options = {}) => { + if (typeof function_ !== 'function') { + throw new TypeError('Expected a function'); + } + + let returnValue; + let callCount = 0; + const functionName = function_.displayName || function_.name || ''; + + const onetime = function (...arguments_) { + calledFunctions.set(onetime, ++callCount); + + if (callCount === 1) { + returnValue = function_.apply(this, arguments_); + function_ = null; + } else if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } + + return returnValue; + }; + + mimicFunction(onetime, function_); + calledFunctions.set(onetime, callCount); + + return onetime; +}; + +onetime.callCount = function_ => { + if (!calledFunctions.has(function_)) { + throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`); + } + + return calledFunctions.get(function_); +}; + +export default onetime; diff --git a/node_modules/onetime/license b/node_modules/onetime/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/onetime/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/onetime/package.json b/node_modules/onetime/package.json new file mode 100644 index 0000000..475a1e3 --- /dev/null +++ b/node_modules/onetime/package.json @@ -0,0 +1,45 @@ +{ + "name": "onetime", + "version": "6.0.0", + "description": "Ensure a function is only called once", + "license": "MIT", + "repository": "sindresorhus/onetime", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": "./index.js", + "engines": { + "node": ">=12" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "once", + "function", + "one", + "onetime", + "func", + "fn", + "single", + "call", + "called", + "prevent" + ], + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "devDependencies": { + "ava": "^3.15.0", + "tsd": "^0.14.0", + "xo": "^0.38.2" + } +} diff --git a/node_modules/onetime/readme.md b/node_modules/onetime/readme.md new file mode 100644 index 0000000..e2b26fb --- /dev/null +++ b/node_modules/onetime/readme.md @@ -0,0 +1,94 @@ +# onetime + +> Ensure a function is only called once + +When called multiple times it will return the return value from the first call. + +*Unlike the module [once](https://github.com/isaacs/once), this one isn't naughty and extending `Function.prototype`.* + +## Install + +``` +$ npm install onetime +``` + +## Usage + +```js +import onetime from 'onetime'; + +let index = 0; + +const foo = onetime(() => ++index); + +foo(); //=> 1 +foo(); //=> 1 +foo(); //=> 1 + +onetime.callCount(foo); //=> 3 +``` + +```js +import onetime from 'onetime'; + +const foo = onetime(() => {}, {throw: true}); + +foo(); + +foo(); +//=> Error: Function `foo` can only be called once +``` + +## API + +### onetime(fn, options?) + +Returns a function that only calls `fn` once. + +#### fn + +Type: `Function` + +Function that should only be called once. + +#### options + +Type: `object` + +##### throw + +Type: `boolean`\ +Default: `false` + +Throw an error when called more than once. + +### onetime.callCount(fn) + +Returns a number representing how many times `fn` has been called. + +Note: It throws an error if you pass in a function that is not wrapped by `onetime`. + +```js +import onetime from 'onetime'; + +const foo = onetime(() => {}); + +foo(); +foo(); +foo(); + +console.log(onetime.callCount(foo)); +//=> 3 +``` + +#### fn + +Type: `Function` + +Function to get call count from. + +## onetime for enterprise + +Available as part of the Tidelift Subscription. + +The maintainers of onetime and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-onetime?utm_source=npm-onetime&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) diff --git a/node_modules/p-limit/async-hooks-stub.js b/node_modules/p-limit/async-hooks-stub.js new file mode 100644 index 0000000..913c7c6 --- /dev/null +++ b/node_modules/p-limit/async-hooks-stub.js @@ -0,0 +1,15 @@ +export const AsyncResource = { + bind(fn, _type, thisArg) { + return fn.bind(thisArg); + }, +}; + +export class AsyncLocalStorage { + getStore() { + return undefined; + } + + run(_store, callback) { + return callback(); + } +} diff --git a/node_modules/p-limit/index.d.ts b/node_modules/p-limit/index.d.ts new file mode 100644 index 0000000..303c7d9 --- /dev/null +++ b/node_modules/p-limit/index.d.ts @@ -0,0 +1,38 @@ +export type LimitFunction = { + /** + The number of promises that are currently running. + */ + readonly activeCount: number; + + /** + The number of promises that are waiting to run (i.e. their internal `fn` was not called yet). + */ + readonly pendingCount: number; + + /** + Discard pending promises that are waiting to run. + + This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app. + + Note: This does not cancel promises that are already running. + */ + clearQueue: () => void; + + /** + @param fn - Promise-returning/async function. + @param arguments - Any arguments to pass through to `fn`. Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions. + @returns The promise returned by calling `fn(...arguments)`. + */ + ( + fn: (...arguments_: Arguments) => PromiseLike | ReturnType, + ...arguments_: Arguments + ): Promise; +}; + +/** +Run multiple promise-returning & async functions with limited concurrency. + +@param concurrency - Concurrency limit. Minimum: `1`. +@returns A `limit` function. +*/ +export default function pLimit(concurrency: number): LimitFunction; diff --git a/node_modules/p-limit/index.js b/node_modules/p-limit/index.js new file mode 100644 index 0000000..4a5a0f0 --- /dev/null +++ b/node_modules/p-limit/index.js @@ -0,0 +1,71 @@ +import Queue from 'yocto-queue'; +import {AsyncResource} from '#async_hooks'; + +export default function pLimit(concurrency) { + if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { + throw new TypeError('Expected `concurrency` to be a number from 1 and up'); + } + + const queue = new Queue(); + let activeCount = 0; + + const next = () => { + activeCount--; + + if (queue.size > 0) { + queue.dequeue()(); + } + }; + + const run = async (function_, resolve, arguments_) => { + activeCount++; + + const result = (async () => function_(...arguments_))(); + + resolve(result); + + try { + await result; + } catch {} + + next(); + }; + + const enqueue = (function_, resolve, arguments_) => { + queue.enqueue( + AsyncResource.bind(run.bind(undefined, function_, resolve, arguments_)), + ); + + (async () => { + // This function needs to wait until the next microtask before comparing + // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously + // when the run function is dequeued and called. The comparison in the if-statement + // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. + await Promise.resolve(); + + if (activeCount < concurrency && queue.size > 0) { + queue.dequeue()(); + } + })(); + }; + + const generator = (function_, ...arguments_) => new Promise(resolve => { + enqueue(function_, resolve, arguments_); + }); + + Object.defineProperties(generator, { + activeCount: { + get: () => activeCount, + }, + pendingCount: { + get: () => queue.size, + }, + clearQueue: { + value() { + queue.clear(); + }, + }, + }); + + return generator; +} diff --git a/node_modules/p-limit/license b/node_modules/p-limit/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/p-limit/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/p-limit/package.json b/node_modules/p-limit/package.json new file mode 100644 index 0000000..6d5a9b7 --- /dev/null +++ b/node_modules/p-limit/package.json @@ -0,0 +1,64 @@ +{ + "name": "p-limit", + "version": "5.0.0", + "description": "Run multiple promise-returning & async functions with limited concurrency", + "license": "MIT", + "repository": "sindresorhus/p-limit", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "imports": { + "#async_hooks": { + "node": "async_hooks", + "default": "./async-hooks-stub.js" + } + }, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts", + "async-hooks-stub.js" + ], + "keywords": [ + "promise", + "limit", + "limited", + "concurrency", + "throttle", + "throat", + "rate", + "batch", + "ratelimit", + "task", + "queue", + "async", + "await", + "promises", + "bluebird" + ], + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "devDependencies": { + "ava": "^5.3.1", + "delay": "^6.0.0", + "in-range": "^3.0.0", + "random-int": "^3.0.0", + "time-span": "^5.1.0", + "tsd": "^0.29.0", + "xo": "^0.56.0" + } +} diff --git a/node_modules/p-limit/readme.md b/node_modules/p-limit/readme.md new file mode 100644 index 0000000..4e890f8 --- /dev/null +++ b/node_modules/p-limit/readme.md @@ -0,0 +1,88 @@ +# p-limit + +> Run multiple promise-returning & async functions with limited concurrency + +*Works in Node.js and browsers.* + +## Install + +```sh +npm install p-limit +``` + +## Usage + +```js +import pLimit from 'p-limit'; + +const limit = pLimit(1); + +const input = [ + limit(() => fetchSomething('foo')), + limit(() => fetchSomething('bar')), + limit(() => doSomething()) +]; + +// Only one promise is run at once +const result = await Promise.all(input); +console.log(result); +``` + +## API + +### pLimit(concurrency) + +Returns a `limit` function. + +#### concurrency + +Type: `number`\ +Minimum: `1`\ +Default: `Infinity` + +Concurrency limit. + +### limit(fn, ...args) + +Returns the promise returned by calling `fn(...args)`. + +#### fn + +Type: `Function` + +Promise-returning/async function. + +#### args + +Any arguments to pass through to `fn`. + +Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a *lot* of functions. + +### limit.activeCount + +The number of promises that are currently running. + +### limit.pendingCount + +The number of promises that are waiting to run (i.e. their internal `fn` was not called yet). + +### limit.clearQueue() + +Discard pending promises that are waiting to run. + +This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app. + +Note: This does not cancel promises that are already running. + +## FAQ + +### How is this different from the [`p-queue`](https://github.com/sindresorhus/p-queue) package? + +This package is only about limiting the number of concurrent executions, while `p-queue` is a fully featured queue implementation with lots of different options, introspection, and ability to pause the queue. + +## Related + +- [p-throttle](https://github.com/sindresorhus/p-throttle) - Throttle promise-returning & async functions +- [p-debounce](https://github.com/sindresorhus/p-debounce) - Debounce promise-returning & async functions +- [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency +- [More…](https://github.com/sindresorhus/promise-fun) diff --git a/node_modules/path-key/index.d.ts b/node_modules/path-key/index.d.ts new file mode 100644 index 0000000..7c575d1 --- /dev/null +++ b/node_modules/path-key/index.d.ts @@ -0,0 +1,40 @@ +/// + +declare namespace pathKey { + interface Options { + /** + Use a custom environment variables object. Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env). + */ + readonly env?: {[key: string]: string | undefined}; + + /** + Get the PATH key for a specific platform. Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform). + */ + readonly platform?: NodeJS.Platform; + } +} + +declare const pathKey: { + /** + Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform. + + @example + ``` + import pathKey = require('path-key'); + + const key = pathKey(); + //=> 'PATH' + + const PATH = process.env[key]; + //=> '/usr/local/bin:/usr/bin:/bin' + ``` + */ + (options?: pathKey.Options): string; + + // TODO: Remove this for the next major release, refactor the whole definition to: + // declare function pathKey(options?: pathKey.Options): string; + // export = pathKey; + default: typeof pathKey; +}; + +export = pathKey; diff --git a/node_modules/path-key/index.js b/node_modules/path-key/index.js new file mode 100644 index 0000000..0cf6415 --- /dev/null +++ b/node_modules/path-key/index.js @@ -0,0 +1,16 @@ +'use strict'; + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; diff --git a/node_modules/path-key/license b/node_modules/path-key/license new file mode 100644 index 0000000..e7af2f7 --- /dev/null +++ b/node_modules/path-key/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/path-key/package.json b/node_modules/path-key/package.json new file mode 100644 index 0000000..c8cbd38 --- /dev/null +++ b/node_modules/path-key/package.json @@ -0,0 +1,39 @@ +{ + "name": "path-key", + "version": "3.1.1", + "description": "Get the PATH environment variable key cross-platform", + "license": "MIT", + "repository": "sindresorhus/path-key", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "path", + "key", + "environment", + "env", + "variable", + "var", + "get", + "cross-platform", + "windows" + ], + "devDependencies": { + "@types/node": "^11.13.0", + "ava": "^1.4.1", + "tsd": "^0.7.2", + "xo": "^0.24.0" + } +} diff --git a/node_modules/path-key/readme.md b/node_modules/path-key/readme.md new file mode 100644 index 0000000..a9052d7 --- /dev/null +++ b/node_modules/path-key/readme.md @@ -0,0 +1,61 @@ +# path-key [![Build Status](https://travis-ci.org/sindresorhus/path-key.svg?branch=master)](https://travis-ci.org/sindresorhus/path-key) + +> Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform + +It's usually `PATH`, but on Windows it can be any casing like `Path`... + + +## Install + +``` +$ npm install path-key +``` + + +## Usage + +```js +const pathKey = require('path-key'); + +const key = pathKey(); +//=> 'PATH' + +const PATH = process.env[key]; +//=> '/usr/local/bin:/usr/bin:/bin' +``` + + +## API + +### pathKey(options?) + +#### options + +Type: `object` + +##### env + +Type: `object`
+Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env) + +Use a custom environment variables object. + +#### platform + +Type: `string`
+Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform) + +Get the PATH key for a specific platform. + + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/pathe/LICENSE b/node_modules/pathe/LICENSE new file mode 100644 index 0000000..743af99 --- /dev/null +++ b/node_modules/pathe/LICENSE @@ -0,0 +1,44 @@ +MIT License + +Copyright (c) Pooya Parsa - Daniel Roe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------------------------- + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pathe/README.md b/node_modules/pathe/README.md new file mode 100644 index 0000000..a2af0fd --- /dev/null +++ b/node_modules/pathe/README.md @@ -0,0 +1,69 @@ +# 🛣️ pathe + +> Universal filesystem path utils + +[![version][npm-v-src]][npm-v-href] +[![downloads][npm-d-src]][npm-d-href] +[![size][size-src]][size-href] + +> **❓ Why** +> +> For [historical reasons](https://docs.microsoft.com/en-us/archive/blogs/larryosterman/why-is-the-dos-path-character), windows followed MS-DOS and using backslash for separating paths rather than slash used for macOS, Linux, and other Posix operating systems. Nowadays, [Windows](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN) supports both Slash and Backslash for paths. [Node.js's built in `path` module](https://nodejs.org/api/path.html) in the default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used. **This makes inconsistent code behavior between Windows and POSIX.** +> Compared to popular [upath](https://github.com/anodynos/upath), pathe is providing **identical exports** of Node.js with normalization on **all operations** and written in modern **ESM/Typescript** and has **no dependency on Node.js**! + +This package is a drop-in replacement of the Node.js's [path module](https://nodejs.org/api/path.html) module and ensures paths are normalized with slash `/` and work in environments including Node.js. + +## 💿 Usage + +Install using npm or yarn: + +```bash +# npm +npm i pathe + +# yarn +yarn add pathe + +# pnpm +pnpm i pathe +``` + +Import: + +```js +// ESM / Typescript +import { resolve } from 'pathe' + +// CommonJS +const { resolve } = require('pathe') +``` + +Read more about path utils from [Node.js documentation](https://nodejs.org/api/path.html) and rest assured behavior is ALWAYS like POSIX regardless of your input paths format and running platform! + +### Extra utilties + +Pathe exports some extra utilities that do not exist in standard Node.js [path module](https://nodejs.org/api/path.html). +In order to use them, you can import from `pathe/utils` subpath: + +```js +import { filename, normalizeAliases, resolveAlias } from 'pathe/utils' +``` + +## License + +MIT. Made with 💖 + +Some code used from Node.js project. See [LICENSE](./LICENSE). + + +[npm-v-src]: https://img.shields.io/npm/v/pathe?style=flat-square +[npm-v-href]: https://npmjs.com/package/pathe + +[npm-d-src]: https://img.shields.io/npm/dm/pathe?style=flat-square +[npm-d-href]: https://npmjs.com/package/pathe + +[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/pathe/ci/main?style=flat-square +[github-actions-href]: https://github.com/unjs/pathe/actions?query=workflow%3Aci + +[size-src]: https://packagephobia.now.sh/badge?p=pathe +[size-href]: https://packagephobia.now.sh/result?p=pathe diff --git a/node_modules/pathe/dist/index.cjs b/node_modules/pathe/dist/index.cjs new file mode 100644 index 0000000..3832e06 --- /dev/null +++ b/node_modules/pathe/dist/index.cjs @@ -0,0 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const index = require('./shared/pathe.1f0a373c.cjs'); + + + +exports.basename = index.basename; +exports.default = index.path; +exports.delimiter = index.delimiter; +exports.dirname = index.dirname; +exports.extname = index.extname; +exports.format = index.format; +exports.isAbsolute = index.isAbsolute; +exports.join = index.join; +exports.normalize = index.normalize; +exports.normalizeString = index.normalizeString; +exports.parse = index.parse; +exports.relative = index.relative; +exports.resolve = index.resolve; +exports.sep = index.sep; +exports.toNamespacedPath = index.toNamespacedPath; diff --git a/node_modules/pathe/dist/index.d.cts b/node_modules/pathe/dist/index.d.cts new file mode 100644 index 0000000..531b690 --- /dev/null +++ b/node_modules/pathe/dist/index.d.cts @@ -0,0 +1,36 @@ +import path$1 from 'node:path'; + +declare const sep = "/"; +declare const delimiter = ":"; +declare const normalize: typeof path$1.normalize; +declare const join: typeof path$1.join; +declare const resolve: typeof path$1.resolve; +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path$1.isAbsolute; +declare const toNamespacedPath: typeof path$1.toNamespacedPath; +declare const extname: typeof path$1.extname; +declare const relative: typeof path$1.relative; +declare const dirname: typeof path$1.dirname; +declare const format: typeof path$1.format; +declare const basename: typeof path$1.basename; +declare const parse: typeof path$1.parse; + +declare const path_basename: typeof basename; +declare const path_delimiter: typeof delimiter; +declare const path_dirname: typeof dirname; +declare const path_extname: typeof extname; +declare const path_format: typeof format; +declare const path_isAbsolute: typeof isAbsolute; +declare const path_join: typeof join; +declare const path_normalize: typeof normalize; +declare const path_normalizeString: typeof normalizeString; +declare const path_parse: typeof parse; +declare const path_relative: typeof relative; +declare const path_resolve: typeof resolve; +declare const path_sep: typeof sep; +declare const path_toNamespacedPath: typeof toNamespacedPath; +declare namespace path { + export { path_basename as basename, path_delimiter as delimiter, path_dirname as dirname, path_extname as extname, path_format as format, path_isAbsolute as isAbsolute, path_join as join, path_normalize as normalize, path_normalizeString as normalizeString, path_parse as parse, path_relative as relative, path_resolve as resolve, path_sep as sep, path_toNamespacedPath as toNamespacedPath }; +} + +export { basename, path as default, delimiter, dirname, extname, format, isAbsolute, join, normalize, normalizeString, parse, relative, resolve, sep, toNamespacedPath }; diff --git a/node_modules/pathe/dist/index.d.mts b/node_modules/pathe/dist/index.d.mts new file mode 100644 index 0000000..531b690 --- /dev/null +++ b/node_modules/pathe/dist/index.d.mts @@ -0,0 +1,36 @@ +import path$1 from 'node:path'; + +declare const sep = "/"; +declare const delimiter = ":"; +declare const normalize: typeof path$1.normalize; +declare const join: typeof path$1.join; +declare const resolve: typeof path$1.resolve; +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path$1.isAbsolute; +declare const toNamespacedPath: typeof path$1.toNamespacedPath; +declare const extname: typeof path$1.extname; +declare const relative: typeof path$1.relative; +declare const dirname: typeof path$1.dirname; +declare const format: typeof path$1.format; +declare const basename: typeof path$1.basename; +declare const parse: typeof path$1.parse; + +declare const path_basename: typeof basename; +declare const path_delimiter: typeof delimiter; +declare const path_dirname: typeof dirname; +declare const path_extname: typeof extname; +declare const path_format: typeof format; +declare const path_isAbsolute: typeof isAbsolute; +declare const path_join: typeof join; +declare const path_normalize: typeof normalize; +declare const path_normalizeString: typeof normalizeString; +declare const path_parse: typeof parse; +declare const path_relative: typeof relative; +declare const path_resolve: typeof resolve; +declare const path_sep: typeof sep; +declare const path_toNamespacedPath: typeof toNamespacedPath; +declare namespace path { + export { path_basename as basename, path_delimiter as delimiter, path_dirname as dirname, path_extname as extname, path_format as format, path_isAbsolute as isAbsolute, path_join as join, path_normalize as normalize, path_normalizeString as normalizeString, path_parse as parse, path_relative as relative, path_resolve as resolve, path_sep as sep, path_toNamespacedPath as toNamespacedPath }; +} + +export { basename, path as default, delimiter, dirname, extname, format, isAbsolute, join, normalize, normalizeString, parse, relative, resolve, sep, toNamespacedPath }; diff --git a/node_modules/pathe/dist/index.d.ts b/node_modules/pathe/dist/index.d.ts new file mode 100644 index 0000000..531b690 --- /dev/null +++ b/node_modules/pathe/dist/index.d.ts @@ -0,0 +1,36 @@ +import path$1 from 'node:path'; + +declare const sep = "/"; +declare const delimiter = ":"; +declare const normalize: typeof path$1.normalize; +declare const join: typeof path$1.join; +declare const resolve: typeof path$1.resolve; +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path$1.isAbsolute; +declare const toNamespacedPath: typeof path$1.toNamespacedPath; +declare const extname: typeof path$1.extname; +declare const relative: typeof path$1.relative; +declare const dirname: typeof path$1.dirname; +declare const format: typeof path$1.format; +declare const basename: typeof path$1.basename; +declare const parse: typeof path$1.parse; + +declare const path_basename: typeof basename; +declare const path_delimiter: typeof delimiter; +declare const path_dirname: typeof dirname; +declare const path_extname: typeof extname; +declare const path_format: typeof format; +declare const path_isAbsolute: typeof isAbsolute; +declare const path_join: typeof join; +declare const path_normalize: typeof normalize; +declare const path_normalizeString: typeof normalizeString; +declare const path_parse: typeof parse; +declare const path_relative: typeof relative; +declare const path_resolve: typeof resolve; +declare const path_sep: typeof sep; +declare const path_toNamespacedPath: typeof toNamespacedPath; +declare namespace path { + export { path_basename as basename, path_delimiter as delimiter, path_dirname as dirname, path_extname as extname, path_format as format, path_isAbsolute as isAbsolute, path_join as join, path_normalize as normalize, path_normalizeString as normalizeString, path_parse as parse, path_relative as relative, path_resolve as resolve, path_sep as sep, path_toNamespacedPath as toNamespacedPath }; +} + +export { basename, path as default, delimiter, dirname, extname, format, isAbsolute, join, normalize, normalizeString, parse, relative, resolve, sep, toNamespacedPath }; diff --git a/node_modules/pathe/dist/index.mjs b/node_modules/pathe/dist/index.mjs new file mode 100644 index 0000000..ecd6cd0 --- /dev/null +++ b/node_modules/pathe/dist/index.mjs @@ -0,0 +1 @@ +export { h as basename, p as default, d as delimiter, f as dirname, e as extname, g as format, i as isAbsolute, j as join, a as normalize, b as normalizeString, k as parse, c as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.ff20891b.mjs'; diff --git a/node_modules/pathe/dist/shared/pathe.1f0a373c.cjs b/node_modules/pathe/dist/shared/pathe.1f0a373c.cjs new file mode 100644 index 0000000..64e3a33 --- /dev/null +++ b/node_modules/pathe/dist/shared/pathe.1f0a373c.cjs @@ -0,0 +1,238 @@ +'use strict'; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const sep = "/"; +const delimiter = ":"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...arguments_) { + if (arguments_.length === 0) { + return "."; + } + let joined; + for (const argument of arguments_) { + if (argument && argument.length > 0) { + if (joined === void 0) { + joined = argument; + } else { + joined += `/${argument}`; + } + } + } + if (joined === void 0) { + return "."; + } + return normalize(joined.replace(/\/\/+/g, "/")); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const _EXTNAME_RE = /.(\.[^./]+)$/; +const extname = function(p) { + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const segments = [p.root, p.dir, p.base ?? p.name + p.ext].filter(Boolean); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const lastSegment = normalizeWindowsPath(p).split("/").pop(); + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = normalizeWindowsPath(p).split("/").shift() || "/"; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; + +const path = { + __proto__: null, + basename: basename, + delimiter: delimiter, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +exports.basename = basename; +exports.delimiter = delimiter; +exports.dirname = dirname; +exports.extname = extname; +exports.format = format; +exports.isAbsolute = isAbsolute; +exports.join = join; +exports.normalize = normalize; +exports.normalizeString = normalizeString; +exports.normalizeWindowsPath = normalizeWindowsPath; +exports.parse = parse; +exports.path = path; +exports.relative = relative; +exports.resolve = resolve; +exports.sep = sep; +exports.toNamespacedPath = toNamespacedPath; diff --git a/node_modules/pathe/dist/shared/pathe.ff20891b.mjs b/node_modules/pathe/dist/shared/pathe.ff20891b.mjs new file mode 100644 index 0000000..e91d8d6 --- /dev/null +++ b/node_modules/pathe/dist/shared/pathe.ff20891b.mjs @@ -0,0 +1,221 @@ +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const sep = "/"; +const delimiter = ":"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...arguments_) { + if (arguments_.length === 0) { + return "."; + } + let joined; + for (const argument of arguments_) { + if (argument && argument.length > 0) { + if (joined === void 0) { + joined = argument; + } else { + joined += `/${argument}`; + } + } + } + if (joined === void 0) { + return "."; + } + return normalize(joined.replace(/\/\/+/g, "/")); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const _EXTNAME_RE = /.(\.[^./]+)$/; +const extname = function(p) { + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const segments = [p.root, p.dir, p.base ?? p.name + p.ext].filter(Boolean); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const lastSegment = normalizeWindowsPath(p).split("/").pop(); + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = normalizeWindowsPath(p).split("/").shift() || "/"; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; + +const path = { + __proto__: null, + basename: basename, + delimiter: delimiter, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +export { normalize as a, normalizeString as b, relative as c, delimiter as d, extname as e, dirname as f, format as g, basename as h, isAbsolute as i, join as j, parse as k, normalizeWindowsPath as n, path as p, resolve as r, sep as s, toNamespacedPath as t }; diff --git a/node_modules/pathe/dist/utils.cjs b/node_modules/pathe/dist/utils.cjs new file mode 100644 index 0000000..e2591bf --- /dev/null +++ b/node_modules/pathe/dist/utils.cjs @@ -0,0 +1,58 @@ +'use strict'; + +const index = require('./shared/pathe.1f0a373c.cjs'); + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key].startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path = index.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + return index.join(to, _path.slice(alias.length)); + } + } + return _path; +} +const FILENAME_RE = /(^|[/\\])([^/\\]+?)(?=(\.[^.]+)?$)/; +function filename(path) { + return path.match(FILENAME_RE)?.[2]; +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +exports.filename = filename; +exports.normalizeAliases = normalizeAliases; +exports.resolveAlias = resolveAlias; diff --git a/node_modules/pathe/dist/utils.d.cts b/node_modules/pathe/dist/utils.d.cts new file mode 100644 index 0000000..2798305 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.cts @@ -0,0 +1,5 @@ +declare function normalizeAliases(_aliases: Record): Record; +declare function resolveAlias(path: string, aliases: Record): string; +declare function filename(path: string): string; + +export { filename, normalizeAliases, resolveAlias }; diff --git a/node_modules/pathe/dist/utils.d.mts b/node_modules/pathe/dist/utils.d.mts new file mode 100644 index 0000000..2798305 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.mts @@ -0,0 +1,5 @@ +declare function normalizeAliases(_aliases: Record): Record; +declare function resolveAlias(path: string, aliases: Record): string; +declare function filename(path: string): string; + +export { filename, normalizeAliases, resolveAlias }; diff --git a/node_modules/pathe/dist/utils.d.ts b/node_modules/pathe/dist/utils.d.ts new file mode 100644 index 0000000..2798305 --- /dev/null +++ b/node_modules/pathe/dist/utils.d.ts @@ -0,0 +1,5 @@ +declare function normalizeAliases(_aliases: Record): Record; +declare function resolveAlias(path: string, aliases: Record): string; +declare function filename(path: string): string; + +export { filename, normalizeAliases, resolveAlias }; diff --git a/node_modules/pathe/dist/utils.mjs b/node_modules/pathe/dist/utils.mjs new file mode 100644 index 0000000..004080b --- /dev/null +++ b/node_modules/pathe/dist/utils.mjs @@ -0,0 +1,54 @@ +import { n as normalizeWindowsPath, j as join } from './shared/pathe.ff20891b.mjs'; + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key].startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + return join(to, _path.slice(alias.length)); + } + } + return _path; +} +const FILENAME_RE = /(^|[/\\])([^/\\]+?)(?=(\.[^.]+)?$)/; +function filename(path) { + return path.match(FILENAME_RE)?.[2]; +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +export { filename, normalizeAliases, resolveAlias }; diff --git a/node_modules/pathe/package.json b/node_modules/pathe/package.json new file mode 100644 index 0000000..1b14f7d --- /dev/null +++ b/node_modules/pathe/package.json @@ -0,0 +1,48 @@ +{ + "name": "pathe", + "version": "1.1.2", + "description": "Universal filesystem path utils", + "repository": "unjs/pathe", + "license": "MIT", + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./utils": { + "types": "./dist/utils.d.ts", + "import": "./dist/utils.mjs", + "require": "./dist/utils.cjs" + } + }, + "main": "./dist/index.cjs", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "utils.d.ts" + ], + "devDependencies": { + "@types/node": "^20.10.8", + "@vitest/coverage-v8": "^1.1.3", + "changelogen": "^0.5.5", + "eslint": "^8.56.0", + "eslint-config-unjs": "^0.2.1", + "jiti": "^1.21.0", + "prettier": "^3.1.1", + "typescript": "^5.3.3", + "unbuild": "^2.0.0", + "vitest": "^1.1.3" + }, + "packageManager": "pnpm@8.14.0", + "scripts": { + "build": "unbuild", + "dev": "vitest", + "lint": "eslint --ext .ts . && prettier -c src test", + "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test -w", + "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags", + "test": "pnpm lint && vitest run --coverage", + "test:types": "tsc --noEmit" + } +} \ No newline at end of file diff --git a/node_modules/pathe/utils.d.ts b/node_modules/pathe/utils.d.ts new file mode 100644 index 0000000..59cabd3 --- /dev/null +++ b/node_modules/pathe/utils.d.ts @@ -0,0 +1 @@ +export * from "./dist/utils"; diff --git a/node_modules/pathval/CHANGELOG.md b/node_modules/pathval/CHANGELOG.md new file mode 100644 index 0000000..804de5e --- /dev/null +++ b/node_modules/pathval/CHANGELOG.md @@ -0,0 +1,18 @@ + +0.1.1 / 2013-12-30 +================== + + * expose parse + * rename lib to index + +0.1.0 / 2013-12-28 +================== + + * API BREAKING! `get` has been changed, see the README for migration path + * Add `set` method + * Start using simple-assert (closes #2) + +0.0.1 / 2013-11-24 +================== + + * Initial implementation diff --git a/node_modules/pathval/LICENSE b/node_modules/pathval/LICENSE new file mode 100644 index 0000000..90d22da --- /dev/null +++ b/node_modules/pathval/LICENSE @@ -0,0 +1,16 @@ +MIT License + +Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pathval/README.md b/node_modules/pathval/README.md new file mode 100644 index 0000000..22a841e --- /dev/null +++ b/node_modules/pathval/README.md @@ -0,0 +1,147 @@ +

+ + ChaiJS + +
+ pathval +

+ +

+ Tool for Object value retrieval given a string path for node and the browser. +

+ +

+ + license:mit + + + tag:? + + + build:? + + + coverage:? + + + npm:? + + + dependencies:? + + + devDependencies:? + +
+ + Selenium Test Status + +
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is pathval? + +Pathval is a module which you can use to retrieve or set an Object's property for a given `String` path. + +## Installation + +### Node.js + +`pathval` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install pathval + +### Browsers + +You can also use it within the browser; install via npm and use the `pathval.js` file found within the download. For example: + +```html + +``` + +## Usage + +The primary export of `pathval` is an object which has the following methods: + +* `hasProperty(object, name)` - Checks whether an `object` has `name`d property or numeric array index. +* `getPathInfo(object, path)` - Returns an object with info indicating the value of the `parent` of that path, the `name ` of the property we're retrieving and its `value`. +* `getPathValue(object, path)` - Retrieves the value of a property at a given `path` inside an `object`'. +* `setPathValue(object, path, value)` - Sets the `value` of a property at a given `path` inside an `object` and returns the object in which the property has been set. + +```js +var pathval = require('pathval'); +``` + +#### .hasProperty(object, name) + +```js +var pathval = require('pathval'); + +var obj = { prop: 'a value' }; +pathval.hasProperty(obj, 'prop'); // true +``` + +#### .getPathInfo(object, path) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.getPathInfo(obj, 'earth.country'); // { parent: { country: 'Brazil' }, name: 'country', value: 'Brazil', exists: true } +``` + +#### .getPathValue(object, path) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.getPathValue(obj, 'earth.country'); // 'Brazil' +``` + +#### .setPathValue(object, path, value) + +```js +var pathval = require('pathval'); + +var obj = { earth: { country: 'Brazil' } }; +pathval.setPathValue(obj, 'earth.country', 'USA'); + +obj.earth.country; // 'USA' +``` diff --git a/node_modules/pathval/index.js b/node_modules/pathval/index.js new file mode 100644 index 0000000..d0dc43e --- /dev/null +++ b/node_modules/pathval/index.js @@ -0,0 +1,301 @@ +'use strict'; + +/* ! + * Chai - pathval utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has own + * or inherited from prototype chain named property. + * + * Basically does the same thing as the `in` + * operator but works properly with null/undefined values + * and other primitives. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty(obj, 'str'); // true + * hasProperty(obj, 'constructor'); // true + * hasProperty(obj, 'bar'); // false + * + * hasProperty(obj.str, 'length'); // true + * hasProperty(obj.str, 1); // true + * hasProperty(obj.str, 5); // false + * + * hasProperty(obj.arr, 'length'); // true + * hasProperty(obj.arr, 2); // true + * hasProperty(obj.arr, 3); // false + * + * @param {Object} object + * @param {String|Symbol} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name hasProperty + * @api public + */ + +function hasProperty(obj, name) { + if (typeof obj === 'undefined' || obj === null) { + return false; + } + + // The `in` operator does not work with primitives. + return name in Object(obj); +} + +/* ! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `internalGetPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be infinitely deep and nested. + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath(path) { + var str = path.replace(/([^\\])\[/g, '$1.['); + var parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function mapMatches(value) { + if ( + value === 'constructor' || + value === '__proto__' || + value === 'prototype' + ) { + return {}; + } + var regexp = /^\[(\d+)\]$/; + var mArr = regexp.exec(value); + var parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.[\]])/g, '$1') }; + } + + return parsed; + }); +} + +/* ! + * ## internalGetPathValue(obj, parsed[, pathDepth]) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(obj, parsed); + * + * @param {Object} object to search against + * @param {Object} parsed definition from `parsePath`. + * @param {Number} depth (nesting level) of the property we want to retrieve + * @returns {Object|Undefined} value + * @api private + */ + +function internalGetPathValue(obj, parsed, pathDepth) { + var temporaryValue = obj; + var res = null; + pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth; + + for (var i = 0; i < pathDepth; i++) { + var part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === 'undefined') { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + + if (i === pathDepth - 1) { + res = temporaryValue; + } + } + } + + return res; +} + +/* ! + * ## internalSetPathValue(obj, value, parsed) + * + * Companion function for `parsePath` that sets + * the value located at a parsed address. + * + * internalSetPathValue(obj, 'value', parsed); + * + * @param {Object} object to search and define on + * @param {*} value to use upon set + * @param {Object} parsed definition from `parsePath` + * @api private + */ + +function internalSetPathValue(obj, val, parsed) { + var tempObj = obj; + var pathDepth = parsed.length; + var part = null; + // Here we iterate through every part of the path + for (var i = 0; i < pathDepth; i++) { + var propName = null; + var propVal = null; + part = parsed[i]; + + // If it's the last part of the path, we set the 'propName' value with the property name + if (i === pathDepth - 1) { + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Now we set the property with the name held by 'propName' on object with the desired val + tempObj[propName] = val; + } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { + tempObj = tempObj[part.p]; + } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { + tempObj = tempObj[part.i]; + } else { + // If the obj doesn't have the property we create one with that name to define it + var next = parsed[i + 1]; + // Here we set the name of the property which will be defined + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Here we decide if this property will be an array or a new object + propVal = typeof next.p === 'undefined' ? [] : {}; + tempObj[propName] = propVal; + tempObj = tempObj[propName]; + } + } +} + +/** + * ### .getPathInfo(object, path) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {Object} object + * @param {String} path + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +function getPathInfo(obj, path) { + var parsed = parsePath(path); + var last = parsed[parsed.length - 1]; + var info = { + parent: + parsed.length > 1 ? + internalGetPathValue(obj, parsed, parsed.length - 1) : + obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed), + }; + info.exists = hasProperty(info.parent, info.name); + + return info; +} + +/** + * ### .getPathValue(object, path) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue(obj, 'prop1.str'); // Hello + * getPathValue(obj, 'prop1.att[2]'); // b + * getPathValue(obj, 'prop2.arr[0].nested'); // Universe + * + * @param {Object} object + * @param {String} path + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ + +function getPathValue(obj, path) { + var info = getPathInfo(obj, path); + return info.value; +} + +/** + * ### .setPathValue(object, path, value) + * + * Define the value in an object at a given string path. + * + * ```js + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * }; + * ``` + * + * The following would be acceptable. + * + * ```js + * var properties = require('tea-properties'); + * properties.set(obj, 'prop1.str', 'Hello Universe!'); + * properties.set(obj, 'prop1.arr[2]', 'B'); + * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); + * ``` + * + * @param {Object} object + * @param {String} path + * @param {Mixed} value + * @api private + */ + +function setPathValue(obj, path, val) { + var parsed = parsePath(path); + internalSetPathValue(obj, val, parsed); + return obj; +} + +module.exports = { + hasProperty: hasProperty, + getPathInfo: getPathInfo, + getPathValue: getPathValue, + setPathValue: setPathValue, +}; diff --git a/node_modules/pathval/package.json b/node_modules/pathval/package.json new file mode 100644 index 0000000..48ead1b --- /dev/null +++ b/node_modules/pathval/package.json @@ -0,0 +1,80 @@ +{ + "name": "pathval", + "description": "Object value retrieval given a string path", + "homepage": "https://github.com/chaijs/pathval", + "version": "1.1.1", + "keywords": [ + "pathval", + "value retrieval", + "chai util" + ], + "license": "MIT", + "author": "Veselin Todorov ", + "files": [ + "index.js", + "pathval.js" + ], + "main": "./index.js", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/pathval.git" + }, + "scripts": { + "build": "browserify --standalone pathval -o pathval.js", + "lint": "eslint --ignore-path .gitignore .", + "lint:fix": "npm run lint -- --fix", + "prepublish": "npm run build", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "pretest": "npm run lint", + "test": "npm run test:node && npm run test:browser && npm run upload-coverage", + "test:browser": "karma start --singleRun=true", + "test:node": "nyc mocha", + "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0" + }, + "config": { + "ghooks": { + "commit-msg": "validate-commit-msg" + } + }, + "eslintConfig": { + "extends": [ + "strict/es5" + ], + "env": { + "es6": true + }, + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": 0, + "max-statements": 0 + } + }, + "devDependencies": { + "browserify": "^17.0.0", + "browserify-istanbul": "^3.0.1", + "coveralls": "^3.1.0", + "eslint": "^7.13.0", + "eslint-config-strict": "^14.0.1", + "eslint-plugin-filenames": "^1.3.2", + "ghooks": "^2.0.4", + "karma": "^5.2.3", + "karma-browserify": "^7.0.0", + "karma-coverage": "^2.0.3", + "karma-mocha": "^2.0.1", + "karma-phantomjs-launcher": "^1.0.4", + "karma-sauce-launcher": "^4.3.3", + "lcov-result-merger": "^3.1.0", + "mocha": "^8.2.1", + "nyc": "^15.1.0", + "phantomjs-prebuilt": "^2.1.16", + "semantic-release": "^17.2.2", + "simple-assert": "^1.0.0", + "travis-after-all": "^1.4.5", + "validate-commit-msg": "^2.14.0" + }, + "engines": { + "node": "*" + } +} diff --git a/node_modules/pathval/pathval.js b/node_modules/pathval/pathval.js new file mode 100644 index 0000000..0070ed4 --- /dev/null +++ b/node_modules/pathval/pathval.js @@ -0,0 +1 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i Colors } + +export = picocolors diff --git a/node_modules/picocolors/picocolors.js b/node_modules/picocolors/picocolors.js new file mode 100644 index 0000000..e32df85 --- /dev/null +++ b/node_modules/picocolors/picocolors.js @@ -0,0 +1,75 @@ +let p = process || {}, argv = p.argv || [], env = p.env || {} +let isColorSupported = + !(!!env.NO_COLOR || argv.includes("--no-color")) && + (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI) + +let formatter = (open, close, replace = open) => + input => { + let string = "" + input, index = string.indexOf(close, open.length) + return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close + } + +let replaceClose = (string, close, replace, index) => { + let result = "", cursor = 0 + do { + result += string.substring(cursor, index) + replace + cursor = index + close.length + index = string.indexOf(close, cursor) + } while (~index) + return result + string.substring(cursor) +} + +let createColors = (enabled = isColorSupported) => { + let f = enabled ? formatter : () => String + return { + isColorSupported: enabled, + reset: f("\x1b[0m", "\x1b[0m"), + bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), + dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), + italic: f("\x1b[3m", "\x1b[23m"), + underline: f("\x1b[4m", "\x1b[24m"), + inverse: f("\x1b[7m", "\x1b[27m"), + hidden: f("\x1b[8m", "\x1b[28m"), + strikethrough: f("\x1b[9m", "\x1b[29m"), + + black: f("\x1b[30m", "\x1b[39m"), + red: f("\x1b[31m", "\x1b[39m"), + green: f("\x1b[32m", "\x1b[39m"), + yellow: f("\x1b[33m", "\x1b[39m"), + blue: f("\x1b[34m", "\x1b[39m"), + magenta: f("\x1b[35m", "\x1b[39m"), + cyan: f("\x1b[36m", "\x1b[39m"), + white: f("\x1b[37m", "\x1b[39m"), + gray: f("\x1b[90m", "\x1b[39m"), + + bgBlack: f("\x1b[40m", "\x1b[49m"), + bgRed: f("\x1b[41m", "\x1b[49m"), + bgGreen: f("\x1b[42m", "\x1b[49m"), + bgYellow: f("\x1b[43m", "\x1b[49m"), + bgBlue: f("\x1b[44m", "\x1b[49m"), + bgMagenta: f("\x1b[45m", "\x1b[49m"), + bgCyan: f("\x1b[46m", "\x1b[49m"), + bgWhite: f("\x1b[47m", "\x1b[49m"), + + blackBright: f("\x1b[90m", "\x1b[39m"), + redBright: f("\x1b[91m", "\x1b[39m"), + greenBright: f("\x1b[92m", "\x1b[39m"), + yellowBright: f("\x1b[93m", "\x1b[39m"), + blueBright: f("\x1b[94m", "\x1b[39m"), + magentaBright: f("\x1b[95m", "\x1b[39m"), + cyanBright: f("\x1b[96m", "\x1b[39m"), + whiteBright: f("\x1b[97m", "\x1b[39m"), + + bgBlackBright: f("\x1b[100m", "\x1b[49m"), + bgRedBright: f("\x1b[101m", "\x1b[49m"), + bgGreenBright: f("\x1b[102m", "\x1b[49m"), + bgYellowBright: f("\x1b[103m", "\x1b[49m"), + bgBlueBright: f("\x1b[104m", "\x1b[49m"), + bgMagentaBright: f("\x1b[105m", "\x1b[49m"), + bgCyanBright: f("\x1b[106m", "\x1b[49m"), + bgWhiteBright: f("\x1b[107m", "\x1b[49m"), + } +} + +module.exports = createColors() +module.exports.createColors = createColors diff --git a/node_modules/picocolors/types.d.ts b/node_modules/picocolors/types.d.ts new file mode 100644 index 0000000..cd1aec4 --- /dev/null +++ b/node_modules/picocolors/types.d.ts @@ -0,0 +1,51 @@ +export type Formatter = (input: string | number | null | undefined) => string + +export interface Colors { + isColorSupported: boolean + + reset: Formatter + bold: Formatter + dim: Formatter + italic: Formatter + underline: Formatter + inverse: Formatter + hidden: Formatter + strikethrough: Formatter + + black: Formatter + red: Formatter + green: Formatter + yellow: Formatter + blue: Formatter + magenta: Formatter + cyan: Formatter + white: Formatter + gray: Formatter + + bgBlack: Formatter + bgRed: Formatter + bgGreen: Formatter + bgYellow: Formatter + bgBlue: Formatter + bgMagenta: Formatter + bgCyan: Formatter + bgWhite: Formatter + + blackBright: Formatter + redBright: Formatter + greenBright: Formatter + yellowBright: Formatter + blueBright: Formatter + magentaBright: Formatter + cyanBright: Formatter + whiteBright: Formatter + + bgBlackBright: Formatter + bgRedBright: Formatter + bgGreenBright: Formatter + bgYellowBright: Formatter + bgBlueBright: Formatter + bgMagentaBright: Formatter + bgCyanBright: Formatter + bgWhiteBright: Formatter +} diff --git a/node_modules/pkg-types/LICENSE b/node_modules/pkg-types/LICENSE new file mode 100644 index 0000000..743af99 --- /dev/null +++ b/node_modules/pkg-types/LICENSE @@ -0,0 +1,44 @@ +MIT License + +Copyright (c) Pooya Parsa - Daniel Roe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------------------------- + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pkg-types/README.md b/node_modules/pkg-types/README.md new file mode 100644 index 0000000..806b054 --- /dev/null +++ b/node_modules/pkg-types/README.md @@ -0,0 +1,167 @@ +# pkg-types + + + +[![npm version](https://img.shields.io/npm/v/pkg-types?color=yellow)](https://npmjs.com/package/pkg-types) +[![npm downloads](https://img.shields.io/npm/dm/pkg-types?color=yellow)](https://npm.chart.dev/pkg-types) +[![codecov](https://img.shields.io/codecov/c/gh/unjs/pkg-types?color=yellow)](https://codecov.io/gh/unjs/pkg-types) + + + +Node.js utilities and TypeScript definitions for `package.json` and `tsconfig.json`. + +## Install + + + +```sh +# ✨ Auto-detect +npx nypm install pkg-types + +# npm +npm install pkg-types + +# yarn +yarn add pkg-types + +# pnpm +pnpm install pkg-types + +# bun +bun install pkg-types + +# deno +deno install pkg-types +``` + + + +## Usage + +### `readPackageJSON` + +```js +import { readPackageJSON } from "pkg-types"; +const localPackageJson = await readPackageJSON(); +// or +const packageJson = await readPackageJSON("/fully/resolved/path/to/folder"); +``` + +### `writePackageJSON` + +```js +import { writePackageJSON } from "pkg-types"; + +await writePackageJSON("path/to/package.json", pkg); +``` + +### `resolvePackageJSON` + +```js +import { resolvePackageJSON } from "pkg-types"; +const filename = await resolvePackageJSON(); +// or +const packageJson = await resolvePackageJSON("/fully/resolved/path/to/folder"); +``` + +### `readTSConfig` + +```js +import { readTSConfig } from "pkg-types"; +const tsconfig = await readTSConfig(); +// or +const tsconfig2 = await readTSConfig("/fully/resolved/path/to/folder"); +``` + +### `writeTSConfig` + +```js +import { writeTSConfig } from "pkg-types"; + +await writeTSConfig("path/to/tsconfig.json", tsconfig); +``` + +### `resolveTSConfig` + +```js +import { resolveTSConfig } from "pkg-types"; +const filename = await resolveTSConfig(); +// or +const tsconfig = await resolveTSConfig("/fully/resolved/path/to/folder"); +``` + +### `resolveFile` + +```js +import { resolveFile } from "pkg-types"; +const filename = await resolveFile("README.md", { + startingFrom: id, + rootPattern: /^node_modules$/, + matcher: (filename) => filename.endsWith(".md"), +}); +``` + +### `resolveLockFile` + +Find path to the lock file (`yarn.lock`, `package-lock.json`, `pnpm-lock.yaml`, `npm-shrinkwrap.json`) or throws an error. + +```js +import { resolveLockFile } from "pkg-types"; +const lockfile = await resolveLockFile("."); +``` + +### `findWorkspaceDir` + +Try to detect workspace dir by in order: + +1. Nearest `.git` directory +2. Farthest lockfile +3. Farthest `package.json` file + +If fails, throws an error. + +```js +import { findWorkspaceDir } from "pkg-types"; +const workspaceDir = await findWorkspaceDir("."); +``` + +## Types + +**Note:** In order to make types working, you need to install `typescript` as a devDependency. + +You can directly use typed interfaces: + +```ts +import type { TSConfig, PackageJSON } from "pkg-types"; +``` + +You can also use define utils for type support for using in plain `.js` files and auto-complete in IDE. + +```js +import type { definePackageJSON } from 'pkg-types' + +const pkg = definePackageJSON({}) +``` + +```js +import type { defineTSConfig } from 'pkg-types' + +const pkg = defineTSConfig({}) +``` + +## Alternatives + +- [dominikg/tsconfck](https://github.com/dominikg/tsconfck) + +## License + + + +Published under the [MIT](https://github.com/unjs/pkg-types/blob/main/LICENSE) license. +Made by [@pi0](https://github.com/pi0), [@danielroe](https://github.com/danielroe) and [community](https://github.com/unjs/pkg-types/graphs/contributors) 💛 +

+ + + + + diff --git a/node_modules/pkg-types/dist/index.cjs b/node_modules/pkg-types/dist/index.cjs new file mode 100644 index 0000000..7672574 --- /dev/null +++ b/node_modules/pkg-types/dist/index.cjs @@ -0,0 +1,171 @@ +'use strict'; + +const node_fs = require('node:fs'); +const pathe = require('pathe'); +const mlly = require('mlly'); +const confbox = require('confbox'); + +const defaultFindOptions = { + startingFrom: ".", + rootPattern: /^node_modules$/, + reverse: false, + test: (filePath) => { + try { + if (node_fs.statSync(filePath).isFile()) { + return true; + } + } catch { + } + } +}; +async function findFile(filename, _options = {}) { + const filenames = Array.isArray(filename) ? filename : [filename]; + const options = { ...defaultFindOptions, ..._options }; + const basePath = pathe.resolve(options.startingFrom); + const leadingSlash = basePath[0] === "/"; + const segments = basePath.split("/").filter(Boolean); + if (leadingSlash) { + segments[0] = "/" + segments[0]; + } + let root = segments.findIndex((r) => r.match(options.rootPattern)); + if (root === -1) { + root = 0; + } + if (options.reverse) { + for (let index = root + 1; index <= segments.length; index++) { + for (const filename2 of filenames) { + const filePath = pathe.join(...segments.slice(0, index), filename2); + if (await options.test(filePath)) { + return filePath; + } + } + } + } else { + for (let index = segments.length; index > root; index--) { + for (const filename2 of filenames) { + const filePath = pathe.join(...segments.slice(0, index), filename2); + if (await options.test(filePath)) { + return filePath; + } + } + } + } + throw new Error( + `Cannot find matching ${filename} in ${options.startingFrom} or parent directories` + ); +} +function findNearestFile(filename, _options = {}) { + return findFile(filename, _options); +} +function findFarthestFile(filename, _options = {}) { + return findFile(filename, { ..._options, reverse: true }); +} + +function definePackageJSON(package_) { + return package_; +} +function defineTSConfig(tsconfig) { + return tsconfig; +} +const FileCache = /* @__PURE__ */ new Map(); +async function readPackageJSON(id, options = {}) { + const resolvedPath = await resolvePackageJSON(id, options); + const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : FileCache; + if (options.cache && cache.has(resolvedPath)) { + return cache.get(resolvedPath); + } + const blob = await node_fs.promises.readFile(resolvedPath, "utf8"); + let parsed; + try { + parsed = confbox.parseJSON(blob); + } catch { + parsed = confbox.parseJSONC(blob); + } + cache.set(resolvedPath, parsed); + return parsed; +} +async function writePackageJSON(path, package_) { + await node_fs.promises.writeFile(path, confbox.stringifyJSON(package_)); +} +async function readTSConfig(id, options = {}) { + const resolvedPath = await resolveTSConfig(id, options); + const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : FileCache; + if (options.cache && cache.has(resolvedPath)) { + return cache.get(resolvedPath); + } + const text = await node_fs.promises.readFile(resolvedPath, "utf8"); + const parsed = confbox.parseJSONC(text); + cache.set(resolvedPath, parsed); + return parsed; +} +async function writeTSConfig(path, tsconfig) { + await node_fs.promises.writeFile(path, confbox.stringifyJSONC(tsconfig)); +} +async function resolvePackageJSON(id = process.cwd(), options = {}) { + const resolvedPath = pathe.isAbsolute(id) ? id : await mlly.resolvePath(id, options); + return findNearestFile("package.json", { + startingFrom: resolvedPath, + ...options + }); +} +async function resolveTSConfig(id = process.cwd(), options = {}) { + const resolvedPath = pathe.isAbsolute(id) ? id : await mlly.resolvePath(id, options); + return findNearestFile("tsconfig.json", { + startingFrom: resolvedPath, + ...options + }); +} +const lockFiles = [ + "yarn.lock", + "package-lock.json", + "pnpm-lock.yaml", + "npm-shrinkwrap.json", + "bun.lockb", + "bun.lock" +]; +async function resolveLockfile(id = process.cwd(), options = {}) { + const resolvedPath = pathe.isAbsolute(id) ? id : await mlly.resolvePath(id, options); + const _options = { startingFrom: resolvedPath, ...options }; + try { + return await findNearestFile(lockFiles, _options); + } catch { + } + throw new Error("No lockfile found from " + id); +} +async function findWorkspaceDir(id = process.cwd(), options = {}) { + const resolvedPath = pathe.isAbsolute(id) ? id : await mlly.resolvePath(id, options); + const _options = { startingFrom: resolvedPath, ...options }; + try { + const r = await findNearestFile(".git/config", _options); + return pathe.resolve(r, "../.."); + } catch { + } + try { + const r = await resolveLockfile(resolvedPath, { + ..._options, + reverse: true + }); + return pathe.dirname(r); + } catch { + } + try { + const r = await findFile(resolvedPath, _options); + return pathe.dirname(r); + } catch { + } + throw new Error("Cannot detect workspace root from " + id); +} + +exports.definePackageJSON = definePackageJSON; +exports.defineTSConfig = defineTSConfig; +exports.findFarthestFile = findFarthestFile; +exports.findFile = findFile; +exports.findNearestFile = findNearestFile; +exports.findWorkspaceDir = findWorkspaceDir; +exports.readPackageJSON = readPackageJSON; +exports.readTSConfig = readTSConfig; +exports.resolveLockfile = resolveLockfile; +exports.resolvePackageJSON = resolvePackageJSON; +exports.resolveTSConfig = resolveTSConfig; +exports.writePackageJSON = writePackageJSON; +exports.writeTSConfig = writeTSConfig; diff --git a/node_modules/pkg-types/dist/index.d.cts b/node_modules/pkg-types/dist/index.d.cts new file mode 100644 index 0000000..75d75eb --- /dev/null +++ b/node_modules/pkg-types/dist/index.d.cts @@ -0,0 +1,411 @@ +import { ResolveOptions as ResolveOptions$1 } from 'mlly'; +import { CompilerOptions, TypeAcquisition } from 'typescript'; + +interface FindFileOptions { + /** + * The starting directory for the search. + * @default . (same as `process.cwd()`) + */ + startingFrom?: string; + /** + * A pattern to match a path segment above which you don't want to ascend + * @default /^node_modules$/ + */ + rootPattern?: RegExp; + /** + * If true, search starts from root level descending into subdirectories + */ + reverse?: boolean; + /** + * A matcher that can evaluate whether the given path is a valid file (for example, + * by testing whether the file path exists. + * + * @default fs.statSync(path).isFile() + */ + test?: (filePath: string) => boolean | undefined | Promise; +} +/** @deprecated */ +type FindNearestFileOptions = FindFileOptions; +/** + * Asynchronously finds a file by name, starting from the specified directory and traversing up (or down if reverse). + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns a promise that resolves to the path of the file found. + * @throws Will throw an error if the file cannot be found. + */ +declare function findFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the next file with the given name, starting in the given directory and moving up. + * Alias for findFile without reversing the search. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns A promise that resolves to the path of the next file found. + */ +declare function findNearestFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the furthest file with the given name, starting from the root directory and moving downwards. + * This is essentially the reverse of `findNearestFile'. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour, with reverse set to true. + * @returns A promise that resolves to the path of the farthest file found. + */ +declare function findFarthestFile(filename: string, _options?: FindFileOptions): Promise; + +type StripEnums> = { + [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array ? T[K] : T[K] extends undefined ? undefined : any; +}; +interface TSConfig { + compilerOptions?: StripEnums; + exclude?: string[]; + compileOnSave?: boolean; + extends?: string | string[]; + files?: string[]; + include?: string[]; + typeAcquisition?: TypeAcquisition; + references?: { + path: string; + }[]; +} + +interface PackageJson { + /** + * The name is what your thing is called. + * Some rules: + * - The name must be less than or equal to 214 characters. This includes the scope for scoped packages. + * - The name can’t start with a dot or an underscore. + * - New packages must not have uppercase letters in the name. + * - The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can’t contain any non-URL-safe characters. + */ + name?: string; + /** + * Version must be parseable by `node-semver`, which is bundled with npm as a dependency. (`npm install semver` to use it yourself.) + */ + version?: string; + /** + * Put a description in it. It’s a string. This helps people discover your package, as it’s listed in `npm search`. + */ + description?: string; + /** + * Put keywords in it. It’s an array of strings. This helps people discover your package as it’s listed in `npm search`. + */ + keywords?: string[]; + /** + * The url to the project homepage. + */ + homepage?: string; + /** + * The url to your project’s issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues with your package. + */ + bugs?: string | { + url?: string; + email?: string; + }; + /** + * You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you’re placing on it. + */ + license?: string; + /** + * Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the `npm docs` command will be able to find you. + * For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for npm install: + */ + repository?: string | { + type: string; + url: string; + /** + * If the `package.json` for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives: + */ + directory?: string; + }; + /** + * The `scripts` field is a dictionary containing script commands that are run at various times in the lifecycle of your package. + */ + scripts?: Record; + /** + * If you set `"private": true` in your package.json, then npm will refuse to publish it. + */ + private?: boolean; + /** + * The “author” is one person. + */ + author?: PackageJsonPerson; + /** + * “contributors” is an array of people. + */ + contributors?: PackageJsonPerson[]; + /** + * The optional `files` field is an array of file patterns that describes the entries to be included when your package is installed as a dependency. File patterns follow a similar syntax to `.gitignore`, but reversed: including a file, directory, or glob pattern (`*`, `**\/*`, and such) will make it so that file is included in the tarball when it’s packed. Omitting the field will make it default to `["*"]`, which means it will include all files. + */ + files?: string[]; + /** + * The main field is a module ID that is the primary entry point to your program. That is, if your package is named `foo`, and a user installs it, and then does `require("foo")`, then your main module’s exports object will be returned. + * This should be a module ID relative to the root of your package folder. + * For most modules, it makes the most sense to have a main script and often not much else. + */ + main?: string; + /** + * If your module is meant to be used client-side the browser field should be used instead of the main field. This is helpful to hint users that it might rely on primitives that aren’t available in Node.js modules. (e.g. window) + */ + browser?: string | Record; + /** + * The `unpkg` field is used to specify the URL to a UMD module for your package. This is used by default in the unpkg.com CDN service. + */ + unpkg?: string; + /** + * A map of command name to local file name. On install, npm will symlink that file into `prefix/bin` for global installs, or `./node_modules/.bin/` for local installs. + */ + bin?: string | Record; + /** + * Specify either a single file or an array of filenames to put in place for the `man` program to find. + */ + man?: string | string[]; + /** + * Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL. + */ + dependencies?: Record; + /** + * If someone is planning on downloading and using your module in their program, then they probably don’t want or need to download and build the external test or documentation framework that you use. + * In this case, it’s best to map these additional items in a `devDependencies` object. + */ + devDependencies?: Record; + /** + * If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the `optionalDependencies` object. This is a map of package name to version or url, just like the `dependencies` object. The difference is that build failures do not cause installation to fail. + */ + optionalDependencies?: Record; + /** + * In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a `require` of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation. + */ + peerDependencies?: Record; + /** + * TypeScript typings, typically ending by `.d.ts`. + */ + types?: string; + /** + * This field is synonymous with `types`. + */ + typings?: string; + /** + * Non-Standard Node.js alternate entry-point to main. + * An initial implementation for supporting CJS packages (from main), and use module for ESM modules. + */ + module?: string; + /** + * Make main entry-point be loaded as an ESM module, support "export" syntax instead of "require" + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_package_json_type_field + * + * @default 'commonjs' + * @since Node.js v14 + */ + type?: "module" | "commonjs"; + /** + * Alternate and extensible alternative to "main" entry point. + * + * When using `{type: "module"}`, any ESM module file MUST end with `.mjs` extension. + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_exports_sugar + * + * @since Node.js v12.7 + */ + exports?: PackageJsonExports; + /** + * Docs: + * - https://nodejs.org/api/packages.html#imports + */ + imports?: Record>; + /** + * The field is used to define a set of sub-packages (or workspaces) within a monorepo. + * + * This field is an array of glob patterns or an object with specific configurations for managing + * multiple packages in a single repository. + */ + workspaces?: string[]; + /** + * The field is is used to specify different TypeScript declaration files for + * different versions of TypeScript, allowing for version-specific type definitions. + */ + typesVersions?: Record>; + /** + * You can specify which operating systems your module will run on: + * ```json + * { + * "os": ["darwin", "linux"] + * } + * ``` + * You can also block instead of allowing operating systems, just prepend the blocked os with a '!': + * ```json + * { + * "os": ["!win32"] + * } + * ``` + * The host operating system is determined by `process.platform` + * It is allowed to both block and allow an item, although there isn't any good reason to do this. + */ + os?: string[]; + /** + * If your code only runs on certain cpu architectures, you can specify which ones. + * ```json + * { + * "cpu": ["x64", "ia32"] + * } + * ``` + * Like the `os` option, you can also block architectures: + * ```json + * { + * "cpu": ["!arm", "!mips"] + * } + * ``` + * The host architecture is determined by `process.arch` + */ + cpu?: string[]; + /** + * This is a set of config values that will be used at publish-time. + */ + publishConfig?: { + /** + * The registry that will be used if the package is published. + */ + registry?: string; + /** + * The tag that will be used if the package is published. + */ + tag?: string; + /** + * The access level that will be used if the package is published. + */ + access?: "public" | "restricted"; + /** + * **pnpm-only** + * + * By default, for portability reasons, no files except those listed in + * the bin field will be marked as executable in the resulting package + * archive. The executableFiles field lets you declare additional fields + * that must have the executable flag (+x) set even if + * they aren't directly accessible through the bin field. + */ + executableFiles?: string[]; + /** + * **pnpm-only** + * + * You also can use the field `publishConfig.directory` to customize + * the published subdirectory relative to the current `package.json`. + * + * It is expected to have a modified version of the current package in + * the specified directory (usually using third party build tools). + */ + directory?: string; + /** + * **pnpm-only** + * + * When set to `true`, the project will be symlinked from the + * `publishConfig.directory` location during local development. + * @default true + */ + linkDirectory?: boolean; + } & Pick; + /** + * See: https://nodejs.org/api/packages.html#packagemanager + * This field defines which package manager is expected to be used when working on the current project. + * Should be of the format: `@[#hash]` + */ + packageManager?: string; + [key: string]: any; +} +/** + * A “person” is an object with a “name” field and optionally “url” and “email”. Or you can shorten that all into a single string, and npm will parse it for you. + */ +type PackageJsonPerson = string | { + name: string; + email?: string; + url?: string; +}; +type PackageJsonExportKey = "." | "import" | "require" | "types" | "node" | "browser" | "default" | (string & {}); +type PackageJsonExportsObject = { + [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array; +}; +type PackageJsonExports = string | PackageJsonExportsObject | Array; + +/** + * Represents the options for resolving paths with additional file finding capabilities. + */ +type ResolveOptions = ResolveOptions$1 & FindFileOptions; +/** + * Options for reading files with optional caching. + */ +type ReadOptions = { + /** + * Specifies whether the read results should be cached. + * Can be a boolean or a map to hold the cached data. + */ + cache?: boolean | Map>; +}; +/** + * Defines a PackageJson structure. + * @param package_ - The `package.json` content as an object. See {@link PackageJson}. + * @returns the same `package.json` object. + */ +declare function definePackageJSON(package_: PackageJson): PackageJson; +/** + * Defines a TSConfig structure. + * @param tsconfig - The contents of `tsconfig.json` as an object. See {@link TSConfig}. + * @returns the same `tsconfig.json` object. + */ +declare function defineTSConfig(tsconfig: TSConfig): TSConfig; +/** + * Asynchronously reads a `package.json` file. + * @param id - The path identifier for the package.json, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `package.json` object. + */ +declare function readPackageJSON(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `package.json` file. + * @param path - The path to the file where the `package.json` is written. + * @param package_ - The `package.json` object to write. See {@link PackageJson}. + */ +declare function writePackageJSON(path: string, package_: PackageJson): Promise; +/** + * Asynchronously reads a `tsconfig.json` file. + * @param id - The path to the `tsconfig.json` file, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `tsconfig.json` object. + */ +declare function readTSConfig(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `tsconfig.json` file. + * @param path - The path to the file where the `tsconfig.json` is written. + * @param tsconfig - The `tsconfig.json` object to write. See {@link TSConfig}. + */ +declare function writeTSConfig(path: string, tsconfig: TSConfig): Promise; +/** + * Resolves the path to the nearest `package.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `package.json` file. + */ +declare function resolvePackageJSON(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest `tsconfig.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `tsconfig.json` file. + */ +declare function resolveTSConfig(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest lockfile from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest lockfile. + */ +declare function resolveLockfile(id?: string, options?: ResolveOptions): Promise; +/** + * Detects the workspace directory based on common project markers (`.git`, lockfiles, `package.json`). + * Throws an error if the workspace root cannot be detected. + * @param id - The base path to search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns a promise resolving to the path of the detected workspace directory. + */ +declare function findWorkspaceDir(id?: string, options?: ResolveOptions): Promise; + +export { type FindFileOptions, type FindNearestFileOptions, type PackageJson, type PackageJsonExports, type PackageJsonPerson, type ReadOptions, type ResolveOptions, type StripEnums, type TSConfig, definePackageJSON, defineTSConfig, findFarthestFile, findFile, findNearestFile, findWorkspaceDir, readPackageJSON, readTSConfig, resolveLockfile, resolvePackageJSON, resolveTSConfig, writePackageJSON, writeTSConfig }; diff --git a/node_modules/pkg-types/dist/index.d.mts b/node_modules/pkg-types/dist/index.d.mts new file mode 100644 index 0000000..75d75eb --- /dev/null +++ b/node_modules/pkg-types/dist/index.d.mts @@ -0,0 +1,411 @@ +import { ResolveOptions as ResolveOptions$1 } from 'mlly'; +import { CompilerOptions, TypeAcquisition } from 'typescript'; + +interface FindFileOptions { + /** + * The starting directory for the search. + * @default . (same as `process.cwd()`) + */ + startingFrom?: string; + /** + * A pattern to match a path segment above which you don't want to ascend + * @default /^node_modules$/ + */ + rootPattern?: RegExp; + /** + * If true, search starts from root level descending into subdirectories + */ + reverse?: boolean; + /** + * A matcher that can evaluate whether the given path is a valid file (for example, + * by testing whether the file path exists. + * + * @default fs.statSync(path).isFile() + */ + test?: (filePath: string) => boolean | undefined | Promise; +} +/** @deprecated */ +type FindNearestFileOptions = FindFileOptions; +/** + * Asynchronously finds a file by name, starting from the specified directory and traversing up (or down if reverse). + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns a promise that resolves to the path of the file found. + * @throws Will throw an error if the file cannot be found. + */ +declare function findFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the next file with the given name, starting in the given directory and moving up. + * Alias for findFile without reversing the search. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns A promise that resolves to the path of the next file found. + */ +declare function findNearestFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the furthest file with the given name, starting from the root directory and moving downwards. + * This is essentially the reverse of `findNearestFile'. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour, with reverse set to true. + * @returns A promise that resolves to the path of the farthest file found. + */ +declare function findFarthestFile(filename: string, _options?: FindFileOptions): Promise; + +type StripEnums> = { + [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array ? T[K] : T[K] extends undefined ? undefined : any; +}; +interface TSConfig { + compilerOptions?: StripEnums; + exclude?: string[]; + compileOnSave?: boolean; + extends?: string | string[]; + files?: string[]; + include?: string[]; + typeAcquisition?: TypeAcquisition; + references?: { + path: string; + }[]; +} + +interface PackageJson { + /** + * The name is what your thing is called. + * Some rules: + * - The name must be less than or equal to 214 characters. This includes the scope for scoped packages. + * - The name can’t start with a dot or an underscore. + * - New packages must not have uppercase letters in the name. + * - The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can’t contain any non-URL-safe characters. + */ + name?: string; + /** + * Version must be parseable by `node-semver`, which is bundled with npm as a dependency. (`npm install semver` to use it yourself.) + */ + version?: string; + /** + * Put a description in it. It’s a string. This helps people discover your package, as it’s listed in `npm search`. + */ + description?: string; + /** + * Put keywords in it. It’s an array of strings. This helps people discover your package as it’s listed in `npm search`. + */ + keywords?: string[]; + /** + * The url to the project homepage. + */ + homepage?: string; + /** + * The url to your project’s issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues with your package. + */ + bugs?: string | { + url?: string; + email?: string; + }; + /** + * You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you’re placing on it. + */ + license?: string; + /** + * Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the `npm docs` command will be able to find you. + * For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for npm install: + */ + repository?: string | { + type: string; + url: string; + /** + * If the `package.json` for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives: + */ + directory?: string; + }; + /** + * The `scripts` field is a dictionary containing script commands that are run at various times in the lifecycle of your package. + */ + scripts?: Record; + /** + * If you set `"private": true` in your package.json, then npm will refuse to publish it. + */ + private?: boolean; + /** + * The “author” is one person. + */ + author?: PackageJsonPerson; + /** + * “contributors” is an array of people. + */ + contributors?: PackageJsonPerson[]; + /** + * The optional `files` field is an array of file patterns that describes the entries to be included when your package is installed as a dependency. File patterns follow a similar syntax to `.gitignore`, but reversed: including a file, directory, or glob pattern (`*`, `**\/*`, and such) will make it so that file is included in the tarball when it’s packed. Omitting the field will make it default to `["*"]`, which means it will include all files. + */ + files?: string[]; + /** + * The main field is a module ID that is the primary entry point to your program. That is, if your package is named `foo`, and a user installs it, and then does `require("foo")`, then your main module’s exports object will be returned. + * This should be a module ID relative to the root of your package folder. + * For most modules, it makes the most sense to have a main script and often not much else. + */ + main?: string; + /** + * If your module is meant to be used client-side the browser field should be used instead of the main field. This is helpful to hint users that it might rely on primitives that aren’t available in Node.js modules. (e.g. window) + */ + browser?: string | Record; + /** + * The `unpkg` field is used to specify the URL to a UMD module for your package. This is used by default in the unpkg.com CDN service. + */ + unpkg?: string; + /** + * A map of command name to local file name. On install, npm will symlink that file into `prefix/bin` for global installs, or `./node_modules/.bin/` for local installs. + */ + bin?: string | Record; + /** + * Specify either a single file or an array of filenames to put in place for the `man` program to find. + */ + man?: string | string[]; + /** + * Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL. + */ + dependencies?: Record; + /** + * If someone is planning on downloading and using your module in their program, then they probably don’t want or need to download and build the external test or documentation framework that you use. + * In this case, it’s best to map these additional items in a `devDependencies` object. + */ + devDependencies?: Record; + /** + * If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the `optionalDependencies` object. This is a map of package name to version or url, just like the `dependencies` object. The difference is that build failures do not cause installation to fail. + */ + optionalDependencies?: Record; + /** + * In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a `require` of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation. + */ + peerDependencies?: Record; + /** + * TypeScript typings, typically ending by `.d.ts`. + */ + types?: string; + /** + * This field is synonymous with `types`. + */ + typings?: string; + /** + * Non-Standard Node.js alternate entry-point to main. + * An initial implementation for supporting CJS packages (from main), and use module for ESM modules. + */ + module?: string; + /** + * Make main entry-point be loaded as an ESM module, support "export" syntax instead of "require" + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_package_json_type_field + * + * @default 'commonjs' + * @since Node.js v14 + */ + type?: "module" | "commonjs"; + /** + * Alternate and extensible alternative to "main" entry point. + * + * When using `{type: "module"}`, any ESM module file MUST end with `.mjs` extension. + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_exports_sugar + * + * @since Node.js v12.7 + */ + exports?: PackageJsonExports; + /** + * Docs: + * - https://nodejs.org/api/packages.html#imports + */ + imports?: Record>; + /** + * The field is used to define a set of sub-packages (or workspaces) within a monorepo. + * + * This field is an array of glob patterns or an object with specific configurations for managing + * multiple packages in a single repository. + */ + workspaces?: string[]; + /** + * The field is is used to specify different TypeScript declaration files for + * different versions of TypeScript, allowing for version-specific type definitions. + */ + typesVersions?: Record>; + /** + * You can specify which operating systems your module will run on: + * ```json + * { + * "os": ["darwin", "linux"] + * } + * ``` + * You can also block instead of allowing operating systems, just prepend the blocked os with a '!': + * ```json + * { + * "os": ["!win32"] + * } + * ``` + * The host operating system is determined by `process.platform` + * It is allowed to both block and allow an item, although there isn't any good reason to do this. + */ + os?: string[]; + /** + * If your code only runs on certain cpu architectures, you can specify which ones. + * ```json + * { + * "cpu": ["x64", "ia32"] + * } + * ``` + * Like the `os` option, you can also block architectures: + * ```json + * { + * "cpu": ["!arm", "!mips"] + * } + * ``` + * The host architecture is determined by `process.arch` + */ + cpu?: string[]; + /** + * This is a set of config values that will be used at publish-time. + */ + publishConfig?: { + /** + * The registry that will be used if the package is published. + */ + registry?: string; + /** + * The tag that will be used if the package is published. + */ + tag?: string; + /** + * The access level that will be used if the package is published. + */ + access?: "public" | "restricted"; + /** + * **pnpm-only** + * + * By default, for portability reasons, no files except those listed in + * the bin field will be marked as executable in the resulting package + * archive. The executableFiles field lets you declare additional fields + * that must have the executable flag (+x) set even if + * they aren't directly accessible through the bin field. + */ + executableFiles?: string[]; + /** + * **pnpm-only** + * + * You also can use the field `publishConfig.directory` to customize + * the published subdirectory relative to the current `package.json`. + * + * It is expected to have a modified version of the current package in + * the specified directory (usually using third party build tools). + */ + directory?: string; + /** + * **pnpm-only** + * + * When set to `true`, the project will be symlinked from the + * `publishConfig.directory` location during local development. + * @default true + */ + linkDirectory?: boolean; + } & Pick; + /** + * See: https://nodejs.org/api/packages.html#packagemanager + * This field defines which package manager is expected to be used when working on the current project. + * Should be of the format: `@[#hash]` + */ + packageManager?: string; + [key: string]: any; +} +/** + * A “person” is an object with a “name” field and optionally “url” and “email”. Or you can shorten that all into a single string, and npm will parse it for you. + */ +type PackageJsonPerson = string | { + name: string; + email?: string; + url?: string; +}; +type PackageJsonExportKey = "." | "import" | "require" | "types" | "node" | "browser" | "default" | (string & {}); +type PackageJsonExportsObject = { + [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array; +}; +type PackageJsonExports = string | PackageJsonExportsObject | Array; + +/** + * Represents the options for resolving paths with additional file finding capabilities. + */ +type ResolveOptions = ResolveOptions$1 & FindFileOptions; +/** + * Options for reading files with optional caching. + */ +type ReadOptions = { + /** + * Specifies whether the read results should be cached. + * Can be a boolean or a map to hold the cached data. + */ + cache?: boolean | Map>; +}; +/** + * Defines a PackageJson structure. + * @param package_ - The `package.json` content as an object. See {@link PackageJson}. + * @returns the same `package.json` object. + */ +declare function definePackageJSON(package_: PackageJson): PackageJson; +/** + * Defines a TSConfig structure. + * @param tsconfig - The contents of `tsconfig.json` as an object. See {@link TSConfig}. + * @returns the same `tsconfig.json` object. + */ +declare function defineTSConfig(tsconfig: TSConfig): TSConfig; +/** + * Asynchronously reads a `package.json` file. + * @param id - The path identifier for the package.json, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `package.json` object. + */ +declare function readPackageJSON(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `package.json` file. + * @param path - The path to the file where the `package.json` is written. + * @param package_ - The `package.json` object to write. See {@link PackageJson}. + */ +declare function writePackageJSON(path: string, package_: PackageJson): Promise; +/** + * Asynchronously reads a `tsconfig.json` file. + * @param id - The path to the `tsconfig.json` file, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `tsconfig.json` object. + */ +declare function readTSConfig(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `tsconfig.json` file. + * @param path - The path to the file where the `tsconfig.json` is written. + * @param tsconfig - The `tsconfig.json` object to write. See {@link TSConfig}. + */ +declare function writeTSConfig(path: string, tsconfig: TSConfig): Promise; +/** + * Resolves the path to the nearest `package.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `package.json` file. + */ +declare function resolvePackageJSON(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest `tsconfig.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `tsconfig.json` file. + */ +declare function resolveTSConfig(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest lockfile from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest lockfile. + */ +declare function resolveLockfile(id?: string, options?: ResolveOptions): Promise; +/** + * Detects the workspace directory based on common project markers (`.git`, lockfiles, `package.json`). + * Throws an error if the workspace root cannot be detected. + * @param id - The base path to search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns a promise resolving to the path of the detected workspace directory. + */ +declare function findWorkspaceDir(id?: string, options?: ResolveOptions): Promise; + +export { type FindFileOptions, type FindNearestFileOptions, type PackageJson, type PackageJsonExports, type PackageJsonPerson, type ReadOptions, type ResolveOptions, type StripEnums, type TSConfig, definePackageJSON, defineTSConfig, findFarthestFile, findFile, findNearestFile, findWorkspaceDir, readPackageJSON, readTSConfig, resolveLockfile, resolvePackageJSON, resolveTSConfig, writePackageJSON, writeTSConfig }; diff --git a/node_modules/pkg-types/dist/index.d.ts b/node_modules/pkg-types/dist/index.d.ts new file mode 100644 index 0000000..75d75eb --- /dev/null +++ b/node_modules/pkg-types/dist/index.d.ts @@ -0,0 +1,411 @@ +import { ResolveOptions as ResolveOptions$1 } from 'mlly'; +import { CompilerOptions, TypeAcquisition } from 'typescript'; + +interface FindFileOptions { + /** + * The starting directory for the search. + * @default . (same as `process.cwd()`) + */ + startingFrom?: string; + /** + * A pattern to match a path segment above which you don't want to ascend + * @default /^node_modules$/ + */ + rootPattern?: RegExp; + /** + * If true, search starts from root level descending into subdirectories + */ + reverse?: boolean; + /** + * A matcher that can evaluate whether the given path is a valid file (for example, + * by testing whether the file path exists. + * + * @default fs.statSync(path).isFile() + */ + test?: (filePath: string) => boolean | undefined | Promise; +} +/** @deprecated */ +type FindNearestFileOptions = FindFileOptions; +/** + * Asynchronously finds a file by name, starting from the specified directory and traversing up (or down if reverse). + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns a promise that resolves to the path of the file found. + * @throws Will throw an error if the file cannot be found. + */ +declare function findFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the next file with the given name, starting in the given directory and moving up. + * Alias for findFile without reversing the search. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour. + * @returns A promise that resolves to the path of the next file found. + */ +declare function findNearestFile(filename: string | string[], _options?: FindFileOptions): Promise; +/** + * Asynchronously finds the furthest file with the given name, starting from the root directory and moving downwards. + * This is essentially the reverse of `findNearestFile'. + * @param filename - The name of the file to find. + * @param _options - Options to customise the search behaviour, with reverse set to true. + * @returns A promise that resolves to the path of the farthest file found. + */ +declare function findFarthestFile(filename: string, _options?: FindFileOptions): Promise; + +type StripEnums> = { + [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array ? T[K] : T[K] extends undefined ? undefined : any; +}; +interface TSConfig { + compilerOptions?: StripEnums; + exclude?: string[]; + compileOnSave?: boolean; + extends?: string | string[]; + files?: string[]; + include?: string[]; + typeAcquisition?: TypeAcquisition; + references?: { + path: string; + }[]; +} + +interface PackageJson { + /** + * The name is what your thing is called. + * Some rules: + * - The name must be less than or equal to 214 characters. This includes the scope for scoped packages. + * - The name can’t start with a dot or an underscore. + * - New packages must not have uppercase letters in the name. + * - The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can’t contain any non-URL-safe characters. + */ + name?: string; + /** + * Version must be parseable by `node-semver`, which is bundled with npm as a dependency. (`npm install semver` to use it yourself.) + */ + version?: string; + /** + * Put a description in it. It’s a string. This helps people discover your package, as it’s listed in `npm search`. + */ + description?: string; + /** + * Put keywords in it. It’s an array of strings. This helps people discover your package as it’s listed in `npm search`. + */ + keywords?: string[]; + /** + * The url to the project homepage. + */ + homepage?: string; + /** + * The url to your project’s issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues with your package. + */ + bugs?: string | { + url?: string; + email?: string; + }; + /** + * You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you’re placing on it. + */ + license?: string; + /** + * Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the `npm docs` command will be able to find you. + * For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for npm install: + */ + repository?: string | { + type: string; + url: string; + /** + * If the `package.json` for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives: + */ + directory?: string; + }; + /** + * The `scripts` field is a dictionary containing script commands that are run at various times in the lifecycle of your package. + */ + scripts?: Record; + /** + * If you set `"private": true` in your package.json, then npm will refuse to publish it. + */ + private?: boolean; + /** + * The “author” is one person. + */ + author?: PackageJsonPerson; + /** + * “contributors” is an array of people. + */ + contributors?: PackageJsonPerson[]; + /** + * The optional `files` field is an array of file patterns that describes the entries to be included when your package is installed as a dependency. File patterns follow a similar syntax to `.gitignore`, but reversed: including a file, directory, or glob pattern (`*`, `**\/*`, and such) will make it so that file is included in the tarball when it’s packed. Omitting the field will make it default to `["*"]`, which means it will include all files. + */ + files?: string[]; + /** + * The main field is a module ID that is the primary entry point to your program. That is, if your package is named `foo`, and a user installs it, and then does `require("foo")`, then your main module’s exports object will be returned. + * This should be a module ID relative to the root of your package folder. + * For most modules, it makes the most sense to have a main script and often not much else. + */ + main?: string; + /** + * If your module is meant to be used client-side the browser field should be used instead of the main field. This is helpful to hint users that it might rely on primitives that aren’t available in Node.js modules. (e.g. window) + */ + browser?: string | Record; + /** + * The `unpkg` field is used to specify the URL to a UMD module for your package. This is used by default in the unpkg.com CDN service. + */ + unpkg?: string; + /** + * A map of command name to local file name. On install, npm will symlink that file into `prefix/bin` for global installs, or `./node_modules/.bin/` for local installs. + */ + bin?: string | Record; + /** + * Specify either a single file or an array of filenames to put in place for the `man` program to find. + */ + man?: string | string[]; + /** + * Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL. + */ + dependencies?: Record; + /** + * If someone is planning on downloading and using your module in their program, then they probably don’t want or need to download and build the external test or documentation framework that you use. + * In this case, it’s best to map these additional items in a `devDependencies` object. + */ + devDependencies?: Record; + /** + * If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the `optionalDependencies` object. This is a map of package name to version or url, just like the `dependencies` object. The difference is that build failures do not cause installation to fail. + */ + optionalDependencies?: Record; + /** + * In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a `require` of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation. + */ + peerDependencies?: Record; + /** + * TypeScript typings, typically ending by `.d.ts`. + */ + types?: string; + /** + * This field is synonymous with `types`. + */ + typings?: string; + /** + * Non-Standard Node.js alternate entry-point to main. + * An initial implementation for supporting CJS packages (from main), and use module for ESM modules. + */ + module?: string; + /** + * Make main entry-point be loaded as an ESM module, support "export" syntax instead of "require" + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_package_json_type_field + * + * @default 'commonjs' + * @since Node.js v14 + */ + type?: "module" | "commonjs"; + /** + * Alternate and extensible alternative to "main" entry point. + * + * When using `{type: "module"}`, any ESM module file MUST end with `.mjs` extension. + * + * Docs: + * - https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_exports_sugar + * + * @since Node.js v12.7 + */ + exports?: PackageJsonExports; + /** + * Docs: + * - https://nodejs.org/api/packages.html#imports + */ + imports?: Record>; + /** + * The field is used to define a set of sub-packages (or workspaces) within a monorepo. + * + * This field is an array of glob patterns or an object with specific configurations for managing + * multiple packages in a single repository. + */ + workspaces?: string[]; + /** + * The field is is used to specify different TypeScript declaration files for + * different versions of TypeScript, allowing for version-specific type definitions. + */ + typesVersions?: Record>; + /** + * You can specify which operating systems your module will run on: + * ```json + * { + * "os": ["darwin", "linux"] + * } + * ``` + * You can also block instead of allowing operating systems, just prepend the blocked os with a '!': + * ```json + * { + * "os": ["!win32"] + * } + * ``` + * The host operating system is determined by `process.platform` + * It is allowed to both block and allow an item, although there isn't any good reason to do this. + */ + os?: string[]; + /** + * If your code only runs on certain cpu architectures, you can specify which ones. + * ```json + * { + * "cpu": ["x64", "ia32"] + * } + * ``` + * Like the `os` option, you can also block architectures: + * ```json + * { + * "cpu": ["!arm", "!mips"] + * } + * ``` + * The host architecture is determined by `process.arch` + */ + cpu?: string[]; + /** + * This is a set of config values that will be used at publish-time. + */ + publishConfig?: { + /** + * The registry that will be used if the package is published. + */ + registry?: string; + /** + * The tag that will be used if the package is published. + */ + tag?: string; + /** + * The access level that will be used if the package is published. + */ + access?: "public" | "restricted"; + /** + * **pnpm-only** + * + * By default, for portability reasons, no files except those listed in + * the bin field will be marked as executable in the resulting package + * archive. The executableFiles field lets you declare additional fields + * that must have the executable flag (+x) set even if + * they aren't directly accessible through the bin field. + */ + executableFiles?: string[]; + /** + * **pnpm-only** + * + * You also can use the field `publishConfig.directory` to customize + * the published subdirectory relative to the current `package.json`. + * + * It is expected to have a modified version of the current package in + * the specified directory (usually using third party build tools). + */ + directory?: string; + /** + * **pnpm-only** + * + * When set to `true`, the project will be symlinked from the + * `publishConfig.directory` location during local development. + * @default true + */ + linkDirectory?: boolean; + } & Pick; + /** + * See: https://nodejs.org/api/packages.html#packagemanager + * This field defines which package manager is expected to be used when working on the current project. + * Should be of the format: `@[#hash]` + */ + packageManager?: string; + [key: string]: any; +} +/** + * A “person” is an object with a “name” field and optionally “url” and “email”. Or you can shorten that all into a single string, and npm will parse it for you. + */ +type PackageJsonPerson = string | { + name: string; + email?: string; + url?: string; +}; +type PackageJsonExportKey = "." | "import" | "require" | "types" | "node" | "browser" | "default" | (string & {}); +type PackageJsonExportsObject = { + [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array; +}; +type PackageJsonExports = string | PackageJsonExportsObject | Array; + +/** + * Represents the options for resolving paths with additional file finding capabilities. + */ +type ResolveOptions = ResolveOptions$1 & FindFileOptions; +/** + * Options for reading files with optional caching. + */ +type ReadOptions = { + /** + * Specifies whether the read results should be cached. + * Can be a boolean or a map to hold the cached data. + */ + cache?: boolean | Map>; +}; +/** + * Defines a PackageJson structure. + * @param package_ - The `package.json` content as an object. See {@link PackageJson}. + * @returns the same `package.json` object. + */ +declare function definePackageJSON(package_: PackageJson): PackageJson; +/** + * Defines a TSConfig structure. + * @param tsconfig - The contents of `tsconfig.json` as an object. See {@link TSConfig}. + * @returns the same `tsconfig.json` object. + */ +declare function defineTSConfig(tsconfig: TSConfig): TSConfig; +/** + * Asynchronously reads a `package.json` file. + * @param id - The path identifier for the package.json, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `package.json` object. + */ +declare function readPackageJSON(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `package.json` file. + * @param path - The path to the file where the `package.json` is written. + * @param package_ - The `package.json` object to write. See {@link PackageJson}. + */ +declare function writePackageJSON(path: string, package_: PackageJson): Promise; +/** + * Asynchronously reads a `tsconfig.json` file. + * @param id - The path to the `tsconfig.json` file, defaults to the current working directory. + * @param options - The options for resolving and reading the file. See {@link ResolveOptions}. + * @returns a promise resolving to the parsed `tsconfig.json` object. + */ +declare function readTSConfig(id?: string, options?: ResolveOptions & ReadOptions): Promise; +/** + * Asynchronously writes data to a `tsconfig.json` file. + * @param path - The path to the file where the `tsconfig.json` is written. + * @param tsconfig - The `tsconfig.json` object to write. See {@link TSConfig}. + */ +declare function writeTSConfig(path: string, tsconfig: TSConfig): Promise; +/** + * Resolves the path to the nearest `package.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `package.json` file. + */ +declare function resolvePackageJSON(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest `tsconfig.json` file from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest `tsconfig.json` file. + */ +declare function resolveTSConfig(id?: string, options?: ResolveOptions): Promise; +/** + * Resolves the path to the nearest lockfile from a given directory. + * @param id - The base path for the search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns A promise resolving to the path of the nearest lockfile. + */ +declare function resolveLockfile(id?: string, options?: ResolveOptions): Promise; +/** + * Detects the workspace directory based on common project markers (`.git`, lockfiles, `package.json`). + * Throws an error if the workspace root cannot be detected. + * @param id - The base path to search, defaults to the current working directory. + * @param options - Options to modify the search behaviour. See {@link ResolveOptions}. + * @returns a promise resolving to the path of the detected workspace directory. + */ +declare function findWorkspaceDir(id?: string, options?: ResolveOptions): Promise; + +export { type FindFileOptions, type FindNearestFileOptions, type PackageJson, type PackageJsonExports, type PackageJsonPerson, type ReadOptions, type ResolveOptions, type StripEnums, type TSConfig, definePackageJSON, defineTSConfig, findFarthestFile, findFile, findNearestFile, findWorkspaceDir, readPackageJSON, readTSConfig, resolveLockfile, resolvePackageJSON, resolveTSConfig, writePackageJSON, writeTSConfig }; diff --git a/node_modules/pkg-types/dist/index.mjs b/node_modules/pkg-types/dist/index.mjs new file mode 100644 index 0000000..a666717 --- /dev/null +++ b/node_modules/pkg-types/dist/index.mjs @@ -0,0 +1,157 @@ +import { statSync, promises } from 'node:fs'; +import { resolve, join, isAbsolute, dirname } from 'pathe'; +import { resolvePath } from 'mlly'; +import { parseJSON, parseJSONC, stringifyJSON, stringifyJSONC } from 'confbox'; + +const defaultFindOptions = { + startingFrom: ".", + rootPattern: /^node_modules$/, + reverse: false, + test: (filePath) => { + try { + if (statSync(filePath).isFile()) { + return true; + } + } catch { + } + } +}; +async function findFile(filename, _options = {}) { + const filenames = Array.isArray(filename) ? filename : [filename]; + const options = { ...defaultFindOptions, ..._options }; + const basePath = resolve(options.startingFrom); + const leadingSlash = basePath[0] === "/"; + const segments = basePath.split("/").filter(Boolean); + if (leadingSlash) { + segments[0] = "/" + segments[0]; + } + let root = segments.findIndex((r) => r.match(options.rootPattern)); + if (root === -1) { + root = 0; + } + if (options.reverse) { + for (let index = root + 1; index <= segments.length; index++) { + for (const filename2 of filenames) { + const filePath = join(...segments.slice(0, index), filename2); + if (await options.test(filePath)) { + return filePath; + } + } + } + } else { + for (let index = segments.length; index > root; index--) { + for (const filename2 of filenames) { + const filePath = join(...segments.slice(0, index), filename2); + if (await options.test(filePath)) { + return filePath; + } + } + } + } + throw new Error( + `Cannot find matching ${filename} in ${options.startingFrom} or parent directories` + ); +} +function findNearestFile(filename, _options = {}) { + return findFile(filename, _options); +} +function findFarthestFile(filename, _options = {}) { + return findFile(filename, { ..._options, reverse: true }); +} + +function definePackageJSON(package_) { + return package_; +} +function defineTSConfig(tsconfig) { + return tsconfig; +} +const FileCache = /* @__PURE__ */ new Map(); +async function readPackageJSON(id, options = {}) { + const resolvedPath = await resolvePackageJSON(id, options); + const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : FileCache; + if (options.cache && cache.has(resolvedPath)) { + return cache.get(resolvedPath); + } + const blob = await promises.readFile(resolvedPath, "utf8"); + let parsed; + try { + parsed = parseJSON(blob); + } catch { + parsed = parseJSONC(blob); + } + cache.set(resolvedPath, parsed); + return parsed; +} +async function writePackageJSON(path, package_) { + await promises.writeFile(path, stringifyJSON(package_)); +} +async function readTSConfig(id, options = {}) { + const resolvedPath = await resolveTSConfig(id, options); + const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : FileCache; + if (options.cache && cache.has(resolvedPath)) { + return cache.get(resolvedPath); + } + const text = await promises.readFile(resolvedPath, "utf8"); + const parsed = parseJSONC(text); + cache.set(resolvedPath, parsed); + return parsed; +} +async function writeTSConfig(path, tsconfig) { + await promises.writeFile(path, stringifyJSONC(tsconfig)); +} +async function resolvePackageJSON(id = process.cwd(), options = {}) { + const resolvedPath = isAbsolute(id) ? id : await resolvePath(id, options); + return findNearestFile("package.json", { + startingFrom: resolvedPath, + ...options + }); +} +async function resolveTSConfig(id = process.cwd(), options = {}) { + const resolvedPath = isAbsolute(id) ? id : await resolvePath(id, options); + return findNearestFile("tsconfig.json", { + startingFrom: resolvedPath, + ...options + }); +} +const lockFiles = [ + "yarn.lock", + "package-lock.json", + "pnpm-lock.yaml", + "npm-shrinkwrap.json", + "bun.lockb", + "bun.lock" +]; +async function resolveLockfile(id = process.cwd(), options = {}) { + const resolvedPath = isAbsolute(id) ? id : await resolvePath(id, options); + const _options = { startingFrom: resolvedPath, ...options }; + try { + return await findNearestFile(lockFiles, _options); + } catch { + } + throw new Error("No lockfile found from " + id); +} +async function findWorkspaceDir(id = process.cwd(), options = {}) { + const resolvedPath = isAbsolute(id) ? id : await resolvePath(id, options); + const _options = { startingFrom: resolvedPath, ...options }; + try { + const r = await findNearestFile(".git/config", _options); + return resolve(r, "../.."); + } catch { + } + try { + const r = await resolveLockfile(resolvedPath, { + ..._options, + reverse: true + }); + return dirname(r); + } catch { + } + try { + const r = await findFile(resolvedPath, _options); + return dirname(r); + } catch { + } + throw new Error("Cannot detect workspace root from " + id); +} + +export { definePackageJSON, defineTSConfig, findFarthestFile, findFile, findNearestFile, findWorkspaceDir, readPackageJSON, readTSConfig, resolveLockfile, resolvePackageJSON, resolveTSConfig, writePackageJSON, writeTSConfig }; diff --git a/node_modules/pkg-types/node_modules/pathe/LICENSE b/node_modules/pkg-types/node_modules/pathe/LICENSE new file mode 100644 index 0000000..8eb90c4 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/LICENSE @@ -0,0 +1,70 @@ +MIT License + +Copyright (c) Pooya Parsa - Daniel Roe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +Bundled zeptomatch (https://github.com/fabiospampinato/zeptomatch) + +The MIT License (MIT) + +Copyright (c) 2023-present Fabio Spampinato + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pkg-types/node_modules/pathe/README.md b/node_modules/pkg-types/node_modules/pathe/README.md new file mode 100644 index 0000000..8eddf93 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/README.md @@ -0,0 +1,73 @@ +# 🛣️ pathe + +> Universal filesystem path utils + +[![version][npm-v-src]][npm-v-href] +[![downloads][npm-d-src]][npm-d-href] +[![size][size-src]][size-href] + +## ❓ Why + +For [historical reasons](https://docs.microsoft.com/en-us/archive/blogs/larryosterman/why-is-the-dos-path-character), windows followed MS-DOS and used backslash for separating paths rather than slash used for macOS, Linux, and other Posix operating systems. Nowadays, [Windows](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN) supports both Slash and Backslash for paths. [Node.js's built-in `path` module](https://nodejs.org/api/path.html) in the default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used. **This makes inconsistent code behavior between Windows and POSIX.** + +Compared to popular [upath](https://github.com/anodynos/upath), pathe provides **identical exports** of Node.js with normalization on **all operations** and is written in modern **ESM/TypeScript** and has **no dependency on Node.js**! + +This package is a drop-in replacement of the Node.js's [path module](https://nodejs.org/api/path.html) module and ensures paths are normalized with slash `/` and work in environments including Node.js. + +## 💿 Usage + +Install using npm or yarn: + +```bash +# npm +npm i pathe + +# yarn +yarn add pathe + +# pnpm +pnpm i pathe +``` + +Import: + +```js +// ESM / Typescript +import { resolve, matchesGlob } from "pathe"; + +// CommonJS +const { resolve, matchesGlob } = require("pathe"); +``` + +Read more about path utils from [Node.js documentation](https://nodejs.org/api/path.html) and rest assured behavior is consistently like POSIX regardless of your input paths format and running platform (the only exception is `delimiter` constant export, it will be set to `;` on windows platform). + +### Extra utilities + +Pathe exports some extra utilities that do not exist in standard Node.js [path module](https://nodejs.org/api/path.html). +In order to use them, you can import from `pathe/utils` subpath: + +```js +import { + filename, + normalizeAliases, + resolveAlias, + reverseResolveAlias, +} from "pathe/utils"; +``` + +## License + +Made with 💛 Published under the [MIT](./LICENSE) license. + +Some code was used from the Node.js project. Glob supported is powered by [zeptomatch](https://github.com/fabiospampinato/zeptomatch). + + + +[npm-v-src]: https://img.shields.io/npm/v/pathe?style=flat-square +[npm-v-href]: https://npmjs.com/package/pathe +[npm-d-src]: https://img.shields.io/npm/dm/pathe?style=flat-square +[npm-d-href]: https://npmjs.com/package/pathe +[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/pathe/ci/main?style=flat-square +[github-actions-href]: https://github.com/unjs/pathe/actions?query=workflow%3Aci +[size-src]: https://packagephobia.now.sh/badge?p=pathe +[size-href]: https://packagephobia.now.sh/result?p=pathe diff --git a/node_modules/pkg-types/node_modules/pathe/dist/index.cjs b/node_modules/pkg-types/node_modules/pathe/dist/index.cjs new file mode 100644 index 0000000..d64a6d2 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/index.cjs @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path._path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path._path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +exports.basename = _path.basename; +exports.dirname = _path.dirname; +exports.extname = _path.extname; +exports.format = _path.format; +exports.isAbsolute = _path.isAbsolute; +exports.join = _path.join; +exports.matchesGlob = _path.matchesGlob; +exports.normalize = _path.normalize; +exports.normalizeString = _path.normalizeString; +exports.parse = _path.parse; +exports.relative = _path.relative; +exports.resolve = _path.resolve; +exports.sep = _path.sep; +exports.toNamespacedPath = _path.toNamespacedPath; +exports.default = posix; +exports.delimiter = delimiter; +exports.posix = posix; +exports.win32 = win32; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/index.d.cts b/node_modules/pkg-types/node_modules/pathe/dist/index.d.cts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/index.d.cts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/index.d.mts b/node_modules/pkg-types/node_modules/pathe/dist/index.d.mts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/index.d.mts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/index.d.ts b/node_modules/pkg-types/node_modules/pathe/dist/index.d.ts new file mode 100644 index 0000000..61046da --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/index.d.ts @@ -0,0 +1,47 @@ +import * as path from 'node:path'; +import path__default from 'node:path'; + +/** + * Constant for path separator. + * + * Always equals to `"/"`. + */ +declare const sep = "/"; +declare const normalize: typeof path__default.normalize; +declare const join: typeof path__default.join; +declare const resolve: typeof path__default.resolve; +/** + * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root. + * + * @param path - The path to normalise. + * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory. + * @returns the normalised path string. + */ +declare function normalizeString(path: string, allowAboveRoot: boolean): string; +declare const isAbsolute: typeof path__default.isAbsolute; +declare const toNamespacedPath: typeof path__default.toNamespacedPath; +declare const extname: typeof path__default.extname; +declare const relative: typeof path__default.relative; +declare const dirname: typeof path__default.dirname; +declare const format: typeof path__default.format; +declare const basename: typeof path__default.basename; +declare const parse: typeof path__default.parse; +/** + * The `path.matchesGlob()` method determines if `path` matches the `pattern`. + * @param path The path to glob-match against. + * @param pattern The glob to check the path against. + */ +declare const matchesGlob: (path: string, pattern: string | string[]) => boolean; + +type NodePath = typeof path; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +declare const delimiter: ";" | ":"; +declare const posix: NodePath["posix"]; +declare const win32: NodePath["win32"]; +declare const _default: NodePath; + +export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/index.mjs b/node_modules/pkg-types/node_modules/pathe/dist/index.mjs new file mode 100644 index 0000000..0582c1f --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/index.mjs @@ -0,0 +1,19 @@ +import { _ as _path } from './shared/pathe.M-eThtNZ.mjs'; +export { c as basename, d as dirname, e as extname, f as format, i as isAbsolute, j as join, m as matchesGlob, n as normalize, a as normalizeString, p as parse, b as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.M-eThtNZ.mjs'; + +const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")(); +const _platforms = { posix: void 0, win32: void 0 }; +const mix = (del = delimiter) => { + return new Proxy(_path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path[prop]; + } + }); +}; +const posix = /* @__PURE__ */ mix(":"); +const win32 = /* @__PURE__ */ mix(";"); + +export { posix as default, delimiter, posix, win32 }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs b/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs new file mode 100644 index 0000000..f4a62e3 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.BSlhyZSM.cjs @@ -0,0 +1,266 @@ +'use strict'; + +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +exports._path = _path; +exports.basename = basename; +exports.dirname = dirname; +exports.extname = extname; +exports.format = format; +exports.isAbsolute = isAbsolute; +exports.join = join; +exports.matchesGlob = matchesGlob; +exports.normalize = normalize; +exports.normalizeString = normalizeString; +exports.normalizeWindowsPath = normalizeWindowsPath; +exports.parse = parse; +exports.relative = relative; +exports.resolve = resolve; +exports.sep = sep; +exports.toNamespacedPath = toNamespacedPath; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs b/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs new file mode 100644 index 0000000..81d714d --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs @@ -0,0 +1,249 @@ +let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.indext){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n{if(eS(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})(); + return __lib__.default || __lib__; }; +let _match; +const zeptomatch = (path, pattern) => { + if (!_match) { + _match = _lazyMatch(); + _lazyMatch = null; + } + return _match(path, pattern); +}; + +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; +const _EXTNAME_RE = /.(\.[^./]+|\.)$/; +const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; +const sep = "/"; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +const join = function(...segments) { + let path = ""; + for (const seg of segments) { + if (!seg) { + continue; + } + if (path.length > 0) { + const pathTrailing = path[path.length - 1] === "/"; + const segLeading = seg[0] === "/"; + const both = pathTrailing && segLeading; + if (both) { + path += seg.slice(1); + } else { + path += pathTrailing || segLeading ? seg : `/${seg}`; + } + } else { + path += seg; + } + } + return normalize(path); +}; +function cwd() { + if (typeof process !== "undefined" && typeof process.cwd === "function") { + return process.cwd().replace(/\\/g, "/"); + } + return "/"; +} +const resolve = function(...arguments_) { + arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); + let resolvedPath = ""; + let resolvedAbsolute = false; + for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { + const path = index >= 0 ? arguments_[index] : cwd(); + if (!path || path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = isAbsolute(path); + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); + if (resolvedAbsolute && !isAbsolute(resolvedPath)) { + return `/${resolvedPath}`; + } + return resolvedPath.length > 0 ? resolvedPath : "."; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; +const toNamespacedPath = function(p) { + return normalizeWindowsPath(p); +}; +const extname = function(p) { + if (p === "..") return ""; + const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); + return match && match[1] || ""; +}; +const relative = function(from, to) { + const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); + const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); + if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { + return _to.join("/"); + } + const _fromCopy = [..._from]; + for (const segment of _fromCopy) { + if (_to[0] !== segment) { + break; + } + _from.shift(); + _to.shift(); + } + return [..._from.map(() => ".."), ..._to].join("/"); +}; +const dirname = function(p) { + const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); + if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { + segments[0] += "/"; + } + return segments.join("/") || (isAbsolute(p) ? "/" : "."); +}; +const format = function(p) { + const ext = p.ext ? p.ext.startsWith(".") ? p.ext : `.${p.ext}` : ""; + const segments = [p.root, p.dir, p.base ?? (p.name ?? "") + ext].filter( + Boolean + ); + return normalizeWindowsPath( + p.root ? resolve(...segments) : segments.join("/") + ); +}; +const basename = function(p, extension) { + const segments = normalizeWindowsPath(p).split("/"); + let lastSegment = ""; + for (let i = segments.length - 1; i >= 0; i--) { + const val = segments[i]; + if (val) { + lastSegment = val; + break; + } + } + return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; +}; +const parse = function(p) { + const root = _PATH_ROOT_RE.exec(p)?.[0]?.replace(/\\/g, "/") || ""; + const base = basename(p); + const extension = extname(base); + return { + root, + dir: dirname(p), + base, + ext: extension, + name: base.slice(0, base.length - extension.length) + }; +}; +const matchesGlob = (path, pattern) => { + return zeptomatch(pattern, normalize(path)); +}; + +const _path = { + __proto__: null, + basename: basename, + dirname: dirname, + extname: extname, + format: format, + isAbsolute: isAbsolute, + join: join, + matchesGlob: matchesGlob, + normalize: normalize, + normalizeString: normalizeString, + parse: parse, + relative: relative, + resolve: resolve, + sep: sep, + toNamespacedPath: toNamespacedPath +}; + +export { _path as _, normalizeString as a, relative as b, basename as c, dirname as d, extname as e, format as f, normalizeWindowsPath as g, isAbsolute as i, join as j, matchesGlob as m, normalize as n, parse as p, resolve as r, sep as s, toNamespacedPath as t }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/utils.cjs b/node_modules/pkg-types/node_modules/pathe/dist/utils.cjs new file mode 100644 index 0000000..03c7ff3 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/utils.cjs @@ -0,0 +1,82 @@ +'use strict'; + +const _path = require('./shared/pathe.BSlhyZSM.cjs'); + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + return _path.join(to, _path$1.slice(alias.length)); + } + } + return _path$1; +} +function reverseResolveAlias(path, aliases) { + const _path$1 = _path.normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path$1.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path$1[_alias.length])) { + matches.push(_path.join(to, _path$1.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +exports.filename = filename; +exports.normalizeAliases = normalizeAliases; +exports.resolveAlias = resolveAlias; +exports.reverseResolveAlias = reverseResolveAlias; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/utils.d.cts b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.cts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.cts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/utils.d.mts b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.mts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.mts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/utils.d.ts b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.ts new file mode 100644 index 0000000..af369d0 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/utils.d.ts @@ -0,0 +1,32 @@ +/** + * Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones. + * This function also ensures that aliases do not resolve to themselves cyclically. + * + * @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to. + * @returns a set of normalised alias mappings. + */ +declare function normalizeAliases(_aliases: Record): Record; +/** + * Resolves a path string to its alias if applicable, otherwise returns the original path. + * This function normalises the path, resolves the alias and then joins it to the alias target if necessary. + * + * @param path - The path string to resolve. + * @param aliases - A set of alias mappings to use for resolution. + * @returns the resolved path as a string. + */ +declare function resolveAlias(path: string, aliases: Record): string; +/** + * Resolves a path string to its possible alias. + * + * Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first). + */ +declare function reverseResolveAlias(path: string, aliases: Record): string[]; +/** + * Extracts the filename from a given path, excluding any directory paths and the file extension. + * + * @param path - The full path of the file from which to extract the filename. + * @returns the filename without the extension, or `undefined` if the filename cannot be extracted. + */ +declare function filename(path: string): string | undefined; + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pkg-types/node_modules/pathe/dist/utils.mjs b/node_modules/pkg-types/node_modules/pathe/dist/utils.mjs new file mode 100644 index 0000000..748072e --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/dist/utils.mjs @@ -0,0 +1,77 @@ +import { g as normalizeWindowsPath, j as join } from './shared/pathe.M-eThtNZ.mjs'; + +const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]); +const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias"); +const SLASH_RE = /[/\\]/; +function normalizeAliases(_aliases) { + if (_aliases[normalizedAliasSymbol]) { + return _aliases; + } + const aliases = Object.fromEntries( + Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)) + ); + for (const key in aliases) { + for (const alias in aliases) { + if (alias === key || key.startsWith(alias)) { + continue; + } + if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) { + aliases[key] = aliases[alias] + aliases[key].slice(alias.length); + } + } + } + Object.defineProperty(aliases, normalizedAliasSymbol, { + value: true, + enumerable: false + }); + return aliases; +} +function resolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + for (const [alias, to] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + return join(to, _path.slice(alias.length)); + } + } + return _path; +} +function reverseResolveAlias(path, aliases) { + const _path = normalizeWindowsPath(path); + aliases = normalizeAliases(aliases); + const matches = []; + for (const [to, alias] of Object.entries(aliases)) { + if (!_path.startsWith(alias)) { + continue; + } + const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias; + if (hasTrailingSlash(_path[_alias.length])) { + matches.push(join(to, _path.slice(alias.length))); + } + } + return matches.sort((a, b) => b.length - a.length); +} +function filename(path) { + const base = path.split(SLASH_RE).pop(); + if (!base) { + return void 0; + } + const separatorIndex = base.lastIndexOf("."); + if (separatorIndex <= 0) { + return base; + } + return base.slice(0, separatorIndex); +} +function _compareAliases(a, b) { + return b.split("/").length - a.split("/").length; +} +function hasTrailingSlash(path = "/") { + const lastChar = path[path.length - 1]; + return lastChar === "/" || lastChar === "\\"; +} + +export { filename, normalizeAliases, resolveAlias, reverseResolveAlias }; diff --git a/node_modules/pkg-types/node_modules/pathe/package.json b/node_modules/pkg-types/node_modules/pathe/package.json new file mode 100644 index 0000000..5522b28 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/package.json @@ -0,0 +1,61 @@ +{ + "name": "pathe", + "version": "2.0.3", + "description": "Universal filesystem path utils", + "repository": "unjs/pathe", + "license": "MIT", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./utils": { + "import": { + "types": "./dist/utils.d.mts", + "default": "./dist/utils.mjs" + }, + "require": { + "types": "./dist/utils.d.cts", + "default": "./dist/utils.cjs" + } + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "utils.d.ts" + ], + "devDependencies": { + "@types/node": "^22.13.1", + "@vitest/coverage-v8": "^3.0.5", + "changelogen": "^0.5.7", + "esbuild": "^0.25.0", + "eslint": "^9.20.1", + "eslint-config-unjs": "^0.4.2", + "jiti": "^2.4.2", + "prettier": "^3.5.0", + "typescript": "^5.7.3", + "unbuild": "^3.3.1", + "vitest": "^3.0.5", + "zeptomatch": "^2.0.0" + }, + "scripts": { + "build": "unbuild", + "dev": "vitest", + "lint": "eslint . && prettier -c src test", + "lint:fix": "eslint . --fix && prettier -w src test", + "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags", + "test": "pnpm lint && vitest run --coverage", + "test:types": "tsc --noEmit" + } +} \ No newline at end of file diff --git a/node_modules/pkg-types/node_modules/pathe/utils.d.ts b/node_modules/pkg-types/node_modules/pathe/utils.d.ts new file mode 100644 index 0000000..59cabd3 --- /dev/null +++ b/node_modules/pkg-types/node_modules/pathe/utils.d.ts @@ -0,0 +1 @@ +export * from "./dist/utils"; diff --git a/node_modules/pkg-types/package.json b/node_modules/pkg-types/package.json new file mode 100644 index 0000000..147829a --- /dev/null +++ b/node_modules/pkg-types/package.json @@ -0,0 +1,47 @@ +{ + "name": "pkg-types", + "version": "1.3.1", + "description": "Node.js utilities and TypeScript definitions for `package.json` and `tsconfig.json`", + "license": "MIT", + "main": "./dist/index.cjs", + "sideEffects": false, + "exports": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "types": "./dist/index.d.ts", + "repository": "unjs/pkg-types", + "files": [ + "dist" + ], + "scripts": { + "build": "unbuild", + "prepack": "pnpm build", + "dev": "vitest --typecheck", + "release": "pnpm test && changelogen --release && npm publish && git push --follow-tags", + "lint": "eslint && prettier -c src test", + "lint:fix": "automd && eslint --fix . && prettier -w src test", + "test": "vitest run --typecheck --coverage" + }, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + }, + "devDependencies": { + "@types/node": "^22.10.6", + "@vitest/coverage-v8": "^2.1.8", + "automd": "^0.3.12", + "changelogen": "^0.5.7", + "eslint": "^9.18.0", + "eslint-config-unjs": "^0.4.2", + "expect-type": "^1.1.0", + "jiti": "^2.4.2", + "prettier": "^3.4.2", + "typescript": "^5.7.3", + "unbuild": "^3.3.1", + "vitest": "^2.1.8" + }, + "packageManager": "pnpm@9.15.4" +} diff --git a/node_modules/postcss/LICENSE b/node_modules/postcss/LICENSE new file mode 100644 index 0000000..c2314d5 --- /dev/null +++ b/node_modules/postcss/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2013 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/postcss/README.md b/node_modules/postcss/README.md new file mode 100644 index 0000000..b74ceee --- /dev/null +++ b/node_modules/postcss/README.md @@ -0,0 +1,28 @@ +# PostCSS + +Philosopher’s stone, logo of PostCSS + +PostCSS is a tool for transforming styles with JS plugins. +These plugins can lint your CSS, support variables and mixins, +transpile future CSS syntax, inline images, and more. + +PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba, +and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins are some of the most popular CSS tools. + +--- + +  Built by +Evil Martians, go-to agency for developer tools. + +--- + +[Abstract Syntax Tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree +[Evil Martians]: https://evilmartians.com/?utm_source=postcss +[Autoprefixer]: https://github.com/postcss/autoprefixer +[Stylelint]: https://stylelint.io/ +[plugins]: https://github.com/postcss/postcss#plugins + +## Docs +Read full docs **[here](https://postcss.org/)**. diff --git a/node_modules/postcss/lib/at-rule.d.ts b/node_modules/postcss/lib/at-rule.d.ts new file mode 100644 index 0000000..703e399 --- /dev/null +++ b/node_modules/postcss/lib/at-rule.d.ts @@ -0,0 +1,139 @@ +import Container, { + ContainerProps, + ContainerWithChildren +} from './container.js' + +declare namespace AtRule { + export interface AtRuleRaws extends Record { + /** + * The space symbols after the last child of the node to the end of the node. + */ + after?: string + + /** + * The space between the at-rule name and its parameters. + */ + afterName?: string + + /** + * The space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + */ + before?: string + + /** + * The symbols between the last parameter and `{` for rules. + */ + between?: string + + /** + * The rule’s selector with comments. + */ + params?: { + raw: string + value: string + } + + /** + * Contains `true` if the last child has an (optional) semicolon. + */ + semicolon?: boolean + } + + export interface AtRuleProps extends ContainerProps { + /** Name of the at-rule. */ + name: string + /** Parameters following the name of the at-rule. */ + params?: number | string + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: AtRuleRaws + } + + export { AtRule_ as default } +} + +/** + * Represents an at-rule. + * + * ```js + * Once (root, { AtRule }) { + * let media = new AtRule({ name: 'media', params: 'print' }) + * media.append(…) + * root.append(media) + * } + * ``` + * + * If it’s followed in the CSS by a `{}` block, this node will have + * a nodes property representing its children. + * + * ```js + * const root = postcss.parse('@charset "UTF-8"; @media print {}') + * + * const charset = root.first + * charset.type //=> 'atrule' + * charset.nodes //=> undefined + * + * const media = root.last + * media.nodes //=> [] + * ``` + */ +declare class AtRule_ extends Container { + /** + * An array containing the layer’s children. + * + * ```js + * const root = postcss.parse('@layer example { a { color: black } }') + * const layer = root.first + * layer.nodes.length //=> 1 + * layer.nodes[0].selector //=> 'a' + * ``` + * + * Can be `undefinded` if the at-rule has no body. + * + * ```js + * const root = postcss.parse('@layer a, b, c;') + * const layer = root.first + * layer.nodes //=> undefined + * ``` + */ + nodes: Container['nodes'] | undefined + parent: ContainerWithChildren | undefined + + raws: AtRule.AtRuleRaws + type: 'atrule' + /** + * The at-rule’s name immediately follows the `@`. + * + * ```js + * const root = postcss.parse('@media print {}') + * const media = root.first + * media.name //=> 'media' + * ``` + */ + get name(): string + set name(value: string) + + /** + * The at-rule’s parameters, the values that follow the at-rule’s name + * but precede any `{}` block. + * + * ```js + * const root = postcss.parse('@media print, screen {}') + * const media = root.first + * media.params //=> 'print, screen' + * ``` + */ + get params(): string + + set params(value: string) + + constructor(defaults?: AtRule.AtRuleProps) + assign(overrides: AtRule.AtRuleProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class AtRule extends AtRule_ {} + +export = AtRule diff --git a/node_modules/postcss/lib/at-rule.js b/node_modules/postcss/lib/at-rule.js new file mode 100644 index 0000000..9486447 --- /dev/null +++ b/node_modules/postcss/lib/at-rule.js @@ -0,0 +1,25 @@ +'use strict' + +let Container = require('./container') + +class AtRule extends Container { + constructor(defaults) { + super(defaults) + this.type = 'atrule' + } + + append(...children) { + if (!this.proxyOf.nodes) this.nodes = [] + return super.append(...children) + } + + prepend(...children) { + if (!this.proxyOf.nodes) this.nodes = [] + return super.prepend(...children) + } +} + +module.exports = AtRule +AtRule.default = AtRule + +Container.registerAtRule(AtRule) diff --git a/node_modules/postcss/lib/comment.d.ts b/node_modules/postcss/lib/comment.d.ts new file mode 100644 index 0000000..f764109 --- /dev/null +++ b/node_modules/postcss/lib/comment.d.ts @@ -0,0 +1,67 @@ +import Container from './container.js' +import Node, { NodeProps } from './node.js' + +declare namespace Comment { + export interface CommentRaws extends Record { + /** + * The space symbols before the node. + */ + before?: string + + /** + * The space symbols between `/*` and the comment’s text. + */ + left?: string + + /** + * The space symbols between the comment’s text. + */ + right?: string + } + + export interface CommentProps extends NodeProps { + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: CommentRaws + /** Content of the comment. */ + text: string + } + + export { Comment_ as default } +} + +/** + * It represents a class that handles + * [CSS comments](https://developer.mozilla.org/en-US/docs/Web/CSS/Comments) + * + * ```js + * Once (root, { Comment }) { + * const note = new Comment({ text: 'Note: …' }) + * root.append(note) + * } + * ``` + * + * Remember that CSS comments inside selectors, at-rule parameters, + * or declaration values will be stored in the `raws` properties + * explained above. + */ +declare class Comment_ extends Node { + parent: Container | undefined + raws: Comment.CommentRaws + type: 'comment' + /** + * The comment's text. + */ + get text(): string + + set text(value: string) + + constructor(defaults?: Comment.CommentProps) + assign(overrides: Comment.CommentProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class Comment extends Comment_ {} + +export = Comment diff --git a/node_modules/postcss/lib/comment.js b/node_modules/postcss/lib/comment.js new file mode 100644 index 0000000..c566506 --- /dev/null +++ b/node_modules/postcss/lib/comment.js @@ -0,0 +1,13 @@ +'use strict' + +let Node = require('./node') + +class Comment extends Node { + constructor(defaults) { + super(defaults) + this.type = 'comment' + } +} + +module.exports = Comment +Comment.default = Comment diff --git a/node_modules/postcss/lib/container.d.ts b/node_modules/postcss/lib/container.d.ts new file mode 100644 index 0000000..82b24d0 --- /dev/null +++ b/node_modules/postcss/lib/container.d.ts @@ -0,0 +1,478 @@ +import AtRule from './at-rule.js' +import Comment from './comment.js' +import Declaration from './declaration.js' +import Node, { ChildNode, ChildProps, NodeProps } from './node.js' +import { Root } from './postcss.js' +import Rule from './rule.js' + +declare namespace Container { + export type ContainerWithChildren = { + nodes: Child[] + } & (AtRule | Root | Rule) + + export interface ValueOptions { + /** + * String that’s used to narrow down values and speed up the regexp search. + */ + fast?: string + + /** + * An array of property names. + */ + props?: readonly string[] + } + + export interface ContainerProps extends NodeProps { + nodes?: readonly (ChildProps | Node)[] + } + + /** + * All types that can be passed into container methods to create or add a new + * child node. + */ + export type NewChild = + | ChildProps + | Node + | readonly ChildProps[] + | readonly Node[] + | readonly string[] + | string + | undefined + + export { Container_ as default } +} + +/** + * The `Root`, `AtRule`, and `Rule` container nodes + * inherit some common methods to help work with their children. + * + * Note that all containers can store any content. If you write a rule inside + * a rule, PostCSS will parse it. + */ +declare abstract class Container_ extends Node { + /** + * An array containing the container’s children. + * + * ```js + * const root = postcss.parse('a { color: black }') + * root.nodes.length //=> 1 + * root.nodes[0].selector //=> 'a' + * root.nodes[0].nodes[0].prop //=> 'color' + * ``` + */ + nodes: Child[] | undefined + + /** + * The container’s first child. + * + * ```js + * rule.first === rules.nodes[0] + * ``` + */ + get first(): Child | undefined + + /** + * The container’s last child. + * + * ```js + * rule.last === rule.nodes[rule.nodes.length - 1] + * ``` + */ + get last(): Child | undefined + /** + * Inserts new nodes to the end of the container. + * + * ```js + * const decl1 = new Declaration({ prop: 'color', value: 'black' }) + * const decl2 = new Declaration({ prop: 'background-color', value: 'white' }) + * rule.append(decl1, decl2) + * + * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule + * root.append({ selector: 'a' }) // rule + * rule.append({ prop: 'color', value: 'black' }) // declaration + * rule.append({ text: 'Comment' }) // comment + * + * root.append('a {}') + * root.first.append('color: black; z-index: 1') + * ``` + * + * @param nodes New nodes. + * @return This node for methods chain. + */ + append(...nodes: Container.NewChild[]): this + assign(overrides: Container.ContainerProps | object): this + clone(overrides?: Partial): this + + cloneAfter(overrides?: Partial): this + + cloneBefore(overrides?: Partial): this + /** + * Iterates through the container’s immediate children, + * calling `callback` for each child. + * + * Returning `false` in the callback will break iteration. + * + * This method only iterates through the container’s immediate children. + * If you need to recursively iterate through all the container’s descendant + * nodes, use `Container#walk`. + * + * Unlike the for `{}`-cycle or `Array#forEach` this iterator is safe + * if you are mutating the array of child nodes during iteration. + * PostCSS will adjust the current index to match the mutations. + * + * ```js + * const root = postcss.parse('a { color: black; z-index: 1 }') + * const rule = root.first + * + * for (const decl of rule.nodes) { + * decl.cloneBefore({ prop: '-webkit-' + decl.prop }) + * // Cycle will be infinite, because cloneBefore moves the current node + * // to the next index + * } + * + * rule.each(decl => { + * decl.cloneBefore({ prop: '-webkit-' + decl.prop }) + * // Will be executed only for color and z-index + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + each( + callback: (node: Child, index: number) => false | void + ): false | undefined + + /** + * Returns `true` if callback returns `true` + * for all of the container’s children. + * + * ```js + * const noPrefixes = rule.every(i => i.prop[0] !== '-') + * ``` + * + * @param condition Iterator returns true or false. + * @return Is every child pass condition. + */ + every( + condition: (node: Child, index: number, nodes: Child[]) => boolean + ): boolean + /** + * Returns a `child`’s index within the `Container#nodes` array. + * + * ```js + * rule.index( rule.nodes[2] ) //=> 2 + * ``` + * + * @param child Child of the current container. + * @return Child index. + */ + index(child: Child | number): number + + /** + * Insert new node after old node within the container. + * + * @param oldNode Child or child’s index. + * @param newNode New node. + * @return This node for methods chain. + */ + insertAfter(oldNode: Child | number, newNode: Container.NewChild): this + + /** + * Traverses the container’s descendant nodes, calling callback + * for each comment node. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * root.walkComments(comment => { + * comment.remove() + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + + /** + * Insert new node before old node within the container. + * + * ```js + * rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop })) + * ``` + * + * @param oldNode Child or child’s index. + * @param newNode New node. + * @return This node for methods chain. + */ + insertBefore(oldNode: Child | number, newNode: Container.NewChild): this + /** + * Inserts new nodes to the start of the container. + * + * ```js + * const decl1 = new Declaration({ prop: 'color', value: 'black' }) + * const decl2 = new Declaration({ prop: 'background-color', value: 'white' }) + * rule.prepend(decl1, decl2) + * + * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule + * root.append({ selector: 'a' }) // rule + * rule.append({ prop: 'color', value: 'black' }) // declaration + * rule.append({ text: 'Comment' }) // comment + * + * root.append('a {}') + * root.first.append('color: black; z-index: 1') + * ``` + * + * @param nodes New nodes. + * @return This node for methods chain. + */ + prepend(...nodes: Container.NewChild[]): this + + /** + * Add child to the end of the node. + * + * ```js + * rule.push(new Declaration({ prop: 'color', value: 'black' })) + * ``` + * + * @param child New node. + * @return This node for methods chain. + */ + push(child: Child): this + + /** + * Removes all children from the container + * and cleans their parent properties. + * + * ```js + * rule.removeAll() + * rule.nodes.length //=> 0 + * ``` + * + * @return This node for methods chain. + */ + removeAll(): this + + /** + * Removes node from the container and cleans the parent properties + * from the node and its children. + * + * ```js + * rule.nodes.length //=> 5 + * rule.removeChild(decl) + * rule.nodes.length //=> 4 + * decl.parent //=> undefined + * ``` + * + * @param child Child or child’s index. + * @return This node for methods chain. + */ + removeChild(child: Child | number): this + + replaceValues( + pattern: RegExp | string, + replaced: { (substring: string, ...args: any[]): string } | string + ): this + /** + * Passes all declaration values within the container that match pattern + * through callback, replacing those values with the returned result + * of callback. + * + * This method is useful if you are using a custom unit or function + * and need to iterate through all values. + * + * ```js + * root.replaceValues(/\d+rem/, { fast: 'rem' }, string => { + * return 15 * parseInt(string) + 'px' + * }) + * ``` + * + * @param pattern Replace pattern. + * @param {object} options Options to speed up the search. + * @param replaced String to replace pattern or callback + * that returns a new value. The callback + * will receive the same arguments + * as those passed to a function parameter + * of `String#replace`. + * @return This node for methods chain. + */ + replaceValues( + pattern: RegExp | string, + options: Container.ValueOptions, + replaced: { (substring: string, ...args: any[]): string } | string + ): this + + /** + * Returns `true` if callback returns `true` for (at least) one + * of the container’s children. + * + * ```js + * const hasPrefix = rule.some(i => i.prop[0] === '-') + * ``` + * + * @param condition Iterator returns true or false. + * @return Is some child pass condition. + */ + some( + condition: (node: Child, index: number, nodes: Child[]) => boolean + ): boolean + + /** + * Traverses the container’s descendant nodes, calling callback + * for each node. + * + * Like container.each(), this method is safe to use + * if you are mutating arrays during iteration. + * + * If you only need to iterate through the container’s immediate children, + * use `Container#each`. + * + * ```js + * root.walk(node => { + * // Traverses all descendant nodes. + * }) + * ``` + * + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walk( + callback: (node: ChildNode, index: number) => false | void + ): false | undefined + + /** + * Traverses the container’s descendant nodes, calling callback + * for each at-rule node. + * + * If you pass a filter, iteration will only happen over at-rules + * that have matching names. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * root.walkAtRules(rule => { + * if (isOld(rule.name)) rule.remove() + * }) + * + * let first = false + * root.walkAtRules('charset', rule => { + * if (!first) { + * first = true + * } else { + * rule.remove() + * } + * }) + * ``` + * + * @param name String or regular expression to filter at-rules by name. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkAtRules( + nameFilter: RegExp | string, + callback: (atRule: AtRule, index: number) => false | void + ): false | undefined + walkAtRules( + callback: (atRule: AtRule, index: number) => false | void + ): false | undefined + + walkComments( + callback: (comment: Comment, indexed: number) => false | void + ): false | undefined + walkComments( + callback: (comment: Comment, indexed: number) => false | void + ): false | undefined + + /** + * Traverses the container’s descendant nodes, calling callback + * for each declaration node. + * + * If you pass a filter, iteration will only happen over declarations + * with matching properties. + * + * ```js + * root.walkDecls(decl => { + * checkPropertySupport(decl.prop) + * }) + * + * root.walkDecls('border-radius', decl => { + * decl.remove() + * }) + * + * root.walkDecls(/^background/, decl => { + * decl.value = takeFirstColorFromGradient(decl.value) + * }) + * ``` + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * @param prop String or regular expression to filter declarations + * by property name. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkDecls( + propFilter: RegExp | string, + callback: (decl: Declaration, index: number) => false | void + ): false | undefined + walkDecls( + callback: (decl: Declaration, index: number) => false | void + ): false | undefined + /** + * Traverses the container’s descendant nodes, calling callback + * for each rule node. + * + * If you pass a filter, iteration will only happen over rules + * with matching selectors. + * + * Like `Container#each`, this method is safe + * to use if you are mutating arrays during iteration. + * + * ```js + * const selectors = [] + * root.walkRules(rule => { + * selectors.push(rule.selector) + * }) + * console.log(`Your CSS uses ${ selectors.length } selectors`) + * ``` + * + * @param selector String or regular expression to filter rules by selector. + * @param callback Iterator receives each node and index. + * @return Returns `false` if iteration was broke. + */ + walkRules( + selectorFilter: RegExp | string, + callback: (rule: Rule, index: number) => false | void + ): false | undefined + walkRules( + callback: (rule: Rule, index: number) => false | void + ): false | undefined + /** + * An internal method that converts a {@link NewChild} into a list of actual + * child nodes that can then be added to this container. + * + * This ensures that the nodes' parent is set to this container, that they use + * the correct prototype chain, and that they're marked as dirty. + * + * @param mnodes The new node or nodes to add. + * @param sample A node from whose raws the new node's `before` raw should be + * taken. + * @param type This should be set to `'prepend'` if the new nodes will be + * inserted at the beginning of the container. + * @hidden + */ + protected normalize( + nodes: Container.NewChild, + sample: Node | undefined, + type?: 'prepend' | false + ): Child[] +} + +declare class Container< + Child extends Node = ChildNode +> extends Container_ {} + +export = Container diff --git a/node_modules/postcss/lib/container.js b/node_modules/postcss/lib/container.js new file mode 100644 index 0000000..edb07cc --- /dev/null +++ b/node_modules/postcss/lib/container.js @@ -0,0 +1,447 @@ +'use strict' + +let Comment = require('./comment') +let Declaration = require('./declaration') +let Node = require('./node') +let { isClean, my } = require('./symbols') + +let AtRule, parse, Root, Rule + +function cleanSource(nodes) { + return nodes.map(i => { + if (i.nodes) i.nodes = cleanSource(i.nodes) + delete i.source + return i + }) +} + +function markTreeDirty(node) { + node[isClean] = false + if (node.proxyOf.nodes) { + for (let i of node.proxyOf.nodes) { + markTreeDirty(i) + } + } +} + +class Container extends Node { + get first() { + if (!this.proxyOf.nodes) return undefined + return this.proxyOf.nodes[0] + } + + get last() { + if (!this.proxyOf.nodes) return undefined + return this.proxyOf.nodes[this.proxyOf.nodes.length - 1] + } + + append(...children) { + for (let child of children) { + let nodes = this.normalize(child, this.last) + for (let node of nodes) this.proxyOf.nodes.push(node) + } + + this.markDirty() + + return this + } + + cleanRaws(keepBetween) { + super.cleanRaws(keepBetween) + if (this.nodes) { + for (let node of this.nodes) node.cleanRaws(keepBetween) + } + } + + each(callback) { + if (!this.proxyOf.nodes) return undefined + let iterator = this.getIterator() + + let index, result + while (this.indexes[iterator] < this.proxyOf.nodes.length) { + index = this.indexes[iterator] + result = callback(this.proxyOf.nodes[index], index) + if (result === false) break + + this.indexes[iterator] += 1 + } + + delete this.indexes[iterator] + return result + } + + every(condition) { + return this.nodes.every(condition) + } + + getIterator() { + if (!this.lastEach) this.lastEach = 0 + if (!this.indexes) this.indexes = {} + + this.lastEach += 1 + let iterator = this.lastEach + this.indexes[iterator] = 0 + + return iterator + } + + getProxyProcessor() { + return { + get(node, prop) { + if (prop === 'proxyOf') { + return node + } else if (!node[prop]) { + return node[prop] + } else if ( + prop === 'each' || + (typeof prop === 'string' && prop.startsWith('walk')) + ) { + return (...args) => { + return node[prop]( + ...args.map(i => { + if (typeof i === 'function') { + return (child, index) => i(child.toProxy(), index) + } else { + return i + } + }) + ) + } + } else if (prop === 'every' || prop === 'some') { + return cb => { + return node[prop]((child, ...other) => + cb(child.toProxy(), ...other) + ) + } + } else if (prop === 'root') { + return () => node.root().toProxy() + } else if (prop === 'nodes') { + return node.nodes.map(i => i.toProxy()) + } else if (prop === 'first' || prop === 'last') { + return node[prop].toProxy() + } else { + return node[prop] + } + }, + + set(node, prop, value) { + if (node[prop] === value) return true + node[prop] = value + if (prop === 'name' || prop === 'params' || prop === 'selector') { + node.markDirty() + } + return true + } + } + } + + index(child) { + if (typeof child === 'number') return child + if (child.proxyOf) child = child.proxyOf + return this.proxyOf.nodes.indexOf(child) + } + + insertAfter(exist, add) { + let existIndex = this.index(exist) + let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse() + existIndex = this.index(exist) + for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (existIndex < index) { + this.indexes[id] = index + nodes.length + } + } + + this.markDirty() + + return this + } + + insertBefore(exist, add) { + let existIndex = this.index(exist) + let type = existIndex === 0 ? 'prepend' : false + let nodes = this.normalize( + add, + this.proxyOf.nodes[existIndex], + type + ).reverse() + existIndex = this.index(exist) + for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (existIndex <= index) { + this.indexes[id] = index + nodes.length + } + } + + this.markDirty() + + return this + } + + normalize(nodes, sample) { + if (typeof nodes === 'string') { + nodes = cleanSource(parse(nodes).nodes) + } else if (typeof nodes === 'undefined') { + nodes = [] + } else if (Array.isArray(nodes)) { + nodes = nodes.slice(0) + for (let i of nodes) { + if (i.parent) i.parent.removeChild(i, 'ignore') + } + } else if (nodes.type === 'root' && this.type !== 'document') { + nodes = nodes.nodes.slice(0) + for (let i of nodes) { + if (i.parent) i.parent.removeChild(i, 'ignore') + } + } else if (nodes.type) { + nodes = [nodes] + } else if (nodes.prop) { + if (typeof nodes.value === 'undefined') { + throw new Error('Value field is missed in node creation') + } else if (typeof nodes.value !== 'string') { + nodes.value = String(nodes.value) + } + nodes = [new Declaration(nodes)] + } else if (nodes.selector || nodes.selectors) { + nodes = [new Rule(nodes)] + } else if (nodes.name) { + nodes = [new AtRule(nodes)] + } else if (nodes.text) { + nodes = [new Comment(nodes)] + } else { + throw new Error('Unknown node type in node creation') + } + + let processed = nodes.map(i => { + /* c8 ignore next */ + if (!i[my]) Container.rebuild(i) + i = i.proxyOf + if (i.parent) i.parent.removeChild(i) + if (i[isClean]) markTreeDirty(i) + + if (!i.raws) i.raws = {} + if (typeof i.raws.before === 'undefined') { + if (sample && typeof sample.raws.before !== 'undefined') { + i.raws.before = sample.raws.before.replace(/\S/g, '') + } + } + i.parent = this.proxyOf + return i + }) + + return processed + } + + prepend(...children) { + children = children.reverse() + for (let child of children) { + let nodes = this.normalize(child, this.first, 'prepend').reverse() + for (let node of nodes) this.proxyOf.nodes.unshift(node) + for (let id in this.indexes) { + this.indexes[id] = this.indexes[id] + nodes.length + } + } + + this.markDirty() + + return this + } + + push(child) { + child.parent = this + this.proxyOf.nodes.push(child) + return this + } + + removeAll() { + for (let node of this.proxyOf.nodes) node.parent = undefined + this.proxyOf.nodes = [] + + this.markDirty() + + return this + } + + removeChild(child) { + child = this.index(child) + this.proxyOf.nodes[child].parent = undefined + this.proxyOf.nodes.splice(child, 1) + + let index + for (let id in this.indexes) { + index = this.indexes[id] + if (index >= child) { + this.indexes[id] = index - 1 + } + } + + this.markDirty() + + return this + } + + replaceValues(pattern, opts, callback) { + if (!callback) { + callback = opts + opts = {} + } + + this.walkDecls(decl => { + if (opts.props && !opts.props.includes(decl.prop)) return + if (opts.fast && !decl.value.includes(opts.fast)) return + + decl.value = decl.value.replace(pattern, callback) + }) + + this.markDirty() + + return this + } + + some(condition) { + return this.nodes.some(condition) + } + + walk(callback) { + return this.each((child, i) => { + let result + try { + result = callback(child, i) + } catch (e) { + throw child.addToError(e) + } + if (result !== false && child.walk) { + result = child.walk(callback) + } + + return result + }) + } + + walkAtRules(name, callback) { + if (!callback) { + callback = name + return this.walk((child, i) => { + if (child.type === 'atrule') { + return callback(child, i) + } + }) + } + if (name instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'atrule' && name.test(child.name)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'atrule' && child.name === name) { + return callback(child, i) + } + }) + } + + walkComments(callback) { + return this.walk((child, i) => { + if (child.type === 'comment') { + return callback(child, i) + } + }) + } + + walkDecls(prop, callback) { + if (!callback) { + callback = prop + return this.walk((child, i) => { + if (child.type === 'decl') { + return callback(child, i) + } + }) + } + if (prop instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'decl' && prop.test(child.prop)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'decl' && child.prop === prop) { + return callback(child, i) + } + }) + } + + walkRules(selector, callback) { + if (!callback) { + callback = selector + + return this.walk((child, i) => { + if (child.type === 'rule') { + return callback(child, i) + } + }) + } + if (selector instanceof RegExp) { + return this.walk((child, i) => { + if (child.type === 'rule' && selector.test(child.selector)) { + return callback(child, i) + } + }) + } + return this.walk((child, i) => { + if (child.type === 'rule' && child.selector === selector) { + return callback(child, i) + } + }) + } +} + +Container.registerParse = dependant => { + parse = dependant +} + +Container.registerRule = dependant => { + Rule = dependant +} + +Container.registerAtRule = dependant => { + AtRule = dependant +} + +Container.registerRoot = dependant => { + Root = dependant +} + +module.exports = Container +Container.default = Container + +/* c8 ignore start */ +Container.rebuild = node => { + if (node.type === 'atrule') { + Object.setPrototypeOf(node, AtRule.prototype) + } else if (node.type === 'rule') { + Object.setPrototypeOf(node, Rule.prototype) + } else if (node.type === 'decl') { + Object.setPrototypeOf(node, Declaration.prototype) + } else if (node.type === 'comment') { + Object.setPrototypeOf(node, Comment.prototype) + } else if (node.type === 'root') { + Object.setPrototypeOf(node, Root.prototype) + } + + node[my] = true + + if (node.nodes) { + node.nodes.forEach(child => { + Container.rebuild(child) + }) + } +} +/* c8 ignore stop */ diff --git a/node_modules/postcss/lib/css-syntax-error.d.ts b/node_modules/postcss/lib/css-syntax-error.d.ts new file mode 100644 index 0000000..03d9ed1 --- /dev/null +++ b/node_modules/postcss/lib/css-syntax-error.d.ts @@ -0,0 +1,247 @@ +import { FilePosition } from './input.js' + +declare namespace CssSyntaxError { + /** + * A position that is part of a range. + */ + export interface RangePosition { + /** + * The column number in the input. + */ + column: number + + /** + * The line number in the input. + */ + line: number + } + + export { CssSyntaxError_ as default } +} + +/** + * The CSS parser throws this error for broken CSS. + * + * Custom parsers can throw this error for broken custom syntax using + * the `Node#error` method. + * + * PostCSS will use the input source map to detect the original error location. + * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS, + * PostCSS will show the original position in the Sass file. + * + * If you need the position in the PostCSS input + * (e.g., to debug the previous compiler), use `error.input.file`. + * + * ```js + * // Raising error from plugin + * throw node.error('Unknown variable', { plugin: 'postcss-vars' }) + * ``` + * + * ```js + * // Catching and checking syntax error + * try { + * postcss.parse('a{') + * } catch (error) { + * if (error.name === 'CssSyntaxError') { + * error //=> CssSyntaxError + * } + * } + * ``` + */ +declare class CssSyntaxError_ extends Error { + /** + * Source column of the error. + * + * ```js + * error.column //=> 1 + * error.input.column //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.column`. + */ + column?: number + + /** + * Source column of the error's end, exclusive. Provided if the error pertains + * to a range. + * + * ```js + * error.endColumn //=> 1 + * error.input.endColumn //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.endColumn`. + */ + endColumn?: number + + /** + * Source line of the error's end, exclusive. Provided if the error pertains + * to a range. + * + * ```js + * error.endLine //=> 3 + * error.input.endLine //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.endLine`. + */ + endLine?: number + + /** + * Absolute path to the broken file. + * + * ```js + * error.file //=> 'a.sass' + * error.input.file //=> 'a.css' + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.file`. + */ + file?: string + + /** + * Input object with PostCSS internal information + * about input file. If input has source map + * from previous tool, PostCSS will use origin + * (for example, Sass) source. You can use this + * object to get PostCSS input source. + * + * ```js + * error.input.file //=> 'a.css' + * error.file //=> 'a.sass' + * ``` + */ + input?: FilePosition + + /** + * Source line of the error. + * + * ```js + * error.line //=> 2 + * error.input.line //=> 4 + * ``` + * + * PostCSS will use the input source map to detect the original location. + * If you need the position in the PostCSS input, use `error.input.line`. + */ + line?: number + + /** + * Full error text in the GNU error format + * with plugin, file, line and column. + * + * ```js + * error.message //=> 'a.css:1:1: Unclosed block' + * ``` + */ + message: string + + /** + * Always equal to `'CssSyntaxError'`. You should always check error type + * by `error.name === 'CssSyntaxError'` + * instead of `error instanceof CssSyntaxError`, + * because npm could have several PostCSS versions. + * + * ```js + * if (error.name === 'CssSyntaxError') { + * error //=> CssSyntaxError + * } + * ``` + */ + name: 'CssSyntaxError' + + /** + * Plugin name, if error came from plugin. + * + * ```js + * error.plugin //=> 'postcss-vars' + * ``` + */ + plugin?: string + + /** + * Error message. + * + * ```js + * error.message //=> 'Unclosed block' + * ``` + */ + reason: string + + /** + * Source code of the broken file. + * + * ```js + * error.source //=> 'a { b {} }' + * error.input.source //=> 'a b { }' + * ``` + */ + source?: string + + stack: string + + /** + * Instantiates a CSS syntax error. Can be instantiated for a single position + * or for a range. + * @param message Error message. + * @param lineOrStartPos If for a single position, the line number, or if for + * a range, the inclusive start position of the error. + * @param columnOrEndPos If for a single position, the column number, or if for + * a range, the exclusive end position of the error. + * @param source Source code of the broken file. + * @param file Absolute path to the broken file. + * @param plugin PostCSS plugin name, if error came from plugin. + */ + constructor( + message: string, + lineOrStartPos?: CssSyntaxError.RangePosition | number, + columnOrEndPos?: CssSyntaxError.RangePosition | number, + source?: string, + file?: string, + plugin?: string + ) + + /** + * Returns a few lines of CSS source that caused the error. + * + * If the CSS has an input source map without `sourceContent`, + * this method will return an empty string. + * + * ```js + * error.showSourceCode() //=> " 4 | } + * // 5 | a { + * // > 6 | bad + * // | ^ + * // 7 | } + * // 8 | b {" + * ``` + * + * @param color Whether arrow will be colored red by terminal + * color codes. By default, PostCSS will detect + * color support by `process.stdout.isTTY` + * and `process.env.NODE_DISABLE_COLORS`. + * @return Few lines of CSS source that caused the error. + */ + showSourceCode(color?: boolean): string + + /** + * Returns error position, message and source code of the broken part. + * + * ```js + * error.toString() //=> "CssSyntaxError: app.css:1:1: Unclosed block + * // > 1 | a { + * // | ^" + * ``` + * + * @return Error position, message and source code. + */ + toString(): string +} + +declare class CssSyntaxError extends CssSyntaxError_ {} + +export = CssSyntaxError diff --git a/node_modules/postcss/lib/css-syntax-error.js b/node_modules/postcss/lib/css-syntax-error.js new file mode 100644 index 0000000..275a4f6 --- /dev/null +++ b/node_modules/postcss/lib/css-syntax-error.js @@ -0,0 +1,133 @@ +'use strict' + +let pico = require('picocolors') + +let terminalHighlight = require('./terminal-highlight') + +class CssSyntaxError extends Error { + constructor(message, line, column, source, file, plugin) { + super(message) + this.name = 'CssSyntaxError' + this.reason = message + + if (file) { + this.file = file + } + if (source) { + this.source = source + } + if (plugin) { + this.plugin = plugin + } + if (typeof line !== 'undefined' && typeof column !== 'undefined') { + if (typeof line === 'number') { + this.line = line + this.column = column + } else { + this.line = line.line + this.column = line.column + this.endLine = column.line + this.endColumn = column.column + } + } + + this.setMessage() + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, CssSyntaxError) + } + } + + setMessage() { + this.message = this.plugin ? this.plugin + ': ' : '' + this.message += this.file ? this.file : '' + if (typeof this.line !== 'undefined') { + this.message += ':' + this.line + ':' + this.column + } + this.message += ': ' + this.reason + } + + showSourceCode(color) { + if (!this.source) return '' + + let css = this.source + if (color == null) color = pico.isColorSupported + + let aside = text => text + let mark = text => text + let highlight = text => text + if (color) { + let { bold, gray, red } = pico.createColors(true) + mark = text => bold(red(text)) + aside = text => gray(text) + if (terminalHighlight) { + highlight = text => terminalHighlight(text) + } + } + + let lines = css.split(/\r?\n/) + let start = Math.max(this.line - 3, 0) + let end = Math.min(this.line + 2, lines.length) + let maxWidth = String(end).length + + return lines + .slice(start, end) + .map((line, index) => { + let number = start + 1 + index + let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | ' + if (number === this.line) { + if (line.length > 160) { + let padding = 20 + let subLineStart = Math.max(0, this.column - padding) + let subLineEnd = Math.max( + this.column + padding, + this.endColumn + padding + ) + let subLine = line.slice(subLineStart, subLineEnd) + + let spacing = + aside(gutter.replace(/\d/g, ' ')) + + line + .slice(0, Math.min(this.column - 1, padding - 1)) + .replace(/[^\t]/g, ' ') + + return ( + mark('>') + + aside(gutter) + + highlight(subLine) + + '\n ' + + spacing + + mark('^') + ) + } + + let spacing = + aside(gutter.replace(/\d/g, ' ')) + + line.slice(0, this.column - 1).replace(/[^\t]/g, ' ') + + return ( + mark('>') + + aside(gutter) + + highlight(line) + + '\n ' + + spacing + + mark('^') + ) + } + + return ' ' + aside(gutter) + highlight(line) + }) + .join('\n') + } + + toString() { + let code = this.showSourceCode() + if (code) { + code = '\n\n' + code + '\n' + } + return this.name + ': ' + this.message + code + } +} + +module.exports = CssSyntaxError +CssSyntaxError.default = CssSyntaxError diff --git a/node_modules/postcss/lib/declaration.d.ts b/node_modules/postcss/lib/declaration.d.ts new file mode 100644 index 0000000..55dec7f --- /dev/null +++ b/node_modules/postcss/lib/declaration.d.ts @@ -0,0 +1,150 @@ +import { ContainerWithChildren } from './container.js' +import Node from './node.js' + +declare namespace Declaration { + export interface DeclarationRaws extends Record { + /** + * The space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + */ + before?: string + + /** + * The symbols between the property and value for declarations. + */ + between?: string + + /** + * The content of the important statement, if it is not just `!important`. + */ + important?: string + + /** + * Declaration value with comments. + */ + value?: { + raw: string + value: string + } + } + + export interface DeclarationProps { + /** Whether the declaration has an `!important` annotation. */ + important?: boolean + /** Name of the declaration. */ + prop: string + /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ + raws?: DeclarationRaws + /** Value of the declaration. */ + value: string + } + + export { Declaration_ as default } +} + +/** + * It represents a class that handles + * [CSS declarations](https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#css_declarations) + * + * ```js + * Once (root, { Declaration }) { + * const color = new Declaration({ prop: 'color', value: 'black' }) + * root.append(color) + * } + * ``` + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first?.first + * + * decl.type //=> 'decl' + * decl.toString() //=> ' color: black' + * ``` + */ +declare class Declaration_ extends Node { + parent: ContainerWithChildren | undefined + raws: Declaration.DeclarationRaws + + type: 'decl' + + /** + * It represents a specificity of the declaration. + * + * If true, the CSS declaration will have an + * [important](https://developer.mozilla.org/en-US/docs/Web/CSS/important) + * specifier. + * + * ```js + * const root = postcss.parse('a { color: black !important; color: red }') + * + * root.first.first.important //=> true + * root.first.last.important //=> undefined + * ``` + */ + get important(): boolean + set important(value: boolean) + + /** + * The property name for a CSS declaration. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first.first + * + * decl.prop //=> 'color' + * ``` + */ + get prop(): string + + set prop(value: string) + + /** + * The property value for a CSS declaration. + * + * Any CSS comments inside the value string will be filtered out. + * CSS comments present in the source value will be available in + * the `raws` property. + * + * Assigning new `value` would ignore the comments in `raws` + * property while compiling node to string. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const decl = root.first.first + * + * decl.value //=> 'black' + * ``` + */ + get value(): string + set value(value: string) + + /** + * It represents a getter that returns `true` if a declaration starts with + * `--` or `$`, which are used to declare variables in CSS and SASS/SCSS. + * + * ```js + * const root = postcss.parse(':root { --one: 1 }') + * const one = root.first.first + * + * one.variable //=> true + * ``` + * + * ```js + * const root = postcss.parse('$one: 1') + * const one = root.first + * + * one.variable //=> true + * ``` + */ + get variable(): boolean + constructor(defaults?: Declaration.DeclarationProps) + + assign(overrides: Declaration.DeclarationProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this +} + +declare class Declaration extends Declaration_ {} + +export = Declaration diff --git a/node_modules/postcss/lib/declaration.js b/node_modules/postcss/lib/declaration.js new file mode 100644 index 0000000..65a03aa --- /dev/null +++ b/node_modules/postcss/lib/declaration.js @@ -0,0 +1,24 @@ +'use strict' + +let Node = require('./node') + +class Declaration extends Node { + get variable() { + return this.prop.startsWith('--') || this.prop[0] === '$' + } + + constructor(defaults) { + if ( + defaults && + typeof defaults.value !== 'undefined' && + typeof defaults.value !== 'string' + ) { + defaults = { ...defaults, value: String(defaults.value) } + } + super(defaults) + this.type = 'decl' + } +} + +module.exports = Declaration +Declaration.default = Declaration diff --git a/node_modules/postcss/lib/document.d.ts b/node_modules/postcss/lib/document.d.ts new file mode 100644 index 0000000..67194dd --- /dev/null +++ b/node_modules/postcss/lib/document.d.ts @@ -0,0 +1,68 @@ +import Container, { ContainerProps } from './container.js' +import { ProcessOptions } from './postcss.js' +import Result from './result.js' +import Root from './root.js' + +declare namespace Document { + export interface DocumentProps extends ContainerProps { + nodes?: readonly Root[] + + /** + * Information to generate byte-to-byte equal node string as it was + * in the origin input. + * + * Every parser saves its own properties. + */ + raws?: Record + } + + export { Document_ as default } +} + +/** + * Represents a file and contains all its parsed nodes. + * + * **Experimental:** some aspects of this node could change within minor + * or patch version releases. + * + * ```js + * const document = htmlParser( + * '' + * ) + * document.type //=> 'document' + * document.nodes.length //=> 2 + * ``` + */ +declare class Document_ extends Container { + nodes: Root[] + parent: undefined + type: 'document' + + constructor(defaults?: Document.DocumentProps) + + assign(overrides: Document.DocumentProps | object): this + clone(overrides?: Partial): this + cloneAfter(overrides?: Partial): this + cloneBefore(overrides?: Partial): this + + /** + * Returns a `Result` instance representing the document’s CSS roots. + * + * ```js + * const root1 = postcss.parse(css1, { from: 'a.css' }) + * const root2 = postcss.parse(css2, { from: 'b.css' }) + * const document = postcss.document() + * document.append(root1) + * document.append(root2) + * const result = document.toResult({ to: 'all.css', map: true }) + * ``` + * + * @param opts Options. + * @return Result with current document’s CSS. + */ + toResult(options?: ProcessOptions): Result +} + +declare class Document extends Document_ {} + +export = Document diff --git a/node_modules/postcss/lib/document.js b/node_modules/postcss/lib/document.js new file mode 100644 index 0000000..4468991 --- /dev/null +++ b/node_modules/postcss/lib/document.js @@ -0,0 +1,33 @@ +'use strict' + +let Container = require('./container') + +let LazyResult, Processor + +class Document extends Container { + constructor(defaults) { + // type needs to be passed to super, otherwise child roots won't be normalized correctly + super({ type: 'document', ...defaults }) + + if (!this.nodes) { + this.nodes = [] + } + } + + toResult(opts = {}) { + let lazy = new LazyResult(new Processor(), this, opts) + + return lazy.stringify() + } +} + +Document.registerLazyResult = dependant => { + LazyResult = dependant +} + +Document.registerProcessor = dependant => { + Processor = dependant +} + +module.exports = Document +Document.default = Document diff --git a/node_modules/postcss/lib/fromJSON.d.ts b/node_modules/postcss/lib/fromJSON.d.ts new file mode 100644 index 0000000..3a0c5b8 --- /dev/null +++ b/node_modules/postcss/lib/fromJSON.d.ts @@ -0,0 +1,9 @@ +import { JSONHydrator } from './postcss.js' + +interface FromJSON extends JSONHydrator { + default: FromJSON +} + +declare let fromJSON: FromJSON + +export = fromJSON diff --git a/node_modules/postcss/lib/fromJSON.js b/node_modules/postcss/lib/fromJSON.js new file mode 100644 index 0000000..c9ac1a8 --- /dev/null +++ b/node_modules/postcss/lib/fromJSON.js @@ -0,0 +1,54 @@ +'use strict' + +let AtRule = require('./at-rule') +let Comment = require('./comment') +let Declaration = require('./declaration') +let Input = require('./input') +let PreviousMap = require('./previous-map') +let Root = require('./root') +let Rule = require('./rule') + +function fromJSON(json, inputs) { + if (Array.isArray(json)) return json.map(n => fromJSON(n)) + + let { inputs: ownInputs, ...defaults } = json + if (ownInputs) { + inputs = [] + for (let input of ownInputs) { + let inputHydrated = { ...input, __proto__: Input.prototype } + if (inputHydrated.map) { + inputHydrated.map = { + ...inputHydrated.map, + __proto__: PreviousMap.prototype + } + } + inputs.push(inputHydrated) + } + } + if (defaults.nodes) { + defaults.nodes = json.nodes.map(n => fromJSON(n, inputs)) + } + if (defaults.source) { + let { inputId, ...source } = defaults.source + defaults.source = source + if (inputId != null) { + defaults.source.input = inputs[inputId] + } + } + if (defaults.type === 'root') { + return new Root(defaults) + } else if (defaults.type === 'decl') { + return new Declaration(defaults) + } else if (defaults.type === 'rule') { + return new Rule(defaults) + } else if (defaults.type === 'comment') { + return new Comment(defaults) + } else if (defaults.type === 'atrule') { + return new AtRule(defaults) + } else { + throw new Error('Unknown node type: ' + json.type) + } +} + +module.exports = fromJSON +fromJSON.default = fromJSON diff --git a/node_modules/postcss/lib/input.d.ts b/node_modules/postcss/lib/input.d.ts new file mode 100644 index 0000000..ca2d26b --- /dev/null +++ b/node_modules/postcss/lib/input.d.ts @@ -0,0 +1,226 @@ +import { CssSyntaxError, ProcessOptions } from './postcss.js' +import PreviousMap from './previous-map.js' + +declare namespace Input { + export interface FilePosition { + /** + * Column of inclusive start position in source file. + */ + column: number + + /** + * Column of exclusive end position in source file. + */ + endColumn?: number + + /** + * Line of exclusive end position in source file. + */ + endLine?: number + + /** + * Offset of exclusive end position in source file. + */ + endOffset?: number + + /** + * Absolute path to the source file. + */ + file?: string + + /** + * Line of inclusive start position in source file. + */ + line: number + + /** + * Offset of inclusive start position in source file. + */ + offset: number + + /** + * Source code. + */ + source?: string + + /** + * URL for the source file. + */ + url: string + } + + export { Input_ as default } +} + +/** + * Represents the source CSS. + * + * ```js + * const root = postcss.parse(css, { from: file }) + * const input = root.source.input + * ``` + */ +declare class Input_ { + /** + * Input CSS source. + * + * ```js + * const input = postcss.parse('a{}', { from: file }).input + * input.css //=> "a{}" + * ``` + */ + css: string + + /** + * Input source with support for non-CSS documents. + * + * ```js + * const input = postcss.parse('a{}', { from: file, document: '' }).input + * input.document //=> "" + * input.css //=> "a{}" + * ``` + */ + document: string + + /** + * The absolute path to the CSS source file defined + * with the `from` option. + * + * ```js + * const root = postcss.parse(css, { from: 'a.css' }) + * root.source.input.file //=> '/home/ai/a.css' + * ``` + */ + file?: string + + /** + * The flag to indicate whether or not the source code has Unicode BOM. + */ + hasBOM: boolean + + /** + * The unique ID of the CSS source. It will be created if `from` option + * is not provided (because PostCSS does not know the file path). + * + * ```js + * const root = postcss.parse(css) + * root.source.input.file //=> undefined + * root.source.input.id //=> "" + * ``` + */ + id?: string + + /** + * The input source map passed from a compilation step before PostCSS + * (for example, from Sass compiler). + * + * ```js + * root.source.input.map.consumer().sources //=> ['a.sass'] + * ``` + */ + map: PreviousMap + + /** + * The CSS source identifier. Contains `Input#file` if the user + * set the `from` option, or `Input#id` if they did not. + * + * ```js + * const root = postcss.parse(css, { from: 'a.css' }) + * root.source.input.from //=> "/home/ai/a.css" + * + * const root = postcss.parse(css) + * root.source.input.from //=> "" + * ``` + */ + get from(): string + + /** + * @param css Input CSS source. + * @param opts Process options. + */ + constructor(css: string, opts?: ProcessOptions) + + /** + * Returns `CssSyntaxError` with information about the error and its position. + */ + error( + message: string, + start: + | { + column: number + line: number + } + | { + offset: number + }, + end: + | { + column: number + line: number + } + | { + offset: number + }, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + error( + message: string, + line: number, + column: number, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + error( + message: string, + offset: number, + opts?: { plugin?: CssSyntaxError['plugin'] } + ): CssSyntaxError + + /** + * Converts source line and column to offset. + * + * @param line Source line. + * @param column Source column. + * @return Source offset. + */ + fromLineAndColumn(line: number, column: number): number + + /** + * Converts source offset to line and column. + * + * @param offset Source offset. + */ + fromOffset(offset: number): { col: number; line: number } | null + + /** + * Reads the input source map and returns a symbol position + * in the input source (e.g., in a Sass file that was compiled + * to CSS before being passed to PostCSS). Optionally takes an + * end position, exclusive. + * + * ```js + * root.source.input.origin(1, 1) //=> { file: 'a.css', line: 3, column: 1 } + * root.source.input.origin(1, 1, 1, 4) + * //=> { file: 'a.css', line: 3, column: 1, endLine: 3, endColumn: 4 } + * ``` + * + * @param line Line for inclusive start position in input CSS. + * @param column Column for inclusive start position in input CSS. + * @param endLine Line for exclusive end position in input CSS. + * @param endColumn Column for exclusive end position in input CSS. + * + * @return Position in input source. + */ + origin( + line: number, + column: number, + endLine?: number, + endColumn?: number + ): false | Input.FilePosition + + /** Converts this to a JSON-friendly object representation. */ + toJSON(): object +} + +declare class Input extends Input_ {} + +export = Input diff --git a/node_modules/postcss/lib/input.js b/node_modules/postcss/lib/input.js new file mode 100644 index 0000000..1dab928 --- /dev/null +++ b/node_modules/postcss/lib/input.js @@ -0,0 +1,273 @@ +'use strict' + +let { nanoid } = require('nanoid/non-secure') +let { isAbsolute, resolve } = require('path') +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { fileURLToPath, pathToFileURL } = require('url') + +let CssSyntaxError = require('./css-syntax-error') +let PreviousMap = require('./previous-map') +let terminalHighlight = require('./terminal-highlight') + +let lineToIndexCache = Symbol('lineToIndexCache') + +let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) +let pathAvailable = Boolean(resolve && isAbsolute) + +function getLineToIndex(input) { + if (input[lineToIndexCache]) return input[lineToIndexCache] + let lines = input.css.split('\n') + let lineToIndex = new Array(lines.length) + let prevIndex = 0 + + for (let i = 0, l = lines.length; i < l; i++) { + lineToIndex[i] = prevIndex + prevIndex += lines[i].length + 1 + } + + input[lineToIndexCache] = lineToIndex + return lineToIndex +} + +class Input { + get from() { + return this.file || this.id + } + + constructor(css, opts = {}) { + if ( + css === null || + typeof css === 'undefined' || + (typeof css === 'object' && !css.toString) + ) { + throw new Error(`PostCSS received ${css} instead of CSS string`) + } + + this.css = css.toString() + + if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { + this.hasBOM = true + this.css = this.css.slice(1) + } else { + this.hasBOM = false + } + + this.document = this.css + if (opts.document) this.document = opts.document.toString() + + if (opts.from) { + if ( + !pathAvailable || + /^\w+:\/\//.test(opts.from) || + isAbsolute(opts.from) + ) { + this.file = opts.from + } else { + this.file = resolve(opts.from) + } + } + + if (pathAvailable && sourceMapAvailable) { + let map = new PreviousMap(this.css, opts) + if (map.text) { + this.map = map + let file = map.consumer().file + if (!this.file && file) this.file = this.mapResolve(file) + } + } + + if (!this.file) { + this.id = '' + } + if (this.map) this.map.file = this.from + } + + error(message, line, column, opts = {}) { + let endColumn, endLine, endOffset, offset, result + + if (line && typeof line === 'object') { + let start = line + let end = column + if (typeof start.offset === 'number') { + offset = start.offset + let pos = this.fromOffset(offset) + line = pos.line + column = pos.col + } else { + line = start.line + column = start.column + offset = this.fromLineAndColumn(line, column) + } + if (typeof end.offset === 'number') { + endOffset = end.offset + let pos = this.fromOffset(endOffset) + endLine = pos.line + endColumn = pos.col + } else { + endLine = end.line + endColumn = end.column + endOffset = this.fromLineAndColumn(end.line, end.column) + } + } else if (!column) { + offset = line + let pos = this.fromOffset(offset) + line = pos.line + column = pos.col + } else { + offset = this.fromLineAndColumn(line, column) + } + + let origin = this.origin(line, column, endLine, endColumn) + if (origin) { + result = new CssSyntaxError( + message, + origin.endLine === undefined + ? origin.line + : { column: origin.column, line: origin.line }, + origin.endLine === undefined + ? origin.column + : { column: origin.endColumn, line: origin.endLine }, + origin.source, + origin.file, + opts.plugin + ) + } else { + result = new CssSyntaxError( + message, + endLine === undefined ? line : { column, line }, + endLine === undefined ? column : { column: endColumn, line: endLine }, + this.css, + this.file, + opts.plugin + ) + } + + result.input = { + column, + endColumn, + endLine, + endOffset, + line, + offset, + source: this.css + } + if (this.file) { + if (pathToFileURL) { + result.input.url = pathToFileURL(this.file).toString() + } + result.input.file = this.file + } + + return result + } + + fromLineAndColumn(line, column) { + let lineToIndex = getLineToIndex(this) + let index = lineToIndex[line - 1] + return index + column - 1 + } + + fromOffset(offset) { + let lineToIndex = getLineToIndex(this) + let lastLine = lineToIndex[lineToIndex.length - 1] + + let min = 0 + if (offset >= lastLine) { + min = lineToIndex.length - 1 + } else { + let max = lineToIndex.length - 2 + let mid + while (min < max) { + mid = min + ((max - min) >> 1) + if (offset < lineToIndex[mid]) { + max = mid - 1 + } else if (offset >= lineToIndex[mid + 1]) { + min = mid + 1 + } else { + min = mid + break + } + } + } + return { + col: offset - lineToIndex[min] + 1, + line: min + 1 + } + } + + mapResolve(file) { + if (/^\w+:\/\//.test(file)) { + return file + } + return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file) + } + + origin(line, column, endLine, endColumn) { + if (!this.map) return false + let consumer = this.map.consumer() + + let from = consumer.originalPositionFor({ column, line }) + if (!from.source) return false + + let to + if (typeof endLine === 'number') { + to = consumer.originalPositionFor({ column: endColumn, line: endLine }) + } + + let fromUrl + + if (isAbsolute(from.source)) { + fromUrl = pathToFileURL(from.source) + } else { + fromUrl = new URL( + from.source, + this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile) + ) + } + + let result = { + column: from.column, + endColumn: to && to.column, + endLine: to && to.line, + line: from.line, + url: fromUrl.toString() + } + + if (fromUrl.protocol === 'file:') { + if (fileURLToPath) { + result.file = fileURLToPath(fromUrl) + } else { + /* c8 ignore next 2 */ + throw new Error(`file: protocol is not available in this PostCSS build`) + } + } + + let source = consumer.sourceContentFor(from.source) + if (source) result.source = source + + return result + } + + toJSON() { + let json = {} + for (let name of ['hasBOM', 'css', 'file', 'id']) { + if (this[name] != null) { + json[name] = this[name] + } + } + if (this.map) { + json.map = { ...this.map } + if (json.map.consumerCache) { + json.map.consumerCache = undefined + } + } + return json + } +} + +module.exports = Input +Input.default = Input + +if (terminalHighlight && terminalHighlight.registerInput) { + terminalHighlight.registerInput(Input) +} diff --git a/node_modules/postcss/lib/lazy-result.d.ts b/node_modules/postcss/lib/lazy-result.d.ts new file mode 100644 index 0000000..599a614 --- /dev/null +++ b/node_modules/postcss/lib/lazy-result.d.ts @@ -0,0 +1,189 @@ +import Document from './document.js' +import { SourceMap } from './postcss.js' +import Processor from './processor.js' +import Result, { Message, ResultOptions } from './result.js' +import Root from './root.js' +import Warning from './warning.js' + +declare namespace LazyResult { + export { LazyResult_ as default } +} + +/** + * A Promise proxy for the result of PostCSS transformations. + * + * A `LazyResult` instance is returned by `Processor#process`. + * + * ```js + * const lazy = postcss([autoprefixer]).process(css) + * ``` + */ +declare class LazyResult_ implements PromiseLike< + Result +> { + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls onRejected for each error thrown in any plugin. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css).then(result => { + * console.log(result.css) + * }).catch(error => { + * console.error(error) + * }) + * ``` + */ + catch: Promise>['catch'] + + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls onFinally on any error or when all plugins will finish work. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css).finally(() => { + * console.log('processing ended') + * }) + * ``` + */ + finally: Promise>['finally'] + + /** + * Processes input CSS through synchronous and asynchronous plugins + * and calls `onFulfilled` with a Result instance. If a plugin throws + * an error, the `onRejected` callback will be executed. + * + * It implements standard Promise API. + * + * ```js + * postcss([autoprefixer]).process(css, { from: cssPath }).then(result => { + * console.log(result.css) + * }) + * ``` + */ + then: Promise>['then'] + + /** + * An alias for the `css` property. Use it with syntaxes + * that generate non-CSS output. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get content(): string + + /** + * Processes input CSS through synchronous plugins, converts `Root` + * to a CSS string and returns `Result#css`. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get css(): string + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#map`. + * + * This property will only work with synchronous plugins. + * If the processor contains any asynchronous plugins + * it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get map(): SourceMap + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#messages`. + * + * This property will only work with synchronous plugins. If the processor + * contains any asynchronous plugins it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get messages(): Message[] + + /** + * Options from the `Processor#process` call. + */ + get opts(): ResultOptions + + /** + * Returns a `Processor` instance, which will be used + * for CSS transformations. + */ + get processor(): Processor + + /** + * Processes input CSS through synchronous plugins + * and returns `Result#root`. + * + * This property will only work with synchronous plugins. If the processor + * contains any asynchronous plugins it will throw an error. + * + * PostCSS runners should always use `LazyResult#then`. + */ + get root(): RootNode + + /** + * Returns the default string description of an object. + * Required to implement the Promise interface. + */ + get [Symbol.toStringTag](): string + + /** + * @param processor Processor used for this transformation. + * @param css CSS to parse and transform. + * @param opts Options from the `Processor#process` or `Root#toResult`. + */ + constructor(processor: Processor, css: string, opts: ResultOptions) + + /** + * Run plugin in async way and return `Result`. + * + * @return Result with output content. + */ + async(): Promise> + + /** + * Run plugin in sync way and return `Result`. + * + * @return Result with output content. + */ + sync(): Result + + /** + * Alias for the `LazyResult#css` property. + * + * ```js + * lazy + '' === lazy.css + * ``` + * + * @return Output CSS. + */ + toString(): string + + /** + * Processes input CSS through synchronous plugins + * and calls `Result#warnings`. + * + * @return Warnings from plugins. + */ + warnings(): Warning[] +} + +declare class LazyResult< + RootNode = Document | Root +> extends LazyResult_ {} + +export = LazyResult diff --git a/node_modules/postcss/lib/lazy-result.js b/node_modules/postcss/lib/lazy-result.js new file mode 100644 index 0000000..9026a7c --- /dev/null +++ b/node_modules/postcss/lib/lazy-result.js @@ -0,0 +1,563 @@ +'use strict' + +let Container = require('./container') +let Document = require('./document') +let MapGenerator = require('./map-generator') +let parse = require('./parse') +let Result = require('./result') +let Root = require('./root') +let stringify = require('./stringify') +let { isClean, my } = require('./symbols') +let warnOnce = require('./warn-once') + +const TYPE_TO_CLASS_NAME = { + atrule: 'AtRule', + comment: 'Comment', + decl: 'Declaration', + document: 'Document', + root: 'Root', + rule: 'Rule' +} + +const PLUGIN_PROPS = { + AtRule: true, + AtRuleExit: true, + Comment: true, + CommentExit: true, + Declaration: true, + DeclarationExit: true, + Document: true, + DocumentExit: true, + Once: true, + OnceExit: true, + postcssPlugin: true, + prepare: true, + Root: true, + RootExit: true, + Rule: true, + RuleExit: true +} + +const NOT_VISITORS = { + Once: true, + postcssPlugin: true, + prepare: true +} + +const CHILDREN = 0 + +function isPromise(obj) { + return typeof obj === 'object' && typeof obj.then === 'function' +} + +function getEvents(node) { + let key = false + let type = TYPE_TO_CLASS_NAME[node.type] + if (node.type === 'decl') { + key = node.prop.toLowerCase() + } else if (node.type === 'atrule') { + key = node.name.toLowerCase() + } + + if (key && node.append) { + return [ + type, + type + '-' + key, + CHILDREN, + type + 'Exit', + type + 'Exit-' + key + ] + } else if (key) { + return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key] + } else if (node.append) { + return [type, CHILDREN, type + 'Exit'] + } else { + return [type, type + 'Exit'] + } +} + +function toStack(node) { + let events + if (node.type === 'document') { + events = ['Document', CHILDREN, 'DocumentExit'] + } else if (node.type === 'root') { + events = ['Root', CHILDREN, 'RootExit'] + } else { + events = getEvents(node) + } + + return { + eventIndex: 0, + events, + iterator: 0, + node, + visitorIndex: 0, + visitors: [] + } +} + +function cleanMarks(node) { + node[isClean] = false + if (node.nodes) node.nodes.forEach(i => cleanMarks(i)) + return node +} + +let postcss = {} + +class LazyResult { + get content() { + return this.stringify().content + } + + get css() { + return this.stringify().css + } + + get map() { + return this.stringify().map + } + + get messages() { + return this.sync().messages + } + + get opts() { + return this.result.opts + } + + get processor() { + return this.result.processor + } + + get root() { + return this.sync().root + } + + get [Symbol.toStringTag]() { + return 'LazyResult' + } + + constructor(processor, css, opts) { + this.stringified = false + this.processed = false + + let root + if ( + typeof css === 'object' && + css !== null && + (css.type === 'root' || css.type === 'document') + ) { + root = cleanMarks(css) + } else if (css instanceof LazyResult || css instanceof Result) { + root = cleanMarks(css.root) + if (css.map) { + if (typeof opts.map === 'undefined') opts.map = {} + if (!opts.map.inline) opts.map.inline = false + opts.map.prev = css.map + } + } else { + let parser = parse + if (opts.syntax) parser = opts.syntax.parse + if (opts.parser) parser = opts.parser + if (parser.parse) parser = parser.parse + + try { + root = parser(css, opts) + } catch (error) { + this.processed = true + this.error = error + } + + if (root && !root[my]) { + /* c8 ignore next 2 */ + Container.rebuild(root) + } + } + + this.result = new Result(processor, root, opts) + this.helpers = { ...postcss, postcss, result: this.result } + this.plugins = this.processor.plugins.map(plugin => { + if (typeof plugin === 'object' && plugin.prepare) { + return { ...plugin, ...plugin.prepare(this.result) } + } else { + return plugin + } + }) + } + + async() { + if (this.error) return Promise.reject(this.error) + if (this.processed) return Promise.resolve(this.result) + if (!this.processing) { + this.processing = this.runAsync() + } + return this.processing + } + + catch(onRejected) { + return this.async().catch(onRejected) + } + + finally(onFinally) { + return this.async().then(onFinally, onFinally) + } + + getAsyncError() { + throw new Error('Use process(css).then(cb) to work with async plugins') + } + + handleError(error, node) { + let plugin = this.result.lastPlugin + try { + if (node) node.addToError(error) + this.error = error + if (error.name === 'CssSyntaxError' && !error.plugin) { + error.plugin = plugin.postcssPlugin + error.setMessage() + } else if (plugin.postcssVersion) { + if (process.env.NODE_ENV !== 'production') { + let pluginName = plugin.postcssPlugin + let pluginVer = plugin.postcssVersion + let runtimeVer = this.result.processor.version + let a = pluginVer.split('.') + let b = runtimeVer.split('.') + + if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) { + // eslint-disable-next-line no-console + console.error( + 'Unknown error from PostCSS plugin. Your current PostCSS ' + + 'version is ' + + runtimeVer + + ', but ' + + pluginName + + ' uses ' + + pluginVer + + '. Perhaps this is the source of the error below.' + ) + } + } + } + } catch (err) { + /* c8 ignore next 3 */ + // eslint-disable-next-line no-console + if (console && console.error) console.error(err) + } + return error + } + + prepareVisitors() { + this.listeners = {} + let add = (plugin, type, cb) => { + if (!this.listeners[type]) this.listeners[type] = [] + this.listeners[type].push([plugin, cb]) + } + for (let plugin of this.plugins) { + if (typeof plugin === 'object') { + for (let event in plugin) { + if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { + throw new Error( + `Unknown event ${event} in ${plugin.postcssPlugin}. ` + + `Try to update PostCSS (${this.processor.version} now).` + ) + } + if (!NOT_VISITORS[event]) { + if (typeof plugin[event] === 'object') { + for (let filter in plugin[event]) { + if (filter === '*') { + add(plugin, event, plugin[event][filter]) + } else { + add( + plugin, + event + '-' + filter.toLowerCase(), + plugin[event][filter] + ) + } + } + } else if (typeof plugin[event] === 'function') { + add(plugin, event, plugin[event]) + } + } + } + } + } + this.hasListener = Object.keys(this.listeners).length > 0 + } + + async runAsync() { + this.plugin = 0 + for (let i = 0; i < this.plugins.length; i++) { + let plugin = this.plugins[i] + let promise = this.runOnRoot(plugin) + if (isPromise(promise)) { + try { + await promise + } catch (error) { + throw this.handleError(error) + } + } + } + + this.prepareVisitors() + if (this.hasListener) { + let root = this.result.root + while (!root[isClean]) { + root[isClean] = true + let stack = [toStack(root)] + while (stack.length > 0) { + let promise = this.visitTick(stack) + if (isPromise(promise)) { + try { + await promise + } catch (e) { + let node = stack[stack.length - 1].node + throw this.handleError(e, node) + } + } + } + } + + if (this.listeners.OnceExit) { + for (let [plugin, visitor] of this.listeners.OnceExit) { + this.result.lastPlugin = plugin + try { + if (root.type === 'document') { + let roots = root.nodes.map(subRoot => + visitor(subRoot, this.helpers) + ) + + await Promise.all(roots) + } else { + await visitor(root, this.helpers) + } + } catch (e) { + throw this.handleError(e) + } + } + } + } + + this.processed = true + return this.stringify() + } + + runOnRoot(plugin) { + this.result.lastPlugin = plugin + try { + if (typeof plugin === 'object' && plugin.Once) { + if (this.result.root.type === 'document') { + let roots = this.result.root.nodes.map(root => + plugin.Once(root, this.helpers) + ) + + if (isPromise(roots[0])) { + return Promise.all(roots) + } + + return roots + } + + return plugin.Once(this.result.root, this.helpers) + } else if (typeof plugin === 'function') { + return plugin(this.result.root, this.result) + } + } catch (error) { + throw this.handleError(error) + } + } + + stringify() { + if (this.error) throw this.error + if (this.stringified) return this.result + this.stringified = true + + this.sync() + + let opts = this.result.opts + let str = stringify + if (opts.syntax) str = opts.syntax.stringify + if (opts.stringifier) str = opts.stringifier + if (str.stringify) str = str.stringify + + let rootSource = this.result.root.source + if ( + opts.map === undefined && + !(rootSource && rootSource.input && rootSource.input.map) + ) { + let result = '' + str(this.result.root, i => { + result += i + }) + this.result.css = result + return this.result + } + + let map = new MapGenerator(str, this.result.root, this.result.opts) + let data = map.generate() + this.result.css = data[0] + this.result.map = data[1] + + return this.result + } + + sync() { + if (this.error) throw this.error + if (this.processed) return this.result + this.processed = true + + if (this.processing) { + throw this.getAsyncError() + } + + for (let plugin of this.plugins) { + let promise = this.runOnRoot(plugin) + if (isPromise(promise)) { + throw this.getAsyncError() + } + } + + this.prepareVisitors() + if (this.hasListener) { + let root = this.result.root + while (!root[isClean]) { + root[isClean] = true + this.walkSync(root) + } + if (this.listeners.OnceExit) { + if (root.type === 'document') { + for (let subRoot of root.nodes) { + this.visitSync(this.listeners.OnceExit, subRoot) + } + } else { + this.visitSync(this.listeners.OnceExit, root) + } + } + } + + return this.result + } + + then(onFulfilled, onRejected) { + if (process.env.NODE_ENV !== 'production') { + if (!('from' in this.opts)) { + warnOnce( + 'Without `from` option PostCSS could generate wrong source map ' + + 'and will not find Browserslist config. Set it to CSS file path ' + + 'or to `undefined` to prevent this warning.' + ) + } + } + return this.async().then(onFulfilled, onRejected) + } + + toString() { + return this.css + } + + visitSync(visitors, node) { + for (let [plugin, visitor] of visitors) { + this.result.lastPlugin = plugin + let promise + try { + promise = visitor(node, this.helpers) + } catch (e) { + throw this.handleError(e, node.proxyOf) + } + if (node.type !== 'root' && node.type !== 'document' && !node.parent) { + return true + } + if (isPromise(promise)) { + throw this.getAsyncError() + } + } + } + + visitTick(stack) { + let visit = stack[stack.length - 1] + let { node, visitors } = visit + + if (node.type !== 'root' && node.type !== 'document' && !node.parent) { + stack.pop() + return + } + + if (visitors.length > 0 && visit.visitorIndex < visitors.length) { + let [plugin, visitor] = visitors[visit.visitorIndex] + visit.visitorIndex += 1 + if (visit.visitorIndex === visitors.length) { + visit.visitors = [] + visit.visitorIndex = 0 + } + this.result.lastPlugin = plugin + try { + return visitor(node.toProxy(), this.helpers) + } catch (e) { + throw this.handleError(e, node) + } + } + + if (visit.iterator !== 0) { + let iterator = visit.iterator + let child + while ((child = node.nodes[node.indexes[iterator]])) { + node.indexes[iterator] += 1 + if (!child[isClean]) { + child[isClean] = true + stack.push(toStack(child)) + return + } + } + visit.iterator = 0 + delete node.indexes[iterator] + } + + let events = visit.events + while (visit.eventIndex < events.length) { + let event = events[visit.eventIndex] + visit.eventIndex += 1 + if (event === CHILDREN) { + if (node.nodes && node.nodes.length) { + node[isClean] = true + visit.iterator = node.getIterator() + } + return + } else if (this.listeners[event]) { + visit.visitors = this.listeners[event] + return + } + } + stack.pop() + } + + walkSync(node) { + node[isClean] = true + let events = getEvents(node) + for (let event of events) { + if (event === CHILDREN) { + if (node.nodes) { + node.each(child => { + if (!child[isClean]) this.walkSync(child) + }) + } + } else { + let visitors = this.listeners[event] + if (visitors) { + if (this.visitSync(visitors, node.toProxy())) return + } + } + } + } + + warnings() { + return this.sync().warnings() + } +} + +LazyResult.registerPostcss = dependant => { + postcss = dependant +} + +module.exports = LazyResult +LazyResult.default = LazyResult + +Root.registerLazyResult(LazyResult) +Document.registerLazyResult(LazyResult) diff --git a/node_modules/postcss/lib/list.d.ts b/node_modules/postcss/lib/list.d.ts new file mode 100644 index 0000000..119624e --- /dev/null +++ b/node_modules/postcss/lib/list.d.ts @@ -0,0 +1,60 @@ +declare namespace list { + type List = { + /** + * Safely splits comma-separated values (such as those for `transition-*` + * and `background` properties). + * + * ```js + * Once (root, { list }) { + * list.comma('black, linear-gradient(white, black)') + * //=> ['black', 'linear-gradient(white, black)'] + * } + * ``` + * + * @param str Comma-separated values. + * @return Split values. + */ + comma(str: string): string[] + + default: List + + /** + * Safely splits space-separated values (such as those for `background`, + * `border-radius`, and other shorthand properties). + * + * ```js + * Once (root, { list }) { + * list.space('1px calc(10% + 1px)') //=> ['1px', 'calc(10% + 1px)'] + * } + * ``` + * + * @param str Space-separated values. + * @return Split values. + */ + space(str: string): string[] + + /** + * Safely splits values. + * + * ```js + * Once (root, { list }) { + * list.split('1px calc(10% + 1px)', [' ', '\n', '\t']) //=> ['1px', 'calc(10% + 1px)'] + * } + * ``` + * + * @param string separated values. + * @param separators array of separators. + * @param last boolean indicator. + * @return Split values. + */ + split( + string: string, + separators: readonly string[], + last: boolean + ): string[] + } +} + +declare let list: list.List + +export = list diff --git a/node_modules/postcss/lib/list.js b/node_modules/postcss/lib/list.js new file mode 100644 index 0000000..1b31f98 --- /dev/null +++ b/node_modules/postcss/lib/list.js @@ -0,0 +1,58 @@ +'use strict' + +let list = { + comma(string) { + return list.split(string, [','], true) + }, + + space(string) { + let spaces = [' ', '\n', '\t'] + return list.split(string, spaces) + }, + + split(string, separators, last) { + let array = [] + let current = '' + let split = false + + let func = 0 + let inQuote = false + let prevQuote = '' + let escape = false + + for (let letter of string) { + if (escape) { + escape = false + } else if (letter === '\\') { + escape = true + } else if (inQuote) { + if (letter === prevQuote) { + inQuote = false + } + } else if (letter === '"' || letter === "'") { + inQuote = true + prevQuote = letter + } else if (letter === '(') { + func += 1 + } else if (letter === ')') { + if (func > 0) func -= 1 + } else if (func === 0) { + if (separators.includes(letter)) split = true + } + + if (split) { + if (current !== '') array.push(current.trim()) + current = '' + split = false + } else { + current += letter + } + } + + if (last || current !== '') array.push(current.trim()) + return array + } +} + +module.exports = list +list.default = list diff --git a/node_modules/postcss/lib/map-generator.js b/node_modules/postcss/lib/map-generator.js new file mode 100644 index 0000000..df880ac --- /dev/null +++ b/node_modules/postcss/lib/map-generator.js @@ -0,0 +1,376 @@ +'use strict' + +let { dirname, relative, resolve, sep } = require('path') +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { pathToFileURL } = require('url') + +let Input = require('./input') + +let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) +let pathAvailable = Boolean(dirname && resolve && relative && sep) + +class MapGenerator { + constructor(stringify, root, opts, cssString) { + this.stringify = stringify + this.mapOpts = opts.map || {} + this.root = root + this.opts = opts + this.css = cssString + this.originalCSS = cssString + this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute + + this.memoizedFileURLs = new Map() + this.memoizedPaths = new Map() + this.memoizedURLs = new Map() + } + + addAnnotation() { + let content + + if (this.isInline()) { + content = + 'data:application/json;base64,' + this.toBase64(this.map.toString()) + } else if (typeof this.mapOpts.annotation === 'string') { + content = this.mapOpts.annotation + } else if (typeof this.mapOpts.annotation === 'function') { + content = this.mapOpts.annotation(this.opts.to, this.root) + } else { + content = this.outputFile() + '.map' + } + let eol = '\n' + if (this.css.includes('\r\n')) eol = '\r\n' + + this.css += eol + '/*# sourceMappingURL=' + content + ' */' + } + + applyPrevMaps() { + for (let prev of this.previous()) { + let from = this.toUrl(this.path(prev.file)) + let root = prev.root || dirname(prev.file) + let map + + if (this.mapOpts.sourcesContent === false) { + map = new SourceMapConsumer(prev.text) + if (map.sourcesContent) { + map.sourcesContent = null + } + } else { + map = prev.consumer() + } + + this.map.applySourceMap(map, from, this.toUrl(this.path(root))) + } + } + + clearAnnotation() { + if (this.mapOpts.annotation === false) return + + if (this.root) { + let node + for (let i = this.root.nodes.length - 1; i >= 0; i--) { + node = this.root.nodes[i] + if (node.type !== 'comment') continue + if (node.text.startsWith('# sourceMappingURL=')) { + this.root.removeChild(i) + } + } + } else if (this.css) { + let startIndex + while ((startIndex = this.css.lastIndexOf('/*#')) !== -1) { + let endIndex = this.css.indexOf('*/', startIndex + 3) + if (endIndex === -1) break + while (startIndex > 0 && this.css[startIndex - 1] === '\n') { + startIndex-- + } + this.css = this.css.slice(0, startIndex) + this.css.slice(endIndex + 2) + } + } + } + + generate() { + this.clearAnnotation() + if (pathAvailable && sourceMapAvailable && this.isMap()) { + return this.generateMap() + } else { + let result = '' + this.stringify(this.root, i => { + result += i + }) + return [result] + } + } + + generateMap() { + if (this.root) { + this.generateString() + } else if (this.previous().length === 1) { + let prev = this.previous()[0].consumer() + prev.file = this.outputFile() + this.map = SourceMapGenerator.fromSourceMap(prev, { + ignoreInvalidMapping: true + }) + } else { + this.map = new SourceMapGenerator({ + file: this.outputFile(), + ignoreInvalidMapping: true + }) + this.map.addMapping({ + generated: { column: 0, line: 1 }, + original: { column: 0, line: 1 }, + source: this.opts.from + ? this.toUrl(this.path(this.opts.from)) + : '' + }) + } + + if (this.isSourcesContent()) this.setSourcesContent() + if (this.root && this.previous().length > 0) this.applyPrevMaps() + if (this.isAnnotation()) this.addAnnotation() + + if (this.isInline()) { + return [this.css] + } else { + return [this.css, this.map] + } + } + + generateString() { + this.css = '' + this.map = new SourceMapGenerator({ + file: this.outputFile(), + ignoreInvalidMapping: true + }) + + let line = 1 + let column = 1 + + let noSource = '' + let mapping = { + generated: { column: 0, line: 0 }, + original: { column: 0, line: 0 }, + source: '' + } + + let last, lines + this.stringify(this.root, (str, node, type) => { + this.css += str + + if (node && type !== 'end') { + mapping.generated.line = line + mapping.generated.column = column - 1 + if (node.source && node.source.start) { + mapping.source = this.sourcePath(node) + mapping.original.line = node.source.start.line + mapping.original.column = node.source.start.column - 1 + this.map.addMapping(mapping) + } else { + mapping.source = noSource + mapping.original.line = 1 + mapping.original.column = 0 + this.map.addMapping(mapping) + } + } + + lines = str.match(/\n/g) + if (lines) { + line += lines.length + last = str.lastIndexOf('\n') + column = str.length - last + } else { + column += str.length + } + + if (node && type !== 'start') { + let p = node.parent || { raws: {} } + let childless = + node.type === 'decl' || (node.type === 'atrule' && !node.nodes) + if (!childless || node !== p.last || p.raws.semicolon) { + if (node.source && node.source.end) { + mapping.source = this.sourcePath(node) + mapping.original.line = node.source.end.line + mapping.original.column = node.source.end.column - 1 + mapping.generated.line = line + mapping.generated.column = column - 2 + this.map.addMapping(mapping) + } else { + mapping.source = noSource + mapping.original.line = 1 + mapping.original.column = 0 + mapping.generated.line = line + mapping.generated.column = column - 1 + this.map.addMapping(mapping) + } + } + } + }) + } + + isAnnotation() { + if (this.isInline()) { + return true + } + if (typeof this.mapOpts.annotation !== 'undefined') { + return this.mapOpts.annotation + } + if (this.previous().length) { + return this.previous().some(i => i.annotation) + } + return true + } + + isInline() { + if (typeof this.mapOpts.inline !== 'undefined') { + return this.mapOpts.inline + } + + let annotation = this.mapOpts.annotation + if (typeof annotation !== 'undefined' && annotation !== true) { + return false + } + + if (this.previous().length) { + return this.previous().some(i => i.inline) + } + return true + } + + isMap() { + if (typeof this.opts.map !== 'undefined') { + return !!this.opts.map + } + return this.previous().length > 0 + } + + isSourcesContent() { + if (typeof this.mapOpts.sourcesContent !== 'undefined') { + return this.mapOpts.sourcesContent + } + if (this.previous().length) { + return this.previous().some(i => i.withContent()) + } + return true + } + + outputFile() { + if (this.opts.to) { + return this.path(this.opts.to) + } else if (this.opts.from) { + return this.path(this.opts.from) + } else { + return 'to.css' + } + } + + path(file) { + if (this.mapOpts.absolute) return file + if (file.charCodeAt(0) === 60 /* `<` */) return file + if (/^\w+:\/\//.test(file)) return file + let cached = this.memoizedPaths.get(file) + if (cached) return cached + + let from = this.opts.to ? dirname(this.opts.to) : '.' + + if (typeof this.mapOpts.annotation === 'string') { + from = dirname(resolve(from, this.mapOpts.annotation)) + } + + let path = relative(from, file) + this.memoizedPaths.set(file, path) + + return path + } + + previous() { + if (!this.previousMaps) { + this.previousMaps = [] + if (this.root) { + this.root.walk(node => { + if (node.source && node.source.input.map) { + let map = node.source.input.map + if (!this.previousMaps.includes(map)) { + this.previousMaps.push(map) + } + } + }) + } else { + let input = new Input(this.originalCSS, this.opts) + if (input.map) this.previousMaps.push(input.map) + } + } + + return this.previousMaps + } + + setSourcesContent() { + let already = {} + if (this.root) { + this.root.walk(node => { + if (node.source) { + let from = node.source.input.from + if (from && !already[from]) { + already[from] = true + let fromUrl = this.usesFileUrls + ? this.toFileUrl(from) + : this.toUrl(this.path(from)) + this.map.setSourceContent(fromUrl, node.source.input.css) + } + } + }) + } else if (this.css) { + let from = this.opts.from + ? this.toUrl(this.path(this.opts.from)) + : '' + this.map.setSourceContent(from, this.css) + } + } + + sourcePath(node) { + if (this.mapOpts.from) { + return this.toUrl(this.mapOpts.from) + } else if (this.usesFileUrls) { + return this.toFileUrl(node.source.input.from) + } else { + return this.toUrl(this.path(node.source.input.from)) + } + } + + toBase64(str) { + if (Buffer) { + return Buffer.from(str).toString('base64') + } else { + return window.btoa(unescape(encodeURIComponent(str))) + } + } + + toFileUrl(path) { + let cached = this.memoizedFileURLs.get(path) + if (cached) return cached + + if (pathToFileURL) { + let fileURL = pathToFileURL(path).toString() + this.memoizedFileURLs.set(path, fileURL) + + return fileURL + } else { + throw new Error( + '`map.absolute` option is not available in this PostCSS build' + ) + } + } + + toUrl(path) { + let cached = this.memoizedURLs.get(path) + if (cached) return cached + + if (sep === '\\') { + path = path.replace(/\\/g, '/') + } + + let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent) + this.memoizedURLs.set(path, url) + + return url + } +} + +module.exports = MapGenerator diff --git a/node_modules/postcss/lib/no-work-result.d.ts b/node_modules/postcss/lib/no-work-result.d.ts new file mode 100644 index 0000000..fa9d284 --- /dev/null +++ b/node_modules/postcss/lib/no-work-result.d.ts @@ -0,0 +1,45 @@ +import LazyResult from './lazy-result.js' +import { SourceMap } from './postcss.js' +import Processor from './processor.js' +import Result, { Message, ResultOptions } from './result.js' +import Root from './root.js' +import Warning from './warning.js' + +declare namespace NoWorkResult { + export { NoWorkResult_ as default } +} + +/** + * A Promise proxy for the result of PostCSS transformations. + * This lazy result instance doesn't parse css unless `NoWorkResult#root` or `Result#root` + * are accessed. See the example below for details. + * A `NoWork` instance is returned by `Processor#process` ONLY when no plugins defined. + * + * ```js + * const noWorkResult = postcss().process(css) // No plugins are defined. + * // CSS is not parsed + * let root = noWorkResult.root // now css is parsed because we accessed the root + * ``` + */ +declare class NoWorkResult_ implements LazyResult { + catch: Promise>['catch'] + finally: Promise>['finally'] + then: Promise>['then'] + get content(): string + get css(): string + get map(): SourceMap + get messages(): Message[] + get opts(): ResultOptions + get processor(): Processor + get root(): Root + get [Symbol.toStringTag](): string + constructor(processor: Processor, css: string, opts: ResultOptions) + async(): Promise> + sync(): Result + toString(): string + warnings(): Warning[] +} + +declare class NoWorkResult extends NoWorkResult_ {} + +export = NoWorkResult diff --git a/node_modules/postcss/lib/no-work-result.js b/node_modules/postcss/lib/no-work-result.js new file mode 100644 index 0000000..7ec1a74 --- /dev/null +++ b/node_modules/postcss/lib/no-work-result.js @@ -0,0 +1,137 @@ +'use strict' + +let MapGenerator = require('./map-generator') +let parse = require('./parse') +let Result = require('./result') +let stringify = require('./stringify') +let warnOnce = require('./warn-once') + +class NoWorkResult { + get content() { + return this.result.css + } + + get css() { + return this.result.css + } + + get map() { + return this.result.map + } + + get messages() { + return [] + } + + get opts() { + return this.result.opts + } + + get processor() { + return this.result.processor + } + + get root() { + if (this._root) { + return this._root + } + + let root + let parser = parse + + try { + root = parser(this._css, this._opts) + } catch (error) { + this.error = error + } + + if (this.error) { + throw this.error + } else { + this._root = root + return root + } + } + + get [Symbol.toStringTag]() { + return 'NoWorkResult' + } + + constructor(processor, css, opts) { + css = css.toString() + this.stringified = false + + this._processor = processor + this._css = css + this._opts = opts + this._map = undefined + + let str = stringify + this.result = new Result(this._processor, undefined, this._opts) + this.result.css = css + + let self = this + Object.defineProperty(this.result, 'root', { + get() { + return self.root + } + }) + + let map = new MapGenerator(str, undefined, this._opts, css) + if (map.isMap()) { + let [generatedCSS, generatedMap] = map.generate() + if (generatedCSS) { + this.result.css = generatedCSS + } + if (generatedMap) { + this.result.map = generatedMap + } + } else { + map.clearAnnotation() + this.result.css = map.css + } + } + + async() { + if (this.error) return Promise.reject(this.error) + return Promise.resolve(this.result) + } + + catch(onRejected) { + return this.async().catch(onRejected) + } + + finally(onFinally) { + return this.async().then(onFinally, onFinally) + } + + sync() { + if (this.error) throw this.error + return this.result + } + + then(onFulfilled, onRejected) { + if (process.env.NODE_ENV !== 'production') { + if (!('from' in this._opts)) { + warnOnce( + 'Without `from` option PostCSS could generate wrong source map ' + + 'and will not find Browserslist config. Set it to CSS file path ' + + 'or to `undefined` to prevent this warning.' + ) + } + } + + return this.async().then(onFulfilled, onRejected) + } + + toString() { + return this._css + } + + warnings() { + return [] + } +} + +module.exports = NoWorkResult +NoWorkResult.default = NoWorkResult diff --git a/node_modules/postcss/lib/node.d.ts b/node_modules/postcss/lib/node.d.ts new file mode 100644 index 0000000..ecd86e2 --- /dev/null +++ b/node_modules/postcss/lib/node.d.ts @@ -0,0 +1,555 @@ +import AtRule = require('./at-rule.js') +import { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container, { NewChild } from './container.js' +import CssSyntaxError from './css-syntax-error.js' +import Declaration, { DeclarationProps } from './declaration.js' +import Document from './document.js' +import Input from './input.js' +import { Stringifier, Syntax } from './postcss.js' +import Result from './result.js' +import Root from './root.js' +import Rule, { RuleProps } from './rule.js' +import Warning, { WarningOptions } from './warning.js' + +declare namespace Node { + export type ChildNode = AtRule.default | Comment | Declaration | Rule + + export type AnyNode = + | AtRule.default + | Comment + | Declaration + | Document + | Root + | Rule + + export type ChildProps = + | AtRuleProps + | CommentProps + | DeclarationProps + | RuleProps + + export interface Position { + /** + * Source line in file. In contrast to `offset` it starts from 1. + */ + column: number + + /** + * Source column in file. + */ + line: number + + /** + * Source offset in file. It starts from 0. + */ + offset: number + } + + export interface Range { + /** + * End position, exclusive. + */ + end: Position + + /** + * Start position, inclusive. + */ + start: Position + } + + /** + * Source represents an interface for the {@link Node.source} property. + */ + export interface Source { + /** + * The inclusive ending position for the source + * code of a node. + * + * However, `end.offset` of a non `Root` node is the exclusive position. + * See https://github.com/postcss/postcss/pull/1879 for details. + * + * ```js + * const root = postcss.parse('a { color: black }') + * const a = root.first + * const color = a.first + * + * // The offset of `Root` node is the inclusive position + * css.source.end // { line: 1, column: 19, offset: 18 } + * + * // The offset of non `Root` node is the exclusive position + * a.source.end // { line: 1, column: 18, offset: 18 } + * color.source.end // { line: 1, column: 16, offset: 16 } + * ``` + */ + end?: Position + + /** + * The source file from where a node has originated. + */ + input: Input + + /** + * The inclusive starting position for the source + * code of a node. + */ + start?: Position + } + + /** + * Interface represents an interface for an object received + * as parameter by Node class constructor. + */ + export interface NodeProps { + source?: Source + } + + export interface NodeErrorOptions { + /** + * An ending index inside a node's string that should be highlighted as + * source of error. + */ + endIndex?: number + /** + * An index inside a node's string that should be highlighted as source + * of error. + */ + index?: number + /** + * Plugin name that created this error. PostCSS will set it automatically. + */ + plugin?: string + /** + * A word inside a node's string, that should be highlighted as source + * of error. + */ + word?: string + } + + class Node extends Node_ {} + export { Node as default } +} + +/** + * It represents an abstract class that handles common + * methods for other CSS abstract syntax tree nodes. + * + * Any node that represents CSS selector or value should + * not extend the `Node` class. + */ +declare abstract class Node_ { + /** + * It represents parent of the current node. + * + * ```js + * root.nodes[0].parent === root //=> true + * ``` + */ + parent: Container | Document | undefined + + /** + * It represents unnecessary whitespace and characters present + * in the css source code. + * + * Information to generate byte-to-byte equal node string as it was + * in the origin input. + * + * The properties of the raws object are decided by parser, + * the default parser uses the following properties: + * + * * `before`: the space symbols before the node. It also stores `*` + * and `_` symbols before the declaration (IE hack). + * * `after`: the space symbols after the last child of the node + * to the end of the node. + * * `between`: the symbols between the property and value + * for declarations, selector and `{` for rules, or last parameter + * and `{` for at-rules. + * * `semicolon`: contains true if the last child has + * an (optional) semicolon. + * * `afterName`: the space between the at-rule name and its parameters. + * * `left`: the space symbols between `/*` and the comment’s text. + * * `right`: the space symbols between the comment’s text + * and */. + * - `important`: the content of the important statement, + * if it is not just `!important`. + * + * PostCSS filters out the comments inside selectors, declaration values + * and at-rule parameters but it stores the origin content in raws. + * + * ```js + * const root = postcss.parse('a {\n color:black\n}') + * root.first.first.raws //=> { before: '\n ', between: ':' } + * ``` + */ + raws: any + + /** + * It represents information related to origin of a node and is required + * for generating source maps. + * + * The nodes that are created manually using the public APIs + * provided by PostCSS will have `source` undefined and + * will be absent in the source map. + * + * For this reason, the plugin developer should consider + * duplicating nodes as the duplicate node will have the + * same source as the original node by default or assign + * source to a node created manually. + * + * ```js + * decl.source.input.from //=> '/home/ai/source.css' + * decl.source.start //=> { line: 10, column: 2 } + * decl.source.end //=> { line: 10, column: 12 } + * ``` + * + * ```js + * // Incorrect method, source not specified! + * const prefixed = postcss.decl({ + * prop: '-moz-' + decl.prop, + * value: decl.value + * }) + * + * // Correct method, source is inherited when duplicating. + * const prefixed = decl.clone({ + * prop: '-moz-' + decl.prop + * }) + * ``` + * + * ```js + * if (atrule.name === 'add-link') { + * const rule = postcss.rule({ + * selector: 'a', + * source: atrule.source + * }) + * + * atrule.parent.insertBefore(atrule, rule) + * } + * ``` + */ + source?: Node.Source + + /** + * It represents type of a node in + * an abstract syntax tree. + * + * A type of node helps in identification of a node + * and perform operation based on it's type. + * + * ```js + * const declaration = new Declaration({ + * prop: 'color', + * value: 'black' + * }) + * + * declaration.type //=> 'decl' + * ``` + */ + type: string + + constructor(defaults?: object) + + /** + * Insert new node after current node to current node’s parent. + * + * Just alias for `node.parent.insertAfter(node, add)`. + * + * ```js + * decl.after('color: black') + * ``` + * + * @param newNode New node. + * @return This node for methods chain. + */ + after( + newNode: Node | Node.ChildProps | readonly Node[] | string | undefined + ): this + + /** + * It assigns properties to an existing node instance. + * + * ```js + * decl.assign({ prop: 'word-wrap', value: 'break-word' }) + * ``` + * + * @param overrides New properties to override the node. + * + * @return `this` for method chaining. + */ + assign(overrides: object): this + + /** + * Insert new node before current node to current node’s parent. + * + * Just alias for `node.parent.insertBefore(node, add)`. + * + * ```js + * decl.before('content: ""') + * ``` + * + * @param newNode New node. + * @return This node for methods chain. + */ + before( + newNode: Node | Node.ChildProps | readonly Node[] | string | undefined + ): this + + /** + * Clear the code style properties for the node and its children. + * + * ```js + * node.raws.before //=> ' ' + * node.cleanRaws() + * node.raws.before //=> undefined + * ``` + * + * @param keepBetween Keep the `raws.between` symbols. + */ + cleanRaws(keepBetween?: boolean): void + + /** + * It creates clone of an existing node, which includes all the properties + * and their values, that includes `raws` but not `type`. + * + * ```js + * decl.raws.before //=> "\n " + * const cloned = decl.clone({ prop: '-moz-' + decl.prop }) + * cloned.raws.before //=> "\n " + * cloned.toString() //=> -moz-transform: scale(0) + * ``` + * + * @param overrides New properties to override in the clone. + * + * @return Duplicate of the node instance. + */ + clone(overrides?: object): this + + /** + * Shortcut to clone the node and insert the resulting cloned node + * after the current node. + * + * @param overrides New properties to override in the clone. + * @return New node. + */ + cloneAfter(overrides?: object): this + + /** + * Shortcut to clone the node and insert the resulting cloned node + * before the current node. + * + * ```js + * decl.cloneBefore({ prop: '-moz-' + decl.prop }) + * ``` + * + * @param overrides Mew properties to override in the clone. + * + * @return New node + */ + cloneBefore(overrides?: object): this + + /** + * It creates an instance of the class `CssSyntaxError` and parameters passed + * to this method are assigned to the error instance. + * + * The error instance will have description for the + * error, original position of the node in the + * source, showing line and column number. + * + * If any previous map is present, it would be used + * to get original position of the source. + * + * The Previous Map here is referred to the source map + * generated by previous compilation, example: Less, + * Stylus and Sass. + * + * This method returns the error instance instead of + * throwing it. + * + * ```js + * if (!variables[name]) { + * throw decl.error(`Unknown variable ${name}`, { word: name }) + * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black + * // color: $black + * // a + * // ^ + * // background: white + * } + * ``` + * + * @param message Description for the error instance. + * @param options Options for the error instance. + * + * @return Error instance is returned. + */ + error(message: string, options?: Node.NodeErrorOptions): CssSyntaxError + + /** + * Returns the next child of the node’s parent. + * Returns `undefined` if the current node is the last child. + * + * ```js + * if (comment.text === 'delete next') { + * const next = comment.next() + * if (next) { + * next.remove() + * } + * } + * ``` + * + * @return Next node. + */ + next(): Node.ChildNode | undefined + + /** + * Get the position for a word or an index inside the node. + * + * @param opts Options. + * @return Position. + */ + positionBy(opts?: Pick): Node.Position + + /** + * Convert string index to line/column. + * + * @param index The symbol number in the node’s string. + * @return Symbol position in file. + */ + positionInside(index: number): Node.Position + + /** + * Returns the previous child of the node’s parent. + * Returns `undefined` if the current node is the first child. + * + * ```js + * const annotation = decl.prev() + * if (annotation.type === 'comment') { + * readAnnotation(annotation.text) + * } + * ``` + * + * @return Previous node. + */ + prev(): Node.ChildNode | undefined + + /** + * Get the range for a word or start and end index inside the node. + * The start index is inclusive; the end index is exclusive. + * + * @param opts Options. + * @return Range. + */ + rangeBy( + opts?: Pick + ): Node.Range + + /** + * Returns a `raws` value. If the node is missing + * the code style property (because the node was manually built or cloned), + * PostCSS will try to autodetect the code style property by looking + * at other nodes in the tree. + * + * ```js + * const root = postcss.parse('a { background: white }') + * root.nodes[0].append({ prop: 'color', value: 'black' }) + * root.nodes[0].nodes[1].raws.before //=> undefined + * root.nodes[0].nodes[1].raw('before') //=> ' ' + * ``` + * + * @param prop Name of code style property. + * @param defaultType Name of default value, it can be missed + * if the value is the same as prop. + * @return {string} Code style value. + */ + raw(prop: string, defaultType?: string): string + + /** + * It removes the node from its parent and deletes its parent property. + * + * ```js + * if (decl.prop.match(/^-webkit-/)) { + * decl.remove() + * } + * ``` + * + * @return `this` for method chaining. + */ + remove(): this + + /** + * Inserts node(s) before the current node and removes the current node. + * + * ```js + * AtRule: { + * mixin: atrule => { + * atrule.replaceWith(mixinRules[atrule.params]) + * } + * } + * ``` + * + * @param nodes Mode(s) to replace current one. + * @return Current node to methods chain. + */ + replaceWith(...nodes: NewChild[]): this + + /** + * Finds the Root instance of the node’s tree. + * + * ```js + * root.nodes[0].nodes[0].root() === root + * ``` + * + * @return Root parent. + */ + root(): Root + + /** + * Fix circular links on `JSON.stringify()`. + * + * @return Cleaned object. + */ + toJSON(): object + + /** + * It compiles the node to browser readable cascading style sheets string + * depending on it's type. + * + * ```js + * new Rule({ selector: 'a' }).toString() //=> "a {}" + * ``` + * + * @param stringifier A syntax to use in string generation. + * @return CSS string of this node. + */ + toString(stringifier?: Stringifier | Syntax): string + + /** + * It is a wrapper for {@link Result#warn}, providing convenient + * way of generating warnings. + * + * ```js + * Declaration: { + * bad: (decl, { result }) => { + * decl.warn(result, 'Deprecated property: bad') + * } + * } + * ``` + * + * @param result The `Result` instance that will receive the warning. + * @param message Description for the warning. + * @param options Options for the warning. + * + * @return `Warning` instance is returned + */ + warn(result: Result, message: string, options?: WarningOptions): Warning + + /** + * If this node isn't already dirty, marks it and its ancestors as such. This + * indicates to the LazyResult processor that the {@link Root} has been + * modified by the current plugin and may need to be processed again by other + * plugins. + */ + protected markDirty(): void +} + +declare class Node extends Node_ {} + +export = Node diff --git a/node_modules/postcss/lib/node.js b/node_modules/postcss/lib/node.js new file mode 100644 index 0000000..b403b71 --- /dev/null +++ b/node_modules/postcss/lib/node.js @@ -0,0 +1,449 @@ +'use strict' + +let CssSyntaxError = require('./css-syntax-error') +let Stringifier = require('./stringifier') +let stringify = require('./stringify') +let { isClean, my } = require('./symbols') + +function cloneNode(obj, parent) { + let cloned = new obj.constructor() + + for (let i in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, i)) { + /* c8 ignore next 2 */ + continue + } + if (i === 'proxyCache') continue + let value = obj[i] + let type = typeof value + + if (i === 'parent' && type === 'object') { + if (parent) cloned[i] = parent + } else if (i === 'source') { + cloned[i] = value + } else if (Array.isArray(value)) { + cloned[i] = value.map(j => cloneNode(j, cloned)) + } else { + if (type === 'object' && value !== null) value = cloneNode(value) + cloned[i] = value + } + } + + return cloned +} + +function sourceOffset(inputCSS, position) { + // Not all custom syntaxes support `offset` in `source.start` and `source.end` + if (position && typeof position.offset !== 'undefined') { + return position.offset + } + + let column = 1 + let line = 1 + let offset = 0 + + for (let i = 0; i < inputCSS.length; i++) { + if (line === position.line && column === position.column) { + offset = i + break + } + + if (inputCSS[i] === '\n') { + column = 1 + line += 1 + } else { + column += 1 + } + } + + return offset +} + +class Node { + get proxyOf() { + return this + } + + constructor(defaults = {}) { + this.raws = {} + this[isClean] = false + this[my] = true + + for (let name in defaults) { + if (name === 'nodes') { + this.nodes = [] + for (let node of defaults[name]) { + if (typeof node.clone === 'function') { + this.append(node.clone()) + } else { + this.append(node) + } + } + } else { + this[name] = defaults[name] + } + } + } + + addToError(error) { + error.postcssNode = this + if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { + let s = this.source + error.stack = error.stack.replace( + /\n\s{4}at /, + `$&${s.input.from}:${s.start.line}:${s.start.column}$&` + ) + } + return error + } + + after(add) { + this.parent.insertAfter(this, add) + return this + } + + assign(overrides = {}) { + for (let name in overrides) { + this[name] = overrides[name] + } + return this + } + + before(add) { + this.parent.insertBefore(this, add) + return this + } + + cleanRaws(keepBetween) { + delete this.raws.before + delete this.raws.after + if (!keepBetween) delete this.raws.between + } + + clone(overrides = {}) { + let cloned = cloneNode(this) + for (let name in overrides) { + cloned[name] = overrides[name] + } + return cloned + } + + cloneAfter(overrides = {}) { + let cloned = this.clone(overrides) + this.parent.insertAfter(this, cloned) + return cloned + } + + cloneBefore(overrides = {}) { + let cloned = this.clone(overrides) + this.parent.insertBefore(this, cloned) + return cloned + } + + error(message, opts = {}) { + if (this.source) { + let { end, start } = this.rangeBy(opts) + return this.source.input.error( + message, + { column: start.column, line: start.line }, + { column: end.column, line: end.line }, + opts + ) + } + return new CssSyntaxError(message) + } + + getProxyProcessor() { + return { + get(node, prop) { + if (prop === 'proxyOf') { + return node + } else if (prop === 'root') { + return () => node.root().toProxy() + } else { + return node[prop] + } + }, + + set(node, prop, value) { + if (node[prop] === value) return true + node[prop] = value + if ( + prop === 'prop' || + prop === 'value' || + prop === 'name' || + prop === 'params' || + prop === 'important' || + /* c8 ignore next */ + prop === 'text' + ) { + node.markDirty() + } + return true + } + } + } + + /* c8 ignore next 3 */ + markClean() { + this[isClean] = true + } + + markDirty() { + if (this[isClean]) { + this[isClean] = false + let next = this + while ((next = next.parent)) { + next[isClean] = false + } + } + } + + next() { + if (!this.parent) return undefined + let index = this.parent.index(this) + return this.parent.nodes[index + 1] + } + + positionBy(opts = {}) { + let pos = this.source.start + if (opts.index) { + pos = this.positionInside(opts.index) + } else if (opts.word) { + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let stringRepresentation = inputString.slice( + sourceOffset(inputString, this.source.start), + sourceOffset(inputString, this.source.end) + ) + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) pos = this.positionInside(index) + } + return pos + } + + positionInside(index) { + let column = this.source.start.column + let line = this.source.start.line + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let offset = sourceOffset(inputString, this.source.start) + let end = offset + index + + for (let i = offset; i < end; i++) { + if (inputString[i] === '\n') { + column = 1 + line += 1 + } else { + column += 1 + } + } + + return { column, line, offset: end } + } + + prev() { + if (!this.parent) return undefined + let index = this.parent.index(this) + return this.parent.nodes[index - 1] + } + + rangeBy(opts = {}) { + let inputString = + 'document' in this.source.input + ? this.source.input.document + : this.source.input.css + let start = { + column: this.source.start.column, + line: this.source.start.line, + offset: sourceOffset(inputString, this.source.start) + } + let end = this.source.end + ? { + column: this.source.end.column + 1, + line: this.source.end.line, + offset: + typeof this.source.end.offset === 'number' + ? // `source.end.offset` is exclusive, so we don't need to add 1 + this.source.end.offset + : // Since line/column in this.source.end is inclusive, + // the `sourceOffset(... , this.source.end)` returns an inclusive offset. + // So, we add 1 to convert it to exclusive. + sourceOffset(inputString, this.source.end) + 1 + } + : { + column: start.column + 1, + line: start.line, + offset: start.offset + 1 + } + + if (opts.word) { + let stringRepresentation = inputString.slice( + sourceOffset(inputString, this.source.start), + sourceOffset(inputString, this.source.end) + ) + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) { + start = this.positionInside(index) + end = this.positionInside(index + opts.word.length) + } + } else { + if (opts.start) { + start = { + column: opts.start.column, + line: opts.start.line, + offset: sourceOffset(inputString, opts.start) + } + } else if (opts.index) { + start = this.positionInside(opts.index) + } + + if (opts.end) { + end = { + column: opts.end.column, + line: opts.end.line, + offset: sourceOffset(inputString, opts.end) + } + } else if (typeof opts.endIndex === 'number') { + end = this.positionInside(opts.endIndex) + } else if (opts.index) { + end = this.positionInside(opts.index + 1) + } + } + + if ( + end.line < start.line || + (end.line === start.line && end.column <= start.column) + ) { + end = { + column: start.column + 1, + line: start.line, + offset: start.offset + 1 + } + } + + return { end, start } + } + + raw(prop, defaultType) { + let str = new Stringifier() + return str.raw(this, prop, defaultType) + } + + remove() { + if (this.parent) { + this.parent.removeChild(this) + } + this.parent = undefined + return this + } + + replaceWith(...nodes) { + if (this.parent) { + let bookmark = this + let foundSelf = false + for (let node of nodes) { + if (node === this) { + foundSelf = true + } else if (foundSelf) { + this.parent.insertAfter(bookmark, node) + bookmark = node + } else { + this.parent.insertBefore(bookmark, node) + } + } + + if (!foundSelf) { + this.remove() + } + } + + return this + } + + root() { + let result = this + while (result.parent && result.parent.type !== 'document') { + result = result.parent + } + return result + } + + toJSON(_, inputs) { + let fixed = {} + let emitInputs = inputs == null + inputs = inputs || new Map() + let inputsNextIndex = 0 + + for (let name in this) { + if (!Object.prototype.hasOwnProperty.call(this, name)) { + /* c8 ignore next 2 */ + continue + } + if (name === 'parent' || name === 'proxyCache') continue + let value = this[name] + + if (Array.isArray(value)) { + fixed[name] = value.map(i => { + if (typeof i === 'object' && i.toJSON) { + return i.toJSON(null, inputs) + } else { + return i + } + }) + } else if (typeof value === 'object' && value.toJSON) { + fixed[name] = value.toJSON(null, inputs) + } else if (name === 'source') { + if (value == null) continue + let inputId = inputs.get(value.input) + if (inputId == null) { + inputId = inputsNextIndex + inputs.set(value.input, inputsNextIndex) + inputsNextIndex++ + } + fixed[name] = { + end: value.end, + inputId, + start: value.start + } + } else { + fixed[name] = value + } + } + + if (emitInputs) { + fixed.inputs = [...inputs.keys()].map(input => input.toJSON()) + } + + return fixed + } + + toProxy() { + if (!this.proxyCache) { + this.proxyCache = new Proxy(this, this.getProxyProcessor()) + } + return this.proxyCache + } + + toString(stringifier = stringify) { + if (stringifier.stringify) stringifier = stringifier.stringify + let result = '' + stringifier(this, i => { + result += i + }) + return result + } + + warn(result, text, opts = {}) { + let data = { node: this } + for (let i in opts) data[i] = opts[i] + return result.warn(text, data) + } +} + +module.exports = Node +Node.default = Node diff --git a/node_modules/postcss/lib/parse.d.ts b/node_modules/postcss/lib/parse.d.ts new file mode 100644 index 0000000..ffe35b4 --- /dev/null +++ b/node_modules/postcss/lib/parse.d.ts @@ -0,0 +1,9 @@ +import { Parser } from './postcss.js' + +interface Parse extends Parser { + default: Parse +} + +declare let parse: Parse + +export = parse diff --git a/node_modules/postcss/lib/parse.js b/node_modules/postcss/lib/parse.js new file mode 100644 index 0000000..00a1037 --- /dev/null +++ b/node_modules/postcss/lib/parse.js @@ -0,0 +1,42 @@ +'use strict' + +let Container = require('./container') +let Input = require('./input') +let Parser = require('./parser') + +function parse(css, opts) { + let input = new Input(css, opts) + let parser = new Parser(input) + try { + parser.parse() + } catch (e) { + if (process.env.NODE_ENV !== 'production') { + if (e.name === 'CssSyntaxError' && opts && opts.from) { + if (/\.scss$/i.test(opts.from)) { + e.message += + '\nYou tried to parse SCSS with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-scss parser' + } else if (/\.sass/i.test(opts.from)) { + e.message += + '\nYou tried to parse Sass with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-sass parser' + } else if (/\.less$/i.test(opts.from)) { + e.message += + '\nYou tried to parse Less with ' + + 'the standard CSS parser; ' + + 'try again with the postcss-less parser' + } + } + } + throw e + } + + return parser.root +} + +module.exports = parse +parse.default = parse + +Container.registerParse(parse) diff --git a/node_modules/postcss/lib/parser.js b/node_modules/postcss/lib/parser.js new file mode 100644 index 0000000..2a16584 --- /dev/null +++ b/node_modules/postcss/lib/parser.js @@ -0,0 +1,618 @@ +'use strict' + +let AtRule = require('./at-rule') +let Comment = require('./comment') +let Declaration = require('./declaration') +let Root = require('./root') +let Rule = require('./rule') +let tokenizer = require('./tokenize') + +const SAFE_COMMENT_NEIGHBOR = { + empty: true, + space: true +} + +function findLastWithPosition(tokens) { + for (let i = tokens.length - 1; i >= 0; i--) { + let token = tokens[i] + let pos = token[3] || token[2] + if (pos) return pos + } +} + +function tokensToString(tokens, from, to) { + let result = '' + for (let i = from; i < to; i++) result += tokens[i][1] + return result +} + +class Parser { + constructor(input) { + this.input = input + + this.root = new Root() + this.current = this.root + this.spaces = '' + this.semicolon = false + + this.createTokenizer() + this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } + } + + atrule(token) { + let node = new AtRule() + node.name = token[1].slice(1) + if (node.name === '') { + this.unnamedAtrule(node, token) + } + this.init(node, token[2]) + + let type + let prev + let shift + let last = false + let open = false + let params = [] + let brackets = [] + + while (!this.tokenizer.endOfFile()) { + token = this.tokenizer.nextToken() + type = token[0] + + if (type === '(' || type === '[') { + brackets.push(type === '(' ? ')' : ']') + } else if (type === '{' && brackets.length > 0) { + brackets.push('}') + } else if (type === brackets[brackets.length - 1]) { + brackets.pop() + } + + if (brackets.length === 0) { + if (type === ';') { + node.source.end = this.getPosition(token[2]) + node.source.end.offset++ + this.semicolon = true + break + } else if (type === '{') { + open = true + break + } else if (type === '}') { + if (params.length > 0) { + shift = params.length - 1 + prev = params[shift] + while (prev && prev[0] === 'space') { + prev = params[--shift] + } + if (prev) { + node.source.end = this.getPosition(prev[3] || prev[2]) + node.source.end.offset++ + } + } + this.end(token) + break + } else { + params.push(token) + } + } else { + params.push(token) + } + + if (this.tokenizer.endOfFile()) { + last = true + break + } + } + + node.raws.between = this.spacesAndCommentsFromEnd(params) + if (params.length) { + node.raws.afterName = this.spacesAndCommentsFromStart(params) + this.raw(node, 'params', params) + if (last) { + token = params[params.length - 1] + node.source.end = this.getPosition(token[3] || token[2]) + node.source.end.offset++ + this.spaces = node.raws.between + node.raws.between = '' + } + } else { + node.raws.afterName = '' + node.params = '' + } + + if (open) { + node.nodes = [] + this.current = node + } + } + + checkMissedSemicolon(tokens) { + let colon = this.colon(tokens) + if (colon === false) return + + let founded = 0 + let token + for (let j = colon - 1; j >= 0; j--) { + token = tokens[j] + if (token[0] !== 'space') { + founded += 1 + if (founded === 2) break + } + } + // If the token is a word, e.g. `!important`, `red` or any other valid + // property's value. Then we need to return the colon after that word + // token. [3] is the "end" colon of that word. And because we need it + // after that one we do +1 to get the next one. + throw this.input.error( + 'Missed semicolon', + token[0] === 'word' ? token[3] + 1 : token[2] + ) + } + + colon(tokens) { + let brackets = 0 + let prev, token, type + for (let [i, element] of tokens.entries()) { + token = element + type = token[0] + + if (type === '(') { + brackets += 1 + } + if (type === ')') { + brackets -= 1 + } + if (brackets === 0 && type === ':') { + if (!prev) { + this.doubleColon(token) + } else if (prev[0] === 'word' && prev[1] === 'progid') { + continue + } else { + return i + } + } + + prev = token + } + return false + } + + comment(token) { + let node = new Comment() + this.init(node, token[2]) + node.source.end = this.getPosition(token[3] || token[2]) + node.source.end.offset++ + + let text = token[1].slice(2, -2) + if (!text.trim()) { + node.text = '' + node.raws.left = text + node.raws.right = '' + } else { + let match = text.match(/^(\s*)([^]*\S)(\s*)$/) + node.text = match[2] + node.raws.left = match[1] + node.raws.right = match[3] + } + } + + createTokenizer() { + this.tokenizer = tokenizer(this.input) + } + + decl(tokens, customProperty) { + let node = new Declaration() + this.init(node, tokens[0][2]) + + let last = tokens[tokens.length - 1] + if (last[0] === ';') { + this.semicolon = true + tokens.pop() + } + + node.source.end = this.getPosition( + last[3] || last[2] || findLastWithPosition(tokens) + ) + node.source.end.offset++ + + let start = 0 + while (tokens[start][0] !== 'word') { + if (start === tokens.length - 1) this.unknownWord([tokens[start]]) + start++ + } + node.raws.before += tokensToString(tokens, 0, start) + node.source.start = this.getPosition(tokens[start][2]) + + let propStart = start + while (start < tokens.length) { + let type = tokens[start][0] + if (type === ':' || type === 'space' || type === 'comment') { + break + } + start++ + } + node.prop = tokensToString(tokens, propStart, start) + + let betweenStart = start + let token + while (start < tokens.length) { + token = tokens[start] + start++ + if (token[0] === ':') break + if (token[0] === 'word' && /\w/.test(token[1])) { + this.unknownWord([token]) + } + } + node.raws.between = tokensToString(tokens, betweenStart, start) + + if (node.prop[0] === '_' || node.prop[0] === '*') { + node.raws.before += node.prop[0] + node.prop = node.prop.slice(1) + } + + let firstSpacesStart = start + while (start < tokens.length) { + let next = tokens[start][0] + if (next !== 'space' && next !== 'comment') break + start++ + } + let firstSpaces = tokens.slice(firstSpacesStart, start) + + tokens = tokens.slice(start) + + this.precheckMissedSemicolon(tokens) + + for (let i = tokens.length - 1; i >= 0; i--) { + token = tokens[i] + if (token[1].toLowerCase() === '!important') { + node.important = true + let string = this.stringFrom(tokens, i) + string = this.spacesFromEnd(tokens) + string + if (string !== ' !important') node.raws.important = string + break + } else if (token[1].toLowerCase() === 'important') { + let cache = tokens.slice(0) + let str = '' + for (let j = i; j > 0; j--) { + let type = cache[j][0] + if (str.trim().startsWith('!') && type !== 'space') { + break + } + str = cache.pop()[1] + str + } + if (str.trim().startsWith('!')) { + node.important = true + node.raws.important = str + tokens = cache + } + } + + if (token[0] !== 'space' && token[0] !== 'comment') { + break + } + } + + let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') + + if (hasWord) { + node.raws.between += firstSpaces.map(i => i[1]).join('') + firstSpaces = [] + } + this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) + + if (node.value.includes(':') && !customProperty) { + this.checkMissedSemicolon(tokens) + } + } + + doubleColon(token) { + throw this.input.error( + 'Double colon', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) + } + + emptyRule(token) { + let node = new Rule() + this.init(node, token[2]) + node.selector = '' + node.raws.between = '' + this.current = node + } + + end(token) { + if (this.current.nodes && this.current.nodes.length) { + this.current.raws.semicolon = this.semicolon + } + this.semicolon = false + + this.current.raws.after = (this.current.raws.after || '') + this.spaces + this.spaces = '' + + if (this.current.parent) { + this.current.source.end = this.getPosition(token[2]) + this.current.source.end.offset++ + this.current = this.current.parent + } else { + this.unexpectedClose(token) + } + } + + endFile() { + if (this.current.parent) this.unclosedBlock() + if (this.current.nodes && this.current.nodes.length) { + this.current.raws.semicolon = this.semicolon + } + this.current.raws.after = (this.current.raws.after || '') + this.spaces + this.root.source.end = this.getPosition(this.tokenizer.position()) + } + + freeSemicolon(token) { + this.spaces += token[1] + if (this.current.nodes) { + let prev = this.current.nodes[this.current.nodes.length - 1] + if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { + prev.raws.ownSemicolon = this.spaces + this.spaces = '' + prev.source.end = this.getPosition(token[2]) + prev.source.end.offset += prev.raws.ownSemicolon.length + } + } + } + + // Helpers + + getPosition(offset) { + let pos = this.input.fromOffset(offset) + return { + column: pos.col, + line: pos.line, + offset + } + } + + init(node, offset) { + this.current.push(node) + node.source = { + input: this.input, + start: this.getPosition(offset) + } + node.raws.before = this.spaces + this.spaces = '' + if (node.type !== 'comment') this.semicolon = false + } + + other(start) { + let end = false + let type = null + let colon = false + let bracket = null + let brackets = [] + let customProperty = start[1].startsWith('--') + + let tokens = [] + let token = start + while (token) { + type = token[0] + tokens.push(token) + + if (type === '(' || type === '[') { + if (!bracket) bracket = token + brackets.push(type === '(' ? ')' : ']') + } else if (customProperty && colon && type === '{') { + if (!bracket) bracket = token + brackets.push('}') + } else if (brackets.length === 0) { + if (type === ';') { + if (colon) { + this.decl(tokens, customProperty) + return + } else { + break + } + } else if (type === '{') { + this.rule(tokens) + return + } else if (type === '}') { + this.tokenizer.back(tokens.pop()) + end = true + break + } else if (type === ':') { + colon = true + } + } else if (type === brackets[brackets.length - 1]) { + brackets.pop() + if (brackets.length === 0) bracket = null + } + + token = this.tokenizer.nextToken() + } + + if (this.tokenizer.endOfFile()) end = true + if (brackets.length > 0) this.unclosedBracket(bracket) + + if (end && colon) { + if (!customProperty) { + while (tokens.length) { + token = tokens[tokens.length - 1][0] + if (token !== 'space' && token !== 'comment') break + this.tokenizer.back(tokens.pop()) + } + } + this.decl(tokens, customProperty) + } else { + this.unknownWord(tokens) + } + } + + parse() { + let token + while (!this.tokenizer.endOfFile()) { + token = this.tokenizer.nextToken() + + switch (token[0]) { + case 'space': + this.spaces += token[1] + break + + case ';': + this.freeSemicolon(token) + break + + case '}': + this.end(token) + break + + case 'comment': + this.comment(token) + break + + case 'at-word': + this.atrule(token) + break + + case '{': + this.emptyRule(token) + break + + default: + this.other(token) + break + } + } + this.endFile() + } + + precheckMissedSemicolon(/* tokens */) { + // Hook for Safe Parser + } + + raw(node, prop, tokens, customProperty) { + let token, type + let length = tokens.length + let value = '' + let clean = true + let next, prev + + for (let i = 0; i < length; i += 1) { + token = tokens[i] + type = token[0] + if (type === 'space' && i === length - 1 && !customProperty) { + clean = false + } else if (type === 'comment') { + prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty' + next = tokens[i + 1] ? tokens[i + 1][0] : 'empty' + if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { + if (value.slice(-1) === ',') { + clean = false + } else { + value += token[1] + } + } else { + clean = false + } + } else { + value += token[1] + } + } + if (!clean) { + let raw = tokens.reduce((all, i) => all + i[1], '') + node.raws[prop] = { raw, value } + } + node[prop] = value + } + + rule(tokens) { + tokens.pop() + + let node = new Rule() + this.init(node, tokens[0][2]) + + node.raws.between = this.spacesAndCommentsFromEnd(tokens) + this.raw(node, 'selector', tokens) + this.current = node + } + + spacesAndCommentsFromEnd(tokens) { + let lastTokenType + let spaces = '' + while (tokens.length) { + lastTokenType = tokens[tokens.length - 1][0] + if (lastTokenType !== 'space' && lastTokenType !== 'comment') break + spaces = tokens.pop()[1] + spaces + } + return spaces + } + + // Errors + + spacesAndCommentsFromStart(tokens) { + let next + let spaces = '' + while (tokens.length) { + next = tokens[0][0] + if (next !== 'space' && next !== 'comment') break + spaces += tokens.shift()[1] + } + return spaces + } + + spacesFromEnd(tokens) { + let lastTokenType + let spaces = '' + while (tokens.length) { + lastTokenType = tokens[tokens.length - 1][0] + if (lastTokenType !== 'space') break + spaces = tokens.pop()[1] + spaces + } + return spaces + } + + stringFrom(tokens, from) { + let result = '' + for (let i = from; i < tokens.length; i++) { + result += tokens[i][1] + } + tokens.splice(from, tokens.length - from) + return result + } + + unclosedBlock() { + let pos = this.current.source.start + throw this.input.error('Unclosed block', pos.line, pos.column) + } + + unclosedBracket(bracket) { + throw this.input.error( + 'Unclosed bracket', + { offset: bracket[2] }, + { offset: bracket[2] + 1 } + ) + } + + unexpectedClose(token) { + throw this.input.error( + 'Unexpected }', + { offset: token[2] }, + { offset: token[2] + 1 } + ) + } + + unknownWord(tokens) { + throw this.input.error( + 'Unknown word ' + tokens[0][1], + { offset: tokens[0][2] }, + { offset: tokens[0][2] + tokens[0][1].length } + ) + } + + unnamedAtrule(node, token) { + throw this.input.error( + 'At-rule without name', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) + } +} + +module.exports = Parser diff --git a/node_modules/postcss/lib/postcss.d.mts b/node_modules/postcss/lib/postcss.d.mts new file mode 100644 index 0000000..eaec868 --- /dev/null +++ b/node_modules/postcss/lib/postcss.d.mts @@ -0,0 +1,66 @@ +export { + // Type-only exports + AcceptedPlugin, + AnyNode, + atRule, + AtRule, + AtRuleProps, + Builder, + ChildNode, + ChildProps, + comment, + Comment, + CommentProps, + Container, + ContainerProps, + CssSyntaxError, + decl, + Declaration, + DeclarationProps, + // postcss function / namespace + default, + document, + Document, + DocumentProps, + FilePosition, + fromJSON, + Helpers, + Input, + JSONHydrator, + // This is a class, but it’s not re-exported. That’s why it’s exported as type-only here. + type LazyResult, + list, + Message, + Node, + NodeErrorOptions, + NodeProps, + OldPlugin, + parse, + Parser, + // @ts-expect-error This value exists, but it’s untyped. + plugin, + Plugin, + PluginCreator, + Position, + Postcss, + ProcessOptions, + Processor, + Result, + root, + Root, + RootProps, + rule, + Rule, + RuleProps, + Source, + SourceMap, + SourceMapOptions, + Stringifier, + // Value exports from postcss.mjs + stringify, + Syntax, + TransformCallback, + Transformer, + Warning, + WarningOptions +} from './postcss.js' diff --git a/node_modules/postcss/lib/postcss.d.ts b/node_modules/postcss/lib/postcss.d.ts new file mode 100644 index 0000000..667d820 --- /dev/null +++ b/node_modules/postcss/lib/postcss.d.ts @@ -0,0 +1,461 @@ +import { RawSourceMap, SourceMapGenerator } from 'source-map-js' + +import AtRule, { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container, { ContainerProps, NewChild } from './container.js' +import CssSyntaxError from './css-syntax-error.js' +import Declaration, { DeclarationProps } from './declaration.js' +import Document, { DocumentProps } from './document.js' +import Input, { FilePosition } from './input.js' +import LazyResult from './lazy-result.js' +import list from './list.js' +import Node, { + AnyNode, + ChildNode, + ChildProps, + NodeErrorOptions, + NodeProps, + Position, + Source +} from './node.js' +import Processor from './processor.js' +import Result, { Message } from './result.js' +import Root, { RootProps } from './root.js' +import Rule, { RuleProps } from './rule.js' +import Warning, { WarningOptions } from './warning.js' + +type DocumentProcessor = ( + document: Document, + helper: postcss.Helpers +) => Promise | void +type RootProcessor = ( + root: Root, + helper: postcss.Helpers +) => Promise | void +type DeclarationProcessor = ( + decl: Declaration, + helper: postcss.Helpers +) => Promise | void +type RuleProcessor = ( + rule: Rule, + helper: postcss.Helpers +) => Promise | void +type AtRuleProcessor = ( + atRule: AtRule, + helper: postcss.Helpers +) => Promise | void +type CommentProcessor = ( + comment: Comment, + helper: postcss.Helpers +) => Promise | void + +interface Processors { + /** + * Will be called on all`AtRule` nodes. + * + * Will be called again on node or children changes. + */ + AtRule?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + + /** + * Will be called on all `AtRule` nodes, when all children will be processed. + * + * Will be called again on node or children changes. + */ + AtRuleExit?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + + /** + * Will be called on all `Comment` nodes. + * + * Will be called again on node or children changes. + */ + Comment?: CommentProcessor + + /** + * Will be called on all `Comment` nodes after listeners + * for `Comment` event. + * + * Will be called again on node or children changes. + */ + CommentExit?: CommentProcessor + + /** + * Will be called on all `Declaration` nodes after listeners + * for `Declaration` event. + * + * Will be called again on node or children changes. + */ + Declaration?: { [prop: string]: DeclarationProcessor } | DeclarationProcessor + + /** + * Will be called on all `Declaration` nodes. + * + * Will be called again on node or children changes. + */ + DeclarationExit?: + | { [prop: string]: DeclarationProcessor } + | DeclarationProcessor + + /** + * Will be called on `Document` node. + * + * Will be called again on children changes. + */ + Document?: DocumentProcessor + + /** + * Will be called on `Document` node, when all children will be processed. + * + * Will be called again on children changes. + */ + DocumentExit?: DocumentProcessor + + /** + * Will be called on `Root` node once. + */ + Once?: RootProcessor + + /** + * Will be called on `Root` node once, when all children will be processed. + */ + OnceExit?: RootProcessor + + /** + * Will be called on `Root` node. + * + * Will be called again on children changes. + */ + Root?: RootProcessor + + /** + * Will be called on `Root` node, when all children will be processed. + * + * Will be called again on children changes. + */ + RootExit?: RootProcessor + + /** + * Will be called on all `Rule` nodes. + * + * Will be called again on node or children changes. + */ + Rule?: RuleProcessor + + /** + * Will be called on all `Rule` nodes, when all children will be processed. + * + * Will be called again on node or children changes. + */ + RuleExit?: RuleProcessor +} + +declare namespace postcss { + export { + AnyNode, + AtRule, + AtRuleProps, + ChildNode, + ChildProps, + Comment, + CommentProps, + Container, + ContainerProps, + CssSyntaxError, + Declaration, + DeclarationProps, + Document, + DocumentProps, + FilePosition, + Input, + LazyResult, + list, + Message, + NewChild, + Node, + NodeErrorOptions, + NodeProps, + Position, + Processor, + Result, + Root, + RootProps, + Rule, + RuleProps, + Source, + Warning, + WarningOptions + } + + export type SourceMap = { + toJSON(): RawSourceMap + } & SourceMapGenerator + + export type Helpers = { postcss: Postcss; result: Result } & Postcss + + export interface Plugin extends Processors { + postcssPlugin: string + prepare?: (result: Result) => Processors + } + + export interface PluginCreator { + (opts?: PluginOptions): Plugin | Processor + postcss: true + } + + export interface Transformer extends TransformCallback { + postcssPlugin: string + postcssVersion: string + } + + export interface TransformCallback { + (root: Root, result: Result): Promise | void + } + + export interface OldPlugin extends Transformer { + (opts?: T): Transformer + postcss: Transformer + } + + export type AcceptedPlugin = + | { + postcss: Processor | TransformCallback + } + | OldPlugin + | Plugin + | PluginCreator + | Processor + | TransformCallback + + export interface Parser { + ( + css: { toString(): string } | string, + opts?: Pick + ): RootNode + } + + export interface Builder { + (part: string, node?: AnyNode, type?: 'end' | 'start'): void + } + + export interface Stringifier { + (node: AnyNode, builder: Builder): void + } + + export interface JSONHydrator { + (data: object): Node + (data: object[]): Node[] + } + + export interface Syntax { + /** + * Function to generate AST by string. + */ + parse?: Parser + + /** + * Class to generate string by AST. + */ + stringify?: Stringifier + } + + export interface SourceMapOptions { + /** + * Use absolute path in generated source map. + */ + absolute?: boolean + + /** + * Indicates that PostCSS should add annotation comments to the CSS. + * By default, PostCSS will always add a comment with a path + * to the source map. PostCSS will not add annotations to CSS files + * that do not contain any comments. + * + * By default, PostCSS presumes that you want to save the source map as + * `opts.to + '.map'` and will use this path in the annotation comment. + * A different path can be set by providing a string value for annotation. + * + * If you have set `inline: true`, annotation cannot be disabled. + */ + annotation?: ((file: string, root: Root) => string) | boolean | string + + /** + * Override `from` in map’s sources. + */ + from?: string + + /** + * Indicates that the source map should be embedded in the output CSS + * as a Base64-encoded comment. By default, it is `true`. + * But if all previous maps are external, not inline, PostCSS will not embed + * the map even if you do not set this option. + * + * If you have an inline source map, the result.map property will be empty, + * as the source map will be contained within the text of `result.css`. + */ + inline?: boolean + + /** + * Source map content from a previous processing step (e.g., Sass). + * + * PostCSS will try to read the previous source map + * automatically (based on comments within the source CSS), but you can use + * this option to identify it manually. + * + * If desired, you can omit the previous map with prev: `false`. + */ + prev?: ((file: string) => string) | boolean | object | string + + /** + * Indicates that PostCSS should set the origin content (e.g., Sass source) + * of the source map. By default, it is true. But if all previous maps do not + * contain sources content, PostCSS will also leave it out even if you + * do not set this option. + */ + sourcesContent?: boolean + } + + export interface ProcessOptions { + /** + * Input file if it is not simple CSS file, but HTML with + + `; +} + +const ERR_LOAD_URL = "ERR_LOAD_URL"; +const ERR_LOAD_PUBLIC_URL = "ERR_LOAD_PUBLIC_URL"; +const ERR_DENIED_ID = "ERR_DENIED_ID"; +const debugLoad = createDebugger("vite:load"); +const debugTransform = createDebugger("vite:transform"); +const debugCache$1 = createDebugger("vite:cache"); +function transformRequest(url, server, options = {}) { + if (server._restartPromise && !options.ssr) throwClosedServerError(); + const cacheKey = (options.ssr ? "ssr:" : options.html ? "html:" : "") + url; + const timestamp = Date.now(); + const pending = server._pendingRequests.get(cacheKey); + if (pending) { + return server.moduleGraph.getModuleByUrl(removeTimestampQuery(url), options.ssr).then((module) => { + if (!module || pending.timestamp > module.lastInvalidationTimestamp) { + return pending.request; + } else { + pending.abort(); + return transformRequest(url, server, options); + } + }); + } + const request = doTransform(url, server, options, timestamp); + let cleared = false; + const clearCache = () => { + if (!cleared) { + server._pendingRequests.delete(cacheKey); + cleared = true; + } + }; + server._pendingRequests.set(cacheKey, { + request, + timestamp, + abort: clearCache + }); + return request.finally(clearCache); +} +async function doTransform(url, server, options, timestamp) { + url = removeTimestampQuery(url); + const { config, pluginContainer } = server; + const ssr = !!options.ssr; + if (ssr && isDepsOptimizerEnabled(config, true)) { + await initDevSsrDepsOptimizer(config, server); + } + let module = await server.moduleGraph.getModuleByUrl(url, ssr); + if (module) { + const cached = await getCachedTransformResult( + url, + module, + server, + ssr, + timestamp + ); + if (cached) return cached; + } + const resolved = module ? void 0 : await pluginContainer.resolveId(url, void 0, { ssr }) ?? void 0; + const id = module?.id ?? resolved?.id ?? url; + module ??= server.moduleGraph.getModuleById(id); + if (module) { + await server.moduleGraph._ensureEntryFromUrl(url, ssr, void 0, resolved); + const cached = await getCachedTransformResult( + url, + module, + server, + ssr, + timestamp + ); + if (cached) return cached; + } + const result = loadAndTransform( + id, + url, + server, + options, + timestamp, + module, + resolved + ); + if (!ssr) { + const depsOptimizer = getDepsOptimizer(config, ssr); + if (!depsOptimizer?.isOptimizedDepFile(id)) { + server._registerRequestProcessing(id, () => result); + } + } + return result; +} +async function getCachedTransformResult(url, module, server, ssr, timestamp) { + const prettyUrl = debugCache$1 ? prettifyUrl(url, server.config.root) : ""; + const softInvalidatedTransformResult = module && await handleModuleSoftInvalidation(module, ssr, timestamp, server); + if (softInvalidatedTransformResult) { + debugCache$1?.(`[memory-hmr] ${prettyUrl}`); + return softInvalidatedTransformResult; + } + const cached = module && (ssr ? module.ssrTransformResult : module.transformResult); + if (cached) { + debugCache$1?.(`[memory] ${prettyUrl}`); + return cached; + } +} +async function loadAndTransform(id, url, server, options, timestamp, mod, resolved) { + const { config, pluginContainer, moduleGraph } = server; + const { logger } = config; + const prettyUrl = debugLoad || debugTransform ? prettifyUrl(url, config.root) : ""; + const ssr = !!options.ssr; + const file = cleanUrl(id); + if (options.allowId && !options.allowId(id)) { + const err = new Error(`Denied ID ${id}`); + err.code = ERR_DENIED_ID; + throw err; + } + let code = null; + let map = null; + const loadStart = debugLoad ? performance$1.now() : 0; + const loadResult = await pluginContainer.load(id, { ssr }); + if (loadResult == null) { + if (options.html && !id.endsWith(".html")) { + return null; + } + if (options.ssr || isFileServingAllowed(file, server)) { + try { + code = await fsp.readFile(file, "utf-8"); + debugLoad?.(`${timeFrom(loadStart)} [fs] ${prettyUrl}`); + } catch (e) { + if (e.code !== "ENOENT") { + if (e.code === "EISDIR") { + e.message = `${e.message} ${file}`; + } + throw e; + } + } + if (code != null) { + ensureWatchedFile(server.watcher, file, config.root); + } + } + if (code) { + try { + const extracted = await extractSourcemapFromFile(code, file); + if (extracted) { + code = extracted.code; + map = extracted.map; + } + } catch (e) { + logger.warn(`Failed to load source map for ${file}. +${e}`, { + timestamp: true + }); + } + } + } else { + debugLoad?.(`${timeFrom(loadStart)} [plugin] ${prettyUrl}`); + if (isObject$1(loadResult)) { + code = loadResult.code; + map = loadResult.map; + } else { + code = loadResult; + } + } + if (code == null) { + const isPublicFile = checkPublicFile(url, config); + let publicDirName = path$n.relative(config.root, config.publicDir); + if (publicDirName[0] !== ".") publicDirName = "/" + publicDirName; + const msg = isPublicFile ? `This file is in ${publicDirName} and will be copied as-is during build without going through the plugin transforms, and therefore should not be imported from source code. It can only be referenced via HTML tags.` : `Does the file exist?`; + const importerMod = server.moduleGraph.idToModuleMap.get(id)?.importers.values().next().value; + const importer = importerMod?.file || importerMod?.url; + const err = new Error( + `Failed to load url ${url} (resolved id: ${id})${importer ? ` in ${importer}` : ""}. ${msg}` + ); + err.code = isPublicFile ? ERR_LOAD_PUBLIC_URL : ERR_LOAD_URL; + throw err; + } + if (server._restartPromise && !ssr) throwClosedServerError(); + mod ??= await moduleGraph._ensureEntryFromUrl(url, ssr, void 0, resolved); + const transformStart = debugTransform ? performance$1.now() : 0; + const transformResult = await pluginContainer.transform(code, id, { + inMap: map, + ssr + }); + const originalCode = code; + if (transformResult == null || isObject$1(transformResult) && transformResult.code == null) { + debugTransform?.( + timeFrom(transformStart) + colors$1.dim(` [skipped] ${prettyUrl}`) + ); + } else { + debugTransform?.(`${timeFrom(transformStart)} ${prettyUrl}`); + code = transformResult.code; + map = transformResult.map; + } + let normalizedMap; + if (typeof map === "string") { + normalizedMap = JSON.parse(map); + } else if (map) { + normalizedMap = map; + } else { + normalizedMap = null; + } + if (normalizedMap && "version" in normalizedMap && mod.file) { + if (normalizedMap.mappings) { + await injectSourcesContent(normalizedMap, mod.file, logger); + } + const sourcemapPath = `${mod.file}.map`; + applySourcemapIgnoreList( + normalizedMap, + sourcemapPath, + config.server.sourcemapIgnoreList, + logger + ); + if (path$n.isAbsolute(mod.file)) { + let modDirname; + for (let sourcesIndex = 0; sourcesIndex < normalizedMap.sources.length; ++sourcesIndex) { + const sourcePath = normalizedMap.sources[sourcesIndex]; + if (sourcePath) { + if (path$n.isAbsolute(sourcePath)) { + modDirname ??= path$n.dirname(mod.file); + normalizedMap.sources[sourcesIndex] = path$n.relative( + modDirname, + sourcePath + ); + } + } + } + } + } + if (server._restartPromise && !ssr) throwClosedServerError(); + const result = ssr && !server.config.experimental.skipSsrTransform ? await server.ssrTransform(code, normalizedMap, url, originalCode) : { + code, + map: normalizedMap, + etag: getEtag(code, { weak: true }) + }; + if (timestamp > mod.lastInvalidationTimestamp) + moduleGraph.updateModuleTransformResult(mod, result, ssr); + return result; +} +async function handleModuleSoftInvalidation(mod, ssr, timestamp, server) { + const transformResult = ssr ? mod.ssrInvalidationState : mod.invalidationState; + if (ssr) mod.ssrInvalidationState = void 0; + else mod.invalidationState = void 0; + if (!transformResult || transformResult === "HARD_INVALIDATED") return; + if (ssr ? mod.ssrTransformResult : mod.transformResult) { + throw new Error( + `Internal server error: Soft-invalidated module "${mod.url}" should not have existing transform result` + ); + } + let result; + if (ssr) { + result = transformResult; + } else { + await init; + const source = transformResult.code; + const s = new MagicString(source); + const [imports] = parse$d(source, mod.id || void 0); + for (const imp of imports) { + let rawUrl = source.slice(imp.s, imp.e); + if (rawUrl === "import.meta") continue; + const hasQuotes = rawUrl[0] === '"' || rawUrl[0] === "'"; + if (hasQuotes) { + rawUrl = rawUrl.slice(1, -1); + } + const urlWithoutTimestamp = removeTimestampQuery(rawUrl); + const hmrUrl = unwrapId$1( + stripBase(removeImportQuery(urlWithoutTimestamp), server.config.base) + ); + for (const importedMod of mod.clientImportedModules) { + if (importedMod.url !== hmrUrl) continue; + if (importedMod.lastHMRTimestamp > 0) { + const replacedUrl = injectQuery( + urlWithoutTimestamp, + `t=${importedMod.lastHMRTimestamp}` + ); + const start = hasQuotes ? imp.s + 1 : imp.s; + const end = hasQuotes ? imp.e - 1 : imp.e; + s.overwrite(start, end, replacedUrl); + } + if (imp.d === -1 && server.config.server.preTransformRequests) { + server.warmupRequest(hmrUrl, { ssr }); + } + break; + } + } + const code = s.toString(); + result = { + ...transformResult, + code, + etag: getEtag(code, { weak: true }) + }; + } + if (timestamp > mod.lastInvalidationTimestamp) + server.moduleGraph.updateModuleTransformResult(mod, result, ssr); + return result; +} + +function analyzeImportedModDifference(mod, rawId, moduleType, metadata) { + if (metadata?.isDynamicImport) return; + if (metadata?.importedNames?.length) { + const missingBindings = metadata.importedNames.filter((s) => !(s in mod)); + if (missingBindings.length) { + const lastBinding = missingBindings[missingBindings.length - 1]; + if (moduleType === "module") { + throw new SyntaxError( + `[vite] The requested module '${rawId}' does not provide an export named '${lastBinding}'` + ); + } else { + throw new SyntaxError(`[vite] Named export '${lastBinding}' not found. The requested module '${rawId}' is a CommonJS module, which may not support all module.exports as named exports. +CommonJS modules can always be imported via the default export, for example using: + +import pkg from '${rawId}'; +const {${missingBindings.join(", ")}} = pkg; +`); + } + } + } +} + +/** + * @param {import('estree').Node} param + * @returns {string[]} + */ +function extract_names(param) { + return extract_identifiers(param).map((node) => node.name); +} + +/** + * @param {import('estree').Node} param + * @param {import('estree').Identifier[]} nodes + * @returns {import('estree').Identifier[]} + */ +function extract_identifiers(param, nodes = []) { + switch (param.type) { + case 'Identifier': + nodes.push(param); + break; + + case 'MemberExpression': + let object = param; + while (object.type === 'MemberExpression') { + object = /** @type {any} */ (object.object); + } + nodes.push(/** @type {any} */ (object)); + break; + + case 'ObjectPattern': + for (const prop of param.properties) { + if (prop.type === 'RestElement') { + extract_identifiers(prop.argument, nodes); + } else { + extract_identifiers(prop.value, nodes); + } + } + + break; + + case 'ArrayPattern': + for (const element of param.elements) { + if (element) extract_identifiers(element, nodes); + } + + break; + + case 'RestElement': + extract_identifiers(param.argument, nodes); + break; + + case 'AssignmentPattern': + extract_identifiers(param.left, nodes); + break; + } + + return nodes; +} + +/** + * @typedef { import('estree').Node} Node + * @typedef {{ + * skip: () => void; + * remove: () => void; + * replace: (node: Node) => void; + * }} WalkerContext + */ + +class WalkerBase { + constructor() { + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + * @param {Node} node + */ + replace(parent, prop, index, node) { + if (parent && prop) { + if (index != null) { + /** @type {Array} */ (parent[prop])[index] = node; + } else { + /** @type {Node} */ (parent[prop]) = node; + } + } + } + + /** + * @template {Node} Parent + * @param {Parent | null | undefined} parent + * @param {keyof Parent | null | undefined} prop + * @param {number | null | undefined} index + */ + remove(parent, prop, index) { + if (parent && prop) { + if (index !== null && index !== undefined) { + /** @type {Array} */ (parent[prop]).splice(index, 1); + } else { + delete parent[prop]; + } + } + } +} + +/** + * @typedef { import('estree').Node} Node + * @typedef { import('./walker.js').WalkerContext} WalkerContext + * @typedef {( + * this: WalkerContext, + * node: Node, + * parent: Node | null, + * key: string | number | symbol | null | undefined, + * index: number | null | undefined + * ) => void} SyncHandler + */ + +class SyncWalker extends WalkerBase { + /** + * + * @param {SyncHandler} [enter] + * @param {SyncHandler} [leave] + */ + constructor(enter, leave) { + super(); + + /** @type {boolean} */ + this.should_skip = false; + + /** @type {boolean} */ + this.should_remove = false; + + /** @type {Node | null} */ + this.replacement = null; + + /** @type {WalkerContext} */ + this.context = { + skip: () => (this.should_skip = true), + remove: () => (this.should_remove = true), + replace: (node) => (this.replacement = node) + }; + + /** @type {SyncHandler | undefined} */ + this.enter = enter; + + /** @type {SyncHandler | undefined} */ + this.leave = leave; + } + + /** + * @template {Node} Parent + * @param {Node} node + * @param {Parent | null} parent + * @param {keyof Parent} [prop] + * @param {number | null} [index] + * @returns {Node | null} + */ + visit(node, parent, prop, index) { + if (node) { + if (this.enter) { + const _should_skip = this.should_skip; + const _should_remove = this.should_remove; + const _replacement = this.replacement; + this.should_skip = false; + this.should_remove = false; + this.replacement = null; + + this.enter.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const skipped = this.should_skip; + const removed = this.should_remove; + + this.should_skip = _should_skip; + this.should_remove = _should_remove; + this.replacement = _replacement; + + if (skipped) return node; + if (removed) return null; + } + + /** @type {keyof Node} */ + let key; + + for (key in node) { + /** @type {unknown} */ + const value = node[key]; + + if (value && typeof value === 'object') { + if (Array.isArray(value)) { + const nodes = /** @type {Array} */ (value); + for (let i = 0; i < nodes.length; i += 1) { + const item = nodes[i]; + if (isNode(item)) { + if (!this.visit(item, node, key, i)) { + // removed + i--; + } + } + } + } else if (isNode(value)) { + this.visit(value, node, key, null); + } + } + } + + if (this.leave) { + const _replacement = this.replacement; + const _should_remove = this.should_remove; + this.replacement = null; + this.should_remove = false; + + this.leave.call(this.context, node, parent, prop, index); + + if (this.replacement) { + node = this.replacement; + this.replace(parent, prop, index, node); + } + + if (this.should_remove) { + this.remove(parent, prop, index); + } + + const removed = this.should_remove; + + this.replacement = _replacement; + this.should_remove = _should_remove; + + if (removed) return null; + } + } + + return node; + } +} + +/** + * Ducktype a node. + * + * @param {unknown} value + * @returns {value is Node} + */ +function isNode(value) { + return ( + value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string' + ); +} + +/** + * @typedef {import('estree').Node} Node + * @typedef {import('./sync.js').SyncHandler} SyncHandler + * @typedef {import('./async.js').AsyncHandler} AsyncHandler + */ + +/** + * @param {Node} ast + * @param {{ + * enter?: SyncHandler + * leave?: SyncHandler + * }} walker + * @returns {Node | null} + */ +function walk$1(ast, { enter, leave }) { + const instance = new SyncWalker(enter, leave); + return instance.visit(ast, null); +} + +const ssrModuleExportsKey = `__vite_ssr_exports__`; +const ssrImportKey = `__vite_ssr_import__`; +const ssrDynamicImportKey = `__vite_ssr_dynamic_import__`; +const ssrExportAllKey = `__vite_ssr_exportAll__`; +const ssrImportMetaKey = `__vite_ssr_import_meta__`; +const hashbangRE = /^#!.*\n/; +async function ssrTransform(code, inMap, url, originalCode, options) { + if (options?.json?.stringify && isJSONRequest(url)) { + return ssrTransformJSON(code, inMap); + } + return ssrTransformScript(code, inMap, url, originalCode); +} +async function ssrTransformJSON(code, inMap) { + return { + code: code.replace("export default", `${ssrModuleExportsKey}.default =`), + map: inMap, + deps: [], + dynamicDeps: [] + }; +} +async function ssrTransformScript(code, inMap, url, originalCode) { + const s = new MagicString(code); + let ast; + try { + ast = await parseAstAsync(code); + } catch (err) { + if (!err.loc || !err.loc.line) throw err; + const line = err.loc.line; + throw new Error( + `Parse failure: ${err.message} +At file: ${url} +Contents of line ${line}: ${code.split("\n")[line - 1]}` + ); + } + let uid = 0; + const deps = /* @__PURE__ */ new Set(); + const dynamicDeps = /* @__PURE__ */ new Set(); + const idToImportMap = /* @__PURE__ */ new Map(); + const declaredConst = /* @__PURE__ */ new Set(); + const hoistIndex = hashbangRE.exec(code)?.[0].length ?? 0; + function defineImport(index, source, metadata) { + deps.add(source); + const importId = `__vite_ssr_import_${uid++}__`; + if (metadata && (metadata.importedNames == null || metadata.importedNames.length === 0)) { + metadata = void 0; + } + const metadataStr = metadata ? `, ${JSON.stringify(metadata)}` : ""; + s.appendLeft( + index, + `const ${importId} = await ${ssrImportKey}(${JSON.stringify( + source + )}${metadataStr}); +` + ); + return importId; + } + function defineExport(position, name, local = name) { + s.appendLeft( + position, + ` +Object.defineProperty(${ssrModuleExportsKey}, "${name}", { enumerable: true, configurable: true, get(){ return ${local} }});` + ); + } + const imports = []; + const exports = []; + for (const node of ast.body) { + if (node.type === "ImportDeclaration") { + imports.push(node); + } else if (node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration" || node.type === "ExportAllDeclaration") { + exports.push(node); + } + } + for (const node of imports) { + const importId = defineImport(hoistIndex, node.source.value, { + importedNames: node.specifiers.map((s2) => { + if (s2.type === "ImportSpecifier") + return s2.imported.type === "Identifier" ? s2.imported.name : ( + // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet + s2.imported.value + ); + else if (s2.type === "ImportDefaultSpecifier") return "default"; + }).filter(isDefined) + }); + s.remove(node.start, node.end); + for (const spec of node.specifiers) { + if (spec.type === "ImportSpecifier") { + if (spec.imported.type === "Identifier") { + idToImportMap.set( + spec.local.name, + `${importId}.${spec.imported.name}` + ); + } else { + idToImportMap.set( + spec.local.name, + `${importId}[${// @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet + JSON.stringify(spec.imported.value)}]` + ); + } + } else if (spec.type === "ImportDefaultSpecifier") { + idToImportMap.set(spec.local.name, `${importId}.default`); + } else { + idToImportMap.set(spec.local.name, importId); + } + } + } + for (const node of exports) { + if (node.type === "ExportNamedDeclaration") { + if (node.declaration) { + if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { + defineExport(node.end, node.declaration.id.name); + } else { + for (const declaration of node.declaration.declarations) { + const names = extract_names(declaration.id); + for (const name of names) { + defineExport(node.end, name); + } + } + } + s.remove(node.start, node.declaration.start); + } else { + s.remove(node.start, node.end); + if (node.source) { + const importId = defineImport( + node.start, + node.source.value, + { + importedNames: node.specifiers.map((s2) => s2.local.name) + } + ); + for (const spec of node.specifiers) { + const exportedAs = spec.exported.type === "Identifier" ? spec.exported.name : ( + // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet + spec.exported.value + ); + defineExport( + node.start, + exportedAs, + `${importId}.${spec.local.name}` + ); + } + } else { + for (const spec of node.specifiers) { + const local = spec.local.name; + const binding = idToImportMap.get(local); + const exportedAs = spec.exported.type === "Identifier" ? spec.exported.name : ( + // @ts-expect-error TODO: Estree types don't consider arbitrary module namespace specifiers yet + spec.exported.value + ); + defineExport(node.end, exportedAs, binding || local); + } + } + } + } + if (node.type === "ExportDefaultDeclaration") { + const expressionTypes = ["FunctionExpression", "ClassExpression"]; + if ("id" in node.declaration && node.declaration.id && !expressionTypes.includes(node.declaration.type)) { + const { name } = node.declaration.id; + s.remove( + node.start, + node.start + 15 + /* 'export default '.length */ + ); + s.append( + ` +Object.defineProperty(${ssrModuleExportsKey}, "default", { enumerable: true, configurable: true, value: ${name} });` + ); + } else { + s.update( + node.start, + node.start + 14, + `${ssrModuleExportsKey}.default =` + ); + } + } + if (node.type === "ExportAllDeclaration") { + s.remove(node.start, node.end); + const importId = defineImport(node.start, node.source.value); + if (node.exported) { + defineExport(node.start, node.exported.name, `${importId}`); + } else { + s.appendLeft(node.start, `${ssrExportAllKey}(${importId}); +`); + } + } + } + walk(ast, { + onIdentifier(id, parent, parentStack) { + const grandparent = parentStack[1]; + const binding = idToImportMap.get(id.name); + if (!binding) { + return; + } + if (isStaticProperty(parent) && parent.shorthand) { + if (!isNodeInPattern(parent) || isInDestructuringAssignment(parent, parentStack)) { + s.appendLeft(id.end, `: ${binding}`); + } + } else if (parent.type === "PropertyDefinition" && grandparent?.type === "ClassBody" || parent.type === "ClassDeclaration" && id === parent.superClass) { + if (!declaredConst.has(id.name)) { + declaredConst.add(id.name); + const topNode = parentStack[parentStack.length - 2]; + s.prependRight(topNode.start, `const ${id.name} = ${binding}; +`); + } + } else if ( + // don't transform class name identifier + !(parent.type === "ClassExpression" && id === parent.id) + ) { + s.update(id.start, id.end, binding); + } + }, + onImportMeta(node) { + s.update(node.start, node.end, ssrImportMetaKey); + }, + onDynamicImport(node) { + s.update(node.start, node.start + 6, ssrDynamicImportKey); + if (node.type === "ImportExpression" && node.source.type === "Literal") { + dynamicDeps.add(node.source.value); + } + } + }); + let map = s.generateMap({ hires: "boundary" }); + map.sources = [path$n.basename(url)]; + map.sourcesContent = [originalCode]; + if (inMap && inMap.mappings && "sources" in inMap && inMap.sources.length > 0) { + map = combineSourcemaps(url, [ + map, + inMap + ]); + } + return { + code: s.toString(), + map, + deps: [...deps], + dynamicDeps: [...dynamicDeps] + }; +} +const isNodeInPatternWeakSet = /* @__PURE__ */ new WeakSet(); +const setIsNodeInPattern = (node) => isNodeInPatternWeakSet.add(node); +const isNodeInPattern = (node) => isNodeInPatternWeakSet.has(node); +function walk(root, { onIdentifier, onImportMeta, onDynamicImport }) { + const parentStack = []; + const varKindStack = []; + const scopeMap = /* @__PURE__ */ new WeakMap(); + const identifiers = []; + const setScope = (node, name) => { + let scopeIds = scopeMap.get(node); + if (scopeIds && scopeIds.has(name)) { + return; + } + if (!scopeIds) { + scopeIds = /* @__PURE__ */ new Set(); + scopeMap.set(node, scopeIds); + } + scopeIds.add(name); + }; + function isInScope(name, parents) { + return parents.some((node) => node && scopeMap.get(node)?.has(name)); + } + function handlePattern(p, parentScope) { + if (p.type === "Identifier") { + setScope(parentScope, p.name); + } else if (p.type === "RestElement") { + handlePattern(p.argument, parentScope); + } else if (p.type === "ObjectPattern") { + p.properties.forEach((property) => { + if (property.type === "RestElement") { + setScope(parentScope, property.argument.name); + } else { + handlePattern(property.value, parentScope); + } + }); + } else if (p.type === "ArrayPattern") { + p.elements.forEach((element) => { + if (element) { + handlePattern(element, parentScope); + } + }); + } else if (p.type === "AssignmentPattern") { + handlePattern(p.left, parentScope); + } else { + setScope(parentScope, p.name); + } + } + walk$1(root, { + enter(node, parent) { + if (node.type === "ImportDeclaration") { + return this.skip(); + } + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) { + parentStack.unshift(parent); + } + if (node.type === "VariableDeclaration") { + varKindStack.unshift(node.kind); + } + if (node.type === "MetaProperty" && node.meta.name === "import") { + onImportMeta(node); + } else if (node.type === "ImportExpression") { + onDynamicImport(node); + } + if (node.type === "Identifier") { + if (!isInScope(node.name, parentStack) && isRefIdentifier(node, parent, parentStack)) { + identifiers.push([node, parentStack.slice(0)]); + } + } else if (isFunction$1(node)) { + if (node.type === "FunctionDeclaration") { + const parentScope = findParentScope(parentStack); + if (parentScope) { + setScope(parentScope, node.id.name); + } + } + if (node.type === "FunctionExpression" && node.id) { + setScope(node, node.id.name); + } + node.params.forEach((p) => { + if (p.type === "ObjectPattern" || p.type === "ArrayPattern") { + handlePattern(p, node); + return; + } + walk$1(p.type === "AssignmentPattern" ? p.left : p, { + enter(child, parent2) { + if (parent2?.type === "AssignmentPattern" && parent2?.right === child) { + return this.skip(); + } + if (child.type !== "Identifier") return; + if (isStaticPropertyKey(child, parent2)) return; + if (parent2?.type === "TemplateLiteral" && parent2?.expressions.includes(child) || parent2?.type === "CallExpression" && parent2?.callee === child) { + return; + } + setScope(node, child.name); + } + }); + }); + } else if (node.type === "ClassDeclaration") { + const parentScope = findParentScope(parentStack); + if (parentScope) { + setScope(parentScope, node.id.name); + } + } else if (node.type === "ClassExpression" && node.id) { + setScope(node, node.id.name); + } else if (node.type === "Property" && parent.type === "ObjectPattern") { + setIsNodeInPattern(node); + } else if (node.type === "VariableDeclarator") { + const parentFunction = findParentScope( + parentStack, + varKindStack[0] === "var" + ); + if (parentFunction) { + handlePattern(node.id, parentFunction); + } + } else if (node.type === "CatchClause" && node.param) { + handlePattern(node.param, node); + } + }, + leave(node, parent) { + if (parent && !(parent.type === "IfStatement" && node === parent.alternate)) { + parentStack.shift(); + } + if (node.type === "VariableDeclaration") { + varKindStack.shift(); + } + } + }); + identifiers.forEach(([node, stack]) => { + if (!isInScope(node.name, stack)) onIdentifier(node, stack[0], stack); + }); +} +function isRefIdentifier(id, parent, parentStack) { + if (parent.type === "CatchClause" || (parent.type === "VariableDeclarator" || parent.type === "ClassDeclaration") && parent.id === id) { + return false; + } + if (isFunction$1(parent)) { + if (parent.id === id) { + return false; + } + if (parent.params.includes(id)) { + return false; + } + } + if (parent.type === "MethodDefinition" && !parent.computed) { + return false; + } + if (isStaticPropertyKey(id, parent)) { + return false; + } + if (isNodeInPattern(parent) && parent.value === id) { + return false; + } + if (parent.type === "ArrayPattern" && !isInDestructuringAssignment(parent, parentStack)) { + return false; + } + if (parent.type === "MemberExpression" && parent.property === id && !parent.computed) { + return false; + } + if (parent.type === "ExportSpecifier") { + return false; + } + if (id.name === "arguments") { + return false; + } + return true; +} +const isStaticProperty = (node) => node && node.type === "Property" && !node.computed; +const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node; +const functionNodeTypeRE = /Function(?:Expression|Declaration)$|Method$/; +function isFunction$1(node) { + return functionNodeTypeRE.test(node.type); +} +const blockNodeTypeRE = /^BlockStatement$|^For(?:In|Of)?Statement$/; +function isBlock(node) { + return blockNodeTypeRE.test(node.type); +} +function findParentScope(parentStack, isVar = false) { + return parentStack.find(isVar ? isFunction$1 : isBlock); +} +function isInDestructuringAssignment(parent, parentStack) { + if (parent && (parent.type === "Property" || parent.type === "ArrayPattern")) { + return parentStack.some((i) => i.type === "AssignmentExpression"); + } + return false; +} + +let offset; +function calculateOffsetOnce() { + if (offset !== void 0) { + return; + } + try { + new Function("throw new Error(1)")(); + } catch (e) { + const match = /:(\d+):\d+\)$/.exec(e.stack.split("\n")[1]); + offset = match ? +match[1] - 1 : 0; + } +} +function ssrRewriteStacktrace(stack, moduleGraph) { + calculateOffsetOnce(); + return stack.split("\n").map((line) => { + return line.replace( + /^ {4}at (?:(\S.*?)\s\()?(.+?):(\d+)(?::(\d+))?\)?/, + (input, varName, id, line2, column) => { + if (!id) return input; + const mod = moduleGraph.idToModuleMap.get(id); + const rawSourceMap = mod?.ssrTransformResult?.map; + if (!rawSourceMap) { + return input; + } + const traced = new TraceMap(rawSourceMap); + const pos = originalPositionFor$1(traced, { + line: Number(line2) - offset, + // stacktrace's column is 1-indexed, but sourcemap's one is 0-indexed + column: Number(column) - 1 + }); + if (!pos.source || pos.line == null || pos.column == null) { + return input; + } + const trimmedVarName = varName.trim(); + const sourceFile = path$n.resolve(path$n.dirname(id), pos.source); + const source = `${sourceFile}:${pos.line}:${pos.column + 1}`; + if (!trimmedVarName || trimmedVarName === "eval") { + return ` at ${source}`; + } else { + return ` at ${trimmedVarName} (${source})`; + } + } + ); + }).join("\n"); +} +function rebindErrorStacktrace(e, stacktrace) { + const { configurable, writable } = Object.getOwnPropertyDescriptor( + e, + "stack" + ); + if (configurable) { + Object.defineProperty(e, "stack", { + value: stacktrace, + enumerable: true, + configurable: true, + writable: true + }); + } else if (writable) { + e.stack = stacktrace; + } +} +const rewroteStacktraces = /* @__PURE__ */ new WeakSet(); +function ssrFixStacktrace(e, moduleGraph) { + if (!e.stack) return; + if (rewroteStacktraces.has(e)) return; + const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph); + rebindErrorStacktrace(e, stacktrace); + rewroteStacktraces.add(e); +} + +const pendingModules = /* @__PURE__ */ new Map(); +const pendingModuleDependencyGraph = /* @__PURE__ */ new Map(); +const importErrors = /* @__PURE__ */ new WeakMap(); +async function ssrLoadModule(url, server, fixStacktrace) { + url = unwrapId$1(url); + const pending = pendingModules.get(url); + if (pending) { + return pending; + } + const modulePromise = instantiateModule(url, server, fixStacktrace); + pendingModules.set(url, modulePromise); + modulePromise.catch(() => { + }).finally(() => { + pendingModules.delete(url); + }); + return modulePromise; +} +async function instantiateModule(url, server, fixStacktrace) { + const { moduleGraph } = server; + const mod = await moduleGraph.ensureEntryFromUrl(url, true); + if (mod.ssrError) { + throw mod.ssrError; + } + if (mod.ssrModule) { + return mod.ssrModule; + } + const result = mod.ssrTransformResult || await transformRequest(url, server, { ssr: true }); + if (!result) { + throw new Error(`failed to load module for ssr: ${url}`); + } + const ssrModule = { + [Symbol.toStringTag]: "Module" + }; + Object.defineProperty(ssrModule, "__esModule", { value: true }); + mod.ssrModule = ssrModule; + const osNormalizedFilename = isWindows$3 ? path$n.resolve(mod.file) : mod.file; + const ssrImportMeta = { + dirname: path$n.dirname(osNormalizedFilename), + filename: osNormalizedFilename, + // The filesystem URL, matching native Node.js modules + url: pathToFileURL(mod.file).toString() + }; + const { + isProduction, + resolve: { dedupe, preserveSymlinks }, + root, + ssr + } = server.config; + const overrideConditions = ssr.resolve?.externalConditions || []; + const resolveOptions = { + mainFields: ["main"], + conditions: [], + overrideConditions: [...overrideConditions, "production", "development"], + extensions: [".js", ".cjs", ".json"], + dedupe, + preserveSymlinks, + isBuild: false, + isProduction, + root, + ssrConfig: ssr, + legacyProxySsrExternalModules: server.config.legacy?.proxySsrExternalModules, + packageCache: server.config.packageCache + }; + const ssrImport = async (dep, metadata) => { + try { + if (dep[0] !== "." && dep[0] !== "/") { + return await nodeImport(dep, mod.file, resolveOptions, metadata); + } + dep = unwrapId$1(dep); + if (!metadata?.isDynamicImport) { + addPendingModuleDependency(url, dep); + if (checkModuleDependencyExists(dep, url)) { + const depSsrModule = moduleGraph.urlToModuleMap.get(dep)?.ssrModule; + if (!depSsrModule) { + throw new Error( + "[vite] The dependency module is not yet fully initialized due to circular dependency. This is a bug in Vite SSR" + ); + } + return depSsrModule; + } + } + return ssrLoadModule(dep, server, fixStacktrace); + } catch (err) { + importErrors.set(err, { importee: dep }); + throw err; + } + }; + const ssrDynamicImport = (dep) => { + if (dep[0] === ".") { + dep = path$n.posix.resolve(path$n.dirname(url), dep); + } + return ssrImport(dep, { isDynamicImport: true }); + }; + function ssrExportAll(sourceModule) { + for (const key in sourceModule) { + if (key !== "default" && key !== "__esModule") { + Object.defineProperty(ssrModule, key, { + enumerable: true, + configurable: true, + get() { + return sourceModule[key]; + } + }); + } + } + } + let sourceMapSuffix = ""; + if (result.map && "version" in result.map) { + const moduleSourceMap = Object.assign({}, result.map, { + mappings: ";".repeat(asyncFunctionDeclarationPaddingLineCount) + result.map.mappings + }); + sourceMapSuffix = ` +//# ${SOURCEMAPPING_URL}=${genSourceMapUrl(moduleSourceMap)}`; + } + try { + const initModule = new AsyncFunction( + ssrModuleExportsKey, + ssrImportMetaKey, + ssrImportKey, + ssrDynamicImportKey, + ssrExportAllKey, + '"use strict";' + result.code + ` +//# sourceURL=${mod.id}${sourceMapSuffix}` + ); + await initModule( + ssrModule, + ssrImportMeta, + ssrImport, + ssrDynamicImport, + ssrExportAll + ); + } catch (e) { + mod.ssrError = e; + const errorData = importErrors.get(e); + if (e.stack && fixStacktrace) { + ssrFixStacktrace(e, moduleGraph); + } + server.config.logger.error( + colors$1.red( + `Error when evaluating SSR module ${url}:` + (errorData?.importee ? ` failed to import "${errorData.importee}"` : "") + ` +|- ${e.stack} +` + ), + { + timestamp: true, + clear: server.config.clearScreen, + error: e + } + ); + throw e; + } finally { + pendingModuleDependencyGraph.delete(url); + } + return Object.freeze(ssrModule); +} +function addPendingModuleDependency(originUrl, depUrl) { + if (pendingModuleDependencyGraph.has(originUrl)) { + pendingModuleDependencyGraph.get(originUrl).add(depUrl); + } else { + pendingModuleDependencyGraph.set(originUrl, /* @__PURE__ */ new Set([depUrl])); + } +} +function checkModuleDependencyExists(originUrl, targetUrl) { + const visited = /* @__PURE__ */ new Set(); + const stack = [originUrl]; + while (stack.length) { + const currentUrl = stack.pop(); + if (currentUrl === targetUrl) { + return true; + } + if (!visited.has(currentUrl)) { + visited.add(currentUrl); + const dependencies = pendingModuleDependencyGraph.get(currentUrl); + if (dependencies) { + for (const depUrl of dependencies) { + if (!visited.has(depUrl)) { + stack.push(depUrl); + } + } + } + } + } + return false; +} +async function nodeImport(id, importer, resolveOptions, metadata) { + let url; + let filePath; + if (id.startsWith("data:") || isExternalUrl(id) || isBuiltin(id)) { + url = id; + } else { + const resolved = tryNodeResolve( + id, + importer, + { ...resolveOptions, tryEsmOnly: true }, + false, + void 0, + true + ); + if (!resolved) { + const err = new Error( + `Cannot find module '${id}' imported from '${importer}'` + ); + err.code = "ERR_MODULE_NOT_FOUND"; + throw err; + } + filePath = resolved.id; + url = pathToFileURL(resolved.id).toString(); + } + const mod = await import(url); + if (resolveOptions.legacyProxySsrExternalModules) { + return proxyESM(mod); + } else if (filePath) { + analyzeImportedModDifference( + mod, + id, + isFilePathESM(filePath, resolveOptions.packageCache) ? "module" : void 0, + metadata + ); + return mod; + } else { + return mod; + } +} +function proxyESM(mod) { + if (isPrimitive(mod)) return { default: mod }; + let defaultExport = "default" in mod ? mod.default : mod; + if (!isPrimitive(defaultExport) && "__esModule" in defaultExport) { + mod = defaultExport; + if ("default" in defaultExport) { + defaultExport = defaultExport.default; + } + } + return new Proxy(mod, { + get(mod2, prop) { + if (prop === "default") return defaultExport; + return mod2[prop] ?? defaultExport?.[prop]; + } + }); +} +function isPrimitive(value) { + return !value || typeof value !== "object" && typeof value !== "function"; +} + +var isWsl$2 = {exports: {}}; + +const fs$3 = require$$0__default; + +let isDocker$2; + +function hasDockerEnv() { + try { + fs$3.statSync('/.dockerenv'); + return true; + } catch (_) { + return false; + } +} + +function hasDockerCGroup() { + try { + return fs$3.readFileSync('/proc/self/cgroup', 'utf8').includes('docker'); + } catch (_) { + return false; + } +} + +var isDocker_1 = () => { + if (isDocker$2 === undefined) { + isDocker$2 = hasDockerEnv() || hasDockerCGroup(); + } + + return isDocker$2; +}; + +const os = require$$2; +const fs$2 = require$$0__default; +const isDocker$1 = isDocker_1; + +const isWsl$1 = () => { + if (process.platform !== 'linux') { + return false; + } + + if (os.release().toLowerCase().includes('microsoft')) { + if (isDocker$1()) { + return false; + } + + return true; + } + + try { + return fs$2.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ? + !isDocker$1() : false; + } catch (_) { + return false; + } +}; + +if (process.env.__IS_WSL_TEST__) { + isWsl$2.exports = isWsl$1; +} else { + isWsl$2.exports = isWsl$1(); +} + +var isWslExports = isWsl$2.exports; + +var defineLazyProp = (object, propertyName, fn) => { + const define = value => Object.defineProperty(object, propertyName, {value, enumerable: true, writable: true}); + + Object.defineProperty(object, propertyName, { + configurable: true, + enumerable: true, + get() { + const result = fn(); + define(result); + return result; + }, + set(value) { + define(value); + } + }); + + return object; +}; + +const path$3 = require$$0$4; +const childProcess = require$$2$1; +const {promises: fs$1, constants: fsConstants} = require$$0__default; +const isWsl = isWslExports; +const isDocker = isDocker_1; +const defineLazyProperty = defineLazyProp; + +// Path to included `xdg-open`. +const localXdgOpenPath = path$3.join(__dirname, 'xdg-open'); + +const {platform, arch} = process; + +// Podman detection +const hasContainerEnv = () => { + try { + fs$1.statSync('/run/.containerenv'); + return true; + } catch { + return false; + } +}; + +let cachedResult; +function isInsideContainer() { + if (cachedResult === undefined) { + cachedResult = hasContainerEnv() || isDocker(); + } + + return cachedResult; +} + +/** +Get the mount point for fixed drives in WSL. + +@inner +@returns {string} The mount point. +*/ +const getWslDrivesMountPoint = (() => { + // Default value for "root" param + // according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config + const defaultMountPoint = '/mnt/'; + + let mountPoint; + + return async function () { + if (mountPoint) { + // Return memoized mount point value + return mountPoint; + } + + const configFilePath = '/etc/wsl.conf'; + + let isConfigFileExists = false; + try { + await fs$1.access(configFilePath, fsConstants.F_OK); + isConfigFileExists = true; + } catch {} + + if (!isConfigFileExists) { + return defaultMountPoint; + } + + const configContent = await fs$1.readFile(configFilePath, {encoding: 'utf8'}); + const configMountPoint = /(?.*)/g.exec(configContent); + + if (!configMountPoint) { + return defaultMountPoint; + } + + mountPoint = configMountPoint.groups.mountPoint.trim(); + mountPoint = mountPoint.endsWith('/') ? mountPoint : `${mountPoint}/`; + + return mountPoint; + }; +})(); + +const pTryEach = async (array, mapper) => { + let latestError; + + for (const item of array) { + try { + return await mapper(item); // eslint-disable-line no-await-in-loop + } catch (error) { + latestError = error; + } + } + + throw latestError; +}; + +const baseOpen = async options => { + options = { + wait: false, + background: false, + newInstance: false, + allowNonzeroExitCode: false, + ...options + }; + + if (Array.isArray(options.app)) { + return pTryEach(options.app, singleApp => baseOpen({ + ...options, + app: singleApp + })); + } + + let {name: app, arguments: appArguments = []} = options.app || {}; + appArguments = [...appArguments]; + + if (Array.isArray(app)) { + return pTryEach(app, appName => baseOpen({ + ...options, + app: { + name: appName, + arguments: appArguments + } + })); + } + + let command; + const cliArguments = []; + const childProcessOptions = {}; + + if (platform === 'darwin') { + command = 'open'; + + if (options.wait) { + cliArguments.push('--wait-apps'); + } + + if (options.background) { + cliArguments.push('--background'); + } + + if (options.newInstance) { + cliArguments.push('--new'); + } + + if (app) { + cliArguments.push('-a', app); + } + } else if (platform === 'win32' || (isWsl && !isInsideContainer() && !app)) { + const mountPoint = await getWslDrivesMountPoint(); + + command = isWsl ? + `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : + `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`; + + cliArguments.push( + '-NoProfile', + '-NonInteractive', + '–ExecutionPolicy', + 'Bypass', + '-EncodedCommand' + ); + + if (!isWsl) { + childProcessOptions.windowsVerbatimArguments = true; + } + + const encodedArguments = ['Start']; + + if (options.wait) { + encodedArguments.push('-Wait'); + } + + if (app) { + // Double quote with double quotes to ensure the inner quotes are passed through. + // Inner quotes are delimited for PowerShell interpretation with backticks. + encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList'); + if (options.target) { + appArguments.unshift(options.target); + } + } else if (options.target) { + encodedArguments.push(`"${options.target}"`); + } + + if (appArguments.length > 0) { + appArguments = appArguments.map(arg => `"\`"${arg}\`""`); + encodedArguments.push(appArguments.join(',')); + } + + // Using Base64-encoded command, accepted by PowerShell, to allow special characters. + options.target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64'); + } else { + if (app) { + command = app; + } else { + // When bundled by Webpack, there's no actual package file path and no local `xdg-open`. + const isBundled = !__dirname || __dirname === '/'; + + // Check if local `xdg-open` exists and is executable. + let exeLocalXdgOpen = false; + try { + await fs$1.access(localXdgOpenPath, fsConstants.X_OK); + exeLocalXdgOpen = true; + } catch {} + + const useSystemXdgOpen = process.versions.electron || + platform === 'android' || isBundled || !exeLocalXdgOpen; + command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath; + } + + if (appArguments.length > 0) { + cliArguments.push(...appArguments); + } + + if (!options.wait) { + // `xdg-open` will block the process unless stdio is ignored + // and it's detached from the parent even if it's unref'd. + childProcessOptions.stdio = 'ignore'; + childProcessOptions.detached = true; + } + } + + if (options.target) { + cliArguments.push(options.target); + } + + if (platform === 'darwin' && appArguments.length > 0) { + cliArguments.push('--args', ...appArguments); + } + + const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions); + + if (options.wait) { + return new Promise((resolve, reject) => { + subprocess.once('error', reject); + + subprocess.once('close', exitCode => { + if (!options.allowNonzeroExitCode && exitCode > 0) { + reject(new Error(`Exited with code ${exitCode}`)); + return; + } + + resolve(subprocess); + }); + }); + } + + subprocess.unref(); + + return subprocess; +}; + +const open = (target, options) => { + if (typeof target !== 'string') { + throw new TypeError('Expected a `target`'); + } + + return baseOpen({ + ...options, + target + }); +}; + +const openApp = (name, options) => { + if (typeof name !== 'string') { + throw new TypeError('Expected a `name`'); + } + + const {arguments: appArguments = []} = options || {}; + if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) { + throw new TypeError('Expected `appArguments` as Array type'); + } + + return baseOpen({ + ...options, + app: { + name, + arguments: appArguments + } + }); +}; + +function detectArchBinary(binary) { + if (typeof binary === 'string' || Array.isArray(binary)) { + return binary; + } + + const {[arch]: archBinary} = binary; + + if (!archBinary) { + throw new Error(`${arch} is not supported`); + } + + return archBinary; +} + +function detectPlatformBinary({[platform]: platformBinary}, {wsl}) { + if (wsl && isWsl) { + return detectArchBinary(wsl); + } + + if (!platformBinary) { + throw new Error(`${platform} is not supported`); + } + + return detectArchBinary(platformBinary); +} + +const apps = {}; + +defineLazyProperty(apps, 'chrome', () => detectPlatformBinary({ + darwin: 'google chrome', + win32: 'chrome', + linux: ['google-chrome', 'google-chrome-stable', 'chromium'] +}, { + wsl: { + ia32: '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe', + x64: ['/mnt/c/Program Files/Google/Chrome/Application/chrome.exe', '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'] + } +})); + +defineLazyProperty(apps, 'firefox', () => detectPlatformBinary({ + darwin: 'firefox', + win32: 'C:\\Program Files\\Mozilla Firefox\\firefox.exe', + linux: 'firefox' +}, { + wsl: '/mnt/c/Program Files/Mozilla Firefox/firefox.exe' +})); + +defineLazyProperty(apps, 'edge', () => detectPlatformBinary({ + darwin: 'microsoft edge', + win32: 'msedge', + linux: ['microsoft-edge', 'microsoft-edge-dev'] +}, { + wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe' +})); + +open.apps = apps; +open.openApp = openApp; + +var open_1 = open; + +var open$1 = /*@__PURE__*/getDefaultExportFromCjs(open_1); + +var crossSpawn = {exports: {}}; + +var windows; +var hasRequiredWindows; + +function requireWindows () { + if (hasRequiredWindows) return windows; + hasRequiredWindows = 1; + windows = isexe; + isexe.sync = sync; + + var fs = require$$0__default; + + function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT; + + if (!pathext) { + return true + } + + pathext = pathext.split(';'); + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase(); + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false + } + + function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) + } + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), path, options) + } + return windows; +} + +var mode; +var hasRequiredMode; + +function requireMode () { + if (hasRequiredMode) return mode; + hasRequiredMode = 1; + mode = isexe; + isexe.sync = sync; + + var fs = require$$0__default; + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), options) + } + + function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) + } + + function checkMode (stat, options) { + var mod = stat.mode; + var uid = stat.uid; + var gid = stat.gid; + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid(); + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid(); + + var u = parseInt('100', 8); + var g = parseInt('010', 8); + var o = parseInt('001', 8); + var ug = u | g; + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0; + + return ret + } + return mode; +} + +var core; +if (process.platform === 'win32' || commonjsGlobal.TESTING_WINDOWS) { + core = requireWindows(); +} else { + core = requireMode(); +} + +var isexe_1 = isexe$1; +isexe$1.sync = sync; + +function isexe$1 (path, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe$1(path, options || {}, function (er, is) { + if (er) { + reject(er); + } else { + resolve(is); + } + }); + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null; + is = false; + } + } + cb(er, is); + }); +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} + +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys'; + +const path$2 = require$$0$4; +const COLON = isWindows ? ';' : ':'; +const isexe = isexe_1; + +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }); + +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON; + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ); + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : ''; + const pathExt = isWindows ? pathExtExe.split(colon) : ['']; + + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift(''); + } + + return { + pathEnv, + pathExt, + pathExtExe, + } +}; + +const which$1 = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt; + opt = {}; + } + if (!opt) + opt = {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) + + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path$2.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + resolve(subStep(p, i, 0)); + }); + + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii]; + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext); + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }); + }); + + return cb ? step(0).then(res => cb(null, res), cb) : step(0) +}; + +const whichSync = (cmd, opt) => { + opt = opt || {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path$2.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j]; + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }); + if (is) { + if (opt.all) + found.push(cur); + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) +}; + +var which_1 = which$1; +which$1.sync = whichSync; + +var pathKey$1 = {exports: {}}; + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +pathKey$1.exports = pathKey; +// TODO: Remove this for the next major release +pathKey$1.exports.default = pathKey; + +var pathKeyExports = pathKey$1.exports; + +const path$1 = require$$0$4; +const which = which_1; +const getPathKey = pathKeyExports; + +function resolveCommandAttempt(parsed, withoutPathExt) { + const env = parsed.options.env || process.env; + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled; + + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } + + let resolved; + + try { + resolved = which.sync(parsed.command, { + path: env[getPathKey({ env })], + pathExt: withoutPathExt ? path$1.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } + + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path$1.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } + + return resolved; +} + +function resolveCommand$1(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} + +var resolveCommand_1 = resolveCommand$1; + +var _escape = {}; + +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; +} + +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; +} + +_escape.command = escapeCommand; +_escape.argument = escapeArgument; + +var shebangRegex$1 = /^#!(.*)/; + +const shebangRegex = shebangRegex$1; + +var shebangCommand$1 = (string = '') => { + const match = string.match(shebangRegex); + + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; +}; + +const fs = require$$0__default; +const shebangCommand = shebangCommand$1; + +function readShebang$1(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); + + let fd; + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } + + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); +} + +var readShebang_1 = readShebang$1; + +const path = require$$0$4; +const resolveCommand = resolveCommand_1; +const escape$1 = _escape; +const readShebang = readShebang_1; + +const isWin$1 = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); + + const shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + + return resolveCommand(parsed); + } + + return parsed.file; +} + +function parseNonShell(parsed) { + if (!isWin$1) { + return parsed; + } + + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); + + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); + + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); + + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); + + // Escape command & arguments + parsed.command = escape$1.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape$1.argument(arg, needsDoubleEscapeMetaChars)); + + const shellCommand = [parsed.command].concat(parsed.args).join(' '); + + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } + + return parsed; +} + +function parse$4(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); +} + +var parse_1 = parse$4; + +const isWin = process.platform === 'win32'; + +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); +} + +function hookChildProcess(cp, parsed) { + if (!isWin) { + return; + } + + const originalEmit = cp.emit; + + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} + +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + return null; +} + +var enoent$1 = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; + +const cp = require$$2$1; +const parse$3 = parse_1; +const enoent = enoent$1; + +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse$3(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; +} + +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse$3(command, args, options); + + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; +} + +crossSpawn.exports = spawn; +crossSpawn.exports.spawn = spawn; +crossSpawn.exports.sync = spawnSync; + +crossSpawn.exports._parse = parse$3; +crossSpawn.exports._enoent = enoent; + +var crossSpawnExports = crossSpawn.exports; +var spawn$1 = /*@__PURE__*/getDefaultExportFromCjs(crossSpawnExports); + +function openBrowser(url, opt, logger) { + const browser = process.env.BROWSER || ""; + if (browser.toLowerCase().endsWith(".js")) { + executeNodeScript(browser, url, logger); + } else if (browser.toLowerCase() !== "none") { + const browserArgs = process.env.BROWSER_ARGS ? process.env.BROWSER_ARGS.split(" ") : []; + startBrowserProcess(browser, browserArgs, url, logger); + } +} +function executeNodeScript(scriptPath, url, logger) { + const extraArgs = process.argv.slice(2); + const child = spawn$1(process.execPath, [scriptPath, ...extraArgs, url], { + stdio: "inherit" + }); + child.on("close", (code) => { + if (code !== 0) { + logger.error( + colors$1.red( + ` +The script specified as BROWSER environment variable failed. + +${colors$1.cyan( + scriptPath + )} exited with code ${code}.` + ), + { error: null } + ); + } + }); +} +const supportedChromiumBrowsers = [ + "Google Chrome Canary", + "Google Chrome Dev", + "Google Chrome Beta", + "Google Chrome", + "Microsoft Edge", + "Brave Browser", + "Vivaldi", + "Chromium" +]; +async function startBrowserProcess(browser, browserArgs, url, logger) { + const preferredOSXBrowser = browser === "google chrome" ? "Google Chrome" : browser; + const shouldTryOpenChromeWithAppleScript = process.platform === "darwin" && (!preferredOSXBrowser || supportedChromiumBrowsers.includes(preferredOSXBrowser)); + if (shouldTryOpenChromeWithAppleScript) { + try { + const ps = await execAsync("ps cax"); + const openedBrowser = preferredOSXBrowser && ps.includes(preferredOSXBrowser) ? preferredOSXBrowser : supportedChromiumBrowsers.find((b) => ps.includes(b)); + if (openedBrowser) { + await execAsync( + `osascript openChrome.applescript "${encodeURI( + url + )}" "${openedBrowser}"`, + { + cwd: join$2(VITE_PACKAGE_DIR, "bin") + } + ); + return true; + } + } catch (err) { + } + } + if (process.platform === "darwin" && browser === "open") { + browser = void 0; + } + try { + const options = browser ? { app: { name: browser, arguments: browserArgs } } : {}; + new Promise((_, reject) => { + open$1(url, options).then((subprocess) => { + subprocess.on("error", reject); + }).catch(reject); + }).catch((err) => { + logger.error(err.stack || err.message); + }); + return true; + } catch (err) { + return false; + } +} +function execAsync(command, options) { + return new Promise((resolve, reject) => { + exec(command, options, (error, stdout) => { + if (error) { + reject(error); + } else { + resolve(stdout.toString()); + } + }); + }); +} + +function bindCLIShortcuts(server, opts) { + if (!server.httpServer || !process.stdin.isTTY || process.env.CI) { + return; + } + const isDev = isDevServer(server); + if (isDev) { + server._shortcutsOptions = opts; + } + if (opts?.print) { + server.config.logger.info( + colors$1.dim(colors$1.green(" \u279C")) + colors$1.dim(" press ") + colors$1.bold("h + enter") + colors$1.dim(" to show help") + ); + } + const shortcuts = (opts?.customShortcuts ?? []).concat( + isDev ? BASE_DEV_SHORTCUTS : BASE_PREVIEW_SHORTCUTS + ); + let actionRunning = false; + const onInput = async (input) => { + if (actionRunning) return; + if (input === "h") { + const loggedKeys = /* @__PURE__ */ new Set(); + server.config.logger.info("\n Shortcuts"); + for (const shortcut2 of shortcuts) { + if (loggedKeys.has(shortcut2.key)) continue; + loggedKeys.add(shortcut2.key); + if (shortcut2.action == null) continue; + server.config.logger.info( + colors$1.dim(" press ") + colors$1.bold(`${shortcut2.key} + enter`) + colors$1.dim(` to ${shortcut2.description}`) + ); + } + return; + } + const shortcut = shortcuts.find((shortcut2) => shortcut2.key === input); + if (!shortcut || shortcut.action == null) return; + actionRunning = true; + await shortcut.action(server); + actionRunning = false; + }; + const rl = readline.createInterface({ input: process.stdin }); + rl.on("line", onInput); + server.httpServer.on("close", () => rl.close()); +} +const BASE_DEV_SHORTCUTS = [ + { + key: "r", + description: "restart the server", + async action(server) { + await restartServerWithUrls(server); + } + }, + { + key: "u", + description: "show server url", + action(server) { + server.config.logger.info(""); + server.printUrls(); + } + }, + { + key: "o", + description: "open in browser", + action(server) { + server.openBrowser(); + } + }, + { + key: "c", + description: "clear console", + action(server) { + server.config.logger.clearScreen("error"); + } + }, + { + key: "q", + description: "quit", + async action(server) { + try { + await server.close(); + } finally { + process.exit(); + } + } + } +]; +const BASE_PREVIEW_SHORTCUTS = [ + { + key: "o", + description: "open in browser", + action(server) { + const url = server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0]; + if (url) { + openBrowser(url, true, server.config.logger); + } else { + server.config.logger.warn("No URL available to open in browser"); + } + } + }, + { + key: "q", + description: "quit", + async action(server) { + try { + await server.close(); + } finally { + process.exit(); + } + } + } +]; + +function getResolvedOutDirs(root, outDir, outputOptions) { + const resolvedOutDir = path$n.resolve(root, outDir); + if (!outputOptions) return /* @__PURE__ */ new Set([resolvedOutDir]); + return new Set( + arraify(outputOptions).map( + ({ dir }) => dir ? path$n.resolve(root, dir) : resolvedOutDir + ) + ); +} +function resolveEmptyOutDir(emptyOutDir, root, outDirs, logger) { + if (emptyOutDir != null) return emptyOutDir; + for (const outDir of outDirs) { + if (!normalizePath$3(outDir).startsWith(withTrailingSlash(root))) { + logger?.warn( + colors$1.yellow( + ` +${colors$1.bold(`(!)`)} outDir ${colors$1.white( + colors$1.dim(outDir) + )} is not inside project root and will not be emptied. +Use --emptyOutDir to override. +` + ) + ); + return false; + } + } + return true; +} +function resolveChokidarOptions(options, resolvedOutDirs, emptyOutDir, cacheDir) { + const { ignored: ignoredList, ...otherOptions } = options ?? {}; + const ignored = [ + "**/.git/**", + "**/node_modules/**", + "**/test-results/**", + // Playwright + glob.escapePath(cacheDir) + "/**", + ...arraify(ignoredList || []) + ]; + if (emptyOutDir) { + ignored.push( + ...[...resolvedOutDirs].map((outDir) => glob.escapePath(outDir) + "/**") + ); + } + const resolvedWatchOptions = { + ignored, + ignoreInitial: true, + ignorePermissionErrors: true, + ...otherOptions + }; + return resolvedWatchOptions; +} +class NoopWatcher extends EventEmitter$4 { + constructor(options) { + super(); + this.options = options; + } + add() { + return this; + } + unwatch() { + return this; + } + getWatched() { + return {}; + } + ref() { + return this; + } + unref() { + return this; + } + async close() { + } +} +function createNoopWatcher(options) { + return new NoopWatcher(options); +} + +async function fetchModule(server, url, importer, options = {}) { + if (url.startsWith("data:") || isBuiltin(url)) { + return { externalize: url, type: "builtin" }; + } + if (isExternalUrl(url)) { + return { externalize: url, type: "network" }; + } + if (url[0] !== "." && url[0] !== "/") { + const { + isProduction, + resolve: { dedupe, preserveSymlinks }, + root, + ssr + } = server.config; + const overrideConditions = ssr.resolve?.externalConditions || []; + const resolveOptions = { + mainFields: ["main"], + conditions: [], + overrideConditions: [...overrideConditions, "production", "development"], + extensions: [".js", ".cjs", ".json"], + dedupe, + preserveSymlinks, + isBuild: false, + isProduction, + root, + ssrConfig: ssr, + packageCache: server.config.packageCache + }; + const resolved = tryNodeResolve( + url, + importer, + { ...resolveOptions, tryEsmOnly: true }, + false, + void 0, + true + ); + if (!resolved) { + const err = new Error( + `Cannot find module '${url}' imported from '${importer}'` + ); + err.code = "ERR_MODULE_NOT_FOUND"; + throw err; + } + const file = pathToFileURL(resolved.id).toString(); + const type = isFilePathESM(resolved.id, server.config.packageCache) ? "module" : "commonjs"; + return { externalize: file, type }; + } + url = unwrapId$1(url); + let result = await server.transformRequest(url, { ssr: true }); + if (!result) { + throw new Error( + `[vite] transform failed for module '${url}'${importer ? ` imported from '${importer}'` : ""}.` + ); + } + const mod = await server.moduleGraph.getModuleByUrl(url, true); + if (!mod) { + throw new Error( + `[vite] cannot find module '${url}' ${importer ? ` imported from '${importer}'` : ""}.` + ); + } + if (options.inlineSourceMap !== false) { + result = inlineSourceMap(mod, result, options.processSourceMap); + } + if (result.code[0] === "#") + result.code = result.code.replace(/^#!.*/, (s) => " ".repeat(s.length)); + return { code: result.code, file: mod.file }; +} +const OTHER_SOURCE_MAP_REGEXP = new RegExp( + `//# ${SOURCEMAPPING_URL}=data:application/json[^,]+base64,([A-Za-z0-9+/=]+)$`, + "gm" +); +function inlineSourceMap(mod, result, processSourceMap) { + const map = result.map; + let code = result.code; + if (!map || !("version" in map) || code.includes(VITE_RUNTIME_SOURCEMAPPING_SOURCE)) + return result; + OTHER_SOURCE_MAP_REGEXP.lastIndex = 0; + if (OTHER_SOURCE_MAP_REGEXP.test(code)) + code = code.replace(OTHER_SOURCE_MAP_REGEXP, ""); + const sourceMap = processSourceMap?.(map) || map; + result.code = `${code.trimEnd()} +//# sourceURL=${mod.id} +${VITE_RUNTIME_SOURCEMAPPING_SOURCE} +//# ${SOURCEMAPPING_URL}=${genSourceMapUrl(sourceMap)} +`; + return result; +} + +function ssrFetchModule(server, id, importer) { + return fetchModule(server, id, importer, { + processSourceMap(map) { + return Object.assign({}, map, { + mappings: ";".repeat(asyncFunctionDeclarationPaddingLineCount) + map.mappings + }); + } + }); +} + +var bufferUtil$1 = {exports: {}}; + +const BINARY_TYPES$2 = ['nodebuffer', 'arraybuffer', 'fragments']; +const hasBlob$1 = typeof Blob !== 'undefined'; + +if (hasBlob$1) BINARY_TYPES$2.push('blob'); + +var constants = { + BINARY_TYPES: BINARY_TYPES$2, + EMPTY_BUFFER: Buffer.alloc(0), + GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', + hasBlob: hasBlob$1, + kForOnEventAttribute: Symbol('kIsForOnEventAttribute'), + kListener: Symbol('kListener'), + kStatusCode: Symbol('status-code'), + kWebSocket: Symbol('websocket'), + NOOP: () => {} +}; + +const { EMPTY_BUFFER: EMPTY_BUFFER$3 } = constants; + +const FastBuffer$2 = Buffer[Symbol.species]; + +/** + * Merges an array of buffers into a new buffer. + * + * @param {Buffer[]} list The array of buffers to concat + * @param {Number} totalLength The total length of buffers in the list + * @return {Buffer} The resulting buffer + * @public + */ +function concat$1(list, totalLength) { + if (list.length === 0) return EMPTY_BUFFER$3; + if (list.length === 1) return list[0]; + + const target = Buffer.allocUnsafe(totalLength); + let offset = 0; + + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + target.set(buf, offset); + offset += buf.length; + } + + if (offset < totalLength) { + return new FastBuffer$2(target.buffer, target.byteOffset, offset); + } + + return target; +} + +/** + * Masks a buffer using the given mask. + * + * @param {Buffer} source The buffer to mask + * @param {Buffer} mask The mask to use + * @param {Buffer} output The buffer where to store the result + * @param {Number} offset The offset at which to start writing + * @param {Number} length The number of bytes to mask. + * @public + */ +function _mask(source, mask, output, offset, length) { + for (let i = 0; i < length; i++) { + output[offset + i] = source[i] ^ mask[i & 3]; + } +} + +/** + * Unmasks a buffer using the given mask. + * + * @param {Buffer} buffer The buffer to unmask + * @param {Buffer} mask The mask to use + * @public + */ +function _unmask(buffer, mask) { + for (let i = 0; i < buffer.length; i++) { + buffer[i] ^= mask[i & 3]; + } +} + +/** + * Converts a buffer to an `ArrayBuffer`. + * + * @param {Buffer} buf The buffer to convert + * @return {ArrayBuffer} Converted buffer + * @public + */ +function toArrayBuffer$1(buf) { + if (buf.length === buf.buffer.byteLength) { + return buf.buffer; + } + + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length); +} + +/** + * Converts `data` to a `Buffer`. + * + * @param {*} data The data to convert + * @return {Buffer} The buffer + * @throws {TypeError} + * @public + */ +function toBuffer$2(data) { + toBuffer$2.readOnly = true; + + if (Buffer.isBuffer(data)) return data; + + let buf; + + if (data instanceof ArrayBuffer) { + buf = new FastBuffer$2(data); + } else if (ArrayBuffer.isView(data)) { + buf = new FastBuffer$2(data.buffer, data.byteOffset, data.byteLength); + } else { + buf = Buffer.from(data); + toBuffer$2.readOnly = false; + } + + return buf; +} + +bufferUtil$1.exports = { + concat: concat$1, + mask: _mask, + toArrayBuffer: toArrayBuffer$1, + toBuffer: toBuffer$2, + unmask: _unmask +}; + +/* istanbul ignore else */ +if (!process.env.WS_NO_BUFFER_UTIL) { + try { + const bufferUtil = require('bufferutil'); + + bufferUtil$1.exports.mask = function (source, mask, output, offset, length) { + if (length < 48) _mask(source, mask, output, offset, length); + else bufferUtil.mask(source, mask, output, offset, length); + }; + + bufferUtil$1.exports.unmask = function (buffer, mask) { + if (buffer.length < 32) _unmask(buffer, mask); + else bufferUtil.unmask(buffer, mask); + }; + } catch (e) { + // Continue regardless of the error. + } +} + +var bufferUtilExports = bufferUtil$1.exports; + +const kDone = Symbol('kDone'); +const kRun = Symbol('kRun'); + +/** + * A very simple job queue with adjustable concurrency. Adapted from + * https://github.com/STRML/async-limiter + */ +let Limiter$1 = class Limiter { + /** + * Creates a new `Limiter`. + * + * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed + * to run concurrently + */ + constructor(concurrency) { + this[kDone] = () => { + this.pending--; + this[kRun](); + }; + this.concurrency = concurrency || Infinity; + this.jobs = []; + this.pending = 0; + } + + /** + * Adds a job to the queue. + * + * @param {Function} job The job to run + * @public + */ + add(job) { + this.jobs.push(job); + this[kRun](); + } + + /** + * Removes a job from the queue and runs it if possible. + * + * @private + */ + [kRun]() { + if (this.pending === this.concurrency) return; + + if (this.jobs.length) { + const job = this.jobs.shift(); + + this.pending++; + job(this[kDone]); + } + } +}; + +var limiter = Limiter$1; + +const zlib = zlib$1; + +const bufferUtil = bufferUtilExports; +const Limiter = limiter; +const { kStatusCode: kStatusCode$2 } = constants; + +const FastBuffer$1 = Buffer[Symbol.species]; +const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]); +const kPerMessageDeflate = Symbol('permessage-deflate'); +const kTotalLength = Symbol('total-length'); +const kCallback = Symbol('callback'); +const kBuffers = Symbol('buffers'); +const kError$1 = Symbol('error'); + +// +// We limit zlib concurrency, which prevents severe memory fragmentation +// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913 +// and https://github.com/websockets/ws/issues/1202 +// +// Intentionally global; it's the global thread pool that's an issue. +// +let zlibLimiter; + +/** + * permessage-deflate implementation. + */ +let PerMessageDeflate$4 = class PerMessageDeflate { + /** + * Creates a PerMessageDeflate instance. + * + * @param {Object} [options] Configuration options + * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support + * for, or request, a custom client window size + * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ + * acknowledge disabling of client context takeover + * @param {Number} [options.concurrencyLimit=10] The number of concurrent + * calls to zlib + * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the + * use of a custom server window size + * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept + * disabling of server context takeover + * @param {Number} [options.threshold=1024] Size (in bytes) below which + * messages should not be compressed if context takeover is disabled + * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on + * deflate + * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on + * inflate + * @param {Boolean} [isServer=false] Create the instance in either server or + * client mode + * @param {Number} [maxPayload=0] The maximum allowed message length + */ + constructor(options, isServer, maxPayload) { + this._maxPayload = maxPayload | 0; + this._options = options || {}; + this._threshold = + this._options.threshold !== undefined ? this._options.threshold : 1024; + this._isServer = !!isServer; + this._deflate = null; + this._inflate = null; + + this.params = null; + + if (!zlibLimiter) { + const concurrency = + this._options.concurrencyLimit !== undefined + ? this._options.concurrencyLimit + : 10; + zlibLimiter = new Limiter(concurrency); + } + } + + /** + * @type {String} + */ + static get extensionName() { + return 'permessage-deflate'; + } + + /** + * Create an extension negotiation offer. + * + * @return {Object} Extension parameters + * @public + */ + offer() { + const params = {}; + + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + + return params; + } + + /** + * Accept an extension negotiation offer/response. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Object} Accepted configuration + * @public + */ + accept(configurations) { + configurations = this.normalizeParams(configurations); + + this.params = this._isServer + ? this.acceptAsServer(configurations) + : this.acceptAsClient(configurations); + + return this.params; + } + + /** + * Releases all resources used by the extension. + * + * @public + */ + cleanup() { + if (this._inflate) { + this._inflate.close(); + this._inflate = null; + } + + if (this._deflate) { + const callback = this._deflate[kCallback]; + + this._deflate.close(); + this._deflate = null; + + if (callback) { + callback( + new Error( + 'The deflate stream was closed while data was being processed' + ) + ); + } + } + } + + /** + * Accept an extension negotiation offer. + * + * @param {Array} offers The extension negotiation offers + * @return {Object} Accepted configuration + * @private + */ + acceptAsServer(offers) { + const opts = this._options; + const accepted = offers.find((params) => { + if ( + (opts.serverNoContextTakeover === false && + params.server_no_context_takeover) || + (params.server_max_window_bits && + (opts.serverMaxWindowBits === false || + (typeof opts.serverMaxWindowBits === 'number' && + opts.serverMaxWindowBits > params.server_max_window_bits))) || + (typeof opts.clientMaxWindowBits === 'number' && + !params.client_max_window_bits) + ) { + return false; + } + + return true; + }); + + if (!accepted) { + throw new Error('None of the extension offers can be accepted'); + } + + if (opts.serverNoContextTakeover) { + accepted.server_no_context_takeover = true; + } + if (opts.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (typeof opts.serverMaxWindowBits === 'number') { + accepted.server_max_window_bits = opts.serverMaxWindowBits; + } + if (typeof opts.clientMaxWindowBits === 'number') { + accepted.client_max_window_bits = opts.clientMaxWindowBits; + } else if ( + accepted.client_max_window_bits === true || + opts.clientMaxWindowBits === false + ) { + delete accepted.client_max_window_bits; + } + + return accepted; + } + + /** + * Accept the extension negotiation response. + * + * @param {Array} response The extension negotiation response + * @return {Object} Accepted configuration + * @private + */ + acceptAsClient(response) { + const params = response[0]; + + if ( + this._options.clientNoContextTakeover === false && + params.client_no_context_takeover + ) { + throw new Error('Unexpected parameter "client_no_context_takeover"'); + } + + if (!params.client_max_window_bits) { + if (typeof this._options.clientMaxWindowBits === 'number') { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } + } else if ( + this._options.clientMaxWindowBits === false || + (typeof this._options.clientMaxWindowBits === 'number' && + params.client_max_window_bits > this._options.clientMaxWindowBits) + ) { + throw new Error( + 'Unexpected or invalid parameter "client_max_window_bits"' + ); + } + + return params; + } + + /** + * Normalize parameters. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Array} The offers/response with normalized parameters + * @private + */ + normalizeParams(configurations) { + configurations.forEach((params) => { + Object.keys(params).forEach((key) => { + let value = params[key]; + + if (value.length > 1) { + throw new Error(`Parameter "${key}" must have only a single value`); + } + + value = value[0]; + + if (key === 'client_max_window_bits') { + if (value !== true) { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if (!this._isServer) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else if (key === 'server_max_window_bits') { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if ( + key === 'client_no_context_takeover' || + key === 'server_no_context_takeover' + ) { + if (value !== true) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else { + throw new Error(`Unknown parameter "${key}"`); + } + + params[key] = value; + }); + }); + + return configurations; + } + + /** + * Decompress data. Concurrency limited. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + decompress(data, fin, callback) { + zlibLimiter.add((done) => { + this._decompress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + + /** + * Compress data. Concurrency limited. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + compress(data, fin, callback) { + zlibLimiter.add((done) => { + this._compress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + + /** + * Decompress data. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _decompress(data, fin, callback) { + const endpoint = this._isServer ? 'client' : 'server'; + + if (!this._inflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = + typeof this.params[key] !== 'number' + ? zlib.Z_DEFAULT_WINDOWBITS + : this.params[key]; + + this._inflate = zlib.createInflateRaw({ + ...this._options.zlibInflateOptions, + windowBits + }); + this._inflate[kPerMessageDeflate] = this; + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + this._inflate.on('error', inflateOnError); + this._inflate.on('data', inflateOnData); + } + + this._inflate[kCallback] = callback; + + this._inflate.write(data); + if (fin) this._inflate.write(TRAILER); + + this._inflate.flush(() => { + const err = this._inflate[kError$1]; + + if (err) { + this._inflate.close(); + this._inflate = null; + callback(err); + return; + } + + const data = bufferUtil.concat( + this._inflate[kBuffers], + this._inflate[kTotalLength] + ); + + if (this._inflate._readableState.endEmitted) { + this._inflate.close(); + this._inflate = null; + } else { + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._inflate.reset(); + } + } + + callback(null, data); + }); + } + + /** + * Compress data. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _compress(data, fin, callback) { + const endpoint = this._isServer ? 'server' : 'client'; + + if (!this._deflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = + typeof this.params[key] !== 'number' + ? zlib.Z_DEFAULT_WINDOWBITS + : this.params[key]; + + this._deflate = zlib.createDeflateRaw({ + ...this._options.zlibDeflateOptions, + windowBits + }); + + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + + this._deflate.on('data', deflateOnData); + } + + this._deflate[kCallback] = callback; + + this._deflate.write(data); + this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { + if (!this._deflate) { + // + // The deflate stream was closed while data was being processed. + // + return; + } + + let data = bufferUtil.concat( + this._deflate[kBuffers], + this._deflate[kTotalLength] + ); + + if (fin) { + data = new FastBuffer$1(data.buffer, data.byteOffset, data.length - 4); + } + + // + // Ensure that the callback will not be called again in + // `PerMessageDeflate#cleanup()`. + // + this._deflate[kCallback] = null; + + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._deflate.reset(); + } + + callback(null, data); + }); + } +}; + +var permessageDeflate = PerMessageDeflate$4; + +/** + * The listener of the `zlib.DeflateRaw` stream `'data'` event. + * + * @param {Buffer} chunk A chunk of data + * @private + */ +function deflateOnData(chunk) { + this[kBuffers].push(chunk); + this[kTotalLength] += chunk.length; +} + +/** + * The listener of the `zlib.InflateRaw` stream `'data'` event. + * + * @param {Buffer} chunk A chunk of data + * @private + */ +function inflateOnData(chunk) { + this[kTotalLength] += chunk.length; + + if ( + this[kPerMessageDeflate]._maxPayload < 1 || + this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload + ) { + this[kBuffers].push(chunk); + return; + } + + this[kError$1] = new RangeError('Max payload size exceeded'); + this[kError$1].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'; + this[kError$1][kStatusCode$2] = 1009; + this.removeListener('data', inflateOnData); + this.reset(); +} + +/** + * The listener of the `zlib.InflateRaw` stream `'error'` event. + * + * @param {Error} err The emitted error + * @private + */ +function inflateOnError(err) { + // + // There is no need to call `Zlib#close()` as the handle is automatically + // closed when an error is emitted. + // + this[kPerMessageDeflate]._inflate = null; + err[kStatusCode$2] = 1007; + this[kCallback](err); +} + +var validation = {exports: {}}; + +const { isUtf8 } = require$$0$a; + +const { hasBlob } = constants; + +// +// Allowed token characters: +// +// '!', '#', '$', '%', '&', ''', '*', '+', '-', +// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~' +// +// tokenChars[32] === 0 // ' ' +// tokenChars[33] === 1 // '!' +// tokenChars[34] === 0 // '"' +// ... +// +// prettier-ignore +const tokenChars$2 = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 + 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127 +]; + +/** + * Checks if a status code is allowed in a close frame. + * + * @param {Number} code The status code + * @return {Boolean} `true` if the status code is valid, else `false` + * @public + */ +function isValidStatusCode$2(code) { + return ( + (code >= 1000 && + code <= 1014 && + code !== 1004 && + code !== 1005 && + code !== 1006) || + (code >= 3000 && code <= 4999) + ); +} + +/** + * Checks if a given buffer contains only correct UTF-8. + * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by + * Markus Kuhn. + * + * @param {Buffer} buf The buffer to check + * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false` + * @public + */ +function _isValidUTF8(buf) { + const len = buf.length; + let i = 0; + + while (i < len) { + if ((buf[i] & 0x80) === 0) { + // 0xxxxxxx + i++; + } else if ((buf[i] & 0xe0) === 0xc0) { + // 110xxxxx 10xxxxxx + if ( + i + 1 === len || + (buf[i + 1] & 0xc0) !== 0x80 || + (buf[i] & 0xfe) === 0xc0 // Overlong + ) { + return false; + } + + i += 2; + } else if ((buf[i] & 0xf0) === 0xe0) { + // 1110xxxx 10xxxxxx 10xxxxxx + if ( + i + 2 >= len || + (buf[i + 1] & 0xc0) !== 0x80 || + (buf[i + 2] & 0xc0) !== 0x80 || + (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong + (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF) + ) { + return false; + } + + i += 3; + } else if ((buf[i] & 0xf8) === 0xf0) { + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + if ( + i + 3 >= len || + (buf[i + 1] & 0xc0) !== 0x80 || + (buf[i + 2] & 0xc0) !== 0x80 || + (buf[i + 3] & 0xc0) !== 0x80 || + (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong + (buf[i] === 0xf4 && buf[i + 1] > 0x8f) || + buf[i] > 0xf4 // > U+10FFFF + ) { + return false; + } + + i += 4; + } else { + return false; + } + } + + return true; +} + +/** + * Determines whether a value is a `Blob`. + * + * @param {*} value The value to be tested + * @return {Boolean} `true` if `value` is a `Blob`, else `false` + * @private + */ +function isBlob$2(value) { + return ( + hasBlob && + typeof value === 'object' && + typeof value.arrayBuffer === 'function' && + typeof value.type === 'string' && + typeof value.stream === 'function' && + (value[Symbol.toStringTag] === 'Blob' || + value[Symbol.toStringTag] === 'File') + ); +} + +validation.exports = { + isBlob: isBlob$2, + isValidStatusCode: isValidStatusCode$2, + isValidUTF8: _isValidUTF8, + tokenChars: tokenChars$2 +}; + +if (isUtf8) { + validation.exports.isValidUTF8 = function (buf) { + return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf); + }; +} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) { + try { + const isValidUTF8 = require('utf-8-validate'); + + validation.exports.isValidUTF8 = function (buf) { + return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf); + }; + } catch (e) { + // Continue regardless of the error. + } +} + +var validationExports = validation.exports; + +const { Writable: Writable$1 } = require$$0$6; + +const PerMessageDeflate$3 = permessageDeflate; +const { + BINARY_TYPES: BINARY_TYPES$1, + EMPTY_BUFFER: EMPTY_BUFFER$2, + kStatusCode: kStatusCode$1, + kWebSocket: kWebSocket$3 +} = constants; +const { concat, toArrayBuffer, unmask } = bufferUtilExports; +const { isValidStatusCode: isValidStatusCode$1, isValidUTF8 } = validationExports; + +const FastBuffer = Buffer[Symbol.species]; + +const GET_INFO = 0; +const GET_PAYLOAD_LENGTH_16 = 1; +const GET_PAYLOAD_LENGTH_64 = 2; +const GET_MASK = 3; +const GET_DATA = 4; +const INFLATING = 5; +const DEFER_EVENT = 6; + +/** + * HyBi Receiver implementation. + * + * @extends Writable + */ +let Receiver$1 = class Receiver extends Writable$1 { + /** + * Creates a Receiver instance. + * + * @param {Object} [options] Options object + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {String} [options.binaryType=nodebuffer] The type for binary data + * @param {Object} [options.extensions] An object containing the negotiated + * extensions + * @param {Boolean} [options.isServer=false] Specifies whether to operate in + * client or server mode + * @param {Number} [options.maxPayload=0] The maximum allowed message length + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + */ + constructor(options = {}) { + super(); + + this._allowSynchronousEvents = + options.allowSynchronousEvents !== undefined + ? options.allowSynchronousEvents + : true; + this._binaryType = options.binaryType || BINARY_TYPES$1[0]; + this._extensions = options.extensions || {}; + this._isServer = !!options.isServer; + this._maxPayload = options.maxPayload | 0; + this._skipUTF8Validation = !!options.skipUTF8Validation; + this[kWebSocket$3] = undefined; + + this._bufferedBytes = 0; + this._buffers = []; + + this._compressed = false; + this._payloadLength = 0; + this._mask = undefined; + this._fragmented = 0; + this._masked = false; + this._fin = false; + this._opcode = 0; + + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragments = []; + + this._errored = false; + this._loop = false; + this._state = GET_INFO; + } + + /** + * Implements `Writable.prototype._write()`. + * + * @param {Buffer} chunk The chunk of data to write + * @param {String} encoding The character encoding of `chunk` + * @param {Function} cb Callback + * @private + */ + _write(chunk, encoding, cb) { + if (this._opcode === 0x08 && this._state == GET_INFO) return cb(); + + this._bufferedBytes += chunk.length; + this._buffers.push(chunk); + this.startLoop(cb); + } + + /** + * Consumes `n` bytes from the buffered data. + * + * @param {Number} n The number of bytes to consume + * @return {Buffer} The consumed bytes + * @private + */ + consume(n) { + this._bufferedBytes -= n; + + if (n === this._buffers[0].length) return this._buffers.shift(); + + if (n < this._buffers[0].length) { + const buf = this._buffers[0]; + this._buffers[0] = new FastBuffer( + buf.buffer, + buf.byteOffset + n, + buf.length - n + ); + + return new FastBuffer(buf.buffer, buf.byteOffset, n); + } + + const dst = Buffer.allocUnsafe(n); + + do { + const buf = this._buffers[0]; + const offset = dst.length - n; + + if (n >= buf.length) { + dst.set(this._buffers.shift(), offset); + } else { + dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); + this._buffers[0] = new FastBuffer( + buf.buffer, + buf.byteOffset + n, + buf.length - n + ); + } + + n -= buf.length; + } while (n > 0); + + return dst; + } + + /** + * Starts the parsing loop. + * + * @param {Function} cb Callback + * @private + */ + startLoop(cb) { + this._loop = true; + + do { + switch (this._state) { + case GET_INFO: + this.getInfo(cb); + break; + case GET_PAYLOAD_LENGTH_16: + this.getPayloadLength16(cb); + break; + case GET_PAYLOAD_LENGTH_64: + this.getPayloadLength64(cb); + break; + case GET_MASK: + this.getMask(); + break; + case GET_DATA: + this.getData(cb); + break; + case INFLATING: + case DEFER_EVENT: + this._loop = false; + return; + } + } while (this._loop); + + if (!this._errored) cb(); + } + + /** + * Reads the first two bytes of a frame. + * + * @param {Function} cb Callback + * @private + */ + getInfo(cb) { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + + const buf = this.consume(2); + + if ((buf[0] & 0x30) !== 0x00) { + const error = this.createError( + RangeError, + 'RSV2 and RSV3 must be clear', + true, + 1002, + 'WS_ERR_UNEXPECTED_RSV_2_3' + ); + + cb(error); + return; + } + + const compressed = (buf[0] & 0x40) === 0x40; + + if (compressed && !this._extensions[PerMessageDeflate$3.extensionName]) { + const error = this.createError( + RangeError, + 'RSV1 must be clear', + true, + 1002, + 'WS_ERR_UNEXPECTED_RSV_1' + ); + + cb(error); + return; + } + + this._fin = (buf[0] & 0x80) === 0x80; + this._opcode = buf[0] & 0x0f; + this._payloadLength = buf[1] & 0x7f; + + if (this._opcode === 0x00) { + if (compressed) { + const error = this.createError( + RangeError, + 'RSV1 must be clear', + true, + 1002, + 'WS_ERR_UNEXPECTED_RSV_1' + ); + + cb(error); + return; + } + + if (!this._fragmented) { + const error = this.createError( + RangeError, + 'invalid opcode 0', + true, + 1002, + 'WS_ERR_INVALID_OPCODE' + ); + + cb(error); + return; + } + + this._opcode = this._fragmented; + } else if (this._opcode === 0x01 || this._opcode === 0x02) { + if (this._fragmented) { + const error = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + 'WS_ERR_INVALID_OPCODE' + ); + + cb(error); + return; + } + + this._compressed = compressed; + } else if (this._opcode > 0x07 && this._opcode < 0x0b) { + if (!this._fin) { + const error = this.createError( + RangeError, + 'FIN must be set', + true, + 1002, + 'WS_ERR_EXPECTED_FIN' + ); + + cb(error); + return; + } + + if (compressed) { + const error = this.createError( + RangeError, + 'RSV1 must be clear', + true, + 1002, + 'WS_ERR_UNEXPECTED_RSV_1' + ); + + cb(error); + return; + } + + if ( + this._payloadLength > 0x7d || + (this._opcode === 0x08 && this._payloadLength === 1) + ) { + const error = this.createError( + RangeError, + `invalid payload length ${this._payloadLength}`, + true, + 1002, + 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH' + ); + + cb(error); + return; + } + } else { + const error = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + 'WS_ERR_INVALID_OPCODE' + ); + + cb(error); + return; + } + + if (!this._fin && !this._fragmented) this._fragmented = this._opcode; + this._masked = (buf[1] & 0x80) === 0x80; + + if (this._isServer) { + if (!this._masked) { + const error = this.createError( + RangeError, + 'MASK must be set', + true, + 1002, + 'WS_ERR_EXPECTED_MASK' + ); + + cb(error); + return; + } + } else if (this._masked) { + const error = this.createError( + RangeError, + 'MASK must be clear', + true, + 1002, + 'WS_ERR_UNEXPECTED_MASK' + ); + + cb(error); + return; + } + + if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16; + else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64; + else this.haveLength(cb); + } + + /** + * Gets extended payload length (7+16). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength16(cb) { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + + this._payloadLength = this.consume(2).readUInt16BE(0); + this.haveLength(cb); + } + + /** + * Gets extended payload length (7+64). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength64(cb) { + if (this._bufferedBytes < 8) { + this._loop = false; + return; + } + + const buf = this.consume(8); + const num = buf.readUInt32BE(0); + + // + // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned + // if payload length is greater than this number. + // + if (num > Math.pow(2, 53 - 32) - 1) { + const error = this.createError( + RangeError, + 'Unsupported WebSocket frame: payload length > 2^53 - 1', + false, + 1009, + 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH' + ); + + cb(error); + return; + } + + this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); + this.haveLength(cb); + } + + /** + * Payload length has been read. + * + * @param {Function} cb Callback + * @private + */ + haveLength(cb) { + if (this._payloadLength && this._opcode < 0x08) { + this._totalPayloadLength += this._payloadLength; + if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { + const error = this.createError( + RangeError, + 'Max payload size exceeded', + false, + 1009, + 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH' + ); + + cb(error); + return; + } + } + + if (this._masked) this._state = GET_MASK; + else this._state = GET_DATA; + } + + /** + * Reads mask bytes. + * + * @private + */ + getMask() { + if (this._bufferedBytes < 4) { + this._loop = false; + return; + } + + this._mask = this.consume(4); + this._state = GET_DATA; + } + + /** + * Reads data bytes. + * + * @param {Function} cb Callback + * @private + */ + getData(cb) { + let data = EMPTY_BUFFER$2; + + if (this._payloadLength) { + if (this._bufferedBytes < this._payloadLength) { + this._loop = false; + return; + } + + data = this.consume(this._payloadLength); + + if ( + this._masked && + (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0 + ) { + unmask(data, this._mask); + } + } + + if (this._opcode > 0x07) { + this.controlMessage(data, cb); + return; + } + + if (this._compressed) { + this._state = INFLATING; + this.decompress(data, cb); + return; + } + + if (data.length) { + // + // This message is not compressed so its length is the sum of the payload + // length of all fragments. + // + this._messageLength = this._totalPayloadLength; + this._fragments.push(data); + } + + this.dataMessage(cb); + } + + /** + * Decompresses data. + * + * @param {Buffer} data Compressed data + * @param {Function} cb Callback + * @private + */ + decompress(data, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate$3.extensionName]; + + perMessageDeflate.decompress(data, this._fin, (err, buf) => { + if (err) return cb(err); + + if (buf.length) { + this._messageLength += buf.length; + if (this._messageLength > this._maxPayload && this._maxPayload > 0) { + const error = this.createError( + RangeError, + 'Max payload size exceeded', + false, + 1009, + 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH' + ); + + cb(error); + return; + } + + this._fragments.push(buf); + } + + this.dataMessage(cb); + if (this._state === GET_INFO) this.startLoop(cb); + }); + } + + /** + * Handles a data message. + * + * @param {Function} cb Callback + * @private + */ + dataMessage(cb) { + if (!this._fin) { + this._state = GET_INFO; + return; + } + + const messageLength = this._messageLength; + const fragments = this._fragments; + + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragmented = 0; + this._fragments = []; + + if (this._opcode === 2) { + let data; + + if (this._binaryType === 'nodebuffer') { + data = concat(fragments, messageLength); + } else if (this._binaryType === 'arraybuffer') { + data = toArrayBuffer(concat(fragments, messageLength)); + } else if (this._binaryType === 'blob') { + data = new Blob(fragments); + } else { + data = fragments; + } + + if (this._allowSynchronousEvents) { + this.emit('message', data, true); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit('message', data, true); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } else { + const buf = concat(fragments, messageLength); + + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + const error = this.createError( + Error, + 'invalid UTF-8 sequence', + true, + 1007, + 'WS_ERR_INVALID_UTF8' + ); + + cb(error); + return; + } + + if (this._state === INFLATING || this._allowSynchronousEvents) { + this.emit('message', buf, false); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit('message', buf, false); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } + } + + /** + * Handles a control message. + * + * @param {Buffer} data Data to handle + * @return {(Error|RangeError|undefined)} A possible error + * @private + */ + controlMessage(data, cb) { + if (this._opcode === 0x08) { + if (data.length === 0) { + this._loop = false; + this.emit('conclude', 1005, EMPTY_BUFFER$2); + this.end(); + } else { + const code = data.readUInt16BE(0); + + if (!isValidStatusCode$1(code)) { + const error = this.createError( + RangeError, + `invalid status code ${code}`, + true, + 1002, + 'WS_ERR_INVALID_CLOSE_CODE' + ); + + cb(error); + return; + } + + const buf = new FastBuffer( + data.buffer, + data.byteOffset + 2, + data.length - 2 + ); + + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + const error = this.createError( + Error, + 'invalid UTF-8 sequence', + true, + 1007, + 'WS_ERR_INVALID_UTF8' + ); + + cb(error); + return; + } + + this._loop = false; + this.emit('conclude', code, buf); + this.end(); + } + + this._state = GET_INFO; + return; + } + + if (this._allowSynchronousEvents) { + this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } + + /** + * Builds an error object. + * + * @param {function(new:Error|RangeError)} ErrorCtor The error constructor + * @param {String} message The error message + * @param {Boolean} prefix Specifies whether or not to add a default prefix to + * `message` + * @param {Number} statusCode The status code + * @param {String} errorCode The exposed error code + * @return {(Error|RangeError)} The error + * @private + */ + createError(ErrorCtor, message, prefix, statusCode, errorCode) { + this._loop = false; + this._errored = true; + + const err = new ErrorCtor( + prefix ? `Invalid WebSocket frame: ${message}` : message + ); + + Error.captureStackTrace(err, this.createError); + err.code = errorCode; + err[kStatusCode$1] = statusCode; + return err; + } +}; + +var receiver = Receiver$1; + +/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */ +const { randomFillSync } = require$$3$1; + +const PerMessageDeflate$2 = permessageDeflate; +const { EMPTY_BUFFER: EMPTY_BUFFER$1, kWebSocket: kWebSocket$2, NOOP: NOOP$2 } = constants; +const { isBlob: isBlob$1, isValidStatusCode } = validationExports; +const { mask: applyMask, toBuffer: toBuffer$1 } = bufferUtilExports; + +const kByteLength = Symbol('kByteLength'); +const maskBuffer = Buffer.alloc(4); +const RANDOM_POOL_SIZE = 8 * 1024; +let randomPool; +let randomPoolPointer = RANDOM_POOL_SIZE; + +const DEFAULT = 0; +const DEFLATING = 1; +const GET_BLOB_DATA = 2; + +/** + * HyBi Sender implementation. + */ +let Sender$1 = class Sender { + /** + * Creates a Sender instance. + * + * @param {Duplex} socket The connection socket + * @param {Object} [extensions] An object containing the negotiated extensions + * @param {Function} [generateMask] The function used to generate the masking + * key + */ + constructor(socket, extensions, generateMask) { + this._extensions = extensions || {}; + + if (generateMask) { + this._generateMask = generateMask; + this._maskBuffer = Buffer.alloc(4); + } + + this._socket = socket; + + this._firstFragment = true; + this._compress = false; + + this._bufferedBytes = 0; + this._queue = []; + this._state = DEFAULT; + this.onerror = NOOP$2; + this[kWebSocket$2] = undefined; + } + + /** + * Frames a piece of data according to the HyBi WebSocket protocol. + * + * @param {(Buffer|String)} data The data to frame + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @return {(Buffer|String)[]} The framed data + * @public + */ + static frame(data, options) { + let mask; + let merge = false; + let offset = 2; + let skipMasking = false; + + if (options.mask) { + mask = options.maskBuffer || maskBuffer; + + if (options.generateMask) { + options.generateMask(mask); + } else { + if (randomPoolPointer === RANDOM_POOL_SIZE) { + /* istanbul ignore else */ + if (randomPool === undefined) { + // + // This is lazily initialized because server-sent frames must not + // be masked so it may never be used. + // + randomPool = Buffer.alloc(RANDOM_POOL_SIZE); + } + + randomFillSync(randomPool, 0, RANDOM_POOL_SIZE); + randomPoolPointer = 0; + } + + mask[0] = randomPool[randomPoolPointer++]; + mask[1] = randomPool[randomPoolPointer++]; + mask[2] = randomPool[randomPoolPointer++]; + mask[3] = randomPool[randomPoolPointer++]; + } + + skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; + offset = 6; + } + + let dataLength; + + if (typeof data === 'string') { + if ( + (!options.mask || skipMasking) && + options[kByteLength] !== undefined + ) { + dataLength = options[kByteLength]; + } else { + data = Buffer.from(data); + dataLength = data.length; + } + } else { + dataLength = data.length; + merge = options.mask && options.readOnly && !skipMasking; + } + + let payloadLength = dataLength; + + if (dataLength >= 65536) { + offset += 8; + payloadLength = 127; + } else if (dataLength > 125) { + offset += 2; + payloadLength = 126; + } + + const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); + + target[0] = options.fin ? options.opcode | 0x80 : options.opcode; + if (options.rsv1) target[0] |= 0x40; + + target[1] = payloadLength; + + if (payloadLength === 126) { + target.writeUInt16BE(dataLength, 2); + } else if (payloadLength === 127) { + target[2] = target[3] = 0; + target.writeUIntBE(dataLength, 4, 6); + } + + if (!options.mask) return [target, data]; + + target[1] |= 0x80; + target[offset - 4] = mask[0]; + target[offset - 3] = mask[1]; + target[offset - 2] = mask[2]; + target[offset - 1] = mask[3]; + + if (skipMasking) return [target, data]; + + if (merge) { + applyMask(data, mask, target, offset, dataLength); + return [target]; + } + + applyMask(data, mask, data, 0, dataLength); + return [target, data]; + } + + /** + * Sends a close message to the other peer. + * + * @param {Number} [code] The status code component of the body + * @param {(String|Buffer)} [data] The message component of the body + * @param {Boolean} [mask=false] Specifies whether or not to mask the message + * @param {Function} [cb] Callback + * @public + */ + close(code, data, mask, cb) { + let buf; + + if (code === undefined) { + buf = EMPTY_BUFFER$1; + } else if (typeof code !== 'number' || !isValidStatusCode(code)) { + throw new TypeError('First argument must be a valid error code number'); + } else if (data === undefined || !data.length) { + buf = Buffer.allocUnsafe(2); + buf.writeUInt16BE(code, 0); + } else { + const length = Buffer.byteLength(data); + + if (length > 123) { + throw new RangeError('The message must not be greater than 123 bytes'); + } + + buf = Buffer.allocUnsafe(2 + length); + buf.writeUInt16BE(code, 0); + + if (typeof data === 'string') { + buf.write(data, 2); + } else { + buf.set(data, 2); + } + } + + const options = { + [kByteLength]: buf.length, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 0x08, + readOnly: false, + rsv1: false + }; + + if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, buf, false, options, cb]); + } else { + this.sendFrame(Sender.frame(buf, options), cb); + } + } + + /** + * Sends a ping message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + ping(data, mask, cb) { + let byteLength; + let readOnly; + + if (typeof data === 'string') { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob$1(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer$1(data); + byteLength = data.length; + readOnly = toBuffer$1.readOnly; + } + + if (byteLength > 125) { + throw new RangeError('The data size must not be greater than 125 bytes'); + } + + const options = { + [kByteLength]: byteLength, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 0x09, + readOnly, + rsv1: false + }; + + if (isBlob$1(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, false, options, cb]); + } else { + this.getBlobData(data, false, options, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(Sender.frame(data, options), cb); + } + } + + /** + * Sends a pong message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + pong(data, mask, cb) { + let byteLength; + let readOnly; + + if (typeof data === 'string') { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob$1(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer$1(data); + byteLength = data.length; + readOnly = toBuffer$1.readOnly; + } + + if (byteLength > 125) { + throw new RangeError('The data size must not be greater than 125 bytes'); + } + + const options = { + [kByteLength]: byteLength, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 0x0a, + readOnly, + rsv1: false + }; + + if (isBlob$1(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, false, options, cb]); + } else { + this.getBlobData(data, false, options, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(Sender.frame(data, options), cb); + } + } + + /** + * Sends a data message to the other peer. + * + * @param {*} data The message to send + * @param {Object} options Options object + * @param {Boolean} [options.binary=false] Specifies whether `data` is binary + * or text + * @param {Boolean} [options.compress=false] Specifies whether or not to + * compress `data` + * @param {Boolean} [options.fin=false] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Function} [cb] Callback + * @public + */ + send(data, options, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName]; + let opcode = options.binary ? 2 : 1; + let rsv1 = options.compress; + + let byteLength; + let readOnly; + + if (typeof data === 'string') { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob$1(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer$1(data); + byteLength = data.length; + readOnly = toBuffer$1.readOnly; + } + + if (this._firstFragment) { + this._firstFragment = false; + if ( + rsv1 && + perMessageDeflate && + perMessageDeflate.params[ + perMessageDeflate._isServer + ? 'server_no_context_takeover' + : 'client_no_context_takeover' + ] + ) { + rsv1 = byteLength >= perMessageDeflate._threshold; + } + this._compress = rsv1; + } else { + rsv1 = false; + opcode = 0; + } + + if (options.fin) this._firstFragment = true; + + const opts = { + [kByteLength]: byteLength, + fin: options.fin, + generateMask: this._generateMask, + mask: options.mask, + maskBuffer: this._maskBuffer, + opcode, + readOnly, + rsv1 + }; + + if (isBlob$1(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, this._compress, opts, cb]); + } else { + this.getBlobData(data, this._compress, opts, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, this._compress, opts, cb]); + } else { + this.dispatch(data, this._compress, opts, cb); + } + } + + /** + * Gets the contents of a blob as binary data. + * + * @param {Blob} blob The blob + * @param {Boolean} [compress=false] Specifies whether or not to compress + * the data + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + getBlobData(blob, compress, options, cb) { + this._bufferedBytes += options[kByteLength]; + this._state = GET_BLOB_DATA; + + blob + .arrayBuffer() + .then((arrayBuffer) => { + if (this._socket.destroyed) { + const err = new Error( + 'The socket was closed while the blob was being read' + ); + + // + // `callCallbacks` is called in the next tick to ensure that errors + // that might be thrown in the callbacks behave like errors thrown + // outside the promise chain. + // + process.nextTick(callCallbacks, this, err, cb); + return; + } + + this._bufferedBytes -= options[kByteLength]; + const data = toBuffer$1(arrayBuffer); + + if (!compress) { + this._state = DEFAULT; + this.sendFrame(Sender.frame(data, options), cb); + this.dequeue(); + } else { + this.dispatch(data, compress, options, cb); + } + }) + .catch((err) => { + // + // `onError` is called in the next tick for the same reason that + // `callCallbacks` above is. + // + process.nextTick(onError, this, err, cb); + }); + } + + /** + * Dispatches a message. + * + * @param {(Buffer|String)} data The message to send + * @param {Boolean} [compress=false] Specifies whether or not to compress + * `data` + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + dispatch(data, compress, options, cb) { + if (!compress) { + this.sendFrame(Sender.frame(data, options), cb); + return; + } + + const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName]; + + this._bufferedBytes += options[kByteLength]; + this._state = DEFLATING; + perMessageDeflate.compress(data, options.fin, (_, buf) => { + if (this._socket.destroyed) { + const err = new Error( + 'The socket was closed while data was being compressed' + ); + + callCallbacks(this, err, cb); + return; + } + + this._bufferedBytes -= options[kByteLength]; + this._state = DEFAULT; + options.readOnly = false; + this.sendFrame(Sender.frame(buf, options), cb); + this.dequeue(); + }); + } + + /** + * Executes queued send operations. + * + * @private + */ + dequeue() { + while (this._state === DEFAULT && this._queue.length) { + const params = this._queue.shift(); + + this._bufferedBytes -= params[3][kByteLength]; + Reflect.apply(params[0], this, params.slice(1)); + } + } + + /** + * Enqueues a send operation. + * + * @param {Array} params Send operation parameters. + * @private + */ + enqueue(params) { + this._bufferedBytes += params[3][kByteLength]; + this._queue.push(params); + } + + /** + * Sends a frame. + * + * @param {Buffer[]} list The frame to send + * @param {Function} [cb] Callback + * @private + */ + sendFrame(list, cb) { + if (list.length === 2) { + this._socket.cork(); + this._socket.write(list[0]); + this._socket.write(list[1], cb); + this._socket.uncork(); + } else { + this._socket.write(list[0], cb); + } + } +}; + +var sender = Sender$1; + +/** + * Calls queued callbacks with an error. + * + * @param {Sender} sender The `Sender` instance + * @param {Error} err The error to call the callbacks with + * @param {Function} [cb] The first callback + * @private + */ +function callCallbacks(sender, err, cb) { + if (typeof cb === 'function') cb(err); + + for (let i = 0; i < sender._queue.length; i++) { + const params = sender._queue[i]; + const callback = params[params.length - 1]; + + if (typeof callback === 'function') callback(err); + } +} + +/** + * Handles a `Sender` error. + * + * @param {Sender} sender The `Sender` instance + * @param {Error} err The error + * @param {Function} [cb] The first pending callback + * @private + */ +function onError(sender, err, cb) { + callCallbacks(sender, err, cb); + sender.onerror(err); +} + +const { kForOnEventAttribute: kForOnEventAttribute$1, kListener: kListener$1 } = constants; + +const kCode = Symbol('kCode'); +const kData = Symbol('kData'); +const kError = Symbol('kError'); +const kMessage = Symbol('kMessage'); +const kReason = Symbol('kReason'); +const kTarget = Symbol('kTarget'); +const kType = Symbol('kType'); +const kWasClean = Symbol('kWasClean'); + +/** + * Class representing an event. + */ +let Event$1 = class Event { + /** + * Create a new `Event`. + * + * @param {String} type The name of the event + * @throws {TypeError} If the `type` argument is not specified + */ + constructor(type) { + this[kTarget] = null; + this[kType] = type; + } + + /** + * @type {*} + */ + get target() { + return this[kTarget]; + } + + /** + * @type {String} + */ + get type() { + return this[kType]; + } +}; + +Object.defineProperty(Event$1.prototype, 'target', { enumerable: true }); +Object.defineProperty(Event$1.prototype, 'type', { enumerable: true }); + +/** + * Class representing a close event. + * + * @extends Event + */ +class CloseEvent extends Event$1 { + /** + * Create a new `CloseEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {Number} [options.code=0] The status code explaining why the + * connection was closed + * @param {String} [options.reason=''] A human-readable string explaining why + * the connection was closed + * @param {Boolean} [options.wasClean=false] Indicates whether or not the + * connection was cleanly closed + */ + constructor(type, options = {}) { + super(type); + + this[kCode] = options.code === undefined ? 0 : options.code; + this[kReason] = options.reason === undefined ? '' : options.reason; + this[kWasClean] = options.wasClean === undefined ? false : options.wasClean; + } + + /** + * @type {Number} + */ + get code() { + return this[kCode]; + } + + /** + * @type {String} + */ + get reason() { + return this[kReason]; + } + + /** + * @type {Boolean} + */ + get wasClean() { + return this[kWasClean]; + } +} + +Object.defineProperty(CloseEvent.prototype, 'code', { enumerable: true }); +Object.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true }); +Object.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true }); + +/** + * Class representing an error event. + * + * @extends Event + */ +class ErrorEvent extends Event$1 { + /** + * Create a new `ErrorEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.error=null] The error that generated this event + * @param {String} [options.message=''] The error message + */ + constructor(type, options = {}) { + super(type); + + this[kError] = options.error === undefined ? null : options.error; + this[kMessage] = options.message === undefined ? '' : options.message; + } + + /** + * @type {*} + */ + get error() { + return this[kError]; + } + + /** + * @type {String} + */ + get message() { + return this[kMessage]; + } +} + +Object.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true }); +Object.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true }); + +/** + * Class representing a message event. + * + * @extends Event + */ +class MessageEvent extends Event$1 { + /** + * Create a new `MessageEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.data=null] The message content + */ + constructor(type, options = {}) { + super(type); + + this[kData] = options.data === undefined ? null : options.data; + } + + /** + * @type {*} + */ + get data() { + return this[kData]; + } +} + +Object.defineProperty(MessageEvent.prototype, 'data', { enumerable: true }); + +/** + * This provides methods for emulating the `EventTarget` interface. It's not + * meant to be used directly. + * + * @mixin + */ +const EventTarget = { + /** + * Register an event listener. + * + * @param {String} type A string representing the event type to listen for + * @param {(Function|Object)} handler The listener to add + * @param {Object} [options] An options object specifies characteristics about + * the event listener + * @param {Boolean} [options.once=false] A `Boolean` indicating that the + * listener should be invoked at most once after being added. If `true`, + * the listener would be automatically removed when invoked. + * @public + */ + addEventListener(type, handler, options = {}) { + for (const listener of this.listeners(type)) { + if ( + !options[kForOnEventAttribute$1] && + listener[kListener$1] === handler && + !listener[kForOnEventAttribute$1] + ) { + return; + } + } + + let wrapper; + + if (type === 'message') { + wrapper = function onMessage(data, isBinary) { + const event = new MessageEvent('message', { + data: isBinary ? data : data.toString() + }); + + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === 'close') { + wrapper = function onClose(code, message) { + const event = new CloseEvent('close', { + code, + reason: message.toString(), + wasClean: this._closeFrameReceived && this._closeFrameSent + }); + + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === 'error') { + wrapper = function onError(error) { + const event = new ErrorEvent('error', { + error, + message: error.message + }); + + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === 'open') { + wrapper = function onOpen() { + const event = new Event$1('open'); + + event[kTarget] = this; + callListener(handler, this, event); + }; + } else { + return; + } + + wrapper[kForOnEventAttribute$1] = !!options[kForOnEventAttribute$1]; + wrapper[kListener$1] = handler; + + if (options.once) { + this.once(type, wrapper); + } else { + this.on(type, wrapper); + } + }, + + /** + * Remove an event listener. + * + * @param {String} type A string representing the event type to remove + * @param {(Function|Object)} handler The listener to remove + * @public + */ + removeEventListener(type, handler) { + for (const listener of this.listeners(type)) { + if (listener[kListener$1] === handler && !listener[kForOnEventAttribute$1]) { + this.removeListener(type, listener); + break; + } + } + } +}; + +var eventTarget = { + CloseEvent, + ErrorEvent, + Event: Event$1, + EventTarget, + MessageEvent +}; + +/** + * Call an event listener + * + * @param {(Function|Object)} listener The listener to call + * @param {*} thisArg The value to use as `this`` when calling the listener + * @param {Event} event The event to pass to the listener + * @private + */ +function callListener(listener, thisArg, event) { + if (typeof listener === 'object' && listener.handleEvent) { + listener.handleEvent.call(listener, event); + } else { + listener.call(thisArg, event); + } +} + +const { tokenChars: tokenChars$1 } = validationExports; + +/** + * Adds an offer to the map of extension offers or a parameter to the map of + * parameters. + * + * @param {Object} dest The map of extension offers or parameters + * @param {String} name The extension or parameter name + * @param {(Object|Boolean|String)} elem The extension parameters or the + * parameter value + * @private + */ +function push(dest, name, elem) { + if (dest[name] === undefined) dest[name] = [elem]; + else dest[name].push(elem); +} + +/** + * Parses the `Sec-WebSocket-Extensions` header into an object. + * + * @param {String} header The field value of the header + * @return {Object} The parsed object + * @public + */ +function parse$2(header) { + const offers = Object.create(null); + let params = Object.create(null); + let mustUnescape = false; + let isEscaping = false; + let inQuotes = false; + let extensionName; + let paramName; + let start = -1; + let code = -1; + let end = -1; + let i = 0; + + for (; i < header.length; i++) { + code = header.charCodeAt(i); + + if (extensionName === undefined) { + if (end === -1 && tokenChars$1[code] === 1) { + if (start === -1) start = i; + } else if ( + i !== 0 && + (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */ + ) { + if (end === -1 && start !== -1) end = i; + } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + + if (end === -1) end = i; + const name = header.slice(start, end); + if (code === 0x2c) { + push(offers, name, params); + params = Object.create(null); + } else { + extensionName = name; + } + + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (paramName === undefined) { + if (end === -1 && tokenChars$1[code] === 1) { + if (start === -1) start = i; + } else if (code === 0x20 || code === 0x09) { + if (end === -1 && start !== -1) end = i; + } else if (code === 0x3b || code === 0x2c) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + + if (end === -1) end = i; + push(params, header.slice(start, end), true); + if (code === 0x2c) { + push(offers, extensionName, params); + params = Object.create(null); + extensionName = undefined; + } + + start = end = -1; + } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) { + paramName = header.slice(start, i); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else { + // + // The value of a quoted-string after unescaping must conform to the + // token ABNF, so only token characters are valid. + // Ref: https://tools.ietf.org/html/rfc6455#section-9.1 + // + if (isEscaping) { + if (tokenChars$1[code] !== 1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (start === -1) start = i; + else if (!mustUnescape) mustUnescape = true; + isEscaping = false; + } else if (inQuotes) { + if (tokenChars$1[code] === 1) { + if (start === -1) start = i; + } else if (code === 0x22 /* '"' */ && start !== -1) { + inQuotes = false; + end = i; + } else if (code === 0x5c /* '\' */) { + isEscaping = true; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) { + inQuotes = true; + } else if (end === -1 && tokenChars$1[code] === 1) { + if (start === -1) start = i; + } else if (start !== -1 && (code === 0x20 || code === 0x09)) { + if (end === -1) end = i; + } else if (code === 0x3b || code === 0x2c) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + + if (end === -1) end = i; + let value = header.slice(start, end); + if (mustUnescape) { + value = value.replace(/\\/g, ''); + mustUnescape = false; + } + push(params, paramName, value); + if (code === 0x2c) { + push(offers, extensionName, params); + params = Object.create(null); + extensionName = undefined; + } + + paramName = undefined; + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + } + + if (start === -1 || inQuotes || code === 0x20 || code === 0x09) { + throw new SyntaxError('Unexpected end of input'); + } + + if (end === -1) end = i; + const token = header.slice(start, end); + if (extensionName === undefined) { + push(offers, token, params); + } else { + if (paramName === undefined) { + push(params, token, true); + } else if (mustUnescape) { + push(params, paramName, token.replace(/\\/g, '')); + } else { + push(params, paramName, token); + } + push(offers, extensionName, params); + } + + return offers; +} + +/** + * Builds the `Sec-WebSocket-Extensions` header field value. + * + * @param {Object} extensions The map of extensions and parameters to format + * @return {String} A string representing the given object + * @public + */ +function format$1(extensions) { + return Object.keys(extensions) + .map((extension) => { + let configurations = extensions[extension]; + if (!Array.isArray(configurations)) configurations = [configurations]; + return configurations + .map((params) => { + return [extension] + .concat( + Object.keys(params).map((k) => { + let values = params[k]; + if (!Array.isArray(values)) values = [values]; + return values + .map((v) => (v === true ? k : `${k}=${v}`)) + .join('; '); + }) + ) + .join('; '); + }) + .join(', '); + }) + .join(', '); +} + +var extension$1 = { format: format$1, parse: parse$2 }; + +/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */ + +const EventEmitter$1 = require$$0$7; +const https$2 = require$$1$1; +const http$3 = require$$1; +const net = require$$4$1; +const tls = require$$4$2; +const { randomBytes, createHash: createHash$1 } = require$$3$1; +const { URL: URL$2 } = require$$0$9; + +const PerMessageDeflate$1 = permessageDeflate; +const Receiver = receiver; +const Sender = sender; +const { isBlob } = validationExports; + +const { + BINARY_TYPES, + EMPTY_BUFFER, + GUID: GUID$1, + kForOnEventAttribute, + kListener, + kStatusCode, + kWebSocket: kWebSocket$1, + NOOP: NOOP$1 +} = constants; +const { + EventTarget: { addEventListener, removeEventListener } +} = eventTarget; +const { format, parse: parse$1 } = extension$1; +const { toBuffer } = bufferUtilExports; + +const closeTimeout = 30 * 1000; +const kAborted = Symbol('kAborted'); +const protocolVersions = [8, 13]; +const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']; +const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; + +/** + * Class representing a WebSocket. + * + * @extends EventEmitter + */ +let WebSocket$1 = class WebSocket extends EventEmitter$1 { + /** + * Create a new `WebSocket`. + * + * @param {(String|URL)} address The URL to which to connect + * @param {(String|String[])} [protocols] The subprotocols + * @param {Object} [options] Connection options + */ + constructor(address, protocols, options) { + super(); + + this._binaryType = BINARY_TYPES[0]; + this._closeCode = 1006; + this._closeFrameReceived = false; + this._closeFrameSent = false; + this._closeMessage = EMPTY_BUFFER; + this._closeTimer = null; + this._errorEmitted = false; + this._extensions = {}; + this._paused = false; + this._protocol = ''; + this._readyState = WebSocket.CONNECTING; + this._receiver = null; + this._sender = null; + this._socket = null; + + if (address !== null) { + this._bufferedAmount = 0; + this._isServer = false; + this._redirects = 0; + + if (protocols === undefined) { + protocols = []; + } else if (!Array.isArray(protocols)) { + if (typeof protocols === 'object' && protocols !== null) { + options = protocols; + protocols = []; + } else { + protocols = [protocols]; + } + } + + initAsClient(this, address, protocols, options); + } else { + this._autoPong = options.autoPong; + this._isServer = true; + } + } + + /** + * For historical reasons, the custom "nodebuffer" type is used by the default + * instead of "blob". + * + * @type {String} + */ + get binaryType() { + return this._binaryType; + } + + set binaryType(type) { + if (!BINARY_TYPES.includes(type)) return; + + this._binaryType = type; + + // + // Allow to change `binaryType` on the fly. + // + if (this._receiver) this._receiver._binaryType = type; + } + + /** + * @type {Number} + */ + get bufferedAmount() { + if (!this._socket) return this._bufferedAmount; + + return this._socket._writableState.length + this._sender._bufferedBytes; + } + + /** + * @type {String} + */ + get extensions() { + return Object.keys(this._extensions).join(); + } + + /** + * @type {Boolean} + */ + get isPaused() { + return this._paused; + } + + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onclose() { + return null; + } + + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onerror() { + return null; + } + + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onopen() { + return null; + } + + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onmessage() { + return null; + } + + /** + * @type {String} + */ + get protocol() { + return this._protocol; + } + + /** + * @type {Number} + */ + get readyState() { + return this._readyState; + } + + /** + * @type {String} + */ + get url() { + return this._url; + } + + /** + * Set up the socket and the internal resources. + * + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Object} options Options object + * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Number} [options.maxPayload=0] The maximum allowed message size + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @private + */ + setSocket(socket, head, options) { + const receiver = new Receiver({ + allowSynchronousEvents: options.allowSynchronousEvents, + binaryType: this.binaryType, + extensions: this._extensions, + isServer: this._isServer, + maxPayload: options.maxPayload, + skipUTF8Validation: options.skipUTF8Validation + }); + + const sender = new Sender(socket, this._extensions, options.generateMask); + + this._receiver = receiver; + this._sender = sender; + this._socket = socket; + + receiver[kWebSocket$1] = this; + sender[kWebSocket$1] = this; + socket[kWebSocket$1] = this; + + receiver.on('conclude', receiverOnConclude); + receiver.on('drain', receiverOnDrain); + receiver.on('error', receiverOnError); + receiver.on('message', receiverOnMessage); + receiver.on('ping', receiverOnPing); + receiver.on('pong', receiverOnPong); + + sender.onerror = senderOnError; + + // + // These methods may not be available if `socket` is just a `Duplex`. + // + if (socket.setTimeout) socket.setTimeout(0); + if (socket.setNoDelay) socket.setNoDelay(); + + if (head.length > 0) socket.unshift(head); + + socket.on('close', socketOnClose); + socket.on('data', socketOnData); + socket.on('end', socketOnEnd); + socket.on('error', socketOnError$1); + + this._readyState = WebSocket.OPEN; + this.emit('open'); + } + + /** + * Emit the `'close'` event. + * + * @private + */ + emitClose() { + if (!this._socket) { + this._readyState = WebSocket.CLOSED; + this.emit('close', this._closeCode, this._closeMessage); + return; + } + + if (this._extensions[PerMessageDeflate$1.extensionName]) { + this._extensions[PerMessageDeflate$1.extensionName].cleanup(); + } + + this._receiver.removeAllListeners(); + this._readyState = WebSocket.CLOSED; + this.emit('close', this._closeCode, this._closeMessage); + } + + /** + * Start a closing handshake. + * + * +----------+ +-----------+ +----------+ + * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - + * | +----------+ +-----------+ +----------+ | + * +----------+ +-----------+ | + * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING + * +----------+ +-----------+ | + * | | | +---+ | + * +------------------------+-->|fin| - - - - + * | +---+ | +---+ + * - - - - -|fin|<---------------------+ + * +---+ + * + * @param {Number} [code] Status code explaining why the connection is closing + * @param {(String|Buffer)} [data] The reason why the connection is + * closing + * @public + */ + close(code, data) { + if (this.readyState === WebSocket.CLOSED) return; + if (this.readyState === WebSocket.CONNECTING) { + const msg = 'WebSocket was closed before the connection was established'; + abortHandshake$1(this, this._req, msg); + return; + } + + if (this.readyState === WebSocket.CLOSING) { + if ( + this._closeFrameSent && + (this._closeFrameReceived || this._receiver._writableState.errorEmitted) + ) { + this._socket.end(); + } + + return; + } + + this._readyState = WebSocket.CLOSING; + this._sender.close(code, data, !this._isServer, (err) => { + // + // This error is handled by the `'error'` listener on the socket. We only + // want to know if the close frame has been sent here. + // + if (err) return; + + this._closeFrameSent = true; + + if ( + this._closeFrameReceived || + this._receiver._writableState.errorEmitted + ) { + this._socket.end(); + } + }); + + setCloseTimer(this); + } + + /** + * Pause the socket. + * + * @public + */ + pause() { + if ( + this.readyState === WebSocket.CONNECTING || + this.readyState === WebSocket.CLOSED + ) { + return; + } + + this._paused = true; + this._socket.pause(); + } + + /** + * Send a ping. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the ping is sent + * @public + */ + ping(data, mask, cb) { + if (this.readyState === WebSocket.CONNECTING) { + throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); + } + + if (typeof data === 'function') { + cb = data; + data = mask = undefined; + } else if (typeof mask === 'function') { + cb = mask; + mask = undefined; + } + + if (typeof data === 'number') data = data.toString(); + + if (this.readyState !== WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + + if (mask === undefined) mask = !this._isServer; + this._sender.ping(data || EMPTY_BUFFER, mask, cb); + } + + /** + * Send a pong. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the pong is sent + * @public + */ + pong(data, mask, cb) { + if (this.readyState === WebSocket.CONNECTING) { + throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); + } + + if (typeof data === 'function') { + cb = data; + data = mask = undefined; + } else if (typeof mask === 'function') { + cb = mask; + mask = undefined; + } + + if (typeof data === 'number') data = data.toString(); + + if (this.readyState !== WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + + if (mask === undefined) mask = !this._isServer; + this._sender.pong(data || EMPTY_BUFFER, mask, cb); + } + + /** + * Resume the socket. + * + * @public + */ + resume() { + if ( + this.readyState === WebSocket.CONNECTING || + this.readyState === WebSocket.CLOSED + ) { + return; + } + + this._paused = false; + if (!this._receiver._writableState.needDrain) this._socket.resume(); + } + + /** + * Send a data message. + * + * @param {*} data The message to send + * @param {Object} [options] Options object + * @param {Boolean} [options.binary] Specifies whether `data` is binary or + * text + * @param {Boolean} [options.compress] Specifies whether or not to compress + * `data` + * @param {Boolean} [options.fin=true] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when data is written out + * @public + */ + send(data, options, cb) { + if (this.readyState === WebSocket.CONNECTING) { + throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); + } + + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (typeof data === 'number') data = data.toString(); + + if (this.readyState !== WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + + const opts = { + binary: typeof data !== 'string', + mask: !this._isServer, + compress: true, + fin: true, + ...options + }; + + if (!this._extensions[PerMessageDeflate$1.extensionName]) { + opts.compress = false; + } + + this._sender.send(data || EMPTY_BUFFER, opts, cb); + } + + /** + * Forcibly close the connection. + * + * @public + */ + terminate() { + if (this.readyState === WebSocket.CLOSED) return; + if (this.readyState === WebSocket.CONNECTING) { + const msg = 'WebSocket was closed before the connection was established'; + abortHandshake$1(this, this._req, msg); + return; + } + + if (this._socket) { + this._readyState = WebSocket.CLOSING; + this._socket.destroy(); + } + } +}; + +/** + * @constant {Number} CONNECTING + * @memberof WebSocket + */ +Object.defineProperty(WebSocket$1, 'CONNECTING', { + enumerable: true, + value: readyStates.indexOf('CONNECTING') +}); + +/** + * @constant {Number} CONNECTING + * @memberof WebSocket.prototype + */ +Object.defineProperty(WebSocket$1.prototype, 'CONNECTING', { + enumerable: true, + value: readyStates.indexOf('CONNECTING') +}); + +/** + * @constant {Number} OPEN + * @memberof WebSocket + */ +Object.defineProperty(WebSocket$1, 'OPEN', { + enumerable: true, + value: readyStates.indexOf('OPEN') +}); + +/** + * @constant {Number} OPEN + * @memberof WebSocket.prototype + */ +Object.defineProperty(WebSocket$1.prototype, 'OPEN', { + enumerable: true, + value: readyStates.indexOf('OPEN') +}); + +/** + * @constant {Number} CLOSING + * @memberof WebSocket + */ +Object.defineProperty(WebSocket$1, 'CLOSING', { + enumerable: true, + value: readyStates.indexOf('CLOSING') +}); + +/** + * @constant {Number} CLOSING + * @memberof WebSocket.prototype + */ +Object.defineProperty(WebSocket$1.prototype, 'CLOSING', { + enumerable: true, + value: readyStates.indexOf('CLOSING') +}); + +/** + * @constant {Number} CLOSED + * @memberof WebSocket + */ +Object.defineProperty(WebSocket$1, 'CLOSED', { + enumerable: true, + value: readyStates.indexOf('CLOSED') +}); + +/** + * @constant {Number} CLOSED + * @memberof WebSocket.prototype + */ +Object.defineProperty(WebSocket$1.prototype, 'CLOSED', { + enumerable: true, + value: readyStates.indexOf('CLOSED') +}); + +[ + 'binaryType', + 'bufferedAmount', + 'extensions', + 'isPaused', + 'protocol', + 'readyState', + 'url' +].forEach((property) => { + Object.defineProperty(WebSocket$1.prototype, property, { enumerable: true }); +}); + +// +// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes. +// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface +// +['open', 'error', 'close', 'message'].forEach((method) => { + Object.defineProperty(WebSocket$1.prototype, `on${method}`, { + enumerable: true, + get() { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) return listener[kListener]; + } + + return null; + }, + set(handler) { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) { + this.removeListener(method, listener); + break; + } + } + + if (typeof handler !== 'function') return; + + this.addEventListener(method, handler, { + [kForOnEventAttribute]: true + }); + } + }); +}); + +WebSocket$1.prototype.addEventListener = addEventListener; +WebSocket$1.prototype.removeEventListener = removeEventListener; + +var websocket = WebSocket$1; + +/** + * Initialize a WebSocket client. + * + * @param {WebSocket} websocket The client to initialize + * @param {(String|URL)} address The URL to which to connect + * @param {Array} protocols The subprotocols + * @param {Object} [options] Connection options + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any + * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple + * times in the same tick + * @param {Boolean} [options.autoPong=true] Specifies whether or not to + * automatically send a pong in response to a ping + * @param {Function} [options.finishRequest] A function which can be used to + * customize the headers of each http request before it is sent + * @param {Boolean} [options.followRedirects=false] Whether or not to follow + * redirects + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the + * handshake request + * @param {Number} [options.maxPayload=104857600] The maximum allowed message + * size + * @param {Number} [options.maxRedirects=10] The maximum number of redirects + * allowed + * @param {String} [options.origin] Value of the `Origin` or + * `Sec-WebSocket-Origin` header + * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable + * permessage-deflate + * @param {Number} [options.protocolVersion=13] Value of the + * `Sec-WebSocket-Version` header + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @private + */ +function initAsClient(websocket, address, protocols, options) { + const opts = { + allowSynchronousEvents: true, + autoPong: true, + protocolVersion: protocolVersions[1], + maxPayload: 100 * 1024 * 1024, + skipUTF8Validation: false, + perMessageDeflate: true, + followRedirects: false, + maxRedirects: 10, + ...options, + socketPath: undefined, + hostname: undefined, + protocol: undefined, + timeout: undefined, + method: 'GET', + host: undefined, + path: undefined, + port: undefined + }; + + websocket._autoPong = opts.autoPong; + + if (!protocolVersions.includes(opts.protocolVersion)) { + throw new RangeError( + `Unsupported protocol version: ${opts.protocolVersion} ` + + `(supported versions: ${protocolVersions.join(', ')})` + ); + } + + let parsedUrl; + + if (address instanceof URL$2) { + parsedUrl = address; + } else { + try { + parsedUrl = new URL$2(address); + } catch (e) { + throw new SyntaxError(`Invalid URL: ${address}`); + } + } + + if (parsedUrl.protocol === 'http:') { + parsedUrl.protocol = 'ws:'; + } else if (parsedUrl.protocol === 'https:') { + parsedUrl.protocol = 'wss:'; + } + + websocket._url = parsedUrl.href; + + const isSecure = parsedUrl.protocol === 'wss:'; + const isIpcUrl = parsedUrl.protocol === 'ws+unix:'; + let invalidUrlMessage; + + if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) { + invalidUrlMessage = + 'The URL\'s protocol must be one of "ws:", "wss:", ' + + '"http:", "https", or "ws+unix:"'; + } else if (isIpcUrl && !parsedUrl.pathname) { + invalidUrlMessage = "The URL's pathname is empty"; + } else if (parsedUrl.hash) { + invalidUrlMessage = 'The URL contains a fragment identifier'; + } + + if (invalidUrlMessage) { + const err = new SyntaxError(invalidUrlMessage); + + if (websocket._redirects === 0) { + throw err; + } else { + emitErrorAndClose(websocket, err); + return; + } + } + + const defaultPort = isSecure ? 443 : 80; + const key = randomBytes(16).toString('base64'); + const request = isSecure ? https$2.request : http$3.request; + const protocolSet = new Set(); + let perMessageDeflate; + + opts.createConnection = + opts.createConnection || (isSecure ? tlsConnect : netConnect); + opts.defaultPort = opts.defaultPort || defaultPort; + opts.port = parsedUrl.port || defaultPort; + opts.host = parsedUrl.hostname.startsWith('[') + ? parsedUrl.hostname.slice(1, -1) + : parsedUrl.hostname; + opts.headers = { + ...opts.headers, + 'Sec-WebSocket-Version': opts.protocolVersion, + 'Sec-WebSocket-Key': key, + Connection: 'Upgrade', + Upgrade: 'websocket' + }; + opts.path = parsedUrl.pathname + parsedUrl.search; + opts.timeout = opts.handshakeTimeout; + + if (opts.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate$1( + opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, + false, + opts.maxPayload + ); + opts.headers['Sec-WebSocket-Extensions'] = format({ + [PerMessageDeflate$1.extensionName]: perMessageDeflate.offer() + }); + } + if (protocols.length) { + for (const protocol of protocols) { + if ( + typeof protocol !== 'string' || + !subprotocolRegex.test(protocol) || + protocolSet.has(protocol) + ) { + throw new SyntaxError( + 'An invalid or duplicated subprotocol was specified' + ); + } + + protocolSet.add(protocol); + } + + opts.headers['Sec-WebSocket-Protocol'] = protocols.join(','); + } + if (opts.origin) { + if (opts.protocolVersion < 13) { + opts.headers['Sec-WebSocket-Origin'] = opts.origin; + } else { + opts.headers.Origin = opts.origin; + } + } + if (parsedUrl.username || parsedUrl.password) { + opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; + } + + if (isIpcUrl) { + const parts = opts.path.split(':'); + + opts.socketPath = parts[0]; + opts.path = parts[1]; + } + + let req; + + if (opts.followRedirects) { + if (websocket._redirects === 0) { + websocket._originalIpc = isIpcUrl; + websocket._originalSecure = isSecure; + websocket._originalHostOrSocketPath = isIpcUrl + ? opts.socketPath + : parsedUrl.host; + + const headers = options && options.headers; + + // + // Shallow copy the user provided options so that headers can be changed + // without mutating the original object. + // + options = { ...options, headers: {} }; + + if (headers) { + for (const [key, value] of Object.entries(headers)) { + options.headers[key.toLowerCase()] = value; + } + } + } else if (websocket.listenerCount('redirect') === 0) { + const isSameHost = isIpcUrl + ? websocket._originalIpc + ? opts.socketPath === websocket._originalHostOrSocketPath + : false + : websocket._originalIpc + ? false + : parsedUrl.host === websocket._originalHostOrSocketPath; + + if (!isSameHost || (websocket._originalSecure && !isSecure)) { + // + // Match curl 7.77.0 behavior and drop the following headers. These + // headers are also dropped when following a redirect to a subdomain. + // + delete opts.headers.authorization; + delete opts.headers.cookie; + + if (!isSameHost) delete opts.headers.host; + + opts.auth = undefined; + } + } + + // + // Match curl 7.77.0 behavior and make the first `Authorization` header win. + // If the `Authorization` header is set, then there is nothing to do as it + // will take precedence. + // + if (opts.auth && !options.headers.authorization) { + options.headers.authorization = + 'Basic ' + Buffer.from(opts.auth).toString('base64'); + } + + req = websocket._req = request(opts); + + if (websocket._redirects) { + // + // Unlike what is done for the `'upgrade'` event, no early exit is + // triggered here if the user calls `websocket.close()` or + // `websocket.terminate()` from a listener of the `'redirect'` event. This + // is because the user can also call `request.destroy()` with an error + // before calling `websocket.close()` or `websocket.terminate()` and this + // would result in an error being emitted on the `request` object with no + // `'error'` event listeners attached. + // + websocket.emit('redirect', websocket.url, req); + } + } else { + req = websocket._req = request(opts); + } + + if (opts.timeout) { + req.on('timeout', () => { + abortHandshake$1(websocket, req, 'Opening handshake has timed out'); + }); + } + + req.on('error', (err) => { + if (req === null || req[kAborted]) return; + + req = websocket._req = null; + emitErrorAndClose(websocket, err); + }); + + req.on('response', (res) => { + const location = res.headers.location; + const statusCode = res.statusCode; + + if ( + location && + opts.followRedirects && + statusCode >= 300 && + statusCode < 400 + ) { + if (++websocket._redirects > opts.maxRedirects) { + abortHandshake$1(websocket, req, 'Maximum redirects exceeded'); + return; + } + + req.abort(); + + let addr; + + try { + addr = new URL$2(location, address); + } catch (e) { + const err = new SyntaxError(`Invalid URL: ${location}`); + emitErrorAndClose(websocket, err); + return; + } + + initAsClient(websocket, addr, protocols, options); + } else if (!websocket.emit('unexpected-response', req, res)) { + abortHandshake$1( + websocket, + req, + `Unexpected server response: ${res.statusCode}` + ); + } + }); + + req.on('upgrade', (res, socket, head) => { + websocket.emit('upgrade', res); + + // + // The user may have closed the connection from a listener of the + // `'upgrade'` event. + // + if (websocket.readyState !== WebSocket$1.CONNECTING) return; + + req = websocket._req = null; + + const upgrade = res.headers.upgrade; + + if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') { + abortHandshake$1(websocket, socket, 'Invalid Upgrade header'); + return; + } + + const digest = createHash$1('sha1') + .update(key + GUID$1) + .digest('base64'); + + if (res.headers['sec-websocket-accept'] !== digest) { + abortHandshake$1(websocket, socket, 'Invalid Sec-WebSocket-Accept header'); + return; + } + + const serverProt = res.headers['sec-websocket-protocol']; + let protError; + + if (serverProt !== undefined) { + if (!protocolSet.size) { + protError = 'Server sent a subprotocol but none was requested'; + } else if (!protocolSet.has(serverProt)) { + protError = 'Server sent an invalid subprotocol'; + } + } else if (protocolSet.size) { + protError = 'Server sent no subprotocol'; + } + + if (protError) { + abortHandshake$1(websocket, socket, protError); + return; + } + + if (serverProt) websocket._protocol = serverProt; + + const secWebSocketExtensions = res.headers['sec-websocket-extensions']; + + if (secWebSocketExtensions !== undefined) { + if (!perMessageDeflate) { + const message = + 'Server sent a Sec-WebSocket-Extensions header but no extension ' + + 'was requested'; + abortHandshake$1(websocket, socket, message); + return; + } + + let extensions; + + try { + extensions = parse$1(secWebSocketExtensions); + } catch (err) { + const message = 'Invalid Sec-WebSocket-Extensions header'; + abortHandshake$1(websocket, socket, message); + return; + } + + const extensionNames = Object.keys(extensions); + + if ( + extensionNames.length !== 1 || + extensionNames[0] !== PerMessageDeflate$1.extensionName + ) { + const message = 'Server indicated an extension that was not requested'; + abortHandshake$1(websocket, socket, message); + return; + } + + try { + perMessageDeflate.accept(extensions[PerMessageDeflate$1.extensionName]); + } catch (err) { + const message = 'Invalid Sec-WebSocket-Extensions header'; + abortHandshake$1(websocket, socket, message); + return; + } + + websocket._extensions[PerMessageDeflate$1.extensionName] = + perMessageDeflate; + } + + websocket.setSocket(socket, head, { + allowSynchronousEvents: opts.allowSynchronousEvents, + generateMask: opts.generateMask, + maxPayload: opts.maxPayload, + skipUTF8Validation: opts.skipUTF8Validation + }); + }); + + if (opts.finishRequest) { + opts.finishRequest(req, websocket); + } else { + req.end(); + } +} + +/** + * Emit the `'error'` and `'close'` events. + * + * @param {WebSocket} websocket The WebSocket instance + * @param {Error} The error to emit + * @private + */ +function emitErrorAndClose(websocket, err) { + websocket._readyState = WebSocket$1.CLOSING; + // + // The following assignment is practically useless and is done only for + // consistency. + // + websocket._errorEmitted = true; + websocket.emit('error', err); + websocket.emitClose(); +} + +/** + * Create a `net.Socket` and initiate a connection. + * + * @param {Object} options Connection options + * @return {net.Socket} The newly created socket used to start the connection + * @private + */ +function netConnect(options) { + options.path = options.socketPath; + return net.connect(options); +} + +/** + * Create a `tls.TLSSocket` and initiate a connection. + * + * @param {Object} options Connection options + * @return {tls.TLSSocket} The newly created socket used to start the connection + * @private + */ +function tlsConnect(options) { + options.path = undefined; + + if (!options.servername && options.servername !== '') { + options.servername = net.isIP(options.host) ? '' : options.host; + } + + return tls.connect(options); +} + +/** + * Abort the handshake and emit an error. + * + * @param {WebSocket} websocket The WebSocket instance + * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to + * abort or the socket to destroy + * @param {String} message The error message + * @private + */ +function abortHandshake$1(websocket, stream, message) { + websocket._readyState = WebSocket$1.CLOSING; + + const err = new Error(message); + Error.captureStackTrace(err, abortHandshake$1); + + if (stream.setHeader) { + stream[kAborted] = true; + stream.abort(); + + if (stream.socket && !stream.socket.destroyed) { + // + // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if + // called after the request completed. See + // https://github.com/websockets/ws/issues/1869. + // + stream.socket.destroy(); + } + + process.nextTick(emitErrorAndClose, websocket, err); + } else { + stream.destroy(err); + stream.once('error', websocket.emit.bind(websocket, 'error')); + stream.once('close', websocket.emitClose.bind(websocket)); + } +} + +/** + * Handle cases where the `ping()`, `pong()`, or `send()` methods are called + * when the `readyState` attribute is `CLOSING` or `CLOSED`. + * + * @param {WebSocket} websocket The WebSocket instance + * @param {*} [data] The data to send + * @param {Function} [cb] Callback + * @private + */ +function sendAfterClose(websocket, data, cb) { + if (data) { + const length = isBlob(data) ? data.size : toBuffer(data).length; + + // + // The `_bufferedAmount` property is used only when the peer is a client and + // the opening handshake fails. Under these circumstances, in fact, the + // `setSocket()` method is not called, so the `_socket` and `_sender` + // properties are set to `null`. + // + if (websocket._socket) websocket._sender._bufferedBytes += length; + else websocket._bufferedAmount += length; + } + + if (cb) { + const err = new Error( + `WebSocket is not open: readyState ${websocket.readyState} ` + + `(${readyStates[websocket.readyState]})` + ); + process.nextTick(cb, err); + } +} + +/** + * The listener of the `Receiver` `'conclude'` event. + * + * @param {Number} code The status code + * @param {Buffer} reason The reason for closing + * @private + */ +function receiverOnConclude(code, reason) { + const websocket = this[kWebSocket$1]; + + websocket._closeFrameReceived = true; + websocket._closeMessage = reason; + websocket._closeCode = code; + + if (websocket._socket[kWebSocket$1] === undefined) return; + + websocket._socket.removeListener('data', socketOnData); + process.nextTick(resume, websocket._socket); + + if (code === 1005) websocket.close(); + else websocket.close(code, reason); +} + +/** + * The listener of the `Receiver` `'drain'` event. + * + * @private + */ +function receiverOnDrain() { + const websocket = this[kWebSocket$1]; + + if (!websocket.isPaused) websocket._socket.resume(); +} + +/** + * The listener of the `Receiver` `'error'` event. + * + * @param {(RangeError|Error)} err The emitted error + * @private + */ +function receiverOnError(err) { + const websocket = this[kWebSocket$1]; + + if (websocket._socket[kWebSocket$1] !== undefined) { + websocket._socket.removeListener('data', socketOnData); + + // + // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See + // https://github.com/websockets/ws/issues/1940. + // + process.nextTick(resume, websocket._socket); + + websocket.close(err[kStatusCode]); + } + + if (!websocket._errorEmitted) { + websocket._errorEmitted = true; + websocket.emit('error', err); + } +} + +/** + * The listener of the `Receiver` `'finish'` event. + * + * @private + */ +function receiverOnFinish() { + this[kWebSocket$1].emitClose(); +} + +/** + * The listener of the `Receiver` `'message'` event. + * + * @param {Buffer|ArrayBuffer|Buffer[])} data The message + * @param {Boolean} isBinary Specifies whether the message is binary or not + * @private + */ +function receiverOnMessage(data, isBinary) { + this[kWebSocket$1].emit('message', data, isBinary); +} + +/** + * The listener of the `Receiver` `'ping'` event. + * + * @param {Buffer} data The data included in the ping frame + * @private + */ +function receiverOnPing(data) { + const websocket = this[kWebSocket$1]; + + if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP$1); + websocket.emit('ping', data); +} + +/** + * The listener of the `Receiver` `'pong'` event. + * + * @param {Buffer} data The data included in the pong frame + * @private + */ +function receiverOnPong(data) { + this[kWebSocket$1].emit('pong', data); +} + +/** + * Resume a readable stream + * + * @param {Readable} stream The readable stream + * @private + */ +function resume(stream) { + stream.resume(); +} + +/** + * The `Sender` error event handler. + * + * @param {Error} The error + * @private + */ +function senderOnError(err) { + const websocket = this[kWebSocket$1]; + + if (websocket.readyState === WebSocket$1.CLOSED) return; + if (websocket.readyState === WebSocket$1.OPEN) { + websocket._readyState = WebSocket$1.CLOSING; + setCloseTimer(websocket); + } + + // + // `socket.end()` is used instead of `socket.destroy()` to allow the other + // peer to finish sending queued data. There is no need to set a timer here + // because `CLOSING` means that it is already set or not needed. + // + this._socket.end(); + + if (!websocket._errorEmitted) { + websocket._errorEmitted = true; + websocket.emit('error', err); + } +} + +/** + * Set a timer to destroy the underlying raw socket of a WebSocket. + * + * @param {WebSocket} websocket The WebSocket instance + * @private + */ +function setCloseTimer(websocket) { + websocket._closeTimer = setTimeout( + websocket._socket.destroy.bind(websocket._socket), + closeTimeout + ); +} + +/** + * The listener of the socket `'close'` event. + * + * @private + */ +function socketOnClose() { + const websocket = this[kWebSocket$1]; + + this.removeListener('close', socketOnClose); + this.removeListener('data', socketOnData); + this.removeListener('end', socketOnEnd); + + websocket._readyState = WebSocket$1.CLOSING; + + let chunk; + + // + // The close frame might not have been received or the `'end'` event emitted, + // for example, if the socket was destroyed due to an error. Ensure that the + // `receiver` stream is closed after writing any remaining buffered data to + // it. If the readable side of the socket is in flowing mode then there is no + // buffered data as everything has been already written and `readable.read()` + // will return `null`. If instead, the socket is paused, any possible buffered + // data will be read as a single chunk. + // + if ( + !this._readableState.endEmitted && + !websocket._closeFrameReceived && + !websocket._receiver._writableState.errorEmitted && + (chunk = websocket._socket.read()) !== null + ) { + websocket._receiver.write(chunk); + } + + websocket._receiver.end(); + + this[kWebSocket$1] = undefined; + + clearTimeout(websocket._closeTimer); + + if ( + websocket._receiver._writableState.finished || + websocket._receiver._writableState.errorEmitted + ) { + websocket.emitClose(); + } else { + websocket._receiver.on('error', receiverOnFinish); + websocket._receiver.on('finish', receiverOnFinish); + } +} + +/** + * The listener of the socket `'data'` event. + * + * @param {Buffer} chunk A chunk of data + * @private + */ +function socketOnData(chunk) { + if (!this[kWebSocket$1]._receiver.write(chunk)) { + this.pause(); + } +} + +/** + * The listener of the socket `'end'` event. + * + * @private + */ +function socketOnEnd() { + const websocket = this[kWebSocket$1]; + + websocket._readyState = WebSocket$1.CLOSING; + websocket._receiver.end(); + this.end(); +} + +/** + * The listener of the socket `'error'` event. + * + * @private + */ +function socketOnError$1() { + const websocket = this[kWebSocket$1]; + + this.removeListener('error', socketOnError$1); + this.on('error', NOOP$1); + + if (websocket) { + websocket._readyState = WebSocket$1.CLOSING; + this.destroy(); + } +} + +const { tokenChars } = validationExports; + +/** + * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names. + * + * @param {String} header The field value of the header + * @return {Set} The subprotocol names + * @public + */ +function parse(header) { + const protocols = new Set(); + let start = -1; + let end = -1; + let i = 0; + + for (i; i < header.length; i++) { + const code = header.charCodeAt(i); + + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if ( + i !== 0 && + (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */ + ) { + if (end === -1 && start !== -1) end = i; + } else if (code === 0x2c /* ',' */) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + + if (end === -1) end = i; + + const protocol = header.slice(start, end); + + if (protocols.has(protocol)) { + throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); + } + + protocols.add(protocol); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + + if (start === -1 || end !== -1) { + throw new SyntaxError('Unexpected end of input'); + } + + const protocol = header.slice(start, i); + + if (protocols.has(protocol)) { + throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); + } + + protocols.add(protocol); + return protocols; +} + +var subprotocol$1 = { parse }; + +/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$", "caughtErrors": "none" }] */ + +const EventEmitter = require$$0$7; +const http$2 = require$$1; +const { createHash } = require$$3$1; + +const extension = extension$1; +const PerMessageDeflate = permessageDeflate; +const subprotocol = subprotocol$1; +const WebSocket = websocket; +const { GUID, kWebSocket } = constants; + +const keyRegex = /^[+/0-9A-Za-z]{22}==$/; + +const RUNNING = 0; +const CLOSING = 1; +const CLOSED = 2; + +/** + * Class representing a WebSocket server. + * + * @extends EventEmitter + */ +class WebSocketServer extends EventEmitter { + /** + * Create a `WebSocketServer` instance. + * + * @param {Object} options Configuration options + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {Boolean} [options.autoPong=true] Specifies whether or not to + * automatically send a pong in response to a ping + * @param {Number} [options.backlog=511] The maximum length of the queue of + * pending connections + * @param {Boolean} [options.clientTracking=true] Specifies whether or not to + * track clients + * @param {Function} [options.handleProtocols] A hook to handle protocols + * @param {String} [options.host] The hostname where to bind the server + * @param {Number} [options.maxPayload=104857600] The maximum allowed message + * size + * @param {Boolean} [options.noServer=false] Enable no server mode + * @param {String} [options.path] Accept only connections matching this path + * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable + * permessage-deflate + * @param {Number} [options.port] The port where to bind the server + * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S + * server to use + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @param {Function} [options.verifyClient] A hook to reject connections + * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket` + * class to use. It must be the `WebSocket` class or class that extends it + * @param {Function} [callback] A listener for the `listening` event + */ + constructor(options, callback) { + super(); + + options = { + allowSynchronousEvents: true, + autoPong: true, + maxPayload: 100 * 1024 * 1024, + skipUTF8Validation: false, + perMessageDeflate: false, + handleProtocols: null, + clientTracking: true, + verifyClient: null, + noServer: false, + backlog: null, // use default (511 as implemented in net.js) + server: null, + host: null, + path: null, + port: null, + WebSocket, + ...options + }; + + if ( + (options.port == null && !options.server && !options.noServer) || + (options.port != null && (options.server || options.noServer)) || + (options.server && options.noServer) + ) { + throw new TypeError( + 'One and only one of the "port", "server", or "noServer" options ' + + 'must be specified' + ); + } + + if (options.port != null) { + this._server = http$2.createServer((req, res) => { + const body = http$2.STATUS_CODES[426]; + + res.writeHead(426, { + 'Content-Length': body.length, + 'Content-Type': 'text/plain' + }); + res.end(body); + }); + this._server.listen( + options.port, + options.host, + options.backlog, + callback + ); + } else if (options.server) { + this._server = options.server; + } + + if (this._server) { + const emitConnection = this.emit.bind(this, 'connection'); + + this._removeListeners = addListeners(this._server, { + listening: this.emit.bind(this, 'listening'), + error: this.emit.bind(this, 'error'), + upgrade: (req, socket, head) => { + this.handleUpgrade(req, socket, head, emitConnection); + } + }); + } + + if (options.perMessageDeflate === true) options.perMessageDeflate = {}; + if (options.clientTracking) { + this.clients = new Set(); + this._shouldEmitClose = false; + } + + this.options = options; + this._state = RUNNING; + } + + /** + * Returns the bound address, the address family name, and port of the server + * as reported by the operating system if listening on an IP socket. + * If the server is listening on a pipe or UNIX domain socket, the name is + * returned as a string. + * + * @return {(Object|String|null)} The address of the server + * @public + */ + address() { + if (this.options.noServer) { + throw new Error('The server is operating in "noServer" mode'); + } + + if (!this._server) return null; + return this._server.address(); + } + + /** + * Stop the server from accepting new connections and emit the `'close'` event + * when all existing connections are closed. + * + * @param {Function} [cb] A one-time listener for the `'close'` event + * @public + */ + close(cb) { + if (this._state === CLOSED) { + if (cb) { + this.once('close', () => { + cb(new Error('The server is not running')); + }); + } + + process.nextTick(emitClose, this); + return; + } + + if (cb) this.once('close', cb); + + if (this._state === CLOSING) return; + this._state = CLOSING; + + if (this.options.noServer || this.options.server) { + if (this._server) { + this._removeListeners(); + this._removeListeners = this._server = null; + } + + if (this.clients) { + if (!this.clients.size) { + process.nextTick(emitClose, this); + } else { + this._shouldEmitClose = true; + } + } else { + process.nextTick(emitClose, this); + } + } else { + const server = this._server; + + this._removeListeners(); + this._removeListeners = this._server = null; + + // + // The HTTP/S server was created internally. Close it, and rely on its + // `'close'` event. + // + server.close(() => { + emitClose(this); + }); + } + } + + /** + * See if a given request should be handled by this server instance. + * + * @param {http.IncomingMessage} req Request object to inspect + * @return {Boolean} `true` if the request is valid, else `false` + * @public + */ + shouldHandle(req) { + if (this.options.path) { + const index = req.url.indexOf('?'); + const pathname = index !== -1 ? req.url.slice(0, index) : req.url; + + if (pathname !== this.options.path) return false; + } + + return true; + } + + /** + * Handle a HTTP Upgrade request. + * + * @param {http.IncomingMessage} req The request object + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @public + */ + handleUpgrade(req, socket, head, cb) { + socket.on('error', socketOnError); + + const key = req.headers['sec-websocket-key']; + const upgrade = req.headers.upgrade; + const version = +req.headers['sec-websocket-version']; + + if (req.method !== 'GET') { + const message = 'Invalid HTTP method'; + abortHandshakeOrEmitwsClientError(this, req, socket, 405, message); + return; + } + + if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') { + const message = 'Invalid Upgrade header'; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + + if (key === undefined || !keyRegex.test(key)) { + const message = 'Missing or invalid Sec-WebSocket-Key header'; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + + if (version !== 8 && version !== 13) { + const message = 'Missing or invalid Sec-WebSocket-Version header'; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + + if (!this.shouldHandle(req)) { + abortHandshake(socket, 400); + return; + } + + const secWebSocketProtocol = req.headers['sec-websocket-protocol']; + let protocols = new Set(); + + if (secWebSocketProtocol !== undefined) { + try { + protocols = subprotocol.parse(secWebSocketProtocol); + } catch (err) { + const message = 'Invalid Sec-WebSocket-Protocol header'; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + + const secWebSocketExtensions = req.headers['sec-websocket-extensions']; + const extensions = {}; + + if ( + this.options.perMessageDeflate && + secWebSocketExtensions !== undefined + ) { + const perMessageDeflate = new PerMessageDeflate( + this.options.perMessageDeflate, + true, + this.options.maxPayload + ); + + try { + const offers = extension.parse(secWebSocketExtensions); + + if (offers[PerMessageDeflate.extensionName]) { + perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); + extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + } catch (err) { + const message = + 'Invalid or unacceptable Sec-WebSocket-Extensions header'; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + + // + // Optionally call external client verification handler. + // + if (this.options.verifyClient) { + const info = { + origin: + req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`], + secure: !!(req.socket.authorized || req.socket.encrypted), + req + }; + + if (this.options.verifyClient.length === 2) { + this.options.verifyClient(info, (verified, code, message, headers) => { + if (!verified) { + return abortHandshake(socket, code || 401, message, headers); + } + + this.completeUpgrade( + extensions, + key, + protocols, + req, + socket, + head, + cb + ); + }); + return; + } + + if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); + } + + this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); + } + + /** + * Upgrade the connection to WebSocket. + * + * @param {Object} extensions The accepted extensions + * @param {String} key The value of the `Sec-WebSocket-Key` header + * @param {Set} protocols The subprotocols + * @param {http.IncomingMessage} req The request object + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @throws {Error} If called more than once with the same socket + * @private + */ + completeUpgrade(extensions, key, protocols, req, socket, head, cb) { + // + // Destroy the socket if the client has already sent a FIN packet. + // + if (!socket.readable || !socket.writable) return socket.destroy(); + + if (socket[kWebSocket]) { + throw new Error( + 'server.handleUpgrade() was called more than once with the same ' + + 'socket, possibly due to a misconfiguration' + ); + } + + if (this._state > RUNNING) return abortHandshake(socket, 503); + + const digest = createHash('sha1') + .update(key + GUID) + .digest('base64'); + + const headers = [ + 'HTTP/1.1 101 Switching Protocols', + 'Upgrade: websocket', + 'Connection: Upgrade', + `Sec-WebSocket-Accept: ${digest}` + ]; + + const ws = new this.options.WebSocket(null, undefined, this.options); + + if (protocols.size) { + // + // Optionally call external protocol selection handler. + // + const protocol = this.options.handleProtocols + ? this.options.handleProtocols(protocols, req) + : protocols.values().next().value; + + if (protocol) { + headers.push(`Sec-WebSocket-Protocol: ${protocol}`); + ws._protocol = protocol; + } + } + + if (extensions[PerMessageDeflate.extensionName]) { + const params = extensions[PerMessageDeflate.extensionName].params; + const value = extension.format({ + [PerMessageDeflate.extensionName]: [params] + }); + headers.push(`Sec-WebSocket-Extensions: ${value}`); + ws._extensions = extensions; + } + + // + // Allow external modification/inspection of handshake headers. + // + this.emit('headers', headers, req); + + socket.write(headers.concat('\r\n').join('\r\n')); + socket.removeListener('error', socketOnError); + + ws.setSocket(socket, head, { + allowSynchronousEvents: this.options.allowSynchronousEvents, + maxPayload: this.options.maxPayload, + skipUTF8Validation: this.options.skipUTF8Validation + }); + + if (this.clients) { + this.clients.add(ws); + ws.on('close', () => { + this.clients.delete(ws); + + if (this._shouldEmitClose && !this.clients.size) { + process.nextTick(emitClose, this); + } + }); + } + + cb(ws, req); + } +} + +var websocketServer = WebSocketServer; + +/** + * Add event listeners on an `EventEmitter` using a map of + * pairs. + * + * @param {EventEmitter} server The event emitter + * @param {Object.} map The listeners to add + * @return {Function} A function that will remove the added listeners when + * called + * @private + */ +function addListeners(server, map) { + for (const event of Object.keys(map)) server.on(event, map[event]); + + return function removeListeners() { + for (const event of Object.keys(map)) { + server.removeListener(event, map[event]); + } + }; +} + +/** + * Emit a `'close'` event on an `EventEmitter`. + * + * @param {EventEmitter} server The event emitter + * @private + */ +function emitClose(server) { + server._state = CLOSED; + server.emit('close'); +} + +/** + * Handle socket errors. + * + * @private + */ +function socketOnError() { + this.destroy(); +} + +/** + * Close the connection when preconditions are not fulfilled. + * + * @param {Duplex} socket The socket of the upgrade request + * @param {Number} code The HTTP response status code + * @param {String} [message] The HTTP response body + * @param {Object} [headers] Additional HTTP response headers + * @private + */ +function abortHandshake(socket, code, message, headers) { + // + // The socket is writable unless the user destroyed or ended it before calling + // `server.handleUpgrade()` or in the `verifyClient` function, which is a user + // error. Handling this does not make much sense as the worst that can happen + // is that some of the data written by the user might be discarded due to the + // call to `socket.end()` below, which triggers an `'error'` event that in + // turn causes the socket to be destroyed. + // + message = message || http$2.STATUS_CODES[code]; + headers = { + Connection: 'close', + 'Content-Type': 'text/html', + 'Content-Length': Buffer.byteLength(message), + ...headers + }; + + socket.once('finish', socket.destroy); + + socket.end( + `HTTP/1.1 ${code} ${http$2.STATUS_CODES[code]}\r\n` + + Object.keys(headers) + .map((h) => `${h}: ${headers[h]}`) + .join('\r\n') + + '\r\n\r\n' + + message + ); +} + +/** + * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least + * one listener for it, otherwise call `abortHandshake()`. + * + * @param {WebSocketServer} server The WebSocket server + * @param {http.IncomingMessage} req The request object + * @param {Duplex} socket The socket of the upgrade request + * @param {Number} code The HTTP response status code + * @param {String} message The HTTP response body + * @private + */ +function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) { + if (server.listenerCount('wsClientError')) { + const err = new Error(message); + Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError); + + server.emit('wsClientError', err, socket, req); + } else { + abortHandshake(socket, code, message); + } +} + +var WebSocketServerRaw_ = /*@__PURE__*/getDefaultExportFromCjs(websocketServer); + +const allowedHostsServerCache = /* @__PURE__ */ new WeakMap(); +const allowedHostsPreviewCache = /* @__PURE__ */ new WeakMap(); +const isFileOrExtensionProtocolRE = /^(?:file|.+-extension):/i; +function getAdditionalAllowedHosts(resolvedServerOptions, resolvedPreviewOptions) { + const list = []; + if (typeof resolvedServerOptions.host === "string" && resolvedServerOptions.host) { + list.push(resolvedServerOptions.host); + } + if (typeof resolvedServerOptions.hmr === "object" && resolvedServerOptions.hmr.host) { + list.push(resolvedServerOptions.hmr.host); + } + if (typeof resolvedPreviewOptions.host === "string" && resolvedPreviewOptions.host) { + list.push(resolvedPreviewOptions.host); + } + if (resolvedServerOptions.origin) { + try { + const serverOriginUrl = new URL(resolvedServerOptions.origin); + list.push(serverOriginUrl.hostname); + } catch { + } + } + return list; +} +function isHostAllowedWithoutCache(allowedHosts, additionalAllowedHosts, host) { + if (isFileOrExtensionProtocolRE.test(host)) { + return true; + } + const trimmedHost = host.trim(); + if (trimmedHost[0] === "[") { + const endIpv6 = trimmedHost.indexOf("]"); + if (endIpv6 < 0) { + return false; + } + return net$1.isIP(trimmedHost.slice(1, endIpv6)) === 6; + } + const colonPos = trimmedHost.indexOf(":"); + const hostname = colonPos === -1 ? trimmedHost : trimmedHost.slice(0, colonPos); + if (net$1.isIP(hostname) === 4) { + return true; + } + if (hostname === "localhost" || hostname.endsWith(".localhost")) { + return true; + } + for (const additionalAllowedHost of additionalAllowedHosts) { + if (additionalAllowedHost === hostname) { + return true; + } + } + for (const allowedHost of allowedHosts) { + if (allowedHost === hostname) { + return true; + } + if (allowedHost[0] === "." && (allowedHost.slice(1) === hostname || hostname.endsWith(allowedHost))) { + return true; + } + } + return false; +} +function isHostAllowed(config, isPreview, host) { + const allowedHosts = isPreview ? config.preview.allowedHosts : config.server.allowedHosts; + if (allowedHosts === true) { + return true; + } + const cache = isPreview ? allowedHostsPreviewCache : allowedHostsServerCache; + if (!cache.has(config)) { + cache.set(config, /* @__PURE__ */ new Set()); + } + const cachedAllowedHosts = cache.get(config); + if (cachedAllowedHosts.has(host)) { + return true; + } + const result = isHostAllowedWithoutCache( + allowedHosts ?? [], + config.additionalAllowedHosts, + host + ); + if (result) { + cachedAllowedHosts.add(host); + } + return result; +} +function hostCheckMiddleware(config, isPreview) { + return function viteHostCheckMiddleware(req, res, next) { + const hostHeader = req.headers.host; + if (!hostHeader || !isHostAllowed(config, isPreview, hostHeader)) { + const hostname = hostHeader?.replace(/:\d+$/, ""); + const hostnameWithQuotes = JSON.stringify(hostname); + const optionName = `${isPreview ? "preview" : "server"}.allowedHosts`; + res.writeHead(403, { + "Content-Type": "text/plain" + }); + res.end( + `Blocked request. This host (${hostnameWithQuotes}) is not allowed. +To allow this host, add ${hostnameWithQuotes} to \`${optionName}\` in vite.config.js.` + ); + return; + } + return next(); + }; +} + +const WebSocketServerRaw = process.versions.bun ? ( + // @ts-expect-error: Bun defines `import.meta.require` + import.meta.require("ws").WebSocketServer +) : WebSocketServerRaw_; +const HMR_HEADER = "vite-hmr"; +const wsServerEvents = [ + "connection", + "error", + "headers", + "listening", + "message" +]; +function noop$1() { +} +function hasValidToken(config, url) { + const token = url.searchParams.get("token"); + if (!token) return false; + try { + const isValidToken = crypto$2.timingSafeEqual( + Buffer.from(token), + Buffer.from(config.webSocketToken) + ); + return isValidToken; + } catch { + } + return false; +} +function createWebSocketServer(server, config, httpsOptions) { + if (config.server.ws === false) { + return { + name: "ws", + get clients() { + return /* @__PURE__ */ new Set(); + }, + async close() { + }, + on: noop$1, + off: noop$1, + listen: noop$1, + send: noop$1 + }; + } + let wsHttpServer = void 0; + const hmr = isObject$1(config.server.hmr) && config.server.hmr; + const hmrServer = hmr && hmr.server; + const hmrPort = hmr && hmr.port; + const portsAreCompatible = !hmrPort || hmrPort === config.server.port; + const wsServer = hmrServer || portsAreCompatible && server; + let hmrServerWsListener; + const customListeners = /* @__PURE__ */ new Map(); + const clientsMap = /* @__PURE__ */ new WeakMap(); + const port = hmrPort || 24678; + const host = hmr && hmr.host || void 0; + const shouldHandle = (req) => { + const hostHeader = req.headers.host; + if (!hostHeader || !isHostAllowed(config, false, hostHeader)) { + return false; + } + if (config.legacy?.skipWebSocketTokenCheck) { + return true; + } + if (req.headers.origin) { + const parsedUrl = new URL(`http://example.com${req.url}`); + return hasValidToken(config, parsedUrl); + } + return true; + }; + const handleUpgrade = (req, socket, head, _isPing) => { + wss.handleUpgrade(req, socket, head, (ws) => { + wss.emit("connection", ws, req); + }); + }; + const wss = new WebSocketServerRaw({ noServer: true }); + wss.shouldHandle = shouldHandle; + if (wsServer) { + let hmrBase = config.base; + const hmrPath = hmr ? hmr.path : void 0; + if (hmrPath) { + hmrBase = path$n.posix.join(hmrBase, hmrPath); + } + hmrServerWsListener = (req, socket, head) => { + const parsedUrl = new URL(`http://example.com${req.url}`); + if (req.headers["sec-websocket-protocol"] === HMR_HEADER && parsedUrl.pathname === hmrBase) { + handleUpgrade(req, socket, head); + } + }; + wsServer.on("upgrade", hmrServerWsListener); + } else { + const route = (_, res) => { + const statusCode = 426; + const body = STATUS_CODES[statusCode]; + if (!body) + throw new Error(`No body text found for the ${statusCode} status code`); + res.writeHead(statusCode, { + "Content-Length": body.length, + "Content-Type": "text/plain" + }); + res.end(body); + }; + if (httpsOptions) { + wsHttpServer = createServer$2(httpsOptions, route); + } else { + wsHttpServer = createServer$3(route); + } + wsHttpServer.on("upgrade", (req, socket, head) => { + handleUpgrade(req, socket, head); + }); + wsHttpServer.on("error", (e) => { + if (e.code === "EADDRINUSE") { + config.logger.error( + colors$1.red(`WebSocket server error: Port is already in use`), + { error: e } + ); + } else { + config.logger.error( + colors$1.red(`WebSocket server error: +${e.stack || e.message}`), + { error: e } + ); + } + }); + } + wss.on("connection", (socket) => { + socket.on("message", (raw) => { + if (!customListeners.size) return; + let parsed; + try { + parsed = JSON.parse(String(raw)); + } catch { + } + if (!parsed || parsed.type !== "custom" || !parsed.event) return; + const listeners = customListeners.get(parsed.event); + if (!listeners?.size) return; + const client = getSocketClient(socket); + listeners.forEach((listener) => listener(parsed.data, client)); + }); + socket.on("error", (err) => { + config.logger.error(`${colors$1.red(`ws error:`)} +${err.stack}`, { + timestamp: true, + error: err + }); + }); + socket.send(JSON.stringify({ type: "connected" })); + if (bufferedError) { + socket.send(JSON.stringify(bufferedError)); + bufferedError = null; + } + }); + wss.on("error", (e) => { + if (e.code === "EADDRINUSE") { + config.logger.error( + colors$1.red(`WebSocket server error: Port is already in use`), + { error: e } + ); + } else { + config.logger.error( + colors$1.red(`WebSocket server error: +${e.stack || e.message}`), + { error: e } + ); + } + }); + function getSocketClient(socket) { + if (!clientsMap.has(socket)) { + clientsMap.set(socket, { + send: (...args) => { + let payload; + if (typeof args[0] === "string") { + payload = { + type: "custom", + event: args[0], + data: args[1] + }; + } else { + payload = args[0]; + } + socket.send(JSON.stringify(payload)); + }, + socket + }); + } + return clientsMap.get(socket); + } + let bufferedError = null; + return { + name: "ws", + listen: () => { + wsHttpServer?.listen(port, host); + }, + on: (event, fn) => { + if (wsServerEvents.includes(event)) wss.on(event, fn); + else { + if (!customListeners.has(event)) { + customListeners.set(event, /* @__PURE__ */ new Set()); + } + customListeners.get(event).add(fn); + } + }, + off: (event, fn) => { + if (wsServerEvents.includes(event)) { + wss.off(event, fn); + } else { + customListeners.get(event)?.delete(fn); + } + }, + get clients() { + return new Set(Array.from(wss.clients).map(getSocketClient)); + }, + send(...args) { + let payload; + if (typeof args[0] === "string") { + payload = { + type: "custom", + event: args[0], + data: args[1] + }; + } else { + payload = args[0]; + } + if (payload.type === "error" && !wss.clients.size) { + bufferedError = payload; + return; + } + const stringified = JSON.stringify(payload); + wss.clients.forEach((client) => { + if (client.readyState === 1) { + client.send(stringified); + } + }); + }, + close() { + if (hmrServerWsListener && wsServer) { + wsServer.off("upgrade", hmrServerWsListener); + } + return new Promise((resolve, reject) => { + wss.clients.forEach((client) => { + client.terminate(); + }); + wss.close((err) => { + if (err) { + reject(err); + } else { + if (wsHttpServer) { + wsHttpServer.close((err2) => { + if (err2) { + reject(err2); + } else { + resolve(); + } + }); + } else { + resolve(); + } + } + }); + }); + } + }; +} + +function baseMiddleware(rawBase, middlewareMode) { + return function viteBaseMiddleware(req, res, next) { + const url = req.url; + const pathname = cleanUrl(url); + const base = rawBase; + if (pathname.startsWith(base)) { + req.url = stripBase(url, base); + return next(); + } + if (middlewareMode) { + return next(); + } + if (pathname === "/" || pathname === "/index.html") { + res.writeHead(302, { + Location: base + url.slice(pathname.length) + }); + res.end(); + return; + } + const redirectPath = withTrailingSlash(url) !== base ? joinUrlSegments(base, url) : base; + if (req.headers.accept?.includes("text/html")) { + res.writeHead(404, { + "Content-Type": "text/html" + }); + res.end( + `The server is configured with a public base URL of ${base} - did you mean to visit ${redirectPath} instead?` + ); + return; + } else { + res.writeHead(404, { + "Content-Type": "text/plain" + }); + res.end( + `The server is configured with a public base URL of ${base} - did you mean to visit ${redirectPath} instead?` + ); + return; + } + }; +} + +var httpProxy$3 = {exports: {}}; + +var eventemitter3 = {exports: {}}; + +(function (module) { + + var has = Object.prototype.hasOwnProperty + , prefix = '~'; + + /** + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private + */ + function Events() {} + + // + // We try to not inherit from `Object.prototype`. In some engines creating an + // instance in this way is faster than calling `Object.create(null)` directly. + // If `Object.create(null)` is not supported we prefix the event names with a + // character to make sure that the built-in object properties are not + // overridden or used as an attack vector. + // + if (Object.create) { + Events.prototype = Object.create(null); + + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; + } + + /** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ + function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; + } + + /** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ + function addListener(emitter, event, fn, context, once) { + if (typeof fn !== 'function') { + throw new TypeError('The listener must be a function'); + } + + var listener = new EE(fn, context || emitter, once) + , evt = prefix ? prefix + event : event; + + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; + + return emitter; + } + + /** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ + function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; + } + + /** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ + function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; + } + + /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ + EventEmitter.prototype.eventNames = function eventNames() { + var names = [] + , events + , name; + + if (this._eventsCount === 0) return names; + + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; + }; + + /** + * Return the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public + */ + EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event + , handlers = this._events[evt]; + + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; + + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } + + return ee; + }; + + /** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ + EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event + , listeners = this._events[evt]; + + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; + }; + + /** + * Calls each of the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public + */ + EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } + + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; + } + + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } + } + } + + return true; + }; + + /** + * Add a listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); + }; + + /** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); + }; + + /** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } + + var listeners = this._events[evt]; + + if (listeners.fn) { + if ( + listeners.fn === fn && + (!once || listeners.once) && + (!context || listeners.context === context) + ) { + clearEvent(this, evt); + } + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn || + (once && !listeners[i].once) || + (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } + } + + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } + + return this; + }; + + /** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; + + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } + + return this; + }; + + // + // Alias methods names because people roll like that. + // + EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + // + // Expose the prefix. + // + EventEmitter.prefixed = prefix; + + // + // Allow `EventEmitter` to be imported as module namespace. + // + EventEmitter.EventEmitter = EventEmitter; + + // + // Expose the module. + // + { + module.exports = EventEmitter; + } +} (eventemitter3)); + +var eventemitter3Exports = eventemitter3.exports; + +var common$3 = {}; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +var requiresPort = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) return false; + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; + +(function (exports) { + var common = exports, + url = require$$0$9, + required = requiresPort; + + var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i, + isSSL = /^https|wss/; + + /** + * Simple Regex for testing if protocol is https + */ + common.isSSL = isSSL; + /** + * Copies the right headers from `options` and `req` to + * `outgoing` which is then used to fire the proxied + * request. + * + * Examples: + * + * common.setupOutgoing(outgoing, options, req) + * // => { host: ..., hostname: ...} + * + * @param {Object} Outgoing Base object to be filled with required properties + * @param {Object} Options Config object passed to the proxy + * @param {ClientRequest} Req Request Object + * @param {String} Forward String to select forward or target + *  + * @return {Object} Outgoing Object with all required properties set + * + * @api private + */ + + common.setupOutgoing = function(outgoing, options, req, forward) { + outgoing.port = options[forward || 'target'].port || + (isSSL.test(options[forward || 'target'].protocol) ? 443 : 80); + + ['host', 'hostname', 'socketPath', 'pfx', 'key', + 'passphrase', 'cert', 'ca', 'ciphers', 'secureProtocol'].forEach( + function(e) { outgoing[e] = options[forward || 'target'][e]; } + ); + + outgoing.method = options.method || req.method; + outgoing.headers = Object.assign({}, req.headers); + + if (options.headers){ + Object.assign(outgoing.headers, options.headers); + } + + if (options.auth) { + outgoing.auth = options.auth; + } + + if (options.ca) { + outgoing.ca = options.ca; + } + + if (isSSL.test(options[forward || 'target'].protocol)) { + outgoing.rejectUnauthorized = (typeof options.secure === "undefined") ? true : options.secure; + } + + + outgoing.agent = options.agent || false; + outgoing.localAddress = options.localAddress; + + // + // Remark: If we are false and not upgrading, set the connection: close. This is the right thing to do + // as node core doesn't handle this COMPLETELY properly yet. + // + if (!outgoing.agent) { + outgoing.headers = outgoing.headers || {}; + if (typeof outgoing.headers.connection !== 'string' + || !upgradeHeader.test(outgoing.headers.connection) + ) { outgoing.headers.connection = 'close'; } + } + + + // the final path is target path + relative path requested by user: + var target = options[forward || 'target']; + var targetPath = target && options.prependPath !== false + ? (target.path || '') + : ''; + + // + // Remark: Can we somehow not use url.parse as a perf optimization? + // + var outgoingPath = !options.toProxy + ? (url.parse(req.url).path || '') + : req.url; + + // + // Remark: ignorePath will just straight up ignore whatever the request's + // path is. This can be labeled as FOOT-GUN material if you do not know what + // you are doing and are using conflicting options. + // + outgoingPath = !options.ignorePath ? outgoingPath : ''; + + outgoing.path = common.urlJoin(targetPath, outgoingPath); + + if (options.changeOrigin) { + outgoing.headers.host = + required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host) + ? outgoing.host + ':' + outgoing.port + : outgoing.host; + } + return outgoing; + }; + + /** + * Set the proper configuration for sockets, + * set no delay and set keep alive, also set + * the timeout to 0. + * + * Examples: + * + * common.setupSocket(socket) + * // => Socket + * + * @param {Socket} Socket instance to setup + *  + * @return {Socket} Return the configured socket. + * + * @api private + */ + + common.setupSocket = function(socket) { + socket.setTimeout(0); + socket.setNoDelay(true); + + socket.setKeepAlive(true, 0); + + return socket; + }; + + /** + * Get the port number from the host. Or guess it based on the connection type. + * + * @param {Request} req Incoming HTTP request. + * + * @return {String} The port number. + * + * @api private + */ + common.getPort = function(req) { + var res = req.headers.host ? req.headers.host.match(/:(\d+)/) : ''; + + return res ? + res[1] : + common.hasEncryptedConnection(req) ? '443' : '80'; + }; + + /** + * Check if the request has an encrypted connection. + * + * @param {Request} req Incoming HTTP request. + * + * @return {Boolean} Whether the connection is encrypted or not. + * + * @api private + */ + common.hasEncryptedConnection = function(req) { + return Boolean(req.connection.encrypted || req.connection.pair); + }; + + /** + * OS-agnostic join (doesn't break on URLs like path.join does on Windows)> + * + * @return {String} The generated path. + * + * @api private + */ + + common.urlJoin = function() { + // + // We do not want to mess with the query string. All we want to touch is the path. + // + var args = Array.prototype.slice.call(arguments), + lastIndex = args.length - 1, + last = args[lastIndex], + lastSegs = last.split('?'), + retSegs; + + args[lastIndex] = lastSegs.shift(); + + // + // Join all strings, but remove empty strings so we don't get extra slashes from + // joining e.g. ['', 'am'] + // + retSegs = [ + args.filter(Boolean).join('/') + .replace(/\/+/g, '/') + .replace('http:/', 'http://') + .replace('https:/', 'https://') + ]; + + // Only join the query string if it exists so we don't have trailing a '?' + // on every request + + // Handle case where there could be multiple ? in the URL. + retSegs.push.apply(retSegs, lastSegs); + + return retSegs.join('?') + }; + + /** + * Rewrites or removes the domain of a cookie header + * + * @param {String|Array} Header + * @param {Object} Config, mapping of domain to rewritten domain. + * '*' key to match any domain, null value to remove the domain. + * + * @api private + */ + common.rewriteCookieProperty = function rewriteCookieProperty(header, config, property) { + if (Array.isArray(header)) { + return header.map(function (headerElement) { + return rewriteCookieProperty(headerElement, config, property); + }); + } + return header.replace(new RegExp("(;\\s*" + property + "=)([^;]+)", 'i'), function(match, prefix, previousValue) { + var newValue; + if (previousValue in config) { + newValue = config[previousValue]; + } else if ('*' in config) { + newValue = config['*']; + } else { + //no match, return previous value + return match; + } + if (newValue) { + //replace value + return prefix + newValue; + } else { + //remove value + return ''; + } + }); + }; + + /** + * Check the host and see if it potentially has a port in it (keep it simple) + * + * @returns {Boolean} Whether we have one or not + * + * @api private + */ + function hasPort(host) { + return !!~host.indexOf(':'); + }} (common$3)); + +var url$1 = require$$0$9, + common$2 = common$3; + + +var redirectRegex = /^201|30(1|2|7|8)$/; + +/*! + * Array of passes. + * + * A `pass` is just a function that is executed on `req, res, options` + * so that you can easily add new checks while still keeping the base + * flexible. + */ + +var webOutgoing = { // <-- + + /** + * If is a HTTP 1.0 request, remove chunk headers + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {proxyResponse} Res Response object from the proxy request + * + * @api private + */ + removeChunked: function removeChunked(req, res, proxyRes) { + if (req.httpVersion === '1.0') { + delete proxyRes.headers['transfer-encoding']; + } + }, + + /** + * If is a HTTP 1.0 request, set the correct connection header + * or if connection header not present, then use `keep-alive` + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {proxyResponse} Res Response object from the proxy request + * + * @api private + */ + setConnection: function setConnection(req, res, proxyRes) { + if (req.httpVersion === '1.0') { + proxyRes.headers.connection = req.headers.connection || 'close'; + } else if (req.httpVersion !== '2.0' && !proxyRes.headers.connection) { + proxyRes.headers.connection = req.headers.connection || 'keep-alive'; + } + }, + + setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) { + if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite) + && proxyRes.headers['location'] + && redirectRegex.test(proxyRes.statusCode)) { + var target = url$1.parse(options.target); + var u = url$1.parse(proxyRes.headers['location']); + + // make sure the redirected host matches the target host before rewriting + if (target.host != u.host) { + return; + } + + if (options.hostRewrite) { + u.host = options.hostRewrite; + } else if (options.autoRewrite) { + u.host = req.headers['host']; + } + if (options.protocolRewrite) { + u.protocol = options.protocolRewrite; + } + + proxyRes.headers['location'] = u.format(); + } + }, + /** + * Copy headers from proxyResponse to response + * set each header in response object. + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {proxyResponse} Res Response object from the proxy request + * @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain + * + * @api private + */ + writeHeaders: function writeHeaders(req, res, proxyRes, options) { + var rewriteCookieDomainConfig = options.cookieDomainRewrite, + rewriteCookiePathConfig = options.cookiePathRewrite, + preserveHeaderKeyCase = options.preserveHeaderKeyCase, + rawHeaderKeyMap, + setHeader = function(key, header) { + if (header == undefined) return; + if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') { + header = common$2.rewriteCookieProperty(header, rewriteCookieDomainConfig, 'domain'); + } + if (rewriteCookiePathConfig && key.toLowerCase() === 'set-cookie') { + header = common$2.rewriteCookieProperty(header, rewriteCookiePathConfig, 'path'); + } + res.setHeader(String(key).trim(), header); + }; + + if (typeof rewriteCookieDomainConfig === 'string') { //also test for '' + rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig }; + } + + if (typeof rewriteCookiePathConfig === 'string') { //also test for '' + rewriteCookiePathConfig = { '*': rewriteCookiePathConfig }; + } + + // message.rawHeaders is added in: v0.11.6 + // https://nodejs.org/api/http.html#http_message_rawheaders + if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) { + rawHeaderKeyMap = {}; + for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) { + var key = proxyRes.rawHeaders[i]; + rawHeaderKeyMap[key.toLowerCase()] = key; + } + } + + Object.keys(proxyRes.headers).forEach(function(key) { + var header = proxyRes.headers[key]; + if (preserveHeaderKeyCase && rawHeaderKeyMap) { + key = rawHeaderKeyMap[key] || key; + } + setHeader(key, header); + }); + }, + + /** + * Set the statusCode from the proxyResponse + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {proxyResponse} Res Response object from the proxy request + * + * @api private + */ + writeStatusCode: function writeStatusCode(req, res, proxyRes) { + // From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers]) + if(proxyRes.statusMessage) { + res.statusCode = proxyRes.statusCode; + res.statusMessage = proxyRes.statusMessage; + } else { + res.statusCode = proxyRes.statusCode; + } + } + +}; + +var followRedirects$1 = {exports: {}}; + +var debug$6; + +var debug_1 = function () { + if (!debug$6) { + try { + /* eslint global-require: off */ + debug$6 = srcExports$1("follow-redirects"); + } + catch (error) { /* */ } + if (typeof debug$6 !== "function") { + debug$6 = function () { /* */ }; + } + } + debug$6.apply(null, arguments); +}; + +var url = require$$0$9; +var URL$1 = url.URL; +var http$1 = require$$1; +var https$1 = require$$1$1; +var Writable = require$$0$6.Writable; +var assert = require$$4$3; +var debug$5 = debug_1; + +// Whether to use the native URL object or the legacy url module +var useNativeURL = false; +try { + assert(new URL$1()); +} +catch (error) { + useNativeURL = error.code === "ERR_INVALID_URL"; +} + +// URL fields to preserve in copy operations +var preservedUrlFields = [ + "auth", + "host", + "hostname", + "href", + "path", + "pathname", + "port", + "protocol", + "query", + "search", + "hash", +]; + +// Create handlers that pass events from native requests +var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; +var eventHandlers = Object.create(null); +events.forEach(function (event) { + eventHandlers[event] = function (arg1, arg2, arg3) { + this._redirectable.emit(event, arg1, arg2, arg3); + }; +}); + +// Error types with codes +var InvalidUrlError = createErrorType( + "ERR_INVALID_URL", + "Invalid URL", + TypeError +); +var RedirectionError = createErrorType( + "ERR_FR_REDIRECTION_FAILURE", + "Redirected request failed" +); +var TooManyRedirectsError = createErrorType( + "ERR_FR_TOO_MANY_REDIRECTS", + "Maximum number of redirects exceeded", + RedirectionError +); +var MaxBodyLengthExceededError = createErrorType( + "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", + "Request body larger than maxBodyLength limit" +); +var WriteAfterEndError = createErrorType( + "ERR_STREAM_WRITE_AFTER_END", + "write after end" +); + +// istanbul ignore next +var destroy = Writable.prototype.destroy || noop; + +// An HTTP(S) request that can be redirected +function RedirectableRequest(options, responseCallback) { + // Initialize the request + Writable.call(this); + this._sanitizeOptions(options); + this._options = options; + this._ended = false; + this._ending = false; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; + + // Attach a callback if passed + if (responseCallback) { + this.on("response", responseCallback); + } + + // React to responses of native requests + var self = this; + this._onNativeResponse = function (response) { + try { + self._processResponse(response); + } + catch (cause) { + self.emit("error", cause instanceof RedirectionError ? + cause : new RedirectionError({ cause: cause })); + } + }; + + // Perform the first request + this._performRequest(); +} +RedirectableRequest.prototype = Object.create(Writable.prototype); + +RedirectableRequest.prototype.abort = function () { + destroyRequest(this._currentRequest); + this._currentRequest.abort(); + this.emit("abort"); +}; + +RedirectableRequest.prototype.destroy = function (error) { + destroyRequest(this._currentRequest, error); + destroy.call(this, error); + return this; +}; + +// Writes buffered data to the current native request +RedirectableRequest.prototype.write = function (data, encoding, callback) { + // Writing is not allowed if end has been called + if (this._ending) { + throw new WriteAfterEndError(); + } + + // Validate input and shift parameters if necessary + if (!isString(data) && !isBuffer(data)) { + throw new TypeError("data should be a string, Buffer or Uint8Array"); + } + if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Ignore empty buffers, since writing them doesn't invoke the callback + // https://github.com/nodejs/node/issues/22066 + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + // Only write when we don't exceed the maximum body length + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data: data, encoding: encoding }); + this._currentRequest.write(data, encoding, callback); + } + // Error when we exceed the maximum body length + else { + this.emit("error", new MaxBodyLengthExceededError()); + this.abort(); + } +}; + +// Ends the current native request +RedirectableRequest.prototype.end = function (data, encoding, callback) { + // Shift parameters if necessary + if (isFunction(data)) { + callback = data; + data = encoding = null; + } + else if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Write data if needed and end + if (!data) { + this._ended = this._ending = true; + this._currentRequest.end(null, null, callback); + } + else { + var self = this; + var currentRequest = this._currentRequest; + this.write(data, encoding, function () { + self._ended = true; + currentRequest.end(null, null, callback); + }); + this._ending = true; + } +}; + +// Sets a header value on the current native request +RedirectableRequest.prototype.setHeader = function (name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); +}; + +// Clears a header value on the current native request +RedirectableRequest.prototype.removeHeader = function (name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); +}; + +// Global timeout for all underlying requests +RedirectableRequest.prototype.setTimeout = function (msecs, callback) { + var self = this; + + // Destroys the socket on timeout + function destroyOnTimeout(socket) { + socket.setTimeout(msecs); + socket.removeListener("timeout", socket.destroy); + socket.addListener("timeout", socket.destroy); + } + + // Sets up a timer to trigger a timeout event + function startTimer(socket) { + if (self._timeout) { + clearTimeout(self._timeout); + } + self._timeout = setTimeout(function () { + self.emit("timeout"); + clearTimer(); + }, msecs); + destroyOnTimeout(socket); + } + + // Stops a timeout from triggering + function clearTimer() { + // Clear the timeout + if (self._timeout) { + clearTimeout(self._timeout); + self._timeout = null; + } + + // Clean up all attached listeners + self.removeListener("abort", clearTimer); + self.removeListener("error", clearTimer); + self.removeListener("response", clearTimer); + self.removeListener("close", clearTimer); + if (callback) { + self.removeListener("timeout", callback); + } + if (!self.socket) { + self._currentRequest.removeListener("socket", startTimer); + } + } + + // Attach callback if passed + if (callback) { + this.on("timeout", callback); + } + + // Start the timer if or when the socket is opened + if (this.socket) { + startTimer(this.socket); + } + else { + this._currentRequest.once("socket", startTimer); + } + + // Clean up on events + this.on("socket", destroyOnTimeout); + this.on("abort", clearTimer); + this.on("error", clearTimer); + this.on("response", clearTimer); + this.on("close", clearTimer); + + return this; +}; + +// Proxy all other public ClientRequest methods +[ + "flushHeaders", "getHeader", + "setNoDelay", "setSocketKeepAlive", +].forEach(function (method) { + RedirectableRequest.prototype[method] = function (a, b) { + return this._currentRequest[method](a, b); + }; +}); + +// Proxy all public ClientRequest properties +["aborted", "connection", "socket"].forEach(function (property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function () { return this._currentRequest[property]; }, + }); +}); + +RedirectableRequest.prototype._sanitizeOptions = function (options) { + // Ensure headers are always present + if (!options.headers) { + options.headers = {}; + } + + // Since http.request treats host as an alias of hostname, + // but the url module interprets host as hostname plus port, + // eliminate the host property to avoid confusion. + if (options.host) { + // Use hostname if set, because it has precedence + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } + + // Complete the URL object when necessary + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } + else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } +}; + + +// Executes the next native request (initial or redirect) +RedirectableRequest.prototype._performRequest = function () { + // Load the native protocol + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + throw new TypeError("Unsupported protocol " + protocol); + } + + // If specified, use the agent corresponding to the protocol + // (HTTP and HTTPS use different types of agents) + if (this._options.agents) { + var scheme = protocol.slice(0, -1); + this._options.agent = this._options.agents[scheme]; + } + + // Create the native request and set up its event handlers + var request = this._currentRequest = + nativeProtocol.request(this._options, this._onNativeResponse); + request._redirectable = this; + for (var event of events) { + request.on(event, eventHandlers[event]); + } + + // RFC7230§5.3.1: When making a request directly to an origin server, […] + // a client MUST send only the absolute path […] as the request-target. + this._currentUrl = /^\//.test(this._options.path) ? + url.format(this._options) : + // When making a request to a proxy, […] + // a client MUST send the target URI in absolute-form […]. + this._options.path; + + // End a redirected request + // (The first request must be ended explicitly with RedirectableRequest#end) + if (this._isRedirect) { + // Write the request entity and end + var i = 0; + var self = this; + var buffers = this._requestBodyBuffers; + (function writeNext(error) { + // Only write if this request has not been redirected yet + /* istanbul ignore else */ + if (request === self._currentRequest) { + // Report any write errors + /* istanbul ignore if */ + if (error) { + self.emit("error", error); + } + // Write the next buffer if there are still left + else if (i < buffers.length) { + var buffer = buffers[i++]; + /* istanbul ignore else */ + if (!request.finished) { + request.write(buffer.data, buffer.encoding, writeNext); + } + } + // End the request if `end` has been called on us + else if (self._ended) { + request.end(); + } + } + }()); + } +}; + +// Processes a response from the current native request +RedirectableRequest.prototype._processResponse = function (response) { + // Store the redirected response + var statusCode = response.statusCode; + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode: statusCode, + }); + } + + // RFC7231§6.4: The 3xx (Redirection) class of status code indicates + // that further action needs to be taken by the user agent in order to + // fulfill the request. If a Location header field is provided, + // the user agent MAY automatically redirect its request to the URI + // referenced by the Location field value, + // even if the specific status code is not understood. + + // If the response is not a redirect; return it as-is + var location = response.headers.location; + if (!location || this._options.followRedirects === false || + statusCode < 300 || statusCode >= 400) { + response.responseUrl = this._currentUrl; + response.redirects = this._redirects; + this.emit("response", response); + + // Clean up + this._requestBodyBuffers = []; + return; + } + + // The response is a redirect, so abort the current request + destroyRequest(this._currentRequest); + // Discard the remainder of the response to avoid waiting for data + response.destroy(); + + // RFC7231§6.4: A client SHOULD detect and intervene + // in cyclical redirections (i.e., "infinite" redirection loops). + if (++this._redirectCount > this._options.maxRedirects) { + throw new TooManyRedirectsError(); + } + + // Store the request headers if applicable + var requestHeaders; + var beforeRedirect = this._options.beforeRedirect; + if (beforeRedirect) { + requestHeaders = Object.assign({ + // The Host header was set by nativeProtocol.request + Host: response.req.getHeader("host"), + }, this._options.headers); + } + + // RFC7231§6.4: Automatic redirection needs to done with + // care for methods not known to be safe, […] + // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change + // the request method from POST to GET for the subsequent request. + var method = this._options.method; + if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || + // RFC7231§6.4.4: The 303 (See Other) status code indicates that + // the server is redirecting the user agent to a different resource […] + // A user agent can perform a retrieval request targeting that URI + // (a GET or HEAD request if using HTTP) […] + (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { + this._options.method = "GET"; + // Drop a possible entity and headers related to it + this._requestBodyBuffers = []; + removeMatchingHeaders(/^content-/i, this._options.headers); + } + + // Drop the Host header, as the redirect might lead to a different host + var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); + + // If the redirect is relative, carry over the host of the last request + var currentUrlParts = parseUrl(this._currentUrl); + var currentHost = currentHostHeader || currentUrlParts.host; + var currentUrl = /^\w+:/.test(location) ? this._currentUrl : + url.format(Object.assign(currentUrlParts, { host: currentHost })); + + // Create the redirected request + var redirectUrl = resolveUrl(location, currentUrl); + debug$5("redirecting to", redirectUrl.href); + this._isRedirect = true; + spreadUrlObject(redirectUrl, this._options); + + // Drop confidential headers when redirecting to a less secure protocol + // or to a different domain that is not a superdomain + if (redirectUrl.protocol !== currentUrlParts.protocol && + redirectUrl.protocol !== "https:" || + redirectUrl.host !== currentHost && + !isSubdomain(redirectUrl.host, currentHost)) { + removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers); + } + + // Evaluate the beforeRedirect callback + if (isFunction(beforeRedirect)) { + var responseDetails = { + headers: response.headers, + statusCode: statusCode, + }; + var requestDetails = { + url: currentUrl, + method: method, + headers: requestHeaders, + }; + beforeRedirect(this._options, responseDetails, requestDetails); + this._sanitizeOptions(this._options); + } + + // Perform the redirected request + this._performRequest(); +}; + +// Wraps the key/value object of protocols with redirect functionality +function wrap(protocols) { + // Default settings + var exports = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024, + }; + + // Wrap each protocol + var nativeProtocols = {}; + Object.keys(protocols).forEach(function (scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); + + // Executes a request, following redirects + function request(input, options, callback) { + // Parse parameters, ensuring that input is an object + if (isURL(input)) { + input = spreadUrlObject(input); + } + else if (isString(input)) { + input = spreadUrlObject(parseUrl(input)); + } + else { + callback = options; + options = validateUrl(input); + input = { protocol: protocol }; + } + if (isFunction(options)) { + callback = options; + options = null; + } + + // Set defaults + options = Object.assign({ + maxRedirects: exports.maxRedirects, + maxBodyLength: exports.maxBodyLength, + }, input, options); + options.nativeProtocols = nativeProtocols; + if (!isString(options.host) && !isString(options.hostname)) { + options.hostname = "::1"; + } + + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug$5("options", options); + return new RedirectableRequest(options, callback); + } + + // Executes a GET request, following redirects + function get(input, options, callback) { + var wrappedRequest = wrappedProtocol.request(input, options, callback); + wrappedRequest.end(); + return wrappedRequest; + } + + // Expose the properties on the wrapped protocol + Object.defineProperties(wrappedProtocol, { + request: { value: request, configurable: true, enumerable: true, writable: true }, + get: { value: get, configurable: true, enumerable: true, writable: true }, + }); + }); + return exports; +} + +function noop() { /* empty */ } + +function parseUrl(input) { + var parsed; + /* istanbul ignore else */ + if (useNativeURL) { + parsed = new URL$1(input); + } + else { + // Ensure the URL is valid and absolute + parsed = validateUrl(url.parse(input)); + if (!isString(parsed.protocol)) { + throw new InvalidUrlError({ input }); + } + } + return parsed; +} + +function resolveUrl(relative, base) { + /* istanbul ignore next */ + return useNativeURL ? new URL$1(relative, base) : parseUrl(url.resolve(base, relative)); +} + +function validateUrl(input) { + if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) { + throw new InvalidUrlError({ input: input.href || input }); + } + if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) { + throw new InvalidUrlError({ input: input.href || input }); + } + return input; +} + +function spreadUrlObject(urlObject, target) { + var spread = target || {}; + for (var key of preservedUrlFields) { + spread[key] = urlObject[key]; + } + + // Fix IPv6 hostname + if (spread.hostname.startsWith("[")) { + spread.hostname = spread.hostname.slice(1, -1); + } + // Ensure port is a number + if (spread.port !== "") { + spread.port = Number(spread.port); + } + // Concatenate path + spread.path = spread.search ? spread.pathname + spread.search : spread.pathname; + + return spread; +} + +function removeMatchingHeaders(regex, headers) { + var lastValue; + for (var header in headers) { + if (regex.test(header)) { + lastValue = headers[header]; + delete headers[header]; + } + } + return (lastValue === null || typeof lastValue === "undefined") ? + undefined : String(lastValue).trim(); +} + +function createErrorType(code, message, baseClass) { + // Create constructor + function CustomError(properties) { + Error.captureStackTrace(this, this.constructor); + Object.assign(this, properties || {}); + this.code = code; + this.message = this.cause ? message + ": " + this.cause.message : message; + } + + // Attach constructor and set default properties + CustomError.prototype = new (baseClass || Error)(); + Object.defineProperties(CustomError.prototype, { + constructor: { + value: CustomError, + enumerable: false, + }, + name: { + value: "Error [" + code + "]", + enumerable: false, + }, + }); + return CustomError; +} + +function destroyRequest(request, error) { + for (var event of events) { + request.removeListener(event, eventHandlers[event]); + } + request.on("error", noop); + request.destroy(error); +} + +function isSubdomain(subdomain, domain) { + assert(isString(subdomain) && isString(domain)); + var dot = subdomain.length - domain.length - 1; + return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); +} + +function isString(value) { + return typeof value === "string" || value instanceof String; +} + +function isFunction(value) { + return typeof value === "function"; +} + +function isBuffer(value) { + return typeof value === "object" && ("length" in value); +} + +function isURL(value) { + return URL$1 && value instanceof URL$1; +} + +// Exports +followRedirects$1.exports = wrap({ http: http$1, https: https$1 }); +followRedirects$1.exports.wrap = wrap; + +var followRedirectsExports = followRedirects$1.exports; + +var httpNative = require$$1, + httpsNative = require$$1$1, + web_o = webOutgoing, + common$1 = common$3, + followRedirects = followRedirectsExports; + +web_o = Object.keys(web_o).map(function(pass) { + return web_o[pass]; +}); + +var nativeAgents = { http: httpNative, https: httpsNative }; + +/*! + * Array of passes. + * + * A `pass` is just a function that is executed on `req, res, options` + * so that you can easily add new checks while still keeping the base + * flexible. + */ + + +var webIncoming = { + + /** + * Sets `content-length` to '0' if request is of DELETE type. + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + + deleteLength: function deleteLength(req, res, options) { + if((req.method === 'DELETE' || req.method === 'OPTIONS') + && !req.headers['content-length']) { + req.headers['content-length'] = '0'; + delete req.headers['transfer-encoding']; + } + }, + + /** + * Sets timeout in request socket if it was specified in options. + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + + timeout: function timeout(req, res, options) { + if(options.timeout) { + req.socket.setTimeout(options.timeout); + } + }, + + /** + * Sets `x-forwarded-*` headers if specified in config. + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + + XHeaders: function XHeaders(req, res, options) { + if(!options.xfwd) return; + + var encrypted = req.isSpdy || common$1.hasEncryptedConnection(req); + var values = { + for : req.connection.remoteAddress || req.socket.remoteAddress, + port : common$1.getPort(req), + proto: encrypted ? 'https' : 'http' + }; + + ['for', 'port', 'proto'].forEach(function(header) { + req.headers['x-forwarded-' + header] = + (req.headers['x-forwarded-' + header] || '') + + (req.headers['x-forwarded-' + header] ? ',' : '') + + values[header]; + }); + + req.headers['x-forwarded-host'] = req.headers['x-forwarded-host'] || req.headers['host'] || ''; + }, + + /** + * Does the actual proxying. If `forward` is enabled fires up + * a ForwardStream, same happens for ProxyStream. The request + * just dies otherwise. + * + * @param {ClientRequest} Req Request object + * @param {IncomingMessage} Res Response object + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + + stream: function stream(req, res, options, _, server, clb) { + + // And we begin! + server.emit('start', req, res, options.target || options.forward); + + var agents = options.followRedirects ? followRedirects : nativeAgents; + var http = agents.http; + var https = agents.https; + + if(options.forward) { + // If forward enable, so just pipe the request + var forwardReq = (options.forward.protocol === 'https:' ? https : http).request( + common$1.setupOutgoing(options.ssl || {}, options, req, 'forward') + ); + + // error handler (e.g. ECONNRESET, ECONNREFUSED) + // Handle errors on incoming request as well as it makes sense to + var forwardError = createErrorHandler(forwardReq, options.forward); + req.on('error', forwardError); + forwardReq.on('error', forwardError); + + (options.buffer || req).pipe(forwardReq); + if(!options.target) { return res.end(); } + } + + // Request initalization + var proxyReq = (options.target.protocol === 'https:' ? https : http).request( + common$1.setupOutgoing(options.ssl || {}, options, req) + ); + + // Enable developers to modify the proxyReq before headers are sent + proxyReq.on('socket', function(socket) { + if(server && !proxyReq.getHeader('expect')) { + server.emit('proxyReq', proxyReq, req, res, options); + } + }); + + // allow outgoing socket to timeout so that we could + // show an error page at the initial request + if(options.proxyTimeout) { + proxyReq.setTimeout(options.proxyTimeout, function() { + proxyReq.abort(); + }); + } + + // Ensure we abort proxy if request is aborted + req.on('aborted', function () { + proxyReq.abort(); + }); + + // handle errors in proxy and incoming request, just like for forward proxy + var proxyError = createErrorHandler(proxyReq, options.target); + req.on('error', proxyError); + proxyReq.on('error', proxyError); + + function createErrorHandler(proxyReq, url) { + return function proxyError(err) { + if (req.socket.destroyed && err.code === 'ECONNRESET') { + server.emit('econnreset', err, req, res, url); + return proxyReq.abort(); + } + + if (clb) { + clb(err, req, res, url); + } else { + server.emit('error', err, req, res, url); + } + } + } + + (options.buffer || req).pipe(proxyReq); + + proxyReq.on('response', function(proxyRes) { + if(server) { server.emit('proxyRes', proxyRes, req, res); } + + if(!res.headersSent && !options.selfHandleResponse) { + for(var i=0; i < web_o.length; i++) { + if(web_o[i](req, res, proxyRes, options)) { break; } + } + } + + if (!res.finished) { + // Allow us to listen when the proxy has completed + proxyRes.on('end', function () { + if (server) server.emit('end', req, res, proxyRes); + }); + // We pipe to the response unless its expected to be handled by the user + if (!options.selfHandleResponse) proxyRes.pipe(res); + } else { + if (server) server.emit('end', req, res, proxyRes); + } + }); + } + +}; + +var http = require$$1, + https = require$$1$1, + common = common$3; + +/*! + * Array of passes. + * + * A `pass` is just a function that is executed on `req, socket, options` + * so that you can easily add new checks while still keeping the base + * flexible. + */ + +/* + * Websockets Passes + * + */ + + +var wsIncoming = { + /** + * WebSocket requests must have the `GET` method and + * the `upgrade:websocket` header + * + * @param {ClientRequest} Req Request object + * @param {Socket} Websocket + * + * @api private + */ + + checkMethodAndHeader : function checkMethodAndHeader(req, socket) { + if (req.method !== 'GET' || !req.headers.upgrade) { + socket.destroy(); + return true; + } + + if (req.headers.upgrade.toLowerCase() !== 'websocket') { + socket.destroy(); + return true; + } + }, + + /** + * Sets `x-forwarded-*` headers if specified in config. + * + * @param {ClientRequest} Req Request object + * @param {Socket} Websocket + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + + XHeaders : function XHeaders(req, socket, options) { + if(!options.xfwd) return; + + var values = { + for : req.connection.remoteAddress || req.socket.remoteAddress, + port : common.getPort(req), + proto: common.hasEncryptedConnection(req) ? 'wss' : 'ws' + }; + + ['for', 'port', 'proto'].forEach(function(header) { + req.headers['x-forwarded-' + header] = + (req.headers['x-forwarded-' + header] || '') + + (req.headers['x-forwarded-' + header] ? ',' : '') + + values[header]; + }); + }, + + /** + * Does the actual proxying. Make the request and upgrade it + * send the Switching Protocols request and pipe the sockets. + * + * @param {ClientRequest} Req Request object + * @param {Socket} Websocket + * @param {Object} Options Config object passed to the proxy + * + * @api private + */ + stream : function stream(req, socket, options, head, server, clb) { + + var createHttpHeader = function(line, headers) { + return Object.keys(headers).reduce(function (head, key) { + var value = headers[key]; + + if (!Array.isArray(value)) { + head.push(key + ': ' + value); + return head; + } + + for (var i = 0; i < value.length; i++) { + head.push(key + ': ' + value[i]); + } + return head; + }, [line]) + .join('\r\n') + '\r\n\r\n'; + }; + + common.setupSocket(socket); + + if (head && head.length) socket.unshift(head); + + + var proxyReq = (common.isSSL.test(options.target.protocol) ? https : http).request( + common.setupOutgoing(options.ssl || {}, options, req) + ); + + // Enable developers to modify the proxyReq before headers are sent + if (server) { server.emit('proxyReqWs', proxyReq, req, socket, options, head); } + + // Error Handler + proxyReq.on('error', onOutgoingError); + proxyReq.on('response', function (res) { + // if upgrade event isn't going to happen, close the socket + if (!res.upgrade) { + socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers)); + res.pipe(socket); + } + }); + + proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) { + proxySocket.on('error', onOutgoingError); + + // Allow us to listen when the websocket has completed + proxySocket.on('end', function () { + server.emit('close', proxyRes, proxySocket, proxyHead); + }); + + // The pipe below will end proxySocket if socket closes cleanly, but not + // if it errors (eg, vanishes from the net and starts returning + // EHOSTUNREACH). We need to do that explicitly. + socket.on('error', function () { + proxySocket.end(); + }); + + common.setupSocket(proxySocket); + + if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead); + + // + // Remark: Handle writing the headers to the socket when switching protocols + // Also handles when a header is an array + // + socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers)); + + proxySocket.pipe(socket).pipe(proxySocket); + + server.emit('open', proxySocket); + server.emit('proxySocket', proxySocket); //DEPRECATED. + }); + + return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT + + function onOutgoingError(err) { + if (clb) { + clb(err, req, socket); + } else { + server.emit('error', err, req, socket); + } + socket.end(); + } + } +}; + +(function (module) { + var httpProxy = module.exports, + parse_url = require$$0$9.parse, + EE3 = eventemitter3Exports, + http = require$$1, + https = require$$1$1, + web = webIncoming, + ws = wsIncoming; + + httpProxy.Server = ProxyServer; + + /** + * Returns a function that creates the loader for + * either `ws` or `web`'s passes. + * + * Examples: + * + * httpProxy.createRightProxy('ws') + * // => [Function] + * + * @param {String} Type Either 'ws' or 'web' + *  + * @return {Function} Loader Function that when called returns an iterator for the right passes + * + * @api private + */ + + function createRightProxy(type) { + + return function(options) { + return function(req, res /*, [head], [opts] */) { + var passes = (type === 'ws') ? this.wsPasses : this.webPasses, + args = [].slice.call(arguments), + cntr = args.length - 1, + head, cbl; + + /* optional args parse begin */ + if(typeof args[cntr] === 'function') { + cbl = args[cntr]; + + cntr--; + } + + var requestOptions = options; + if( + !(args[cntr] instanceof Buffer) && + args[cntr] !== res + ) { + //Copy global options + requestOptions = Object.assign({}, options); + //Overwrite with request options + Object.assign(requestOptions, args[cntr]); + + cntr--; + } + + if(args[cntr] instanceof Buffer) { + head = args[cntr]; + } + + /* optional args parse end */ + + ['target', 'forward'].forEach(function(e) { + if (typeof requestOptions[e] === 'string') + requestOptions[e] = parse_url(requestOptions[e]); + }); + + if (!requestOptions.target && !requestOptions.forward) { + return this.emit('error', new Error('Must provide a proper URL as target')); + } + + for(var i=0; i < passes.length; i++) { + /** + * Call of passes functions + * pass(req, res, options, head) + * + * In WebSockets case the `res` variable + * refer to the connection socket + * pass(req, socket, options, head) + */ + if(passes[i](req, res, requestOptions, head, this, cbl)) { // passes can return a truthy value to halt the loop + break; + } + } + }; + }; + } + httpProxy.createRightProxy = createRightProxy; + + function ProxyServer(options) { + EE3.call(this); + + options = options || {}; + options.prependPath = options.prependPath === false ? false : true; + + this.web = this.proxyRequest = createRightProxy('web')(options); + this.ws = this.proxyWebsocketRequest = createRightProxy('ws')(options); + this.options = options; + + this.webPasses = Object.keys(web).map(function(pass) { + return web[pass]; + }); + + this.wsPasses = Object.keys(ws).map(function(pass) { + return ws[pass]; + }); + + this.on('error', this.onError, this); + + } + + require$$0$5.inherits(ProxyServer, EE3); + + ProxyServer.prototype.onError = function (err) { + // + // Remark: Replicate node core behavior using EE3 + // so we force people to handle their own errors + // + if(this.listeners('error').length === 1) { + throw err; + } + }; + + ProxyServer.prototype.listen = function(port, hostname) { + var self = this, + closure = function(req, res) { self.web(req, res); }; + + this._server = this.options.ssl ? + https.createServer(this.options.ssl, closure) : + http.createServer(closure); + + if(this.options.ws) { + this._server.on('upgrade', function(req, socket, head) { self.ws(req, socket, head); }); + } + + this._server.listen(port, hostname); + + return this; + }; + + ProxyServer.prototype.close = function(callback) { + var self = this; + if (this._server) { + this._server.close(done); + } + + // Wrap callback to nullify server after all open connections are closed. + function done() { + self._server = null; + if (callback) { + callback.apply(null, arguments); + } + } }; + + ProxyServer.prototype.before = function(type, passName, callback) { + if (type !== 'ws' && type !== 'web') { + throw new Error('type must be `web` or `ws`'); + } + var passes = (type === 'ws') ? this.wsPasses : this.webPasses, + i = false; + + passes.forEach(function(v, idx) { + if(v.name === passName) i = idx; + }); + + if(i === false) throw new Error('No such pass'); + + passes.splice(i, 0, callback); + }; + ProxyServer.prototype.after = function(type, passName, callback) { + if (type !== 'ws' && type !== 'web') { + throw new Error('type must be `web` or `ws`'); + } + var passes = (type === 'ws') ? this.wsPasses : this.webPasses, + i = false; + + passes.forEach(function(v, idx) { + if(v.name === passName) i = idx; + }); + + if(i === false) throw new Error('No such pass'); + + passes.splice(i++, 0, callback); + }; +} (httpProxy$3)); + +var httpProxyExports = httpProxy$3.exports; + +// Use explicit /index.js to help browserify negociation in require '/lib/http-proxy' (!) +var ProxyServer = httpProxyExports.Server; + + +/** + * Creates the proxy server. + * + * Examples: + * + * httpProxy.createProxyServer({ .. }, 8000) + * // => '{ web: [Function], ws: [Function] ... }' + * + * @param {Object} Options Config object passed to the proxy + * + * @return {Object} Proxy Proxy object with handlers for `ws` and `web` requests + * + * @api public + */ + + +function createProxyServer(options) { + /* + * `options` is needed and it must have the following layout: + * + * { + * target : + * forward: + * agent : + * ssl : + * ws : + * xfwd : + * secure : + * toProxy: + * prependPath: + * ignorePath: + * localAddress : + * changeOrigin: + * preserveHeaderKeyCase: + * auth : Basic authentication i.e. 'user:password' to compute an Authorization header. + * hostRewrite: rewrites the location hostname on (201/301/302/307/308) redirects, Default: null. + * autoRewrite: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false. + * protocolRewrite: rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null. + * } + * + * NOTE: `options.ws` and `options.ssl` are optional. + * `options.target and `options.forward` cannot be + * both missing + * } + */ + + return new ProxyServer(options); +} + + +ProxyServer.createProxyServer = createProxyServer; +ProxyServer.createServer = createProxyServer; +ProxyServer.createProxy = createProxyServer; + + + + +/** + * Export the proxy "Server" as the main export. + */ +var httpProxy$2 = ProxyServer; + +/*! + * Caron dimonio, con occhi di bragia + * loro accennando, tutte le raccoglie; + * batte col remo qualunque s’adagia + * + * Charon the demon, with the eyes of glede, + * Beckoning to them, collects them all together, + * Beats with his oar whoever lags behind + * + * Dante - The Divine Comedy (Canto III) + */ + +var httpProxy = httpProxy$2; + +var httpProxy$1 = /*@__PURE__*/getDefaultExportFromCjs(httpProxy); + +const debug$4 = createDebugger("vite:proxy"); +const rewriteOriginHeader = (proxyReq, options, config) => { + if (options.rewriteWsOrigin) { + const { target } = options; + if (proxyReq.headersSent) { + config.logger.warn( + colors$1.yellow( + `Unable to rewrite Origin header as headers are already sent.` + ) + ); + return; + } + if (proxyReq.getHeader("origin") && target) { + const changedOrigin = typeof target === "object" ? `${target.protocol}//${target.host}` : target; + proxyReq.setHeader("origin", changedOrigin); + } + } +}; +function proxyMiddleware(httpServer, options, config) { + const proxies = {}; + Object.keys(options).forEach((context) => { + let opts = options[context]; + if (!opts) { + return; + } + if (typeof opts === "string") { + opts = { target: opts, changeOrigin: true }; + } + const proxy = httpProxy$1.createProxyServer(opts); + if (opts.configure) { + opts.configure(proxy, opts); + } + proxy.on("error", (err, req, originalRes) => { + const res = originalRes; + if (!res) { + config.logger.error( + `${colors$1.red(`http proxy error: ${err.message}`)} +${err.stack}`, + { + timestamp: true, + error: err + } + ); + } else if ("req" in res) { + config.logger.error( + `${colors$1.red(`http proxy error: ${originalRes.req.url}`)} +${err.stack}`, + { + timestamp: true, + error: err + } + ); + if (!res.headersSent && !res.writableEnded) { + res.writeHead(500, { + "Content-Type": "text/plain" + }).end(); + } + } else { + config.logger.error(`${colors$1.red(`ws proxy error:`)} +${err.stack}`, { + timestamp: true, + error: err + }); + res.end(); + } + }); + proxy.on("proxyReqWs", (proxyReq, req, socket, options2, head) => { + rewriteOriginHeader(proxyReq, options2, config); + socket.on("error", (err) => { + config.logger.error( + `${colors$1.red(`ws proxy socket error:`)} +${err.stack}`, + { + timestamp: true, + error: err + } + ); + }); + }); + proxy.on("proxyRes", (proxyRes, req, res) => { + res.on("close", () => { + if (!res.writableEnded) { + debug$4?.("destroying proxyRes in proxyRes close event"); + proxyRes.destroy(); + } + }); + }); + proxies[context] = [proxy, { ...opts }]; + }); + if (httpServer) { + httpServer.on("upgrade", (req, socket, head) => { + const url = req.url; + for (const context in proxies) { + if (doesProxyContextMatchUrl(context, url)) { + const [proxy, opts] = proxies[context]; + if (opts.ws || opts.target?.toString().startsWith("ws:") || opts.target?.toString().startsWith("wss:")) { + if (opts.rewrite) { + req.url = opts.rewrite(url); + } + debug$4?.(`${req.url} -> ws ${opts.target}`); + proxy.ws(req, socket, head); + return; + } + } + } + }); + } + return function viteProxyMiddleware(req, res, next) { + const url = req.url; + for (const context in proxies) { + if (doesProxyContextMatchUrl(context, url)) { + const [proxy, opts] = proxies[context]; + const options2 = {}; + if (opts.bypass) { + const bypassResult = opts.bypass(req, res, opts); + if (typeof bypassResult === "string") { + req.url = bypassResult; + debug$4?.(`bypass: ${req.url} -> ${bypassResult}`); + return next(); + } else if (bypassResult === false) { + debug$4?.(`bypass: ${req.url} -> 404`); + res.statusCode = 404; + return res.end(); + } + } + debug$4?.(`${req.url} -> ${opts.target || opts.forward}`); + if (opts.rewrite) { + req.url = opts.rewrite(req.url); + } + proxy.web(req, res, options2); + return; + } + } + next(); + }; +} +function doesProxyContextMatchUrl(context, url) { + return context[0] === "^" && new RegExp(context).test(url) || url.startsWith(context); +} + +const debug$3 = createDebugger("vite:html-fallback"); +function htmlFallbackMiddleware(root, spaFallback, fsUtils = commonFsUtils) { + return function viteHtmlFallbackMiddleware(req, res, next) { + if ( + // Only accept GET or HEAD + req.method !== "GET" && req.method !== "HEAD" || // Exclude default favicon requests + req.url === "/favicon.ico" || // Require Accept: text/html or */* + !(req.headers.accept === void 0 || // equivalent to `Accept: */*` + req.headers.accept === "" || // equivalent to `Accept: */*` + req.headers.accept.includes("text/html") || req.headers.accept.includes("*/*")) + ) { + return next(); + } + const url = cleanUrl(req.url); + const pathname = decodeURIComponent(url); + if (pathname.endsWith(".html")) { + const filePath = path$n.join(root, pathname); + if (fsUtils.existsSync(filePath)) { + debug$3?.(`Rewriting ${req.method} ${req.url} to ${url}`); + req.url = url; + return next(); + } + } else if (pathname[pathname.length - 1] === "/") { + const filePath = path$n.join(root, pathname, "index.html"); + if (fsUtils.existsSync(filePath)) { + const newUrl = url + "index.html"; + debug$3?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`); + req.url = newUrl; + return next(); + } + } else { + const filePath = path$n.join(root, pathname + ".html"); + if (fsUtils.existsSync(filePath)) { + const newUrl = url + ".html"; + debug$3?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`); + req.url = newUrl; + return next(); + } + } + if (spaFallback) { + debug$3?.(`Rewriting ${req.method} ${req.url} to /index.html`); + req.url = "/index.html"; + } + next(); + }; +} + +const debug$2 = createDebugger("vite:send", { + onlyWhenFocused: true +}); +const alias = { + js: "text/javascript", + css: "text/css", + html: "text/html", + json: "application/json" +}; +function send(req, res, content, type, options) { + const { + etag = getEtag(content, { weak: true }), + cacheControl = "no-cache", + headers, + map + } = options; + if (res.writableEnded) { + return; + } + if (req.headers["if-none-match"] === etag) { + res.statusCode = 304; + res.end(); + return; + } + res.setHeader("Content-Type", alias[type] || type); + res.setHeader("Cache-Control", cacheControl); + res.setHeader("Etag", etag); + if (headers) { + for (const name in headers) { + res.setHeader(name, headers[name]); + } + } + if (map && "version" in map && map.mappings) { + if (type === "js" || type === "css") { + content = getCodeWithSourcemap(type, content.toString(), map); + } + } else if (type === "js" && (!map || map.mappings !== "")) { + const code = content.toString(); + if (convertSourceMap.mapFileCommentRegex.test(code)) { + debug$2?.(`Skipped injecting fallback sourcemap for ${req.url}`); + } else { + const urlWithoutTimestamp = removeTimestampQuery(req.url); + const ms = new MagicString(code); + content = getCodeWithSourcemap( + type, + code, + ms.generateMap({ + source: path$n.basename(urlWithoutTimestamp), + hires: "boundary", + includeContent: true + }) + ); + } + } + res.statusCode = 200; + res.end(content); + return; +} + +const debugCache = createDebugger("vite:cache"); +const knownIgnoreList = /* @__PURE__ */ new Set(["/", "/favicon.ico"]); +const trailingQuerySeparatorsRE = /[?&]+$/; +const urlRE = /[?&]url\b/; +const rawRE = /[?&]raw\b/; +const inlineRE = /[?&]inline\b/; +const svgRE = /\.svg\b/; +function deniedServingAccessForTransform(url, server, res, next) { + if (rawRE.test(url) || urlRE.test(url) || inlineRE.test(url) || svgRE.test(url)) { + const servingAccessResult = checkServingAccess(url, server); + if (servingAccessResult === "denied") { + respondWithAccessDenied(url, server, res); + return true; + } + if (servingAccessResult === "fallback") { + next(); + return true; + } + } + return false; +} +function cachedTransformMiddleware(server) { + return function viteCachedTransformMiddleware(req, res, next) { + const ifNoneMatch = req.headers["if-none-match"]; + if (ifNoneMatch) { + const moduleByEtag = server.moduleGraph.getModuleByEtag(ifNoneMatch); + if (moduleByEtag?.transformResult?.etag === ifNoneMatch && moduleByEtag?.url === req.url) { + const maybeMixedEtag = isCSSRequest(req.url); + if (!maybeMixedEtag) { + debugCache?.(`[304] ${prettifyUrl(req.url, server.config.root)}`); + res.statusCode = 304; + return res.end(); + } + } + } + next(); + }; +} +function transformMiddleware(server) { + const { root, publicDir } = server.config; + const publicDirInRoot = publicDir.startsWith(withTrailingSlash(root)); + const publicPath = `${publicDir.slice(root.length)}/`; + return async function viteTransformMiddleware(req, res, next) { + if (req.method !== "GET" || knownIgnoreList.has(req.url)) { + return next(); + } + let url; + try { + url = decodeURI(removeTimestampQuery(req.url)).replace( + NULL_BYTE_PLACEHOLDER, + "\0" + ); + } catch (e) { + return next(e); + } + const withoutQuery = cleanUrl(url); + try { + const isSourceMap = withoutQuery.endsWith(".map"); + if (isSourceMap) { + const depsOptimizer = getDepsOptimizer(server.config, false); + if (depsOptimizer?.isOptimizedDepUrl(url)) { + const sourcemapPath = url.startsWith(FS_PREFIX) ? fsPathFromId(url) : normalizePath$3(path$n.resolve(server.config.root, url.slice(1))); + try { + const map = JSON.parse( + await fsp.readFile(sourcemapPath, "utf-8") + ); + applySourcemapIgnoreList( + map, + sourcemapPath, + server.config.server.sourcemapIgnoreList, + server.config.logger + ); + return send(req, res, JSON.stringify(map), "json", { + headers: server.config.server.headers + }); + } catch (e) { + const dummySourceMap = { + version: 3, + file: sourcemapPath.replace(/\.map$/, ""), + sources: [], + sourcesContent: [], + names: [], + mappings: ";;;;;;;;;" + }; + return send(req, res, JSON.stringify(dummySourceMap), "json", { + cacheControl: "no-cache", + headers: server.config.server.headers + }); + } + } else { + const originalUrl = url.replace(/\.map($|\?)/, "$1"); + const map = (await server.moduleGraph.getModuleByUrl(originalUrl, false))?.transformResult?.map; + if (map) { + return send(req, res, JSON.stringify(map), "json", { + headers: server.config.server.headers + }); + } else { + return next(); + } + } + } + if (publicDirInRoot && url.startsWith(publicPath)) { + warnAboutExplicitPublicPathInUrl(url); + } + const urlWithoutTrailingQuerySeparators = url.replace( + trailingQuerySeparatorsRE, + "" + ); + if (deniedServingAccessForTransform( + urlWithoutTrailingQuerySeparators, + server, + res, + next + )) { + return; + } + if (isJSRequest(url) || isImportRequest(url) || isCSSRequest(url) || isHTMLProxy(url)) { + url = removeImportQuery(url); + url = unwrapId$1(url); + if (isCSSRequest(url)) { + if (req.headers.accept?.includes("text/css") && !isDirectRequest(url)) { + url = injectQuery(url, "direct"); + } + const ifNoneMatch = req.headers["if-none-match"]; + if (ifNoneMatch && (await server.moduleGraph.getModuleByUrl(url, false))?.transformResult?.etag === ifNoneMatch) { + debugCache?.(`[304] ${prettifyUrl(url, server.config.root)}`); + res.statusCode = 304; + return res.end(); + } + } + const result = await transformRequest(url, server, { + html: req.headers.accept?.includes("text/html"), + allowId(id) { + return !deniedServingAccessForTransform(id, server, res, next); + } + }); + if (result) { + const depsOptimizer = getDepsOptimizer(server.config, false); + const type = isDirectCSSRequest(url) ? "css" : "js"; + const isDep = DEP_VERSION_RE.test(url) || depsOptimizer?.isOptimizedDepUrl(url); + return send(req, res, result.code, type, { + etag: result.etag, + // allow browser to cache npm deps! + cacheControl: isDep ? "max-age=31536000,immutable" : "no-cache", + headers: server.config.server.headers, + map: result.map + }); + } + } + } catch (e) { + if (e?.code === ERR_OPTIMIZE_DEPS_PROCESSING_ERROR) { + if (!res.writableEnded) { + res.statusCode = 504; + res.statusMessage = "Optimize Deps Processing Error"; + res.end(); + } + server.config.logger.error(e.message); + return; + } + if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) { + if (!res.writableEnded) { + res.statusCode = 504; + res.statusMessage = "Outdated Optimize Dep"; + res.end(); + } + return; + } + if (e?.code === ERR_CLOSED_SERVER) { + if (!res.writableEnded) { + res.statusCode = 504; + res.statusMessage = "Outdated Request"; + res.end(); + } + return; + } + if (e?.code === ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR) { + if (!res.writableEnded) { + res.statusCode = 404; + res.end(); + } + server.config.logger.warn(colors$1.yellow(e.message)); + return; + } + if (e?.code === ERR_LOAD_URL) { + return next(); + } + if (e?.code === ERR_DENIED_ID) { + return; + } + return next(e); + } + next(); + }; + function warnAboutExplicitPublicPathInUrl(url) { + let warning; + if (isImportRequest(url)) { + const rawUrl = removeImportQuery(url); + if (urlRE.test(url)) { + warning = `Assets in the public directory are served at the root path. +Instead of ${colors$1.cyan(rawUrl)}, use ${colors$1.cyan( + rawUrl.replace(publicPath, "/") + )}.`; + } else { + warning = `Assets in public directory cannot be imported from JavaScript. +If you intend to import that asset, put the file in the src directory, and use ${colors$1.cyan( + rawUrl.replace(publicPath, "/src/") + )} instead of ${colors$1.cyan(rawUrl)}. +If you intend to use the URL of that asset, use ${colors$1.cyan( + injectQuery(rawUrl.replace(publicPath, "/"), "url") + )}.`; + } + } else { + warning = `Files in the public directory are served at the root path. +Instead of ${colors$1.cyan(url)}, use ${colors$1.cyan( + url.replace(publicPath, "/") + )}.`; + } + server.config.logger.warn(colors$1.yellow(warning)); + } +} + +function createDevHtmlTransformFn(config) { + const [preHooks, normalHooks, postHooks] = resolveHtmlTransforms( + config.plugins, + config.logger + ); + const transformHooks = [ + preImportMapHook(config), + injectCspNonceMetaTagHook(config), + ...preHooks, + htmlEnvHook(config), + devHtmlHook, + ...normalHooks, + ...postHooks, + injectNonceAttributeTagHook(config), + postImportMapHook() + ]; + return (server, url, html, originalUrl) => { + return applyHtmlTransforms(html, transformHooks, { + path: url, + filename: getHtmlFilename(url, server), + server, + originalUrl + }); + }; +} +function getHtmlFilename(url, server) { + if (url.startsWith(FS_PREFIX)) { + return decodeURIComponent(fsPathFromId(url)); + } else { + return decodeURIComponent( + normalizePath$3(path$n.join(server.config.root, url.slice(1))) + ); + } +} +function shouldPreTransform(url, config) { + return !checkPublicFile(url, config) && (isJSRequest(url) || isCSSRequest(url)); +} +const wordCharRE = /\w/; +function isBareRelative(url) { + return wordCharRE.test(url[0]) && !url.includes(":"); +} +const isSrcSet = (attr) => attr.name === "srcset" && attr.prefix === void 0; +const processNodeUrl = (url, useSrcSetReplacer, config, htmlPath, originalUrl, server, isClassicScriptLink) => { + const replacer = (url2) => { + if (server?.moduleGraph) { + const mod = server.moduleGraph.urlToModuleMap.get(url2); + if (mod && mod.lastHMRTimestamp > 0) { + url2 = injectQuery(url2, `t=${mod.lastHMRTimestamp}`); + } + } + if (url2[0] === "/" && url2[1] !== "/" || // #3230 if some request url (localhost:3000/a/b) return to fallback html, the relative assets + // path will add `/a/` prefix, it will caused 404. + // + // skip if url contains `:` as it implies a url protocol or Windows path that we don't want to replace. + // + // rewrite `./index.js` -> `localhost:5173/a/index.js`. + // rewrite `../index.js` -> `localhost:5173/index.js`. + // rewrite `relative/index.js` -> `localhost:5173/a/relative/index.js`. + (url2[0] === "." || isBareRelative(url2)) && originalUrl && originalUrl !== "/" && htmlPath === "/index.html") { + url2 = path$n.posix.join(config.base, url2); + } + if (server && !isClassicScriptLink && shouldPreTransform(url2, config)) { + let preTransformUrl; + if (url2[0] === "/" && url2[1] !== "/") { + preTransformUrl = url2; + } else if (url2[0] === "." || isBareRelative(url2)) { + preTransformUrl = path$n.posix.join( + config.base, + path$n.posix.dirname(htmlPath), + url2 + ); + } + if (preTransformUrl) { + try { + preTransformUrl = decodeURI(preTransformUrl); + } catch (err) { + return url2; + } + preTransformRequest(server, preTransformUrl, config.decodedBase); + } + } + return url2; + }; + const processedUrl = useSrcSetReplacer ? processSrcSetSync(url, ({ url: url2 }) => replacer(url2)) : replacer(url); + return processedUrl; +}; +const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl }) => { + const { config, moduleGraph, watcher } = server; + const base = config.base || "/"; + const decodedBase = config.decodedBase || "/"; + let proxyModulePath; + let proxyModuleUrl; + const trailingSlash = htmlPath.endsWith("/"); + if (!trailingSlash && getFsUtils(config).existsSync(filename)) { + proxyModulePath = htmlPath; + proxyModuleUrl = proxyModulePath; + } else { + const validPath = `${htmlPath}${trailingSlash ? "index.html" : ""}`; + proxyModulePath = `\0${validPath}`; + proxyModuleUrl = wrapId$1(proxyModulePath); + } + proxyModuleUrl = joinUrlSegments(decodedBase, proxyModuleUrl); + const s = new MagicString(html); + let inlineModuleIndex = -1; + const proxyCacheUrl = decodeURI( + cleanUrl(proxyModulePath).replace(normalizePath$3(config.root), "") + ); + const styleUrl = []; + const inlineStyles = []; + const addInlineModule = (node, ext) => { + inlineModuleIndex++; + const contentNode = node.childNodes[0]; + const code = contentNode.value; + let map; + if (proxyModulePath[0] !== "\0") { + map = new MagicString(html).snip( + contentNode.sourceCodeLocation.startOffset, + contentNode.sourceCodeLocation.endOffset + ).generateMap({ hires: "boundary" }); + map.sources = [filename]; + map.file = filename; + } + addToHTMLProxyCache(config, proxyCacheUrl, inlineModuleIndex, { code, map }); + const modulePath = `${proxyModuleUrl}?html-proxy&index=${inlineModuleIndex}.${ext}`; + const module = server?.moduleGraph.getModuleById(modulePath); + if (module) { + server?.moduleGraph.invalidateModule(module); + } + s.update( + node.sourceCodeLocation.startOffset, + node.sourceCodeLocation.endOffset, + `