Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/utils/logfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ILogEntry, IRawLogEntry } from '../interfaces'

import { parseException } from './exception'
import { logger } from './logger'
import { splitter } from './splitter'

/**
* Parse a given log file
Expand All @@ -30,7 +31,6 @@ export async function parseLogString(raw: string): Promise<ILogEntry[]> {
} catch (e) {
logger.debug('falling back to json splitter')

const splitter = (await import('json-string-splitter')).default
// the input might have had its data reformatted, breaking the original newline separated json
const lines = splitter(raw).jsons
entries = lines.map(tryParseJSON)
Expand Down
79 changes: 79 additions & 0 deletions src/utils/splitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud Gmbh and Nextcloud contributors
* SPDX-License-Identifier: LGPL-3.0+
*/

/**
* Copied from Densaugeo/JSON-String-Splitter
*
* Split concatenated JSON strings
* Accepts a string consisting of one or more valid JSON substrings and splits it. Any remaining string after the end of the last complete JSON substring is returned in the 'remainder' field.
* Passing in invalid JSON can result in garbage output
*
* @param {string} string The string to look for JSON in
* @returns {{ jsons: string[], remainder: '' }}
*
* @example
* var splitter = require('json-string-splitter');
*
* var pieces = splitter('{"foo":"bar"}{"more":"json"}{"partial":"json"');
*
* console.log(pieces.jsons[0]); // '{"foo":"bar"}'
* console.log(pieces.jsons[1]); // '{"more":"json"}'
* console.log(pieces.remainder); // '{"partial":"json"'
*/
export function splitter(string) {
var START = 0, JSON = 1, STRING = 2, ESCAPE = 3;

var state = START;
var nesting_level = 0;
var json_start = null;
var bounds = [];

for(var i = 0 || 0; i < string.length; ++i) {
switch(state) {
case START:
switch(string[i]) {
case '{':
++nesting_level;
state = JSON;
json_start = i;
break;
}
break;
case JSON:
switch(string[i]) {
case '{': ++nesting_level; break;
case '}':
--nesting_level;
if(nesting_level === 0) {
state = START;
bounds.push({ start: json_start, end: i + 1 });
}
break;
case '"': state = STRING; break;
}
break;
case STRING:
switch(string[i]) {
case '"': state = JSON; break;
case '\\': state = ESCAPE; break;
}
break;
case ESCAPE:
state = STRING;
break;
}
}

var result = {
jsons: [],
remainder: string.substring(bounds[bounds.length - 1].end),
}

bounds.forEach(function(v) {
result.jsons.push(string.substring(v.start, v.end));
});

return result;
}