From 493be261ee7fe6b062f47c12f15c294f386bd332 Mon Sep 17 00:00:00 2001 From: HeyEvgenii Date: Tue, 28 Jul 2026 17:16:13 +0700 Subject: [PATCH] suggest plugin id from display name --- README.md | 11 +++++++++++ src/index.ts | 29 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ebf5a78..8e4f636 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,17 @@ const initData: BoltInitData = { if (!process.env.BOLT_MODULEONLY) main(initData); ``` +### Suggested Plugin IDs + +If your template has an arg named `displayName` and an arg named `id`, the `id` prompt is pre-filled from the display name the user just entered, by swapping the name segment of the default `id` you declared: + +| your `initialValue` | user types | prompt suggests | +| ------------------- | ----------------------- | ------------------------------- | +| `com.bolt.uxp` | photoshop automator | `com.PhotoshopAutomator.uxp` | +| `com.bolt.cep` | after effects automator | `com.AfterEffectsAutomator.cep` | + +The suffix comes from your own default, so each project keeps its own convention. It's only a suggestion — the user can type over it. Your default is used unchanged if the display name has no usable characters, or if the `id` has no name segment to swap. + Once you've built out your template with all the options for your project, now you will need to update your template to be dynamic with this create script. You can accomplish this by: diff --git a/src/index.ts b/src/index.ts index d504865..d360610 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,22 @@ const handleCancel = (value: unknown) => { } }; +const toPascalCase = (text: string) => + text + .replace(/\w+/g, (word) => word[0].toUpperCase() + word.slice(1)) + .replace(/\W/g, ""); + +/** + * get suggested ID from user typed displayName + * eg "photoshop automator" will suggest "com.PhotoshopAutomator.uxp" + */ +const suggestIdFromDisplayName = (defaultId: string, displayName: unknown) => { + const nameSegment = + typeof displayName === "string" ? toPascalCase(displayName) : ""; + if (!nameSegment) return defaultId; //if no value return default + return defaultId.replace(/\.[^.]+\./, `.${nameSegment}.`); +}; + export const main = async ( initData: BoltInitData, overrideArgs: ResArgs = {} @@ -58,11 +74,22 @@ export const main = async ( let res; if (arg.type === "folder" || arg.type === "string") { + //everything answered so far so the id prompt can read the display name + const answeredArgs: ResArgs = { + ...cliArgs, + ...promptArgs, + ...overrideArgs, + }; + const initialValue = + arg.name === "id" + ? suggestIdFromDisplayName(arg.initialValue, answeredArgs.displayName) + : arg.initialValue; + let completed = false; while (!completed) { res = (await text({ message: arg.message, - initialValue: arg.initialValue, + initialValue, validate: arg.validator, })) as string; if (arg.type === "folder") {