1- import type { MicroApp , StoryboardFunction } from "@next-core/types" ;
1+ import type {
2+ MicroApp ,
3+ StoryboardFunction ,
4+ TransformedFunction ,
5+ } from "@next-core/types" ;
26import {
37 cook ,
48 precookFunction ,
@@ -8,6 +12,7 @@ import {
812} from "@next-core/cook" ;
913import { supply } from "@next-core/supply" ;
1014import { collectMemberUsageInFunction } from "@next-core/utils/storyboard" ;
15+ import { hasOwnProperty } from "@next-core/utils/general" ;
1116import type _ from "lodash" ;
1217import { getGeneralGlobals } from "./internal/compute/getGeneralGlobals.js" ;
1318
@@ -17,7 +22,7 @@ export type ReadonlyStoryboardFunctions = Readonly<Record<string, Function>>;
1722/** @internal */
1823export type StoryboardFunctionPatch = Pick <
1924 StoryboardFunction ,
20- "source" | "typescript"
25+ "source" | "typescript" | "transformed"
2126> ;
2227
2328/** @internal */
@@ -50,6 +55,7 @@ export interface RuntimeStoryboardFunction {
5055 cooked ?: Function ;
5156 deps : Set < string > | string [ ] ;
5257 hasPermissionsCheck : boolean ;
58+ transformed ?: TransformedFunction ;
5359}
5460
5561/** @internal */
@@ -66,7 +72,7 @@ export interface FunctionCoverageSettings {
6672}
6773
6874/** @internal */
69- export type PartialMicroApp = Pick < MicroApp , "id" | "isBuildPush" > ;
75+ export type PartialMicroApp = Pick < MicroApp , "id" | "isBuildPush" | "config" > ;
7076
7177/** @internal */
7278export function StoryboardFunctionRegistryFactory ( {
@@ -130,13 +136,29 @@ export function StoryboardFunctionRegistryFactory({
130136 registeredFunctions . set ( fn . name , {
131137 source : fn . source ,
132138 typescript : fn . typescript ,
139+ transformed : fn . transformed ,
133140 deps,
134141 hasPermissionsCheck,
135142 } ) ;
136143 }
137144 }
138145 }
139146
147+ function getGlobalVariables ( globals : Set < string > | string [ ] ) {
148+ return supply (
149+ globals ,
150+ getGeneralGlobals ( globals , {
151+ collectCoverage,
152+ widgetId,
153+ widgetVersion,
154+ app : currentApp ,
155+ storyboardFunctions,
156+ isStoryboardFunction : true ,
157+ } ) ,
158+ ! ! collectCoverage
159+ ) ;
160+ }
161+
140162 function getStoryboardFunction ( name : string ) : Function | undefined {
141163 const fn = registeredFunctions . get ( name ) ;
142164 if ( ! fn ) {
@@ -149,67 +171,77 @@ export function StoryboardFunctionRegistryFactory({
149171 if ( collectCoverage ) {
150172 collector = collectCoverage . createCollector ( name ) ;
151173 }
152- const precooked = precookFunction ( fn . source , {
153- typescript : fn . typescript ,
154- hooks : collector && {
155- beforeVisit : collector . beforeVisit ,
156- } ,
157- cacheKey : fn ,
158- } ) ;
159- const globalVariables = supply (
160- precooked . attemptToVisitGlobals ,
161- getGeneralGlobals ( precooked . attemptToVisitGlobals , {
162- collectCoverage,
163- widgetId,
164- widgetVersion,
165- app : currentApp ,
166- storyboardFunctions,
167- isStoryboardFunction : true ,
168- } ) ,
169- ! ! collectCoverage
170- ) ;
171174
172- fn . cooked = cook ( precooked . function , fn . source , {
173- rules : {
174- noVar : true ,
175- } ,
176- globalVariables : overrides
177- ? {
178- ...globalVariables ,
179- ...( overrides ?. LodashWithStaticFields &&
180- precooked . attemptToVisitGlobals . has ( "_" )
181- ? {
182- _ : {
183- ...( globalVariables . _ as typeof _ ) ,
184- ...overrides . LodashWithStaticFields ,
185- } ,
186- }
187- : null ) ,
188- ...( overrides ?. ArrayConstructor &&
189- precooked . attemptToVisitGlobals . has ( "Array" )
190- ? {
191- Array : overrides . ArrayConstructor ,
192- }
193- : null ) ,
194- ...( overrides ?. ObjectWithStaticFields &&
195- precooked . attemptToVisitGlobals . has ( "Object" )
196- ? {
197- Object : {
198- ...( globalVariables . Object as typeof Object ) ,
199- ...overrides . ObjectWithStaticFields ,
200- } ,
201- }
202- : null ) ,
203- }
204- : globalVariables ,
205- ArrayConstructor : overrides ?. ArrayConstructor ,
206- hooks : collector && {
207- beforeEvaluate : collector . beforeEvaluate ,
208- beforeCall : collector . beforeCall ,
209- beforeBranch : collector . beforeBranch ,
210- } ,
211- debug : ! ! debuggerOverrides ,
212- } ) as Function ;
175+ // Do not use transformed functions when debugging.
176+ const transformed = ! overrides && ! collector && fn . transformed ;
177+ if ( transformed ) {
178+ const globalVariables = getGlobalVariables ( transformed . globals ) ;
179+ // Spread globals as params to prevent accessing forbidden globals.
180+ // NOTE: in native mode, forbidden globals are declared as `undefined`,
181+ // thus accessing them will not throw a ReferenceError.
182+ fn . cooked = new Function (
183+ ...transformed . globals ,
184+ `"use strict";return (${ transformed . source } )`
185+ ) (
186+ ...transformed . globals . map ( ( key ) =>
187+ hasOwnProperty ( globalVariables , key )
188+ ? globalVariables [ key ]
189+ : undefined
190+ )
191+ ) ;
192+ } else {
193+ const precooked = precookFunction ( fn . source , {
194+ typescript : fn . typescript ,
195+ hooks : collector && {
196+ beforeVisit : collector . beforeVisit ,
197+ } ,
198+ cacheKey : fn ,
199+ } ) ;
200+ const globalVariables = getGlobalVariables (
201+ precooked . attemptToVisitGlobals
202+ ) ;
203+ fn . cooked = cook ( precooked . function , fn . source , {
204+ rules : {
205+ noVar : true ,
206+ } ,
207+ globalVariables : overrides
208+ ? {
209+ ...globalVariables ,
210+ ...( overrides ?. LodashWithStaticFields &&
211+ precooked . attemptToVisitGlobals . has ( "_" )
212+ ? {
213+ _ : {
214+ ...( globalVariables . _ as typeof _ ) ,
215+ ...overrides . LodashWithStaticFields ,
216+ } ,
217+ }
218+ : null ) ,
219+ ...( overrides ?. ArrayConstructor &&
220+ precooked . attemptToVisitGlobals . has ( "Array" )
221+ ? {
222+ Array : overrides . ArrayConstructor ,
223+ }
224+ : null ) ,
225+ ...( overrides ?. ObjectWithStaticFields &&
226+ precooked . attemptToVisitGlobals . has ( "Object" )
227+ ? {
228+ Object : {
229+ ...( globalVariables . Object as typeof Object ) ,
230+ ...overrides . ObjectWithStaticFields ,
231+ } ,
232+ }
233+ : null ) ,
234+ }
235+ : globalVariables ,
236+ ArrayConstructor : overrides ?. ArrayConstructor ,
237+ hooks : collector && {
238+ beforeEvaluate : collector . beforeEvaluate ,
239+ beforeCall : collector . beforeCall ,
240+ beforeBranch : collector . beforeBranch ,
241+ } ,
242+ debug : ! ! debuggerOverrides ,
243+ } ) as Function ;
244+ }
213245 fn . processed = true ;
214246 return fn . cooked ;
215247 }
@@ -234,6 +266,7 @@ export function StoryboardFunctionRegistryFactory({
234266 registeredFunctions . set ( name , {
235267 source : data . source ,
236268 typescript : data . typescript ,
269+ transformed : data . transformed ,
237270 deps,
238271 hasPermissionsCheck,
239272 } ) ;
0 commit comments