diff --git a/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/index.ts b/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/index.ts index 61bfaba..8acd927 100644 --- a/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/index.ts +++ b/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/index.ts @@ -57,8 +57,8 @@ if (!inSharedWorker()) { ); }; - // Just check fetch is blocked on registration, don't slow down message processing. - rpc.receive("registerScript", enforceFetchIsBlocked(registerScript)); + // Allow fetch in user scripts at runtime by removing the CSP wrapper: + rpc.receive("registerScript", registerScript); rpc.receive("processMessage", processMessage); port.start(); diff --git a/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/registry.ts b/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/registry.ts index 6be5354..be42bf6 100644 --- a/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/registry.ts +++ b/packages/suite-base/src/players/UserScriptPlayer/runtimeWorker/registry.ts @@ -135,13 +135,13 @@ export const registerScript = ({ } }; -export const processMessage = ({ +export const processMessage = async ({ message, globalVariables, }: { message: unknown; globalVariables: GlobalVariables; -}): ProcessMessageOutput => { +}): Promise => { const userScriptLogs: UserScriptLog[] = []; const userScriptDiagnostics: Diagnostic[] = []; (self as { log?: unknown }).log = function (...args: unknown[]) { @@ -157,8 +157,12 @@ export const processMessage = ({ userScriptLogs.push(...args.map((value) => ({ source: "processMessage" as const, value }))); }; try { - const newMessage = nodeCallback(message, globalVariables); - return { message: newMessage, error: undefined, userScriptLogs, userScriptDiagnostics }; + // Invoke the user script; if it's async, await its completion + const result = await (async () => { + const r = nodeCallback(message, globalVariables); + return Promise.resolve(r); + })(); + return { message: result, error: undefined, userScriptLogs, userScriptDiagnostics }; } catch (err) { const error: string = err.toString(); const diagnostic: Diagnostic = { diff --git a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/index.ts b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/index.ts index 0719edd..09b06e2 100644 --- a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/index.ts +++ b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/index.ts @@ -69,7 +69,7 @@ if (!inSharedWorker()) { rpc.receive("close", () => { global.close(); }); - rpc.receive("transform", enforceFetchIsBlocked(transform)); + rpc.receive("transform", transform); rpc.receive("generateRosLib", generateRosLib); port.start(); }; diff --git a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/ast.ts b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/ast.ts index b96078a..32872ae 100644 --- a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/ast.ts +++ b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/ast.ts @@ -200,8 +200,12 @@ export const findReturnType = ( throw new DatatypeExtractionError(nonFuncError); } + // Determine the actual return type, unwrapping Promise if needed const fullReturnType = typeChecker.getReturnTypeOfSignature(signature); - const nonNullable = fullReturnType.getNonNullableType(); + // If it's a Promise, get the promised inner type; otherwise use as-is + const unwrappedType = + typeChecker.getPromisedTypeOfPromise(fullReturnType) ?? fullReturnType; + const nonNullable = unwrappedType.getNonNullableType(); // In some future we could support intersection types where all the fields are known if (nonNullable.isIntersection()) { diff --git a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/lib.ts b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/lib.ts index 2a9e985..480bdca 100644 --- a/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/lib.ts +++ b/packages/suite-base/src/players/UserScriptPlayer/transformerWorker/typescript/lib.ts @@ -61,6 +61,8 @@ import lib_es2022_regexp from "typescript/lib/lib.es2022.regexp.d.ts?raw"; import lib_es2022_sharedmemory from "typescript/lib/lib.es2022.sharedmemory.d.ts?raw"; import lib_es2022_string from "typescript/lib/lib.es2022.string.d.ts?raw"; import lib_es5_dts from "typescript/lib/lib.es5.d.ts?raw"; +import lib_dom_dts from "typescript/lib/lib.dom.d.ts?raw"; +import lib_dom_iterable_dts from "typescript/lib/lib.dom.iterable.d.ts?raw"; export const lib_filename = "lib.d.ts"; @@ -147,5 +149,7 @@ function resolveReferences(originalSrc: string): string { }); } -const resolvedDts = resolveReferences(lib_es2022_dts); -export const lib_dts = `${resolvedDts}\n\n${lib_logger}`; +const resolvedEsDts = resolveReferences(lib_es2022_dts); +const resolvedDomDts = resolveReferences(lib_dom_dts); +const resolvedDomIterableDts = resolveReferences(lib_dom_iterable_dts); +export const lib_dts = `${resolvedEsDts}\n\n${resolvedDomDts}\n\n${resolvedDomIterableDts}\n\n${lib_logger}`;