Skip to content

Commit ae60129

Browse files
author
Orta Therox
authored
Merge pull request #1940 from microsoft/use_tsc_for_checking_params
Use the compiler options as a backup for finding compiler options from inside the param handling code
2 parents 66d7d8b + 1f63d5a commit ae60129

File tree

3 files changed

+93
-16
lines changed

3 files changed

+93
-16
lines changed

packages/sandbox/src/compilerOptions.ts

+33-15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ type Monaco = typeof import("monaco-editor")
1010
export function getDefaultSandboxCompilerOptions(config: SandboxConfig, monaco: Monaco) {
1111
const useJavaScript = config.filetype === "js"
1212
const settings: CompilerOptions = {
13+
strict: true,
14+
1315
noImplicitAny: true,
1416
strictNullChecks: !useJavaScript,
1517
strictFunctionTypes: true,
@@ -60,24 +62,40 @@ export function getDefaultSandboxCompilerOptions(config: SandboxConfig, monaco:
6062
* Loop through all of the entries in the existing compiler options then compare them with the
6163
* query params and return an object which is the changed settings via the query params
6264
*/
63-
export const getCompilerOptionsFromParams = (options: CompilerOptions, params: URLSearchParams): CompilerOptions => {
64-
const urlDefaults = Object.entries(options).reduce((acc: any, [key, value]) => {
65-
if (params.has(key)) {
66-
const urlValue = params.get(key)!
67-
68-
if (urlValue === "true") {
69-
acc[key] = true
70-
} else if (urlValue === "false") {
71-
acc[key] = false
72-
} else if (!isNaN(parseInt(urlValue, 10))) {
73-
acc[key] = parseInt(urlValue, 10)
65+
export const getCompilerOptionsFromParams = (
66+
playgroundDefaults: CompilerOptions,
67+
ts: typeof import("typescript"),
68+
params: URLSearchParams
69+
): CompilerOptions => {
70+
const returnedOptions: CompilerOptions = {}
71+
72+
params.forEach((val, key) => {
73+
// First use the defaults object to drop compiler flags which are already set to the default
74+
if (playgroundDefaults[key]) {
75+
let toSet = undefined
76+
if (val === "true" && playgroundDefaults[key] !== true) {
77+
toSet = true
78+
} else if (val === "false" && playgroundDefaults[key] !== false) {
79+
toSet = false
80+
} else if (!isNaN(parseInt(val, 10)) && playgroundDefaults[key] !== parseInt(val, 10)) {
81+
toSet = parseInt(val, 10)
7482
}
75-
}
7683

77-
return acc
78-
}, {})
84+
if (toSet !== undefined) returnedOptions[key] = toSet
85+
} else {
86+
// If that doesn't work, double check that the flag exists and allow it through
87+
// @ts-ignore
88+
const flagExists = ts.optionDeclarations.find(opt => opt.name === key)
89+
if (flagExists) {
90+
let realValue: number | boolean = true
91+
if (val === "false") realValue = false
92+
if (!isNaN(parseInt(val, 10))) realValue = parseInt(val, 10)
93+
returnedOptions[key] = realValue
94+
}
95+
}
96+
})
7997

80-
return urlDefaults
98+
return returnedOptions
8199
}
82100

83101
// Can't set sandbox to be the right type because the param would contain this function

packages/sandbox/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export const createTypeScriptSandbox = (
123123
let compilerOptions: CompilerOptions
124124
if (!config.suppressAutomaticallyGettingCompilerFlags) {
125125
const params = new URLSearchParams(location.search)
126-
let queryParamCompilerOptions = getCompilerOptionsFromParams(compilerDefaults, params)
126+
let queryParamCompilerOptions = getCompilerOptionsFromParams(compilerDefaults, ts, params)
127127
if (Object.keys(queryParamCompilerOptions).length)
128128
config.logger.log("[Compiler] Found compiler options in query params: ", queryParamCompilerOptions)
129129
compilerOptions = { ...compilerDefaults, ...queryParamCompilerOptions }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { getCompilerOptionsFromParams, getDefaultSandboxCompilerOptions } from "../src/compilerOptions"
2+
import ts from "typescript"
3+
4+
const fauxMonaco: any = {
5+
languages: {
6+
typescript: {
7+
ModuleResolutionKind: ts.ModuleResolutionKind,
8+
ScriptTarget: ts.ScriptTarget,
9+
JsxEmit: ts.JsxEmit,
10+
ModuleKind: ts.ModuleKind,
11+
},
12+
},
13+
}
14+
15+
describe(getCompilerOptionsFromParams, () => {
16+
it("ignores compiler flags which are the same as the defaults", () => {
17+
// noImplicitReturns=true is the default, and shouldnt be in the object
18+
const params = new URLSearchParams("?noImplicitThis=false&noImplicitReturns=true#code/JYOw")
19+
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)
20+
21+
expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
22+
Object {
23+
"noImplicitThis": false,
24+
}
25+
`)
26+
})
27+
28+
it("ignores non-compiler flags", () => {
29+
const params = new URLSearchParams("?asdasdasdasd=false")
30+
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)
31+
32+
expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`Object {}`)
33+
})
34+
35+
it("handles mapped types like target et", () => {
36+
const params = new URLSearchParams("?target=6")
37+
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)
38+
39+
expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
40+
Object {
41+
"target": 6,
42+
}
43+
`)
44+
})
45+
46+
it("handles settings options which haven't been given defaults in the monaco defaults", () => {
47+
const search = "?ts=4.4.0-beta&exactOptionalPropertyTypes=true#code/JYOw"
48+
const params = new URLSearchParams(search)
49+
expect(params.has("exactOptionalPropertyTypes")).toBeTruthy()
50+
51+
const defaults = getDefaultSandboxCompilerOptions({ filetype: "js" } as any, fauxMonaco)
52+
53+
expect(getCompilerOptionsFromParams(defaults, ts, params)).toMatchInlineSnapshot(`
54+
Object {
55+
"exactOptionalPropertyTypes": true,
56+
}
57+
`)
58+
})
59+
})

0 commit comments

Comments
 (0)