139 lines
6 KiB
JavaScript
139 lines
6 KiB
JavaScript
import jsonpointer from "jsonpointer";
|
|
import { TextLoader } from "./text.js";
|
|
/**
|
|
* Class that extends the `TextLoader` class. It represents a document
|
|
* loader that loads documents from JSON files. It has a constructor that
|
|
* takes a `filePathOrBlob` parameter representing the path to the JSON
|
|
* file or a `Blob` object, and an optional `pointers` parameter that
|
|
* specifies the JSON pointers to extract.
|
|
*/
|
|
export class JSONLoader extends TextLoader {
|
|
constructor(filePathOrBlob, pointers = []) {
|
|
super(filePathOrBlob);
|
|
Object.defineProperty(this, "pointers", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
this.pointers = Array.isArray(pointers) ? pointers : [pointers];
|
|
}
|
|
/**
|
|
* Method that takes a `raw` string as a parameter and returns a promise
|
|
* that resolves to an array of strings. It parses the raw JSON string and
|
|
* extracts the values based on the specified JSON pointers. If no JSON
|
|
* pointers are specified, it extracts all the strings from the JSON
|
|
* object.
|
|
* @param raw The raw JSON string to parse.
|
|
* @returns A promise that resolves to an array of strings.
|
|
*/
|
|
async parse(raw) {
|
|
const json = JSON.parse(raw.trim());
|
|
// If there is no pointers specified we extract all strings we found
|
|
const extractAllStrings = !(this.pointers.length > 0);
|
|
const compiledPointers = this.pointers.map((pointer) => jsonpointer.compile(pointer));
|
|
return this.extractArrayStringsFromObject(json, compiledPointers, extractAllStrings);
|
|
}
|
|
/**
|
|
* If JSON pointers are specified, return all strings below any of them
|
|
* and exclude all other nodes expect if they match a JSON pointer (to allow to extract strings from different levels)
|
|
*
|
|
* If no JSON pointer is specified then return all string in the object
|
|
*/
|
|
extractArrayStringsFromObject(
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
json, pointers, extractAllStrings = false, keyHasBeenFound = false) {
|
|
if (!json) {
|
|
return [];
|
|
}
|
|
if (typeof json === "string" && extractAllStrings) {
|
|
return [json];
|
|
}
|
|
if (Array.isArray(json) && extractAllStrings) {
|
|
let extractedString = [];
|
|
for (const element of json) {
|
|
extractedString = extractedString.concat(this.extractArrayStringsFromObject(element, pointers, true));
|
|
}
|
|
return extractedString;
|
|
}
|
|
if (typeof json === "object") {
|
|
if (extractAllStrings) {
|
|
return this.extractArrayStringsFromObject(Object.values(json), pointers, true);
|
|
}
|
|
const targetedEntries = this.getTargetedEntries(json, pointers);
|
|
const thisLevelEntries = Object.values(json);
|
|
const notTargetedEntries = thisLevelEntries.filter((entry) => !targetedEntries.includes(entry));
|
|
let extractedStrings = [];
|
|
// If we found a targeted entry, we extract all strings from it
|
|
if (targetedEntries.length > 0) {
|
|
for (const oneEntry of targetedEntries) {
|
|
extractedStrings = extractedStrings.concat(this.extractArrayStringsFromObject(oneEntry, pointers, true, true));
|
|
}
|
|
for (const oneEntry of notTargetedEntries) {
|
|
extractedStrings = extractedStrings.concat(this.extractArrayStringsFromObject(oneEntry, pointers, false, true));
|
|
}
|
|
}
|
|
else if (extractAllStrings || !keyHasBeenFound) {
|
|
for (const oneEntry of notTargetedEntries) {
|
|
extractedStrings = extractedStrings.concat(this.extractArrayStringsFromObject(oneEntry, pointers, extractAllStrings));
|
|
}
|
|
}
|
|
return extractedStrings;
|
|
}
|
|
return [];
|
|
}
|
|
/**
|
|
* Method that takes a `json` object and an array of `pointers` as
|
|
* parameters and returns an array of targeted entries. It iterates over
|
|
* the JSON pointers and uses the `jsonpointer.get()` function to get the
|
|
* targeted entries from the JSON object.
|
|
* @param json The JSON object to get targeted entries from.
|
|
* @param pointers The JSON pointers to get targeted entries.
|
|
* @returns An array of targeted entries.
|
|
*/
|
|
getTargetedEntries(json, pointers) {
|
|
const targetEntries = [];
|
|
for (const pointer of pointers) {
|
|
const targetedEntry = pointer.get(json);
|
|
if (targetedEntry) {
|
|
targetEntries.push(targetedEntry);
|
|
}
|
|
}
|
|
return targetEntries;
|
|
}
|
|
}
|
|
/**
|
|
* Class that extends the `TextLoader` class. It represents a document
|
|
* loader that loads documents from JSON Lines files. It has a constructor
|
|
* that takes a `filePathOrBlob` parameter representing the path to the
|
|
* JSON Lines file or a `Blob` object, and a `pointer` parameter that
|
|
* specifies the JSON pointer to extract.
|
|
*/
|
|
export class JSONLinesLoader extends TextLoader {
|
|
constructor(filePathOrBlob, pointer) {
|
|
super(filePathOrBlob);
|
|
Object.defineProperty(this, "pointer", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: pointer
|
|
});
|
|
}
|
|
/**
|
|
* Method that takes a `raw` string as a parameter and returns a promise
|
|
* that resolves to an array of strings. It parses the raw JSON Lines
|
|
* string, splits it into lines, parses each line as JSON, and extracts
|
|
* the values based on the specified JSON pointer.
|
|
* @param raw The raw JSON Lines string to parse.
|
|
* @returns A promise that resolves to an array of strings.
|
|
*/
|
|
async parse(raw) {
|
|
const lines = raw.split("\n");
|
|
const jsons = lines
|
|
.map((line) => line.trim())
|
|
.filter(Boolean)
|
|
.map((line) => JSON.parse(line));
|
|
const pointer = jsonpointer.compile(this.pointer);
|
|
return jsons.map((json) => pointer.get(json));
|
|
}
|
|
}
|