@sanity/import
Version:
Import documents to a Sanity dataset
66 lines (65 loc) • 2.49 kB
JavaScript
import { Transform } from 'node:stream';
import { StringDecoder } from 'node:string_decoder';
import { validateDocument } from '../documentHasErrors.js';
import { ReplacementCharError, validateLineForReplacementChar } from './validateReplacementCharacters.js';
export function getJsonStreamer(options = {}) {
let lineNumber = 0;
let remainder = '';
const decoder = new StringDecoder('utf8');
const { allowReplacementCharacters } = options;
return new Transform({
objectMode: true,
transform (chunk, _encoding, callback) {
const text = remainder + decoder.write(chunk);
const lines = text.split('\n');
// Last element may be an incomplete line - save for next chunk
remainder = lines.pop() ?? '';
for (const line of lines){
parseLine(this, line);
}
callback();
},
flush (callback) {
// Flush any remaining bytes from the decoder
remainder += decoder.end();
if (remainder) {
parseLine(this, remainder);
remainder = '';
}
callback();
}
});
function parseLine(stream, row) {
lineNumber++;
if (!row) {
return;
}
try {
if (allowReplacementCharacters !== true) {
const replacementError = validateLineForReplacementChar(row, lineNumber);
if (replacementError) {
throw new ReplacementCharError(replacementError);
}
}
const doc = JSON.parse(row);
const error = validateDocument(doc);
if (error) {
throw new Error(error);
}
stream.push(doc);
} catch (err) {
if (err instanceof ReplacementCharError) {
stream.emit('error', err);
} else if (err instanceof Error) {
stream.emit('error', new Error(getErrorMessage(err)));
} else {
stream.emit('error', new Error(`Unknown error occurred at line #${lineNumber}: ${String(err)}`));
}
}
}
function getErrorMessage(err) {
const suffix = lineNumber === 1 ? '\n\nMake sure this is valid ndjson (one JSON-document *per line*)' : '';
return `Failed to parse line #${lineNumber}: ${err.message}${suffix}`;
}
}
//# sourceMappingURL=getJsonStreamer.js.map