diff --git a/packages/mountable/src/options.test.ts b/packages/mountable/src/options.test.ts index d26f5049c..84dcb4da4 100644 --- a/packages/mountable/src/options.test.ts +++ b/packages/mountable/src/options.test.ts @@ -68,8 +68,15 @@ describe("parseMountOptions()", () => { }); }); - it("fills `entrypoint`, and `requirements` fields and converts the `files` into the canonical form", () => { + it("throws an error if the `entrypoint` option is not provided", () => { + expect(() => parseMountOptions({})).toThrowError( + "The `entrypoint` field is required.", + ); + }); + + it("fills the `requirements` field and converts the `files` into the canonical form", () => { const { kernelOptions } = parseMountOptions({ + entrypoint: "streamlit_app.py", files: { "streamlit_app.py": "foo", "foo.txt": { @@ -101,6 +108,7 @@ describe("parseMountOptions()", () => { it("normalizes the archives field", () => { const { kernelOptions } = parseMountOptions({ + entrypoint: "app.py", archives: [ { url: "./foo.zip", @@ -120,7 +128,7 @@ describe("parseMountOptions()", () => { ], }); expect(kernelOptions).toEqual({ - entrypoint: "streamlit_app.py", + entrypoint: "app.py", requirements: [], prebuiltPackageNames: [], files: {}, @@ -167,11 +175,12 @@ describe("parseMountOptions()", () => { it("preserves the `requirements` option if specified", () => { const { kernelOptions } = parseMountOptions({ requirements: ["matplotlib"], + entrypoint: "app.py", }); expect(kernelOptions).toEqual({ requirements: ["matplotlib"], prebuiltPackageNames: [], - entrypoint: "streamlit_app.py", + entrypoint: "app.py", files: {}, archives: [], }); @@ -180,11 +189,12 @@ describe("parseMountOptions()", () => { it("preserves the `prebuiltPackageNames` option if specified", () => { const { kernelOptions } = parseMountOptions({ prebuiltPackageNames: ["openssl"], + entrypoint: "foo.py", }); expect(kernelOptions).toEqual({ requirements: [], prebuiltPackageNames: ["openssl"], - entrypoint: "streamlit_app.py", + entrypoint: "foo.py", files: {}, archives: [], }); @@ -200,6 +210,7 @@ describe("parseMountOptions()", () => { it("passes the toast callback options", () => { const { toastCallbackOptions } = parseMountOptions({ + entrypoint: "foo.py", disableProgressToasts: true, disableErrorToasts: true, }); diff --git a/packages/mountable/src/options.ts b/packages/mountable/src/options.ts index 6e1838e51..f5970a73e 100644 --- a/packages/mountable/src/options.ts +++ b/packages/mountable/src/options.ts @@ -5,20 +5,23 @@ import type { } from "@stlite/kernel"; import type { MakeToastKernelCallbacksOptions } from "@stlite/common-react"; -export interface SimplifiedStliteKernelOptions { - entrypoint?: string; - requirements?: StliteKernelOptions["requirements"]; - prebuiltPackageNames?: StliteKernelOptions["prebuiltPackageNames"]; - files?: Record< +// Simplified version of StliteKernelOptions for the mount function. +// This is exposed to non-typed consumers of the mount function, +// so all fields are typed as optional. +export type SimplifiedStliteKernelOptions = Partial<{ + entrypoint: string; + requirements: StliteKernelOptions["requirements"]; + prebuiltPackageNames: StliteKernelOptions["prebuiltPackageNames"]; + files: Record< string, EmscriptenFile | EmscriptenFileUrl | EmscriptenFile["data"] // EmscriptenFile["data"] is allowed as a shorthand for convenience. >; - archives?: StliteKernelOptions["archives"]; - hostConfig?: StliteKernelOptions["hostConfigResponse"]; - pyodideUrl?: StliteKernelOptions["pyodideUrl"]; - streamlitConfig?: StliteKernelOptions["streamlitConfig"]; - idbfsMountpoints?: StliteKernelOptions["idbfsMountpoints"]; -} + archives: StliteKernelOptions["archives"]; + hostConfig: StliteKernelOptions["hostConfigResponse"]; + pyodideUrl: StliteKernelOptions["pyodideUrl"]; + streamlitConfig: StliteKernelOptions["streamlitConfig"]; + idbfsMountpoints: StliteKernelOptions["idbfsMountpoints"]; +}>; function canonicalizeFiles( files: SimplifiedStliteKernelOptions["files"], @@ -111,9 +114,15 @@ export function parseMountOptions(options: MountOptions): { const files = canonicalizeFiles(options.files); const archives = canonicalizeArchives(options.archives); + // TODO: Validate the options object using superstruct. + const entrypoint = options.entrypoint; + if (entrypoint == null) { + throw new Error("The `entrypoint` field is required."); + } + return { kernelOptions: { - entrypoint: options.entrypoint || DEFAULT_ENTRYPOINT, + entrypoint, files, archives, requirements: options.requirements || [],