Skip to content

Custom block input params: an app config selector #260

Description

@07prajwal2000

Why

A custom block's input params can be a text input, checkbox, dropdown, array editor, or an integration selector. The integration selector landed in #259: a param declared as integration_selector shows up inside the integration picker on the block's own canvas, and picking it writes param:<name>, so the concrete integration is chosen by whoever places the block. That is what makes a custom block reusable across projects without baking a connection id into it.

App config has no equivalent, and it is the other half of the same problem. Anything a block needs that is environment, not logic — a signing secret, an API key, a base URL, a feature flag — has to be typed into the block's graph as a literal today.

The e2e fixture added alongside this (testing/e2e/blocks/jwt-ops.json) makes the gap concrete: it hardcodes "e2e-custom-block-secret" in two JS blocks, because there is no way to say "the caller decides which config key holds the secret". A test can shrug at that. A real block cannot — the secret would live in the block's source, shared with every project that installs it.

What

An app_config_selector input param type: a param whose value is an app config key, chosen by the caller in the block's settings panel.

Sketch, to be argued with rather than followed:

  • Portal, authoring — a new type in InputParamsEditor alongside the existing five.
  • Portal, calling — the settings panel renders a picker of the project's app config keys, the same way BlockIntegrationField renders integrations. It writes param:<name> like every other param.
  • Runtime — nothing new is obviously required. param: already resolves from the invocation ($state.params), and getConfig(key) is already project-scoped in the context vars. The block's JS would read getConfig(params.secretKey). Worth confirming that reads as intended before adding machinery for it.

The open question is whether the param should carry the key (block does getConfig(params.secretKey)) or the resolved value (block does params.secret). The key is more honest — it keeps resolution project-scoped at call time and never puts a secret in a job payload — but it costs a getConfig call the author has to remember. Resolving eagerly is friendlier and leaks further. Worth deciding deliberately.

Notes

  • Unlike integrations, app config has no consumer block: it is only ever read from JS. So this is a param type plus a picker, not a change to any block's settings.
  • Same scoping rule as the integration selector: this belongs to the custom block chain only. A route canvas has no caller to resolve it.
  • Once it lands, drop the hardcoded secret from blocks/jwt-ops.json and let the fixture prove the path end to end.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions