30a2164980
Quick proof of concept for twenty-apps + twenty-cli, with local development / hot reload Let's discuss it! https://github.com/user-attachments/assets/c6789936-cd5f-4110-a265-863a6ac1af2d
69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import * as fs from 'fs-extra';
|
|
import { ParseError, parse as parseJsonc } from 'jsonc-parser';
|
|
|
|
export interface JsoncParseOptions {
|
|
allowTrailingComma?: boolean;
|
|
disallowComments?: boolean;
|
|
allowEmptyContent?: boolean;
|
|
}
|
|
|
|
export class JsoncParseError extends Error {
|
|
constructor(
|
|
message: string,
|
|
public readonly parseErrors: ParseError[],
|
|
public readonly filePath?: string,
|
|
) {
|
|
super(message);
|
|
this.name = 'JsoncParseError';
|
|
}
|
|
}
|
|
|
|
export const parseJsoncString = (
|
|
content: string,
|
|
options: JsoncParseOptions = {},
|
|
): any => {
|
|
const parseErrors: ParseError[] = [];
|
|
|
|
const result = parseJsonc(content, parseErrors, {
|
|
allowTrailingComma: options.allowTrailingComma ?? true,
|
|
disallowComments: options.disallowComments ?? false,
|
|
allowEmptyContent: options.allowEmptyContent ?? false,
|
|
});
|
|
|
|
if (parseErrors.length > 0) {
|
|
const errorMessages = parseErrors.map(
|
|
(error) => `Line ${error.offset}: ${error.error}`,
|
|
);
|
|
throw new JsoncParseError(
|
|
`JSONC parse errors:\n${errorMessages.join('\n')}`,
|
|
parseErrors,
|
|
);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
export const parseJsoncFile = async (
|
|
filePath: string,
|
|
options: JsoncParseOptions = {},
|
|
): Promise<any> => {
|
|
try {
|
|
const content = await fs.readFile(filePath, 'utf8');
|
|
return parseJsoncString(content, options);
|
|
} catch (error) {
|
|
if (error instanceof JsoncParseError) {
|
|
throw new JsoncParseError(error.message, error.parseErrors, filePath);
|
|
}
|
|
throw new Error(`Failed to read file ${filePath}: ${error}`);
|
|
}
|
|
};
|
|
|
|
export const writeJsoncFile = async (
|
|
filePath: string,
|
|
data: any,
|
|
options: { spaces?: number } = {},
|
|
): Promise<void> => {
|
|
const content = JSON.stringify(data, null, options.spaces ?? 2);
|
|
await fs.writeFile(filePath, content, 'utf8');
|
|
};
|