diff --git a/demo/genaisrc/genaiscript.d.ts b/demo/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/demo/genaisrc/genaiscript.d.ts +++ b/demo/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/docs/genaisrc/genaiscript.d.ts b/docs/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/docs/genaisrc/genaiscript.d.ts +++ b/docs/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/docs/src/content/docs/reference/scripts/files.md b/docs/src/content/docs/reference/scripts/files.md index d6cc030d1f..c654e9add4 100644 --- a/docs/src/content/docs/reference/scripts/files.md +++ b/docs/src/content/docs/reference/scripts/files.md @@ -71,6 +71,14 @@ const content = file.content It will automatically convert PDFs and DOCX files to text. +### `readJSON` + +Reads the content of a file as JSON (using a [JSON5](https://json5.org/) parser) + +```ts +const data = await workspace.readJSON("data.json") +``` + ### `writeText` Writes text to a file, relative to the workspace root. diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/genaisrc/genaiscript.d.ts +++ b/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/core/src/fs.ts b/packages/core/src/fs.ts index 5eb87a5cd7..5fc42d139a 100644 --- a/packages/core/src/fs.ts +++ b/packages/core/src/fs.ts @@ -2,6 +2,7 @@ import { DOT_ENV_REGEX, HTTPS_REGEX } from "./constants" import { NotSupportedError, errorMessage } from "./error" import { resolveFileContent } from "./file" import { host } from "./host" +import { JSON5parse } from "./json5" import { logVerbose, unique, utf8Decode, utf8Encode } from "./util" import ignorer from "ignore" @@ -105,6 +106,11 @@ export function createFileSystem(): Omit { } return file }, + readJSON: async (f: string | WorkspaceFile) => { + const file = await fs.readText(f) + const res = JSON5parse(file.content) + return res + }, } ;(fs as any).readFile = readText return Object.freeze(fs) diff --git a/packages/core/src/genaisrc/genaiscript.d.ts b/packages/core/src/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/core/src/genaisrc/genaiscript.d.ts +++ b/packages/core/src/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/core/src/promptcontext.ts b/packages/core/src/promptcontext.ts index e4d7be153e..1d93ce3151 100644 --- a/packages/core/src/promptcontext.ts +++ b/packages/core/src/promptcontext.ts @@ -89,6 +89,7 @@ export function createPromptContext( const path = runtimeHost.path const workspace: WorkspaceFileSystem = { readText: (f) => runtimeHost.workspace.readText(f), + readJSON: (f) => runtimeHost.workspace.readJSON(f), writeText: (f, c) => runtimeHost.workspace.writeText(f, c), findFiles: async (pattern, options) => { const res = await runtimeHost.workspace.findFiles(pattern, options) diff --git a/packages/core/src/types/prompt_template.d.ts b/packages/core/src/types/prompt_template.d.ts index 96837d66fd..88ea3a9bc8 100644 --- a/packages/core/src/types/prompt_template.d.ts +++ b/packages/core/src/types/prompt_template.d.ts @@ -492,6 +492,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/genaisrc/genaiscript.d.ts b/packages/sample/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/genaisrc/genaiscript.d.ts +++ b/packages/sample/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/genaisrc/git-release-notes.genai.js b/packages/sample/genaisrc/git-release-notes.genai.js index 4e4f6843b6..b6c1b74bcd 100644 --- a/packages/sample/genaisrc/git-release-notes.genai.js +++ b/packages/sample/genaisrc/git-release-notes.genai.js @@ -3,7 +3,7 @@ script({ system: ["system"], temperature: 0.5, model: "openai:gpt-4-turbo" }) const product = env.vars.product || "GenAIScript" // find previous tag -const pkg = JSON.parse((await workspace.readText("package.json")).content) +const pkg = await workspace.readJSON("package.json") const { version } = pkg const { stdout: tag } = await host.exec("git", [ "describe", diff --git a/packages/sample/genaisrc/node/genaiscript.d.ts b/packages/sample/genaisrc/node/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/genaisrc/node/genaiscript.d.ts +++ b/packages/sample/genaisrc/node/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/genaisrc/python/genaiscript.d.ts b/packages/sample/genaisrc/python/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/genaisrc/python/genaiscript.d.ts +++ b/packages/sample/genaisrc/python/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/genaisrc/style/genaiscript.d.ts b/packages/sample/genaisrc/style/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/genaisrc/style/genaiscript.d.ts +++ b/packages/sample/genaisrc/style/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/genaisrc/writefile.genai.js b/packages/sample/genaisrc/writefile.genai.js index cdd62946eb..5dae6bf974 100644 --- a/packages/sample/genaisrc/writefile.genai.js +++ b/packages/sample/genaisrc/writefile.genai.js @@ -3,9 +3,12 @@ script({ model: "openai:gpt-3.5-turbo", }) const fn = `temp/${Math.random() + ""}.txt` -const content = Math.random() + "" +const content = JSON.stringify({ val: Math.random() + "" }) await workspace.writeText(fn, content) const res = await workspace.readText(fn) if (content !== res.content) throw new Error("file write error") +const jres = await workspace.readJSON(fn) +if (JSON.stringify(jres) !== content) throw new Error("readJSON error") + $`All good!` diff --git a/packages/sample/src/aici/genaiscript.d.ts b/packages/sample/src/aici/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/src/aici/genaiscript.d.ts +++ b/packages/sample/src/aici/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/src/errors/genaiscript.d.ts b/packages/sample/src/errors/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/src/errors/genaiscript.d.ts +++ b/packages/sample/src/errors/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/src/makecode/genaiscript.d.ts b/packages/sample/src/makecode/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/src/makecode/genaiscript.d.ts +++ b/packages/sample/src/makecode/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/src/makecode/makecode-loc.genai.js b/packages/sample/src/makecode/makecode-loc.genai.js index d41f038735..35914f6722 100644 --- a/packages/sample/src/makecode/makecode-loc.genai.js +++ b/packages/sample/src/makecode/makecode-loc.genai.js @@ -31,7 +31,7 @@ const strings = JSON.parse(content) // find the existing translation and remove existing translations const trfn = path.join(dir, langCode, path.basename(filename)) -const translated = parsers.JSON5(await workspace.readText(trfn)) +const translated = await workspace.readJSON(trfn) if (translated) for (const k of Object.keys(strings)) if (translated[k]) delete strings[k] @@ -113,8 +113,8 @@ defFileMerge((filename, label, before, generated) => { // parse out kv const news = generated .split(/\n/g) - .map(line => /^([^=]+)=(.+)$/.exec(line)) - .filter(m => !!m) + .map((line) => /^([^=]+)=(.+)$/.exec(line)) + .filter((m) => !!m) .reduce((o, m) => { const [, key, value] = m // assign diff --git a/packages/sample/src/tla/genaiscript.d.ts b/packages/sample/src/tla/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/src/tla/genaiscript.d.ts +++ b/packages/sample/src/tla/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/packages/sample/src/vision/genaiscript.d.ts b/packages/sample/src/vision/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/packages/sample/src/vision/genaiscript.d.ts +++ b/packages/sample/src/vision/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path diff --git a/slides/genaisrc/genaiscript.d.ts b/slides/genaisrc/genaiscript.d.ts index fcfe5b7479..6671ae0ad0 100644 --- a/slides/genaisrc/genaiscript.d.ts +++ b/slides/genaisrc/genaiscript.d.ts @@ -526,6 +526,12 @@ interface WorkspaceFileSystem { */ readText(path: string | WorkspaceFile): Promise + /** + * Reads the content of a file and parses to JSON, using the JSON5 parser. + * @param path + */ + readJSON(path: string | WorkspaceFile): Promise + /** * Writes a file as text to the file system * @param path