modelfusion 0.47.0 → 0.47.2
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/README.md +37 -36
- package/core/structure/Schema.d.ts +5 -5
- package/core/structure/UncheckedSchema.cjs +2 -2
- package/core/structure/UncheckedSchema.d.ts +2 -2
- package/core/structure/UncheckedSchema.js +2 -2
- package/core/structure/ZodSchema.cjs +2 -5
- package/core/structure/ZodSchema.d.ts +2 -2
- package/core/structure/ZodSchema.js +2 -5
- package/event-source/readEventSource.cjs +5 -8
- package/event-source/readEventSource.d.ts +1 -1
- package/event-source/readEventSource.js +5 -5
- package/event-source/readEventSourceStream.cjs +3 -6
- package/event-source/readEventSourceStream.js +3 -3
- package/guard/fixStructure.cjs +50 -0
- package/guard/fixStructure.d.ts +50 -0
- package/guard/fixStructure.js +50 -0
- package/guard/guard.d.ts +1 -1
- package/model-function/generate-structure/fixJson.test.cjs +183 -181
- package/model-function/generate-structure/fixJson.test.js +181 -182
- package/model-function/generate-structure/generateStructure.cjs +1 -1
- package/model-function/generate-structure/generateStructure.js +1 -1
- package/model-function/generate-structure/generateStructureOrText.cjs +1 -1
- package/model-function/generate-structure/generateStructureOrText.js +1 -1
- package/model-function/generate-structure/streamStructure.cjs +3 -8
- package/model-function/generate-structure/streamStructure.js +3 -5
- package/model-provider/anthropic/AnthropicError.cjs +7 -14
- package/model-provider/anthropic/AnthropicError.js +7 -11
- package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +2 -15
- package/model-provider/anthropic/AnthropicTextGenerationModel.js +2 -12
- package/model-provider/automatic1111/Automatic1111Error.cjs +2 -5
- package/model-provider/automatic1111/Automatic1111Error.d.ts +1 -1
- package/model-provider/automatic1111/Automatic1111Error.js +2 -2
- package/model-provider/cohere/CohereError.cjs +2 -5
- package/model-provider/cohere/CohereError.js +2 -2
- package/model-provider/cohere/CohereTextEmbeddingModel.cjs +8 -11
- package/model-provider/cohere/CohereTextEmbeddingModel.d.ts +1 -1
- package/model-provider/cohere/CohereTextEmbeddingModel.js +1 -1
- package/model-provider/cohere/CohereTextGenerationModel.cjs +22 -21
- package/model-provider/cohere/CohereTextGenerationModel.js +22 -18
- package/model-provider/cohere/CohereTokenizer.cjs +12 -15
- package/model-provider/cohere/CohereTokenizer.d.ts +1 -1
- package/model-provider/cohere/CohereTokenizer.js +1 -1
- package/model-provider/huggingface/HuggingFaceError.cjs +7 -31
- package/model-provider/huggingface/HuggingFaceError.js +7 -28
- package/model-provider/huggingface/HuggingFaceImageDescriptionModel.cjs +3 -6
- package/model-provider/huggingface/HuggingFaceImageDescriptionModel.d.ts +1 -1
- package/model-provider/huggingface/HuggingFaceImageDescriptionModel.js +1 -1
- package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.cjs +2 -5
- package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.d.ts +1 -1
- package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.js +1 -1
- package/model-provider/huggingface/HuggingFaceTextGenerationModel.cjs +3 -6
- package/model-provider/huggingface/HuggingFaceTextGenerationModel.d.ts +1 -1
- package/model-provider/huggingface/HuggingFaceTextGenerationModel.js +1 -1
- package/model-provider/llamacpp/LlamaCppError.cjs +7 -30
- package/model-provider/llamacpp/LlamaCppError.js +7 -27
- package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.cjs +3 -6
- package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.d.ts +1 -1
- package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.js +1 -1
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +53 -66
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.d.ts +1 -1
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +3 -13
- package/model-provider/llamacpp/LlamaCppTokenizer.cjs +3 -6
- package/model-provider/llamacpp/LlamaCppTokenizer.d.ts +1 -1
- package/model-provider/llamacpp/LlamaCppTokenizer.js +1 -1
- package/model-provider/openai/OpenAIError.cjs +2 -5
- package/model-provider/openai/OpenAIError.js +2 -2
- package/model-provider/openai/OpenAITextEmbeddingModel.cjs +11 -14
- package/model-provider/openai/OpenAITextEmbeddingModel.d.ts +1 -1
- package/model-provider/openai/OpenAITextEmbeddingModel.js +1 -1
- package/model-provider/openai/OpenAITextGenerationModel.cjs +26 -39
- package/model-provider/openai/OpenAITextGenerationModel.d.ts +1 -1
- package/model-provider/openai/OpenAITextGenerationModel.js +3 -13
- package/model-provider/openai/OpenAITranscriptionModel.cjs +20 -23
- package/model-provider/openai/OpenAITranscriptionModel.d.ts +1 -1
- package/model-provider/openai/OpenAITranscriptionModel.js +1 -1
- package/model-provider/openai/chat/OpenAIChatModel.cjs +21 -21
- package/model-provider/openai/chat/OpenAIChatModel.d.ts +1 -1
- package/model-provider/openai/chat/OpenAIChatModel.js +2 -2
- package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +2 -6
- package/model-provider/openai/chat/OpenAIChatStreamIterable.js +2 -3
- package/model-provider/stability/StabilityError.cjs +2 -5
- package/model-provider/stability/StabilityError.js +2 -2
- package/package.json +4 -4
- package/util/JSONParseError.cjs +33 -0
- package/util/JSONParseError.d.ts +9 -0
- package/util/JSONParseError.js +29 -0
- package/util/index.cjs +2 -0
- package/util/index.d.ts +2 -0
- package/util/index.js +2 -0
- package/util/isDeepEqualData.cjs +53 -0
- package/util/isDeepEqualData.d.ts +8 -0
- package/util/isDeepEqualData.js +49 -0
- package/util/isDeepEqualData.test.cjs +108 -0
- package/util/isDeepEqualData.test.d.ts +1 -0
- package/util/isDeepEqualData.test.js +103 -0
- package/util/parseJSON.cjs +67 -0
- package/util/parseJSON.d.ts +18 -0
- package/util/parseJSON.js +58 -0
- package/vector-index/memory/MemoryVectorIndex.cjs +7 -10
- package/vector-index/memory/MemoryVectorIndex.js +3 -3
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.OpenAIChatResponseFormat = exports.OpenAIChatModel = exports.calculateOpenAIChatCostInMillicents = exports.isOpenAIChatModel = exports.getOpenAIChatModelInformation = exports.OPENAI_CHAT_MODELS = void 0;
|
7
7
|
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
|
-
const zod_1 =
|
8
|
+
const zod_1 = require("zod");
|
9
9
|
const callWithRetryAndThrottle_js_1 = require("../../../core/api/callWithRetryAndThrottle.cjs");
|
10
10
|
const postToApi_js_1 = require("../../../core/api/postToApi.cjs");
|
11
11
|
const AbstractModel_js_1 = require("../../../model-function/AbstractModel.cjs");
|
@@ -270,7 +270,7 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
270
270
|
catch (error) {
|
271
271
|
throw new StructureParseError_js_1.StructureParseError({
|
272
272
|
structureName: structureDefinition.name,
|
273
|
-
valueText
|
273
|
+
valueText,
|
274
274
|
cause: error,
|
275
275
|
});
|
276
276
|
}
|
@@ -370,30 +370,30 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
370
370
|
}
|
371
371
|
}
|
372
372
|
exports.OpenAIChatModel = OpenAIChatModel;
|
373
|
-
const openAIChatResponseSchema = zod_1.
|
374
|
-
id: zod_1.
|
375
|
-
object: zod_1.
|
376
|
-
created: zod_1.
|
377
|
-
model: zod_1.
|
378
|
-
choices: zod_1.
|
379
|
-
message: zod_1.
|
380
|
-
role: zod_1.
|
381
|
-
content: zod_1.
|
382
|
-
function_call: zod_1.
|
373
|
+
const openAIChatResponseSchema = zod_1.z.object({
|
374
|
+
id: zod_1.z.string(),
|
375
|
+
object: zod_1.z.literal("chat.completion"),
|
376
|
+
created: zod_1.z.number(),
|
377
|
+
model: zod_1.z.string(),
|
378
|
+
choices: zod_1.z.array(zod_1.z.object({
|
379
|
+
message: zod_1.z.object({
|
380
|
+
role: zod_1.z.literal("assistant"),
|
381
|
+
content: zod_1.z.string().nullable(),
|
382
|
+
function_call: zod_1.z
|
383
383
|
.object({
|
384
|
-
name: zod_1.
|
385
|
-
arguments: zod_1.
|
384
|
+
name: zod_1.z.string(),
|
385
|
+
arguments: zod_1.z.string(),
|
386
386
|
})
|
387
387
|
.optional(),
|
388
388
|
}),
|
389
|
-
index: zod_1.
|
390
|
-
logprobs: zod_1.
|
391
|
-
finish_reason: zod_1.
|
389
|
+
index: zod_1.z.number(),
|
390
|
+
logprobs: zod_1.z.nullable(zod_1.z.any()),
|
391
|
+
finish_reason: zod_1.z.string(),
|
392
392
|
})),
|
393
|
-
usage: zod_1.
|
394
|
-
prompt_tokens: zod_1.
|
395
|
-
completion_tokens: zod_1.
|
396
|
-
total_tokens: zod_1.
|
393
|
+
usage: zod_1.z.object({
|
394
|
+
prompt_tokens: zod_1.z.number(),
|
395
|
+
completion_tokens: zod_1.z.number(),
|
396
|
+
total_tokens: zod_1.z.number(),
|
397
397
|
}),
|
398
398
|
});
|
399
399
|
async function callOpenAIChatCompletionAPI({ api = new OpenAIApiConfiguration_js_1.OpenAIApiConfiguration(), abortSignal, responseFormat, model, messages, functions, functionCall, temperature, topP, n, stop, maxTokens, presencePenalty, frequencyPenalty, logitBias, user, }) {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import SecureJSON from "secure-json-parse";
|
2
|
-
import z from "zod";
|
2
|
+
import { z } from "zod";
|
3
3
|
import { callWithRetryAndThrottle } from "../../../core/api/callWithRetryAndThrottle.js";
|
4
4
|
import { createJsonResponseHandler, postJsonToApi, } from "../../../core/api/postToApi.js";
|
5
5
|
import { AbstractModel } from "../../../model-function/AbstractModel.js";
|
@@ -261,7 +261,7 @@ export class OpenAIChatModel extends AbstractModel {
|
|
261
261
|
catch (error) {
|
262
262
|
throw new StructureParseError({
|
263
263
|
structureName: structureDefinition.name,
|
264
|
-
valueText
|
264
|
+
valueText,
|
265
265
|
cause: error,
|
266
266
|
});
|
267
267
|
}
|
@@ -1,13 +1,10 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
3
|
exports.createOpenAIChatDeltaIterableQueue = void 0;
|
7
|
-
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
4
|
const zod_1 = require("zod");
|
9
5
|
const AsyncQueue_js_1 = require("../../../event-source/AsyncQueue.cjs");
|
10
6
|
const parseEventSourceStream_js_1 = require("../../../event-source/parseEventSourceStream.cjs");
|
7
|
+
const parseJSON_js_1 = require("../../../util/parseJSON.cjs");
|
11
8
|
const chatResponseStreamEventSchema = zod_1.z.object({
|
12
9
|
choices: zod_1.z.array(zod_1.z.object({
|
13
10
|
delta: zod_1.z.object({
|
@@ -41,8 +38,7 @@ async function createOpenAIChatDeltaIterableQueue(stream, extractDeltaValue) {
|
|
41
38
|
queue.close();
|
42
39
|
return;
|
43
40
|
}
|
44
|
-
const
|
45
|
-
const parseResult = chatResponseStreamEventSchema.safeParse(json);
|
41
|
+
const parseResult = (0, parseJSON_js_1.safeParseJsonWithZod)(data, chatResponseStreamEventSchema);
|
46
42
|
if (!parseResult.success) {
|
47
43
|
queue.push({
|
48
44
|
type: "error",
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import SecureJSON from "secure-json-parse";
|
2
1
|
import { z } from "zod";
|
3
2
|
import { AsyncQueue } from "../../../event-source/AsyncQueue.js";
|
4
3
|
import { parseEventSourceStream } from "../../../event-source/parseEventSourceStream.js";
|
4
|
+
import { safeParseJsonWithZod } from "../../../util/parseJSON.js";
|
5
5
|
const chatResponseStreamEventSchema = z.object({
|
6
6
|
choices: z.array(z.object({
|
7
7
|
delta: z.object({
|
@@ -35,8 +35,7 @@ export async function createOpenAIChatDeltaIterableQueue(stream, extractDeltaVal
|
|
35
35
|
queue.close();
|
36
36
|
return;
|
37
37
|
}
|
38
|
-
const
|
39
|
-
const parseResult = chatResponseStreamEventSchema.safeParse(json);
|
38
|
+
const parseResult = safeParseJsonWithZod(data, chatResponseStreamEventSchema);
|
40
39
|
if (!parseResult.success) {
|
41
40
|
queue.push({
|
42
41
|
type: "error",
|
@@ -1,12 +1,9 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
3
|
exports.failedStabilityCallResponseHandler = exports.StabilityError = exports.stabilityErrorDataSchema = void 0;
|
7
|
-
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
4
|
const zod_1 = require("zod");
|
9
5
|
const ApiCallError_js_1 = require("../../core/api/ApiCallError.cjs");
|
6
|
+
const parseJSON_js_1 = require("../../util/parseJSON.cjs");
|
10
7
|
exports.stabilityErrorDataSchema = zod_1.z.object({
|
11
8
|
message: zod_1.z.string(),
|
12
9
|
});
|
@@ -25,7 +22,7 @@ class StabilityError extends ApiCallError_js_1.ApiCallError {
|
|
25
22
|
exports.StabilityError = StabilityError;
|
26
23
|
const failedStabilityCallResponseHandler = async ({ response, url, requestBodyValues }) => {
|
27
24
|
const responseBody = await response.text();
|
28
|
-
const parsedError =
|
25
|
+
const parsedError = (0, parseJSON_js_1.parseJsonWithZod)(responseBody, exports.stabilityErrorDataSchema);
|
29
26
|
return new StabilityError({
|
30
27
|
url,
|
31
28
|
requestBodyValues,
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import SecureJSON from "secure-json-parse";
|
2
1
|
import { z } from "zod";
|
3
2
|
import { ApiCallError } from "../../core/api/ApiCallError.js";
|
3
|
+
import { parseJsonWithZod } from "../../util/parseJSON.js";
|
4
4
|
export const stabilityErrorDataSchema = z.object({
|
5
5
|
message: z.string(),
|
6
6
|
});
|
@@ -18,7 +18,7 @@ export class StabilityError extends ApiCallError {
|
|
18
18
|
}
|
19
19
|
export const failedStabilityCallResponseHandler = async ({ response, url, requestBodyValues }) => {
|
20
20
|
const responseBody = await response.text();
|
21
|
-
const parsedError =
|
21
|
+
const parsedError = parseJsonWithZod(responseBody, stabilityErrorDataSchema);
|
22
22
|
return new StabilityError({
|
23
23
|
url,
|
24
24
|
requestBodyValues,
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "modelfusion",
|
3
3
|
"description": "Build multimodal applications, chatbots, and agents with JavaScript and TypeScript.",
|
4
|
-
"version": "0.47.
|
4
|
+
"version": "0.47.2",
|
5
5
|
"author": "Lars Grammel",
|
6
6
|
"license": "MIT",
|
7
7
|
"keywords": [
|
@@ -47,12 +47,12 @@
|
|
47
47
|
"build": "npm run build:esm && npm run build:cjs",
|
48
48
|
"build:esm": "tsc --outDir dist/",
|
49
49
|
"build:cjs": "tsc --outDir build/cjs/ -p tsconfig.cjs.json && node bin/prepare-cjs.js",
|
50
|
-
"test": "vitest",
|
51
|
-
"
|
50
|
+
"test": "vitest run src",
|
51
|
+
"test-interactive": "vitest run",
|
52
|
+
"dist": "npm run clean && npm run lint && npm run test && npm run build && npm run dist:copy-files",
|
52
53
|
"dist:copy-files": "copyfiles package.json README.md LICENSE dist"
|
53
54
|
},
|
54
55
|
"dependencies": {
|
55
|
-
"deep-equal": "2.2.2",
|
56
56
|
"eventsource-parser": "1.1.1",
|
57
57
|
"js-tiktoken": "1.0.7",
|
58
58
|
"nanoid": "3.3.6",
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.JSONParseError = void 0;
|
4
|
+
const getErrorMessage_js_1 = require("./getErrorMessage.cjs");
|
5
|
+
class JSONParseError extends Error {
|
6
|
+
constructor({ valueText, cause }) {
|
7
|
+
super(`JSON parsing failed: ` +
|
8
|
+
`Value: ${valueText}.\n` +
|
9
|
+
`Error message: ${(0, getErrorMessage_js_1.getErrorMessage)(cause)}`);
|
10
|
+
Object.defineProperty(this, "structureName", {
|
11
|
+
enumerable: true,
|
12
|
+
configurable: true,
|
13
|
+
writable: true,
|
14
|
+
value: void 0
|
15
|
+
});
|
16
|
+
Object.defineProperty(this, "cause", {
|
17
|
+
enumerable: true,
|
18
|
+
configurable: true,
|
19
|
+
writable: true,
|
20
|
+
value: void 0
|
21
|
+
});
|
22
|
+
Object.defineProperty(this, "valueText", {
|
23
|
+
enumerable: true,
|
24
|
+
configurable: true,
|
25
|
+
writable: true,
|
26
|
+
value: void 0
|
27
|
+
});
|
28
|
+
this.name = "JSONParseError";
|
29
|
+
this.cause = cause;
|
30
|
+
this.valueText = valueText;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
exports.JSONParseError = JSONParseError;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { getErrorMessage } from "./getErrorMessage.js";
|
2
|
+
export class JSONParseError extends Error {
|
3
|
+
constructor({ valueText, cause }) {
|
4
|
+
super(`JSON parsing failed: ` +
|
5
|
+
`Value: ${valueText}.\n` +
|
6
|
+
`Error message: ${getErrorMessage(cause)}`);
|
7
|
+
Object.defineProperty(this, "structureName", {
|
8
|
+
enumerable: true,
|
9
|
+
configurable: true,
|
10
|
+
writable: true,
|
11
|
+
value: void 0
|
12
|
+
});
|
13
|
+
Object.defineProperty(this, "cause", {
|
14
|
+
enumerable: true,
|
15
|
+
configurable: true,
|
16
|
+
writable: true,
|
17
|
+
value: void 0
|
18
|
+
});
|
19
|
+
Object.defineProperty(this, "valueText", {
|
20
|
+
enumerable: true,
|
21
|
+
configurable: true,
|
22
|
+
writable: true,
|
23
|
+
value: void 0
|
24
|
+
});
|
25
|
+
this.name = "JSONParseError";
|
26
|
+
this.cause = cause;
|
27
|
+
this.valueText = valueText;
|
28
|
+
}
|
29
|
+
}
|
package/util/index.cjs
CHANGED
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
15
|
};
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./JSONParseError.cjs"), exports);
|
17
18
|
__exportStar(require("./cosineSimilarity.cjs"), exports);
|
18
19
|
__exportStar(require("./getAudioFileExtension.cjs"), exports);
|
20
|
+
__exportStar(require("./parseJSON.cjs"), exports);
|
package/util/index.d.ts
CHANGED
package/util/index.js
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.isDeepEqualData = void 0;
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
5
|
+
/**
|
6
|
+
* Performs a deep-equal comparison of two parsed JSON structures.
|
7
|
+
*
|
8
|
+
* @param {any} obj1 - The first object to compare.
|
9
|
+
* @param {any} obj2 - The second object to compare.
|
10
|
+
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
|
11
|
+
*/
|
12
|
+
function isDeepEqualData(obj1, obj2) {
|
13
|
+
// Check for strict equality first
|
14
|
+
if (obj1 === obj2)
|
15
|
+
return true;
|
16
|
+
// Check if either is null or undefined
|
17
|
+
if (obj1 == null || obj2 == null)
|
18
|
+
return false;
|
19
|
+
// Check if both are objects
|
20
|
+
if (typeof obj1 !== "object" && typeof obj2 !== "object")
|
21
|
+
return obj1 === obj2;
|
22
|
+
// If they are not strictly equal, they both need to be Objects
|
23
|
+
if (obj1.constructor !== obj2.constructor)
|
24
|
+
return false;
|
25
|
+
// Special handling for Date objects
|
26
|
+
if (obj1 instanceof Date && obj2 instanceof Date) {
|
27
|
+
return obj1.getTime() === obj2.getTime();
|
28
|
+
}
|
29
|
+
// Handle arrays: compare length and then perform a recursive deep comparison on each item
|
30
|
+
if (Array.isArray(obj1)) {
|
31
|
+
if (obj1.length !== obj2.length)
|
32
|
+
return false;
|
33
|
+
for (let i = 0; i < obj1.length; i++) {
|
34
|
+
if (!isDeepEqualData(obj1[i], obj2[i]))
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
return true; // All array elements matched
|
38
|
+
}
|
39
|
+
// Compare the set of keys in each object
|
40
|
+
const keys1 = Object.keys(obj1);
|
41
|
+
const keys2 = Object.keys(obj2);
|
42
|
+
if (keys1.length !== keys2.length)
|
43
|
+
return false;
|
44
|
+
// Check each key-value pair recursively
|
45
|
+
for (const key of keys1) {
|
46
|
+
if (!keys2.includes(key))
|
47
|
+
return false;
|
48
|
+
if (!isDeepEqualData(obj1[key], obj2[key]))
|
49
|
+
return false;
|
50
|
+
}
|
51
|
+
return true; // All keys and values matched
|
52
|
+
}
|
53
|
+
exports.isDeepEqualData = isDeepEqualData;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/**
|
2
|
+
* Performs a deep-equal comparison of two parsed JSON structures.
|
3
|
+
*
|
4
|
+
* @param {any} obj1 - The first object to compare.
|
5
|
+
* @param {any} obj2 - The second object to compare.
|
6
|
+
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
|
7
|
+
*/
|
8
|
+
export declare function isDeepEqualData(obj1: any, obj2: any): boolean;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
+
/**
|
3
|
+
* Performs a deep-equal comparison of two parsed JSON structures.
|
4
|
+
*
|
5
|
+
* @param {any} obj1 - The first object to compare.
|
6
|
+
* @param {any} obj2 - The second object to compare.
|
7
|
+
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
|
8
|
+
*/
|
9
|
+
export function isDeepEqualData(obj1, obj2) {
|
10
|
+
// Check for strict equality first
|
11
|
+
if (obj1 === obj2)
|
12
|
+
return true;
|
13
|
+
// Check if either is null or undefined
|
14
|
+
if (obj1 == null || obj2 == null)
|
15
|
+
return false;
|
16
|
+
// Check if both are objects
|
17
|
+
if (typeof obj1 !== "object" && typeof obj2 !== "object")
|
18
|
+
return obj1 === obj2;
|
19
|
+
// If they are not strictly equal, they both need to be Objects
|
20
|
+
if (obj1.constructor !== obj2.constructor)
|
21
|
+
return false;
|
22
|
+
// Special handling for Date objects
|
23
|
+
if (obj1 instanceof Date && obj2 instanceof Date) {
|
24
|
+
return obj1.getTime() === obj2.getTime();
|
25
|
+
}
|
26
|
+
// Handle arrays: compare length and then perform a recursive deep comparison on each item
|
27
|
+
if (Array.isArray(obj1)) {
|
28
|
+
if (obj1.length !== obj2.length)
|
29
|
+
return false;
|
30
|
+
for (let i = 0; i < obj1.length; i++) {
|
31
|
+
if (!isDeepEqualData(obj1[i], obj2[i]))
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
return true; // All array elements matched
|
35
|
+
}
|
36
|
+
// Compare the set of keys in each object
|
37
|
+
const keys1 = Object.keys(obj1);
|
38
|
+
const keys2 = Object.keys(obj2);
|
39
|
+
if (keys1.length !== keys2.length)
|
40
|
+
return false;
|
41
|
+
// Check each key-value pair recursively
|
42
|
+
for (const key of keys1) {
|
43
|
+
if (!keys2.includes(key))
|
44
|
+
return false;
|
45
|
+
if (!isDeepEqualData(obj1[key], obj2[key]))
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
return true; // All keys and values matched
|
49
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
7
|
+
const vitest_1 = require("vitest");
|
8
|
+
const isDeepEqualData_js_1 = require("./isDeepEqualData.cjs");
|
9
|
+
(0, vitest_1.test)("checks if two primitives are equal", async () => {
|
10
|
+
let x = 1;
|
11
|
+
let y = 1;
|
12
|
+
let result = (0, isDeepEqualData_js_1.isDeepEqualData)(x, y);
|
13
|
+
node_assert_1.default.equal(result, true);
|
14
|
+
x = 1;
|
15
|
+
y = 2;
|
16
|
+
result = (0, isDeepEqualData_js_1.isDeepEqualData)(x, y);
|
17
|
+
node_assert_1.default.equal(result, false);
|
18
|
+
});
|
19
|
+
(0, vitest_1.test)("returns false for different types", async () => {
|
20
|
+
const obj = { a: 1 };
|
21
|
+
const num = 1;
|
22
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj, num);
|
23
|
+
node_assert_1.default.equal(result, false);
|
24
|
+
});
|
25
|
+
(0, vitest_1.test)("returns false for null values compared with objects", async () => {
|
26
|
+
const obj = { a: 1 };
|
27
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj, null);
|
28
|
+
node_assert_1.default.equal(result, false);
|
29
|
+
});
|
30
|
+
(0, vitest_1.test)("identifies two equal objects", async () => {
|
31
|
+
const obj1 = { a: 1, b: 2 };
|
32
|
+
const obj2 = { a: 1, b: 2 };
|
33
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
34
|
+
node_assert_1.default.equal(result, true);
|
35
|
+
});
|
36
|
+
(0, vitest_1.test)("identifies two objects with different values", async () => {
|
37
|
+
const obj1 = { a: 1, b: 2 };
|
38
|
+
const obj2 = { a: 1, b: 3 };
|
39
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
40
|
+
node_assert_1.default.equal(result, false);
|
41
|
+
});
|
42
|
+
(0, vitest_1.test)("identifies two objects with different number of keys", async () => {
|
43
|
+
const obj1 = { a: 1, b: 2 };
|
44
|
+
const obj2 = { a: 1, b: 2, c: 3 };
|
45
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
46
|
+
node_assert_1.default.equal(result, false);
|
47
|
+
});
|
48
|
+
(0, vitest_1.test)("handles nested objects", async () => {
|
49
|
+
const obj1 = { a: { c: 1 }, b: 2 };
|
50
|
+
const obj2 = { a: { c: 1 }, b: 2 };
|
51
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
52
|
+
node_assert_1.default.equal(result, true);
|
53
|
+
});
|
54
|
+
(0, vitest_1.test)("detects inequality in nested objects", async () => {
|
55
|
+
const obj1 = { a: { c: 1 }, b: 2 };
|
56
|
+
const obj2 = { a: { c: 2 }, b: 2 };
|
57
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
58
|
+
node_assert_1.default.equal(result, false);
|
59
|
+
});
|
60
|
+
(0, vitest_1.test)("compares arrays correctly", async () => {
|
61
|
+
const arr1 = [1, 2, 3];
|
62
|
+
const arr2 = [1, 2, 3];
|
63
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(arr1, arr2);
|
64
|
+
node_assert_1.default.equal(result, true);
|
65
|
+
const arr3 = [1, 2, 3];
|
66
|
+
const arr4 = [1, 2, 4];
|
67
|
+
const result2 = (0, isDeepEqualData_js_1.isDeepEqualData)(arr3, arr4);
|
68
|
+
node_assert_1.default.equal(result2, false);
|
69
|
+
});
|
70
|
+
(0, vitest_1.test)("returns false for null comparison with object", () => {
|
71
|
+
const obj = { a: 1 };
|
72
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj, null);
|
73
|
+
node_assert_1.default.equal(result, false);
|
74
|
+
});
|
75
|
+
(0, vitest_1.test)("distinguishes between array and object with same enumerable properties", () => {
|
76
|
+
const obj = { 0: "one", 1: "two", length: 2 };
|
77
|
+
const arr = ["one", "two"];
|
78
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj, arr);
|
79
|
+
node_assert_1.default.equal(result, false);
|
80
|
+
});
|
81
|
+
(0, vitest_1.test)("returns false when comparing objects with different prototypes", () => {
|
82
|
+
const obj1 = Object.create({ a: 1 });
|
83
|
+
const obj2 = Object.create(null);
|
84
|
+
obj1.b = 2;
|
85
|
+
obj2.b = 2;
|
86
|
+
const result = (0, isDeepEqualData_js_1.isDeepEqualData)(obj1, obj2);
|
87
|
+
node_assert_1.default.equal(result, false);
|
88
|
+
});
|
89
|
+
(0, vitest_1.test)("handles date object comparisons correctly", () => {
|
90
|
+
const date1 = new Date(2000, 0, 1);
|
91
|
+
const date2 = new Date(2000, 0, 1);
|
92
|
+
const date3 = new Date(2000, 0, 2);
|
93
|
+
node_assert_1.default.equal((0, isDeepEqualData_js_1.isDeepEqualData)(date1, date2), true);
|
94
|
+
node_assert_1.default.equal((0, isDeepEqualData_js_1.isDeepEqualData)(date1, date3), false);
|
95
|
+
});
|
96
|
+
(0, vitest_1.test)("handles function comparisons", () => {
|
97
|
+
const func1 = () => {
|
98
|
+
console.log("hello");
|
99
|
+
};
|
100
|
+
const func2 = () => {
|
101
|
+
console.log("hello");
|
102
|
+
};
|
103
|
+
const func3 = () => {
|
104
|
+
console.log("world");
|
105
|
+
};
|
106
|
+
node_assert_1.default.equal((0, isDeepEqualData_js_1.isDeepEqualData)(func1, func2), false);
|
107
|
+
node_assert_1.default.equal((0, isDeepEqualData_js_1.isDeepEqualData)(func1, func3), false);
|
108
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import assert from "node:assert";
|
2
|
+
import { test } from "vitest";
|
3
|
+
import { isDeepEqualData } from "./isDeepEqualData.js";
|
4
|
+
test("checks if two primitives are equal", async () => {
|
5
|
+
let x = 1;
|
6
|
+
let y = 1;
|
7
|
+
let result = isDeepEqualData(x, y);
|
8
|
+
assert.equal(result, true);
|
9
|
+
x = 1;
|
10
|
+
y = 2;
|
11
|
+
result = isDeepEqualData(x, y);
|
12
|
+
assert.equal(result, false);
|
13
|
+
});
|
14
|
+
test("returns false for different types", async () => {
|
15
|
+
const obj = { a: 1 };
|
16
|
+
const num = 1;
|
17
|
+
const result = isDeepEqualData(obj, num);
|
18
|
+
assert.equal(result, false);
|
19
|
+
});
|
20
|
+
test("returns false for null values compared with objects", async () => {
|
21
|
+
const obj = { a: 1 };
|
22
|
+
const result = isDeepEqualData(obj, null);
|
23
|
+
assert.equal(result, false);
|
24
|
+
});
|
25
|
+
test("identifies two equal objects", async () => {
|
26
|
+
const obj1 = { a: 1, b: 2 };
|
27
|
+
const obj2 = { a: 1, b: 2 };
|
28
|
+
const result = isDeepEqualData(obj1, obj2);
|
29
|
+
assert.equal(result, true);
|
30
|
+
});
|
31
|
+
test("identifies two objects with different values", async () => {
|
32
|
+
const obj1 = { a: 1, b: 2 };
|
33
|
+
const obj2 = { a: 1, b: 3 };
|
34
|
+
const result = isDeepEqualData(obj1, obj2);
|
35
|
+
assert.equal(result, false);
|
36
|
+
});
|
37
|
+
test("identifies two objects with different number of keys", async () => {
|
38
|
+
const obj1 = { a: 1, b: 2 };
|
39
|
+
const obj2 = { a: 1, b: 2, c: 3 };
|
40
|
+
const result = isDeepEqualData(obj1, obj2);
|
41
|
+
assert.equal(result, false);
|
42
|
+
});
|
43
|
+
test("handles nested objects", async () => {
|
44
|
+
const obj1 = { a: { c: 1 }, b: 2 };
|
45
|
+
const obj2 = { a: { c: 1 }, b: 2 };
|
46
|
+
const result = isDeepEqualData(obj1, obj2);
|
47
|
+
assert.equal(result, true);
|
48
|
+
});
|
49
|
+
test("detects inequality in nested objects", async () => {
|
50
|
+
const obj1 = { a: { c: 1 }, b: 2 };
|
51
|
+
const obj2 = { a: { c: 2 }, b: 2 };
|
52
|
+
const result = isDeepEqualData(obj1, obj2);
|
53
|
+
assert.equal(result, false);
|
54
|
+
});
|
55
|
+
test("compares arrays correctly", async () => {
|
56
|
+
const arr1 = [1, 2, 3];
|
57
|
+
const arr2 = [1, 2, 3];
|
58
|
+
const result = isDeepEqualData(arr1, arr2);
|
59
|
+
assert.equal(result, true);
|
60
|
+
const arr3 = [1, 2, 3];
|
61
|
+
const arr4 = [1, 2, 4];
|
62
|
+
const result2 = isDeepEqualData(arr3, arr4);
|
63
|
+
assert.equal(result2, false);
|
64
|
+
});
|
65
|
+
test("returns false for null comparison with object", () => {
|
66
|
+
const obj = { a: 1 };
|
67
|
+
const result = isDeepEqualData(obj, null);
|
68
|
+
assert.equal(result, false);
|
69
|
+
});
|
70
|
+
test("distinguishes between array and object with same enumerable properties", () => {
|
71
|
+
const obj = { 0: "one", 1: "two", length: 2 };
|
72
|
+
const arr = ["one", "two"];
|
73
|
+
const result = isDeepEqualData(obj, arr);
|
74
|
+
assert.equal(result, false);
|
75
|
+
});
|
76
|
+
test("returns false when comparing objects with different prototypes", () => {
|
77
|
+
const obj1 = Object.create({ a: 1 });
|
78
|
+
const obj2 = Object.create(null);
|
79
|
+
obj1.b = 2;
|
80
|
+
obj2.b = 2;
|
81
|
+
const result = isDeepEqualData(obj1, obj2);
|
82
|
+
assert.equal(result, false);
|
83
|
+
});
|
84
|
+
test("handles date object comparisons correctly", () => {
|
85
|
+
const date1 = new Date(2000, 0, 1);
|
86
|
+
const date2 = new Date(2000, 0, 1);
|
87
|
+
const date3 = new Date(2000, 0, 2);
|
88
|
+
assert.equal(isDeepEqualData(date1, date2), true);
|
89
|
+
assert.equal(isDeepEqualData(date1, date3), false);
|
90
|
+
});
|
91
|
+
test("handles function comparisons", () => {
|
92
|
+
const func1 = () => {
|
93
|
+
console.log("hello");
|
94
|
+
};
|
95
|
+
const func2 = () => {
|
96
|
+
console.log("hello");
|
97
|
+
};
|
98
|
+
const func3 = () => {
|
99
|
+
console.log("world");
|
100
|
+
};
|
101
|
+
assert.equal(isDeepEqualData(func1, func2), false);
|
102
|
+
assert.equal(isDeepEqualData(func1, func3), false);
|
103
|
+
});
|