@voltagent/internal 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/index.js +27 -17
- package/dist/main/index.js.map +1 -1
- package/dist/main/index.mjs +27 -17
- package/dist/main/index.mjs.map +1 -1
- package/dist/utils/index.js +27 -17
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +27 -17
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/main/index.js
CHANGED
|
@@ -166,25 +166,35 @@ function safeStringify(input, { indentation } = {}) {
|
|
|
166
166
|
}
|
|
167
167
|
__name(safeStringify, "safeStringify");
|
|
168
168
|
function safeStringifyReplacer(seen) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
169
|
+
const stack = [];
|
|
170
|
+
return /* @__PURE__ */ __name(function safeStringifyCircularReplacer(_key, value) {
|
|
171
|
+
if (stack.length === 0) {
|
|
172
|
+
stack.push(this);
|
|
173
|
+
} else {
|
|
174
|
+
const thisIndex = stack.indexOf(this);
|
|
175
|
+
if (thisIndex === -1) {
|
|
176
|
+
stack.push(this);
|
|
177
|
+
} else {
|
|
178
|
+
stack.splice(thisIndex + 1);
|
|
179
|
+
}
|
|
178
180
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
if (value && typeof value === "object") {
|
|
182
|
+
if (typeof value.toJSON === "function") {
|
|
183
|
+
value = value.toJSON();
|
|
184
|
+
}
|
|
185
|
+
if (value && typeof value === "object") {
|
|
186
|
+
if (stack.includes(value)) {
|
|
187
|
+
return "[Circular]";
|
|
188
|
+
}
|
|
189
|
+
if (!seen.has(value)) {
|
|
190
|
+
seen.add(value);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
return value;
|
|
194
|
+
}
|
|
183
195
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}, "replacer");
|
|
187
|
-
return replacer;
|
|
196
|
+
return value;
|
|
197
|
+
}, "safeStringifyCircularReplacer");
|
|
188
198
|
}
|
|
189
199
|
__name(safeStringifyReplacer, "safeStringifyReplacer");
|
|
190
200
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/main/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/test/conversions.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["export * from \"./test\";\nexport * from \"./utils\";\nexport * from \"./a2a\";\nexport * from \"./mcp\";\nexport type * from \"./logger/types\";\n","/**\n * Convert a readable stream to an array\n * @param stream - The readable stream to convert\n * @returns The array of values\n */\nexport async function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]> {\n const reader = stream.getReader();\n const result: T[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n result.push(value);\n }\n\n return result;\n}\n\n/**\n * Convert an array to an async iterable\n * @param values - The array to convert\n * @returns The async iterable\n */\nexport function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of values) {\n yield value;\n }\n },\n };\n}\n\n/**\n * Convert an async iterable to an array\n * @param iterable - The async iterable to convert\n * @returns The array of values\n */\nexport async function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const result: T[] = [];\n for await (const item of iterable) {\n result.push(item);\n }\n return result;\n}\n\n/**\n * Convert an array to a readable stream\n * @param values - The array to convert\n * @returns The readable stream\n */\nexport function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T> {\n return new ReadableStream({\n start(controller) {\n try {\n for (const value of values) {\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Convert a response stream to an array\n * @param response - The response to convert\n * @returns The array of values\n */\nexport async function convertResponseStreamToArray(response: Response): Promise<string[]> {\n // biome-ignore lint/style/noNonNullAssertion: ignore this\n return convertReadableStreamToArray(response.body!.pipeThrough(new TextDecoderStream()));\n}\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const replacer = (_key: string, value: DangerouslyAllowAny) => {\n // Handle objects with a custom `.toJSON()` method.\n if (typeof value?.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (!(value !== null && typeof value === \"object\")) {\n return value;\n }\n\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n\n seen.add(value);\n\n const newValue = Array.isArray(value) ? [] : {};\n\n for (const [key2, value2] of Object.entries(value)) {\n // @ts-expect-error - ignore as this is needed to handle circular references\n newValue[key2] = replacer(key2, value2);\n }\n\n seen.delete(value);\n\n return newValue;\n };\n\n return replacer;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/test/conversions.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["export * from \"./test\";\nexport * from \"./utils\";\nexport * from \"./a2a\";\nexport * from \"./mcp\";\nexport type * from \"./logger/types\";\n","/**\n * Convert a readable stream to an array\n * @param stream - The readable stream to convert\n * @returns The array of values\n */\nexport async function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]> {\n const reader = stream.getReader();\n const result: T[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n result.push(value);\n }\n\n return result;\n}\n\n/**\n * Convert an array to an async iterable\n * @param values - The array to convert\n * @returns The async iterable\n */\nexport function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of values) {\n yield value;\n }\n },\n };\n}\n\n/**\n * Convert an async iterable to an array\n * @param iterable - The async iterable to convert\n * @returns The array of values\n */\nexport async function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const result: T[] = [];\n for await (const item of iterable) {\n result.push(item);\n }\n return result;\n}\n\n/**\n * Convert an array to a readable stream\n * @param values - The array to convert\n * @returns The readable stream\n */\nexport function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T> {\n return new ReadableStream({\n start(controller) {\n try {\n for (const value of values) {\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Convert a response stream to an array\n * @param response - The response to convert\n * @returns The array of values\n */\nexport async function convertResponseStreamToArray(response: Response): Promise<string[]> {\n // biome-ignore lint/style/noNonNullAssertion: ignore this\n return convertReadableStreamToArray(response.body!.pipeThrough(new TextDecoderStream()));\n}\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const stack: DangerouslyAllowAny[] = [];\n return function safeStringifyCircularReplacer(\n this: DangerouslyAllowAny,\n _key: string,\n value: DangerouslyAllowAny,\n ) {\n if (stack.length === 0) {\n stack.push(this);\n } else {\n const thisIndex = stack.indexOf(this);\n if (thisIndex === -1) {\n stack.push(this);\n } else {\n stack.splice(thisIndex + 1);\n }\n }\n\n if (value && typeof value === \"object\") {\n if (typeof value.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (value && typeof value === \"object\") {\n if (stack.includes(value)) {\n return \"[Circular]\";\n }\n\n if (!seen.has(value)) {\n seen.add(value);\n }\n } else {\n return value;\n }\n }\n\n return value;\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/main/index.mjs
CHANGED
|
@@ -129,25 +129,35 @@ function safeStringify(input, { indentation } = {}) {
|
|
|
129
129
|
}
|
|
130
130
|
__name(safeStringify, "safeStringify");
|
|
131
131
|
function safeStringifyReplacer(seen) {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
const stack = [];
|
|
133
|
+
return /* @__PURE__ */ __name(function safeStringifyCircularReplacer(_key, value) {
|
|
134
|
+
if (stack.length === 0) {
|
|
135
|
+
stack.push(this);
|
|
136
|
+
} else {
|
|
137
|
+
const thisIndex = stack.indexOf(this);
|
|
138
|
+
if (thisIndex === -1) {
|
|
139
|
+
stack.push(this);
|
|
140
|
+
} else {
|
|
141
|
+
stack.splice(thisIndex + 1);
|
|
142
|
+
}
|
|
141
143
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
if (value && typeof value === "object") {
|
|
145
|
+
if (typeof value.toJSON === "function") {
|
|
146
|
+
value = value.toJSON();
|
|
147
|
+
}
|
|
148
|
+
if (value && typeof value === "object") {
|
|
149
|
+
if (stack.includes(value)) {
|
|
150
|
+
return "[Circular]";
|
|
151
|
+
}
|
|
152
|
+
if (!seen.has(value)) {
|
|
153
|
+
seen.add(value);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
146
158
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}, "replacer");
|
|
150
|
-
return replacer;
|
|
159
|
+
return value;
|
|
160
|
+
}, "safeStringifyCircularReplacer");
|
|
151
161
|
}
|
|
152
162
|
__name(safeStringifyReplacer, "safeStringifyReplacer");
|
|
153
163
|
export {
|
package/dist/main/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/conversions.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * Convert a readable stream to an array\n * @param stream - The readable stream to convert\n * @returns The array of values\n */\nexport async function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]> {\n const reader = stream.getReader();\n const result: T[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n result.push(value);\n }\n\n return result;\n}\n\n/**\n * Convert an array to an async iterable\n * @param values - The array to convert\n * @returns The async iterable\n */\nexport function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of values) {\n yield value;\n }\n },\n };\n}\n\n/**\n * Convert an async iterable to an array\n * @param iterable - The async iterable to convert\n * @returns The array of values\n */\nexport async function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const result: T[] = [];\n for await (const item of iterable) {\n result.push(item);\n }\n return result;\n}\n\n/**\n * Convert an array to a readable stream\n * @param values - The array to convert\n * @returns The readable stream\n */\nexport function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T> {\n return new ReadableStream({\n start(controller) {\n try {\n for (const value of values) {\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Convert a response stream to an array\n * @param response - The response to convert\n * @returns The array of values\n */\nexport async function convertResponseStreamToArray(response: Response): Promise<string[]> {\n // biome-ignore lint/style/noNonNullAssertion: ignore this\n return convertReadableStreamToArray(response.body!.pipeThrough(new TextDecoderStream()));\n}\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const replacer = (_key: string, value: DangerouslyAllowAny) => {\n // Handle objects with a custom `.toJSON()` method.\n if (typeof value?.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (!(value !== null && typeof value === \"object\")) {\n return value;\n }\n\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n\n seen.add(value);\n\n const newValue = Array.isArray(value) ? [] : {};\n\n for (const [key2, value2] of Object.entries(value)) {\n // @ts-expect-error - ignore as this is needed to handle circular references\n newValue[key2] = replacer(key2, value2);\n }\n\n seen.delete(value);\n\n return newValue;\n };\n\n return replacer;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/test/conversions.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * Convert a readable stream to an array\n * @param stream - The readable stream to convert\n * @returns The array of values\n */\nexport async function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]> {\n const reader = stream.getReader();\n const result: T[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n result.push(value);\n }\n\n return result;\n}\n\n/**\n * Convert an array to an async iterable\n * @param values - The array to convert\n * @returns The async iterable\n */\nexport function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of values) {\n yield value;\n }\n },\n };\n}\n\n/**\n * Convert an async iterable to an array\n * @param iterable - The async iterable to convert\n * @returns The array of values\n */\nexport async function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const result: T[] = [];\n for await (const item of iterable) {\n result.push(item);\n }\n return result;\n}\n\n/**\n * Convert an array to a readable stream\n * @param values - The array to convert\n * @returns The readable stream\n */\nexport function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T> {\n return new ReadableStream({\n start(controller) {\n try {\n for (const value of values) {\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Convert a response stream to an array\n * @param response - The response to convert\n * @returns The array of values\n */\nexport async function convertResponseStreamToArray(response: Response): Promise<string[]> {\n // biome-ignore lint/style/noNonNullAssertion: ignore this\n return convertReadableStreamToArray(response.body!.pipeThrough(new TextDecoderStream()));\n}\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const stack: DangerouslyAllowAny[] = [];\n return function safeStringifyCircularReplacer(\n this: DangerouslyAllowAny,\n _key: string,\n value: DangerouslyAllowAny,\n ) {\n if (stack.length === 0) {\n stack.push(this);\n } else {\n const thisIndex = stack.indexOf(this);\n if (thisIndex === -1) {\n stack.push(this);\n } else {\n stack.splice(thisIndex + 1);\n }\n }\n\n if (value && typeof value === \"object\") {\n if (typeof value.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (value && typeof value === \"object\") {\n if (stack.includes(value)) {\n return \"[Circular]\";\n }\n\n if (!seen.has(value)) {\n seen.add(value);\n }\n } else {\n return value;\n }\n }\n\n return value;\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/utils/index.js
CHANGED
|
@@ -112,25 +112,35 @@ function safeStringify(input, { indentation } = {}) {
|
|
|
112
112
|
}
|
|
113
113
|
__name(safeStringify, "safeStringify");
|
|
114
114
|
function safeStringifyReplacer(seen) {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
const stack = [];
|
|
116
|
+
return /* @__PURE__ */ __name(function safeStringifyCircularReplacer(_key, value) {
|
|
117
|
+
if (stack.length === 0) {
|
|
118
|
+
stack.push(this);
|
|
119
|
+
} else {
|
|
120
|
+
const thisIndex = stack.indexOf(this);
|
|
121
|
+
if (thisIndex === -1) {
|
|
122
|
+
stack.push(this);
|
|
123
|
+
} else {
|
|
124
|
+
stack.splice(thisIndex + 1);
|
|
125
|
+
}
|
|
124
126
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
if (value && typeof value === "object") {
|
|
128
|
+
if (typeof value.toJSON === "function") {
|
|
129
|
+
value = value.toJSON();
|
|
130
|
+
}
|
|
131
|
+
if (value && typeof value === "object") {
|
|
132
|
+
if (stack.includes(value)) {
|
|
133
|
+
return "[Circular]";
|
|
134
|
+
}
|
|
135
|
+
if (!seen.has(value)) {
|
|
136
|
+
seen.add(value);
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
129
141
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}, "replacer");
|
|
133
|
-
return replacer;
|
|
142
|
+
return value;
|
|
143
|
+
}, "safeStringifyCircularReplacer");
|
|
134
144
|
}
|
|
135
145
|
__name(safeStringifyReplacer, "safeStringifyReplacer");
|
|
136
146
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["export { deepClone, hasKey } from \"./objects\";\nexport { isNil, isObject, isEmptyObject, isFunction, isPlainObject } from \"./lang\";\nexport type { AsyncIterableStream } from \"./async-iterable-stream\";\nexport { createAsyncIterableStream } from \"./async-iterable-stream\";\nexport { safeStringify, type SafeStringifyOptions } from \"./safe-stringify\";\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts","../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["export { deepClone, hasKey } from \"./objects\";\nexport { isNil, isObject, isEmptyObject, isFunction, isPlainObject } from \"./lang\";\nexport type { AsyncIterableStream } from \"./async-iterable-stream\";\nexport { createAsyncIterableStream } from \"./async-iterable-stream\";\nexport { safeStringify, type SafeStringifyOptions } from \"./safe-stringify\";\n","import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const stack: DangerouslyAllowAny[] = [];\n return function safeStringifyCircularReplacer(\n this: DangerouslyAllowAny,\n _key: string,\n value: DangerouslyAllowAny,\n ) {\n if (stack.length === 0) {\n stack.push(this);\n } else {\n const thisIndex = stack.indexOf(this);\n if (thisIndex === -1) {\n stack.push(this);\n } else {\n stack.splice(thisIndex + 1);\n }\n }\n\n if (value && typeof value === \"object\") {\n if (typeof value.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (value && typeof value === \"object\") {\n if (stack.includes(value)) {\n return \"[Circular]\";\n }\n\n if (!seen.has(value)) {\n seen.add(value);\n }\n } else {\n return value;\n }\n }\n\n return value;\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -80,25 +80,35 @@ function safeStringify(input, { indentation } = {}) {
|
|
|
80
80
|
}
|
|
81
81
|
__name(safeStringify, "safeStringify");
|
|
82
82
|
function safeStringifyReplacer(seen) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
const stack = [];
|
|
84
|
+
return /* @__PURE__ */ __name(function safeStringifyCircularReplacer(_key, value) {
|
|
85
|
+
if (stack.length === 0) {
|
|
86
|
+
stack.push(this);
|
|
87
|
+
} else {
|
|
88
|
+
const thisIndex = stack.indexOf(this);
|
|
89
|
+
if (thisIndex === -1) {
|
|
90
|
+
stack.push(this);
|
|
91
|
+
} else {
|
|
92
|
+
stack.splice(thisIndex + 1);
|
|
93
|
+
}
|
|
92
94
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
if (value && typeof value === "object") {
|
|
96
|
+
if (typeof value.toJSON === "function") {
|
|
97
|
+
value = value.toJSON();
|
|
98
|
+
}
|
|
99
|
+
if (value && typeof value === "object") {
|
|
100
|
+
if (stack.includes(value)) {
|
|
101
|
+
return "[Circular]";
|
|
102
|
+
}
|
|
103
|
+
if (!seen.has(value)) {
|
|
104
|
+
seen.add(value);
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
97
109
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}, "replacer");
|
|
101
|
-
return replacer;
|
|
110
|
+
return value;
|
|
111
|
+
}, "safeStringifyCircularReplacer");
|
|
102
112
|
}
|
|
103
113
|
__name(safeStringifyReplacer, "safeStringifyReplacer");
|
|
104
114
|
export {
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/utils/lang.ts","../../src/utils/objects.ts","../../src/utils/async-iterable-stream.ts","../../src/utils/safe-stringify.ts"],"sourcesContent":["import type { EmptyObject } from \"type-fest\";\nimport type { AnyFunction, Nil, PlainObject } from \"../types\";\n\n/**\n * Check if a value is nil\n *\n * @param obj - The value to check\n * @returns True if the value is nil, false otherwise\n */\nexport function isNil(obj: unknown): obj is Nil {\n return obj === null || obj === undefined;\n}\n\n/**\n * Check if an object is a JS object\n *\n * @param obj - The object to check\n * @returns True if the object is a JS object}\n */\nexport function isObject<T extends object>(obj: unknown): obj is T {\n return (typeof obj === \"object\" || typeof obj === \"function\") && !isNil(obj);\n}\n\n/**\n * Check if a value is a function\n *\n * @param obj - The value to check\n * @returns True if the value is a function, false otherwise\n */\nexport function isFunction<T extends AnyFunction>(obj: unknown): obj is T {\n return typeof obj === \"function\";\n}\n\n/**\n * Check if an object is a plain object (i.e. a JS object but not including arrays or functions)\n *\n * @param obj - The object to check\n * @returns True if the object is a plain object, false otherwise.\n */\nexport function isPlainObject<T extends PlainObject>(obj: unknown): obj is T {\n if (!isObject(obj)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Check if an object is an empty object\n *\n * @param obj - The object to check\n * @returns True if the object is an empty object, false otherwise\n */\nexport function isEmptyObject(obj: unknown): obj is EmptyObject {\n if (!isObject(obj)) {\n return false;\n }\n\n // Check for own string and symbol properties (enumerable or not)\n if (Object.getOwnPropertyNames(obj).length > 0 || Object.getOwnPropertySymbols(obj).length > 0) {\n return false;\n }\n\n return true;\n}\n","import type { SetRequired } from \"type-fest\";\nimport type { PlainObject } from \"../types\";\nimport { isObject } from \"./lang\";\n\n/**\n * Deep clone an object\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object (fallback to shallow clone for failures)\n */\nexport function deepClone<T>(obj: T): T {\n try {\n // Use structuredClone if available (Node.js 17+, modern browsers)\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n throw new Error(\"structuredClone is not available\");\n } catch (_error) {\n // Fallback to shallow clone for primitive types and simple objects\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n return { ...obj } as T;\n }\n}\n\n/**\n * Check if an object has a key\n *\n * @param obj - The object to check\n * @param key - The key to check\n * @returns True if the object has the key, false otherwise\n */\nexport function hasKey<T extends PlainObject, K extends string>(\n obj: T,\n key: K,\n): obj is T & SetRequired<T, K> {\n return isObject(obj) && key in obj;\n}\n","import type { Merge } from \"type-fest\";\n\n/**\n * An async iterable stream that can be read from.\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = getStream();\n * for await (const chunk of stream) {\n * console.log(chunk);\n * }\n * ```\n */\nexport type AsyncIterableStream<T> = Merge<AsyncIterable<T>, ReadableStream<T>>;\n\n/**\n * Create an async iterable stream from a readable stream.\n *\n * This is useful for creating an async iterable stream from a readable stream.\n *\n * @example\n * ```typescript\n * const stream: AsyncIterableStream<string> = createAsyncIterableStream(new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"Hello\");\n * controller.close();\n * },\n * }));\n * ```\n * @param source The readable stream to create an async iterable stream from.\n * @returns The async iterable stream.\n */\nexport function createAsyncIterableStream<T>(source: ReadableStream<T>): AsyncIterableStream<T> {\n const stream = source.pipeThrough(new TransformStream<T, T>());\n\n (stream as AsyncIterableStream<T>)[Symbol.asyncIterator] = () => {\n const reader = stream.getReader();\n return {\n async next(): Promise<IteratorResult<T>> {\n const { done, value } = await reader.read();\n return done ? { done: true, value: undefined } : { done: false, value };\n },\n };\n };\n\n return stream as AsyncIterableStream<T>;\n}\n","import type { DangerouslyAllowAny } from \"../types\";\n\nexport type SafeStringifyOptions = {\n /**\n * The indentation to use for the output.\n */\n indentation?: string | number;\n};\n\n/**\n * Stringifies an object, handling circular references and ensuring the output is safe to use in a JSON string.\n * @param input - The object to stringify.\n * @param options.indentation - The indentation to use for the output.\n * @returns The stringified object.\n */\nexport function safeStringify(\n input: DangerouslyAllowAny,\n { indentation }: SafeStringifyOptions = {},\n) {\n try {\n const seen = new WeakSet();\n return JSON.stringify(input, safeStringifyReplacer(seen), indentation);\n } catch (error) {\n return `SAFE_STRINGIFY_ERROR: Error stringifying object: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n}\n\nfunction safeStringifyReplacer(seen: WeakSet<DangerouslyAllowAny>) {\n const stack: DangerouslyAllowAny[] = [];\n return function safeStringifyCircularReplacer(\n this: DangerouslyAllowAny,\n _key: string,\n value: DangerouslyAllowAny,\n ) {\n if (stack.length === 0) {\n stack.push(this);\n } else {\n const thisIndex = stack.indexOf(this);\n if (thisIndex === -1) {\n stack.push(this);\n } else {\n stack.splice(thisIndex + 1);\n }\n }\n\n if (value && typeof value === \"object\") {\n if (typeof value.toJSON === \"function\") {\n // biome-ignore lint/style/noParameterAssign: needed to handle circular references\n value = value.toJSON();\n }\n\n if (value && typeof value === \"object\") {\n if (stack.includes(value)) {\n return \"[Circular]\";\n }\n\n if (!seen.has(value)) {\n seen.add(value);\n }\n } else {\n return value;\n }\n }\n\n return value;\n };\n}\n"],"mappings":";;;;AASO,SAAS,MAAM,KAA0B;AAC9C,SAAO,QAAQ,QAAQ,QAAQ;AACjC;AAFgB;AAUT,SAAS,SAA2B,KAAwB;AACjE,UAAQ,OAAO,QAAQ,YAAY,OAAO,QAAQ,eAAe,CAAC,MAAM,GAAG;AAC7E;AAFgB;AAUT,SAAS,WAAkC,KAAwB;AACxE,SAAO,OAAO,QAAQ;AACxB;AAFgB;AAUT,SAAS,cAAqC,KAAwB;AAC3E,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,OAAO,eAAe,GAAG;AAC3C,SAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AAPgB;AAeT,SAAS,cAAc,KAAkC;AAC9D,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,oBAAoB,GAAG,EAAE,SAAS,KAAK,OAAO,sBAAsB,GAAG,EAAE,SAAS,GAAG;AAC9F,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAXgB;;;AC5CT,SAAS,UAAa,KAAW;AACtC,MAAI;AAEF,QAAI,OAAO,oBAAoB,YAAY;AACzC,aAAO,gBAAgB,GAAG;AAAA,IAC5B;AAEA,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD,SAAS,QAAQ;AAEf,QAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,aAAO;AAAA,IACT;AACA,WAAO,EAAE,GAAG,IAAI;AAAA,EAClB;AACF;AAfgB;AAwBT,SAAS,OACd,KACA,KAC8B;AAC9B,SAAO,SAAS,GAAG,KAAK,OAAO;AACjC;AALgB;;;ACHT,SAAS,0BAA6B,QAAmD;AAC9F,QAAM,SAAS,OAAO,YAAY,IAAI,gBAAsB,CAAC;AAE7D,EAAC,OAAkC,OAAO,aAAa,IAAI,MAAM;AAC/D,UAAM,SAAS,OAAO,UAAU;AAChC,WAAO;AAAA,MACL,MAAM,OAAmC;AACvC,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,eAAO,OAAO,EAAE,MAAM,MAAM,OAAO,OAAU,IAAI,EAAE,MAAM,OAAO,MAAM;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAdgB;;;AChBT,SAAS,cACd,OACA,EAAE,YAAY,IAA0B,CAAC,GACzC;AACA,MAAI;AACF,UAAM,OAAO,oBAAI,QAAQ;AACzB,WAAO,KAAK,UAAU,OAAO,sBAAsB,IAAI,GAAG,WAAW;AAAA,EACvE,SAAS,OAAO;AACd,WAAO,oDAAoD,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,EACrH;AACF;AAVgB;AAYhB,SAAS,sBAAsB,MAAoC;AACjE,QAAM,QAA+B,CAAC;AACtC,SAAO,gCAAS,8BAEd,MACA,OACA;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,YAAM,YAAY,MAAM,QAAQ,IAAI;AACpC,UAAI,cAAc,IAAI;AACpB,cAAM,KAAK,IAAI;AAAA,MACjB,OAAO;AACL,cAAM,OAAO,YAAY,CAAC;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAI,OAAO,MAAM,WAAW,YAAY;AAEtC,gBAAQ,MAAM,OAAO;AAAA,MACvB;AAEA,UAAI,SAAS,OAAO,UAAU,UAAU;AACtC,YAAI,MAAM,SAAS,KAAK,GAAG;AACzB,iBAAO;AAAA,QACT;AAEA,YAAI,CAAC,KAAK,IAAI,KAAK,GAAG;AACpB,eAAK,IAAI,KAAK;AAAA,QAChB;AAAA,MACF,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GApCO;AAqCT;AAvCS;","names":[]}
|