diff --git a/README.md b/README.md
index ba484cc..ab56c8d 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,8 @@ This plugin aims to solve this problem by making logging as easy as possible!
1. Select one or more Figma elements to get them logged in the Console
2. Add expressions to be evaluated on the selected Figma elements (`name,id,reactions[0].actions` results in each expression to be evaluated and logged in the Console)
+ - And if the value is a function, invoke it
+ - And if the returned value is a promise, await it
3. Stringy and format the result for better readability
4. Preferences are stored locally
diff --git a/manifest.json b/manifest.json
index 8ee5366..391b81d 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1 +1,16 @@
-{ "api": "1.0.0", "editorType": ["figma"], "id": "1348339696557868933", "name": "Select and Inspect", "main": "build/main.js", "ui": "build/ui.js", "networkAccess": { "allowedDomains": ["none"] }, "documentAccess": "dynamic-page" }
+{
+ "api": "1.0.0",
+ "editorType": [
+ "figma"
+ ],
+ "id": "1348339696557868933",
+ "name": "Select and Inspect",
+ "main": "build/main.js",
+ "ui": "build/ui.js",
+ "networkAccess": {
+ "allowedDomains": [
+ "none"
+ ]
+ },
+ "documentAccess": "dynamic-page"
+}
diff --git a/src/components/fields.tsx b/src/components/fields.tsx
index 0b29877..f203b32 100644
--- a/src/components/fields.tsx
+++ b/src/components/fields.tsx
@@ -80,3 +80,15 @@ export function FormatStringifiedEvaluatedExpressions({ defaultValue, onChange }
)
}
+
+export function ExecuteFunctionsAndAwaitPromises({ defaultValue, onChange }: { defaultValue: boolean; onChange: (newValue: boolean) => void }) {
+ const [value, setValue] = useState(defaultValue)
+
+ useOnChange(value, onChange)
+
+ return (
+
+ Execute functions and await promises
+
+ )
+}
diff --git a/src/core/createSelectAndInspect.ts b/src/core/createSelectAndInspect.ts
index 9ffe5a0..2bd46bf 100644
--- a/src/core/createSelectAndInspect.ts
+++ b/src/core/createSelectAndInspect.ts
@@ -4,7 +4,7 @@ import type { CreateFigmaPluginEmit, CreateFigmaPluginShowUI, FigmaPluginApi, Lo
import { createAreReferencesChanged } from '../utils/areReferencesChanged'
import { processCurrentSelection } from './processCurrentSelection'
-const uiOptions = { width: 480, height: 260 } as const
+const uiOptions = { width: 480, height: 290 } as const
interface Params {
configuration: LogOptions
@@ -69,6 +69,11 @@ export function createSelectAndInspect(params: Params) {
break
}
+ case 'hideExpressionErrorsChanged':
+ currentConfiguration.hideExpressionErrors = event.value
+ logChange('Hide evaluated expressions errors changed')
+ break
+
case 'expressionsToEvaluateChanged':
currentConfiguration.expressionsToEvaluate = event.value
logChange('Expressions to evaluate changed')
@@ -79,9 +84,9 @@ export function createSelectAndInspect(params: Params) {
logChange('Stringify evaluated expressions changed')
break
- case 'hideExpressionErrorsChanged':
- currentConfiguration.hideExpressionErrors = event.value
- logChange('Hide evaluated expressions errors changed')
+ case 'executeFunctionsAndAwaitPromisesChanged':
+ currentConfiguration.executeFunctionsAndAwaitPromises = event.value
+ logChange('Execute functions and await promises changed')
break
case 'formatStringifiedEvaluatedExpressionsChanged':
diff --git a/src/core/processCurrentSelection.ts b/src/core/processCurrentSelection.ts
index 81edc94..5304f9e 100644
--- a/src/core/processCurrentSelection.ts
+++ b/src/core/processCurrentSelection.ts
@@ -1,29 +1,42 @@
import { logExpression, logExpressionError, logStringifiedExpression } from '../utils/loggers'
-import { stringifiedValueIsTheSame, stringifyError } from '../utils/generic'
+import { isPromise, stringifiedValueIsTheSame, stringifyError } from '../utils/generic'
import type { LogOptions } from '../types'
-export function processCurrentSelection(selection: ReadonlyArray, configuration: LogOptions) {
- processItems(
+export async function processCurrentSelection(selection: ReadonlyArray, configuration: LogOptions) {
+ await processItems(
selection,
configuration,
)
}
-function processItems(items: readonly unknown[], logOptions: LogOptions) {
+async function processItems(items: readonly unknown[], logOptions: LogOptions) {
for (const item of items) {
- processItem(
+ await processItem(
item,
logOptions,
)
}
}
-function evaluateExpression(item: unknown, expression: string) {
+function evaluateExpression(item: unknown, expression: string, options: { invokeFunctions: boolean }) {
+ const { invokeFunctions } = options
// eslint-disable-next-line no-new-func
- return new Function('obj', `return obj.${expression}`)(item)
+ return new Function('obj', `
+ function evaluator(obj) {
+ let value = obj.${expression}
+
+ if(typeof value === 'function' && ${invokeFunctions}) {
+ return obj.${expression}()
+ }
+
+ return value
+ }
+
+ return evaluator(obj)
+`)(item)
}
-function processItem(item: unknown, logOptions: LogOptions) {
+async function processItem(item: unknown, logOptions: LogOptions) {
console.log(item)
const expressions = logOptions.expressionsToEvaluate.split(',')
@@ -32,23 +45,34 @@ function processItem(item: unknown, logOptions: LogOptions) {
const trimmedExpression = expression.trim()
if (expression === '')
continue
- processExpression(item, trimmedExpression, logOptions)
+ await processExpression(item, trimmedExpression, logOptions)
}
}
-function processExpression(
+async function processExpression(
item: unknown,
expression: string,
logOptions: LogOptions,
) {
- const { stringifyEvaluatedExpressions, hideExpressionErrors, formatStringifiedEvaluatedExpressions } = logOptions
+ const { stringifyEvaluatedExpressions, hideExpressionErrors, formatStringifiedEvaluatedExpressions, executeFunctionsAndAwaitPromises } = logOptions
let value
let stringifiedValue = ''
let errored = false
try {
- value = evaluateExpression(item, expression)
- logExpression(expression, value)
+ value = evaluateExpression(item, expression, { invokeFunctions: executeFunctionsAndAwaitPromises })
+ if (executeFunctionsAndAwaitPromises) {
+ if (isPromise(value)) {
+ const resolvedValue = await value
+ logExpression(expression, resolvedValue)
+ }
+ else {
+ logExpression(expression, value)
+ }
+ }
+ else {
+ logExpression(expression, value)
+ }
}
catch (e) {
errored = true
diff --git a/src/main.ts b/src/main.ts
index af7ee9b..26fc6b8 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,6 +8,7 @@ const defaultConfiguration: LogOptions = {
expressionsToEvaluate: '',
hideExpressionErrors: false,
stringifyEvaluatedExpressions: false,
+ executeFunctionsAndAwaitPromises: false,
formatStringifiedEvaluatedExpressions: false,
}
diff --git a/src/types.ts b/src/types.ts
index 61c7e46..a1c6d67 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -25,6 +25,7 @@ export const logOptionsSchema = z.object({
expressionsToEvaluate: z.string(),
hideExpressionErrors: z.boolean(),
stringifyEvaluatedExpressions: z.boolean(),
+ executeFunctionsAndAwaitPromises: z.boolean(),
formatStringifiedEvaluatedExpressions: z.boolean(),
})
@@ -37,6 +38,10 @@ export const uiEventSchema = z.union([
type: z.literal('enabledChanged'),
value: z.boolean(),
}),
+ z.object({
+ type: z.literal('hideExpressionErrorsChanged'),
+ value: z.boolean(),
+ }),
z.object({
type: z.literal('expressionsToEvaluateChanged'),
value: z.string(),
@@ -46,11 +51,11 @@ export const uiEventSchema = z.union([
value: z.boolean(),
}),
z.object({
- type: z.literal('formatStringifiedEvaluatedExpressionsChanged'),
+ type: z.literal('executeFunctionsAndAwaitPromisesChanged'),
value: z.boolean(),
}),
z.object({
- type: z.literal('hideExpressionErrorsChanged'),
+ type: z.literal('formatStringifiedEvaluatedExpressionsChanged'),
value: z.boolean(),
}),
])
diff --git a/src/ui.tsx b/src/ui.tsx
index ef9b15a..f702bf8 100644
--- a/src/ui.tsx
+++ b/src/ui.tsx
@@ -17,6 +17,7 @@ import { type UiEvent, logOptionsSchema, serverEventSchema } from './types'
import {
EnabledDisabled,
+ ExecuteFunctionsAndAwaitPromises,
ExpressionsToEvaluate,
FormatStringifiedEvaluatedExpressions,
HideExpressionErrors,
@@ -97,6 +98,8 @@ function UI({ configuration }: { configuration: unknown }) {
emit('uiEvent', event)
}}
/>
+
+
{
@@ -104,6 +107,13 @@ function UI({ configuration }: { configuration: unknown }) {
emit('uiEvent', event)
}}
/>
+ {
+ const event: UiEvent = { type: 'executeFunctionsAndAwaitPromisesChanged', value }
+ emit('uiEvent', event)
+ }}
+ />