@flowerforce/flowerbase 1.7.2 → 1.7.3-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -111,6 +111,56 @@ const shouldFallbackFromVmModules = (error: unknown): boolean => {
111
111
  return code === 'ERR_VM_MODULES_DISABLED' || code === 'ERR_VM_MODULES_NOT_SUPPORTED'
112
112
  }
113
113
 
114
+ type ExportedFunction = (...args: unknown[]) => unknown
115
+ type SandboxModule = { exports: unknown }
116
+ type SandboxContext = vm.Context & {
117
+ exports?: unknown
118
+ module?: SandboxModule
119
+ __fb_module?: SandboxModule
120
+ __fb_exports?: unknown
121
+ __fb_require?: NodeRequire
122
+ __fb_filename?: string
123
+ __fb_dirname?: string
124
+ }
125
+
126
+ const isExportedFunction = (value: unknown): value is ExportedFunction =>
127
+ typeof value === 'function'
128
+
129
+ const getDefaultExport = (value: unknown): ExportedFunction | undefined => {
130
+ if (!value || typeof value !== 'object') return undefined
131
+ if (!('default' in value)) return undefined
132
+ const maybeDefault = (value as { default?: unknown }).default
133
+ return isExportedFunction(maybeDefault) ? maybeDefault : undefined
134
+ }
135
+
136
+ const resolveExport = (ctx: SandboxContext): ExportedFunction | undefined => {
137
+ const moduleExports = ctx.module?.exports ?? ctx.__fb_module?.exports
138
+ if (isExportedFunction(moduleExports)) return moduleExports
139
+ const contextExports = ctx.exports ?? ctx.__fb_exports
140
+ if (isExportedFunction(contextExports)) return contextExports
141
+ return getDefaultExport(moduleExports) ?? getDefaultExport(contextExports)
142
+ }
143
+
144
+ const buildVmContext = (contextData: ReturnType<typeof generateContextData>) => {
145
+ const sandboxModule: SandboxModule = { exports: {} }
146
+ const entryFile = require.main?.filename ?? process.cwd()
147
+ const customRequire = createRequire(entryFile)
148
+
149
+ const vmContext: SandboxContext = vm.createContext({
150
+ ...contextData,
151
+ require: customRequire,
152
+ exports: sandboxModule.exports,
153
+ module: sandboxModule,
154
+ __filename,
155
+ __dirname,
156
+ __fb_require: customRequire,
157
+ __fb_filename: __filename,
158
+ __fb_dirname: __dirname
159
+ }) as SandboxContext
160
+
161
+ return { sandboxModule, entryFile, customRequire, vmContext }
162
+ }
163
+
114
164
  /**
115
165
  * > Used to generate the current context
116
166
  * @testable
@@ -153,55 +203,10 @@ export async function GenerateContext({
153
203
  functionName,
154
204
  functionsList,
155
205
  GenerateContext,
206
+ GenerateContextSync,
156
207
  request
157
208
  })
158
-
159
- type ExportedFunction = (...args: unknown[]) => unknown
160
- type SandboxModule = { exports: unknown }
161
- type SandboxContext = vm.Context & {
162
- exports?: unknown
163
- module?: SandboxModule
164
- __fb_module?: SandboxModule
165
- __fb_exports?: unknown
166
- __fb_require?: NodeRequire
167
- __fb_filename?: string
168
- __fb_dirname?: string
169
- }
170
-
171
- const isExportedFunction = (value: unknown): value is ExportedFunction =>
172
- typeof value === 'function'
173
-
174
- const getDefaultExport = (value: unknown): ExportedFunction | undefined => {
175
- if (!value || typeof value !== 'object') return undefined
176
- if (!('default' in value)) return undefined
177
- const maybeDefault = (value as { default?: unknown }).default
178
- return isExportedFunction(maybeDefault) ? maybeDefault : undefined
179
- }
180
-
181
- const resolveExport = (ctx: SandboxContext): ExportedFunction | undefined => {
182
- const moduleExports = ctx.module?.exports ?? ctx.__fb_module?.exports
183
- if (isExportedFunction(moduleExports)) return moduleExports
184
- const contextExports = ctx.exports ?? ctx.__fb_exports
185
- if (isExportedFunction(contextExports)) return contextExports
186
- return getDefaultExport(moduleExports) ?? getDefaultExport(contextExports)
187
- }
188
-
189
- const sandboxModule: SandboxModule = { exports: {} }
190
-
191
- const entryFile = require.main?.filename ?? process.cwd()
192
- const customRequire = createRequire(entryFile)
193
-
194
- const vmContext: SandboxContext = vm.createContext({
195
- ...contextData,
196
- require: customRequire,
197
- exports: sandboxModule.exports,
198
- module: sandboxModule,
199
- __filename,
200
- __dirname,
201
- __fb_require: customRequire,
202
- __fb_filename: __filename,
203
- __fb_dirname: __dirname
204
- }) as SandboxContext
209
+ const { sandboxModule, entryFile, customRequire, vmContext } = buildVmContext(contextData)
205
210
 
206
211
  const vmModules = vm as typeof vm & {
207
212
  SourceTextModule?: typeof vm.SourceTextModule
@@ -288,3 +293,45 @@ export async function GenerateContext({
288
293
  return res
289
294
 
290
295
  }
296
+
297
+ export function GenerateContextSync({
298
+ args,
299
+ app,
300
+ rules,
301
+ user,
302
+ currentFunction,
303
+ functionsList,
304
+ services,
305
+ functionName,
306
+ runAsSystem,
307
+ deserializeArgs = true,
308
+ request
309
+ }: GenerateContextParams): unknown {
310
+ if (!currentFunction) return
311
+
312
+ const functionToRun = { run_as_system: runAsSystem, ...currentFunction }
313
+ const contextData = generateContextData({
314
+ user,
315
+ services,
316
+ app,
317
+ rules,
318
+ currentFunction: functionToRun,
319
+ functionName,
320
+ functionsList,
321
+ GenerateContext,
322
+ GenerateContextSync,
323
+ request
324
+ })
325
+ const { sandboxModule, vmContext } = buildVmContext(contextData)
326
+ const codeToRun = functionToRun.code.includes('import ')
327
+ ? transformImportsToRequire(functionToRun.code)
328
+ : functionToRun.code
329
+
330
+ vm.runInContext(codeToRun, vmContext)
331
+ sandboxModule.exports = resolveExport(vmContext) ?? sandboxModule.exports
332
+ const fn = sandboxModule.exports as ExportedFunction
333
+ if (deserializeArgs) {
334
+ return fn(...EJSON.deserialize(args))
335
+ }
336
+ return fn(...args)
337
+ }
@@ -22,4 +22,5 @@ export interface GenerateContextParams {
22
22
  type ContextRequest = Pick<FastifyRequest, "ips" | "host" | "hostname" | "url" | "method" | "ip" | "id">
23
23
  export interface GenerateContextDataParams extends Omit<GenerateContextParams, 'args'> {
24
24
  GenerateContext: (params: GenerateContextParams) => Promise<unknown>
25
+ GenerateContextSync: (params: GenerateContextParams) => unknown
25
26
  }