Skip to content

Use the compiler options as a backup for finding compiler options from inside the param handling code #1940

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
48 changes: 33 additions & 15 deletions packages/sandbox/src/compilerOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type Monaco = typeof import("monaco-editor")
export function getDefaultSandboxCompilerOptions(config: SandboxConfig, monaco: Monaco) {
const useJavaScript = config.filetype === "js"
const settings: CompilerOptions = {
strict: true,

noImplicitAny: true,
strictNullChecks: !useJavaScript,
strictFunctionTypes: true,
Expand Down Expand Up @@ -60,24 +62,40 @@ export function getDefaultSandboxCompilerOptions(config: SandboxConfig, monaco:
* Loop through all of the entries in the existing compiler options then compare them with the
* query params and return an object which is the changed settings via the query params
*/
export const getCompilerOptionsFromParams = (options: CompilerOptions, params: URLSearchParams): CompilerOptions => {
const urlDefaults = Object.entries(options).reduce((acc: any, [key, value]) => {
if (params.has(key)) {
const urlValue = params.get(key)!

if (urlValue === "true") {
acc[key] = true
} else if (urlValue === "false") {
acc[key] = false
} else if (!isNaN(parseInt(urlValue, 10))) {
acc[key] = parseInt(urlValue, 10)
export const getCompilerOptionsFromParams = (
playgroundDefaults: CompilerOptions,
ts: typeof import("typescript"),
params: URLSearchParams
): CompilerOptions => {
const returnedOptions: CompilerOptions = {}

params.forEach((val, key) => {
// First use the defaults object to drop compiler flags which are already set to the default
if (playgroundDefaults[key]) {
let toSet = undefined
if (val === "true" && playgroundDefaults[key] !== true) {
toSet = true
} else if (val === "false" && playgroundDefaults[key] !== false) {
toSet = false
} else if (!isNaN(parseInt(val, 10)) && playgroundDefaults[key] !== parseInt(val, 10)) {
toSet = parseInt(val, 10)
}
}

return acc
}, {})
if (toSet !== undefined) returnedOptions[key] = toSet
} else {
// If that doesn't work, double check that the flag exists and allow it through
// @ts-ignore
const flagExists = ts.optionDeclarations.find(opt => opt.name === key)
if (flagExists) {
let realValue: number | boolean = true
if (val === "false") realValue = false
if (!isNaN(parseInt(val, 10))) realValue = parseInt(val, 10)
returnedOptions[key] = realValue
}
}
})

return urlDefaults
return returnedOptions
}

// Can't set sandbox to be the right type because the param would contain this function
Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export const createTypeScriptSandbox = (
let compilerOptions: CompilerOptions
if (!config.suppressAutomaticallyGettingCompilerFlags) {
const params = new URLSearchParams(location.search)
let queryParamCompilerOptions = getCompilerOptionsFromParams(compilerDefaults, params)
let queryParamCompilerOptions = getCompilerOptionsFromParams(compilerDefaults, ts, params)
if (Object.keys(queryParamCompilerOptions).length)
config.logger.log("[Compiler] Found compiler options in query params: ", queryParamCompilerOptions)
compilerOptions = { ...compilerDefaults, ...queryParamCompilerOptions }
Expand Down
59 changes: 59 additions & 0 deletions packages/sandbox/test/defaultCompilerOptions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { getCompilerOptionsFromParams, getDefaultSandboxCompilerOptions } from "../src/compilerOptions"
import ts from "typescript"

const fauxMonaco: any = {
languages: {
typescript: {
ModuleResolutionKind: ts.ModuleResolutionKind,
ScriptTarget: ts.ScriptTarget,
JsxEmit: ts.JsxEmit,
ModuleKind: ts.ModuleKind,
},
},
}

describe(getCompilerOptionsFromParams, () => {
it("ignores compiler flags which are the same as the defaults", () => {
// noImplicitReturns=true is the default, and shouldnt be in the object
const params = new URLSearchParams("?noImplicitThis=false&noImplicitReturns=true#code/JYOw")
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)

expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
Object {
"noImplicitThis": false,
}
`)
})

it("ignores non-compiler flags", () => {
const params = new URLSearchParams("?asdasdasdasd=false")
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)

expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`Object {}`)
})

it("handles mapped types like target et", () => {
const params = new URLSearchParams("?target=6")
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)

expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
Object {
"target": 6,
}
`)
})

it("handles settings options which haven't been given defaults in the monaco defaults", () => {
const search = "?ts=4.4.0-beta&exactOptionalPropertyTypes=true#code/JYOw"
const params = new URLSearchParams(search)
expect(params.has("exactOptionalPropertyTypes")).toBeTruthy()

const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)

expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
Object {
"exactOptionalPropertyTypes": true,
}
`)
})
})