@fluid-app/fluid-cli-widget 0.1.0 → 0.1.2
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.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +7 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/templates/default/package.json.template +14 -6
package/dist/index.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ interface WidgetTemplateVariables {
|
|
|
8
8
|
readonly widgetScope: string;
|
|
9
9
|
readonly widgetPackageVersion: string;
|
|
10
10
|
readonly sdkVersion: string;
|
|
11
|
-
readonly
|
|
11
|
+
readonly localCoreVersion?: string;
|
|
12
12
|
readonly fluidCliVersion: string;
|
|
13
13
|
readonly widgetCliVersion: string;
|
|
14
14
|
readonly droplet?: string;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/commands/build.ts","../src/commands/create.ts","../src/commands/dev.ts","../src/commands/link.ts","../src/commands/logs.ts","../src/commands/publish.ts","../src/commands/status.ts","../src/commands/validate.ts","../src/utils/config.ts","../src/utils/source-package.ts","../src/utils/validation.ts","../src/index.ts"],"mappings":";;;;;UAAiB,uBAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA;EAAA,SACA,oBAAA;EAAA,SACA,UAAA;EAAA,SACA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/commands/build.ts","../src/commands/create.ts","../src/commands/dev.ts","../src/commands/link.ts","../src/commands/logs.ts","../src/commands/publish.ts","../src/commands/status.ts","../src/commands/validate.ts","../src/utils/config.ts","../src/utils/source-package.ts","../src/utils/validation.ts","../src/index.ts"],"mappings":";;;;;UAAiB,uBAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA;EAAA,SACA,oBAAA;EAAA,SACA,UAAA;EAAA,SACA,gBAAA;EAAA,SACA,eAAA;EAAA,SACA,gBAAA;EAAA,SACA,OAAA;AAAA;AAAA,UAGM,mBAAA;EAAA,SACN,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;;WAEA,cAAA;AAAA;AAAA,UAGM,iBAAA;EAAA,SACN,OAAA;AAAA;AAAA,UAGM,oBAAA;EAAA,SACN,GAAA;AAAA;;;UCXM,kBAAA;EAAA,SACN,MAAA;EAAA,SACA,aAAA;AAAA;AAAA,UAGM,yBAAA;EAAA,SACN,UAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;AAAA;AAAA,UAGM,wBAAA;EAAA,SACN,MAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;AAAA;AAAA,iBAGW,kBAAA,CACpB,OAAA,EAAS,yBAAA,GACR,OAAA,CAAQ,wBAAA;AAAA,cAoCE,YAAA,EAAc,OAAA;;;cC1Cd,aAAA,EAAe,OAAA;AAAA,iBAsCN,mBAAA,CACpB,WAAA,UACA,OAAA,EAAS,mBAAA,GACR,OAAA;;;cC7DU,uBAAA;AAAA,cAEA,iBAAA;AAAA,UAQI,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;AAAA;AAAA,UAGM,uBAAA;EAAA,SACN,UAAA;EAAA,SACA,WAAA;EAAA,SACA,cAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,cAGE,UAAA,EAAY,OAAA;AAAA,iBAmBH,uBAAA,CACpB,UAAA,UACA,OAAA,GAAS,gBAAA,GACR,OAAA,CAAQ,uBAAA;AAAA,iBAkCK,gBAAA,CAAiB,OAAA,GAAS,gBAAA;AAAA,iBAa1B,qBAAA,CAAsB,OAAA,EAAS,uBAAA;AAAA,iBAazB,gBAAA,CACpB,UAAA,UACA,OAAA,GAAS,gBAAA,GACR,OAAA;;;cCxGU,WAAA,EAAa,OAAA;;;UCRT,kBAAA;EAAA,SACN,OAAA;EAAA,SACA,KAAA;EAAA,SACA,IAAA;AAAA;AAAA,cAGE,WAAA,EAAa,OAAA;;;UCMT,2BAAA;EAAA,SACN,UAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,0BAAA;EAAA,SACN,MAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA;AAAA;AAAA,UAGM,gCAAA;EAAA,SACN,kBAAA,GAAqB,OAAA;IAAA,SACnB,UAAA;IAAA,SACA,MAAA;EAAA,MACL,OAAA;EAAA,SACG,mBAAA,GAAsB,OAAA;IAAA,SACpB,MAAA;IAAA,SACA,OAAA;IAAA,SACA,MAAA;EAAA,MACL,OAAA;AAAA;AAAA,iBAGc,oBAAA,CACpB,OAAA,EAAS,2BAAA,EACT,YAAA,GAAe,gCAAA,GACd,OAAA,CAAQ,0BAAA;AAAA,UAwDM,qBAAA;EAAA,SACN,MAAA;EAAA,SACA,OAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;AAAA;AAAA,cAGE,cAAA,EAAgB,OAAA;;;UCvGZ,oBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;AAAA;AAAA,cAGE,aAAA,EAAe,OAAA;;;UCPX,qBAAA;EAAA,SACN,IAAA;AAAA;AAAA,cAGE,eAAA,EAAiB,OAAA;;;cCTjB,kBAAA;AAAA,UAEI,iBAAA;EAAA,SACN,OAAA;AAAA;AAAA,UAGM,kBAAA;EAAA,SACN,IAAA;EAAA,SACA,MAAA,EAAQ,OAAA,CAAQ,iBAAA;AAAA;AAAA,iBAUX,uBAAA,CAAwB,UAAA;AAAA,iBAIlB,gBAAA,CACpB,UAAA,WACC,OAAA,CAAQ,kBAAA;AAAA,iBAiBW,iBAAA,CACpB,UAAA,UACA,MAAA,EAAQ,iBAAA,GACP,OAAA;AAAA,iBAQa,kBAAA,CAAmB,MAAA,EAAQ,iBAAA;AAAA,iBAwB3B,uBAAA,CACd,MAAA,WACC,OAAA,CAAQ,iBAAA;AAAA,iBAOK,iBAAA,CACd,OAAA,EAAS,OAAA,CAAQ,iBAAA,GACjB,OAAA,EAAS,OAAA,CAAQ,iBAAA,IAChB,iBAAA;AAAA,iBAQa,mBAAA,CAAoB,WAAA;;;cCjFvB,sBAAA;AAAA,cACA,uBAAA;AAAA,UAQI,sBAAA;EAAA,SACN,UAAA;EAAA,SACA,gBAAA;EAAA,SACA,SAAA,EAAW,2BAAA;AAAA;AAAA,cAGT,qBAAA,SAA8B,KAAA;EAAA,SACzB,MAAA,WAAiB,4BAAA;EAEjC,WAAA,CAAY,MAAA,WAAiB,4BAAA;AAAA;AAAA,iBAOT,4BAAA,CACpB,UAAA,UACA,kBAAA,YACC,OAAA,CAAQ,sBAAA;AAAA,iBA+DW,0BAAA,GAAA,CACpB,UAAA,UACA,QAAA,QAAgB,OAAA,CAAQ,CAAA,GACxB,kBAAA,YACC,OAAA,CAAQ,CAAA;AAAA,iBA+DK,yBAAA,CACd,UAAA;EAAA,SACY,IAAA;EAAA,SAAuB,YAAA;AAAA;AAAA,iBASrB,uBAAA,CACd,MAAA,EAAQ,sBAAA;;;UC5LO,wBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;AAAA;AAAA,iBAGK,sBAAA,CACd,MAAA,WAAiB,wBAAA;;;cCKN,aAAA,EAAe,OAAA;AAAA,cAatB,MAAA,EAAQ,WAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -710,7 +710,7 @@ async function getWorkspacePackageVersion(packagePathSegments, fallback, options
|
|
|
710
710
|
const packageRoot = findPackageRoot();
|
|
711
711
|
const packagesRoot = path.join(packageRoot, "..", "..");
|
|
712
712
|
const targetPackageRoot = path.join(packagesRoot, ...packagePathSegments);
|
|
713
|
-
if (options.local) return `
|
|
713
|
+
if (options.local) return `link:${(options.targetPath ? path.relative(options.targetPath, targetPackageRoot) : targetPackageRoot).replace(/\\/g, "/") || "."}`;
|
|
714
714
|
const content = await readFile(path.join(targetPackageRoot, "package.json"), "utf-8");
|
|
715
715
|
return `^${JSON.parse(content).version ?? fallback.replace(/^\^/, "")}`;
|
|
716
716
|
} catch {
|
|
@@ -728,7 +728,10 @@ async function getFiles(dir, baseDir = dir) {
|
|
|
728
728
|
return files;
|
|
729
729
|
}
|
|
730
730
|
function renderTemplate(content, variables) {
|
|
731
|
-
return content.replace(/{{\s
|
|
731
|
+
return content.replace(/{{\s*#if\s+([a-zA-Z0-9_]+)\s*}}([\s\S]*?){{\s*\/if\s*}}/g, (match, key, block) => {
|
|
732
|
+
if (!isTemplateVariableKey(key)) return match;
|
|
733
|
+
return variables[key] ? String(block) : "";
|
|
734
|
+
}).replace(/{{\s*([a-zA-Z0-9_]+)\s*}}/g, (match, key) => {
|
|
732
735
|
if (isTemplateVariableKey(key)) return variables[key] ?? "";
|
|
733
736
|
return match;
|
|
734
737
|
});
|
|
@@ -739,7 +742,7 @@ function isTemplateVariableKey(key) {
|
|
|
739
742
|
"widgetScope",
|
|
740
743
|
"widgetPackageVersion",
|
|
741
744
|
"sdkVersion",
|
|
742
|
-
"
|
|
745
|
+
"localCoreVersion",
|
|
743
746
|
"fluidCliVersion",
|
|
744
747
|
"widgetCliVersion",
|
|
745
748
|
"droplet"
|
|
@@ -799,7 +802,7 @@ async function createWidgetProject(projectName, options) {
|
|
|
799
802
|
widgetScope,
|
|
800
803
|
widgetPackageVersion: options.packageVersion ?? DEFAULT_WIDGET_PACKAGE_VERSION,
|
|
801
804
|
sdkVersion: await getPortalSdkVersion(localOptions),
|
|
802
|
-
|
|
805
|
+
localCoreVersion: options.local ? await getPortalCoreVersion(localOptions) : void 0,
|
|
803
806
|
fluidCliVersion: await getCliVersion(localOptions),
|
|
804
807
|
widgetCliVersion: await getWidgetCliVersion(localOptions)
|
|
805
808
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["isNodeError","isRecord","isRecord","readPackageJson","isRecord","isRecord","isRecord","resolveDroplet"],"sources":["../src/utils/config.ts","../src/utils/validation.ts","../src/utils/source-package.ts","../src/utils/command.ts","../src/utils/package-manager.ts","../src/utils/package-scripts.ts","../src/commands/build.ts","../src/utils/template.ts","../src/commands/create.ts","../src/commands/dev.ts","../src/utils/auth-client.ts","../src/utils/droplets.ts","../src/commands/link.ts","../src/utils/droplet-api.ts","../src/commands/logs.ts","../src/commands/publish.ts","../src/commands/status.ts","../src/commands/validate.ts","../src/index.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const WIDGET_CONFIG_FILE = \"fluid.widget.config.ts\";\n\nexport interface FluidWidgetConfig {\n readonly droplet?: string;\n}\n\nexport interface LoadedWidgetConfig {\n readonly path: string;\n readonly config: Partial<FluidWidgetConfig>;\n}\n\nexport class WidgetConfigParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WidgetConfigParseError\";\n }\n}\n\nexport function resolveWidgetConfigPath(projectDir: string): string {\n return path.join(projectDir, WIDGET_CONFIG_FILE);\n}\n\nexport async function loadWidgetConfig(\n projectDir: string,\n): Promise<LoadedWidgetConfig> {\n const configPath = resolveWidgetConfigPath(projectDir);\n\n let source: string;\n try {\n source = await readFile(configPath, \"utf-8\");\n } catch (err) {\n if (isNodeError(err) && err.code === \"ENOENT\") {\n return { path: configPath, config: {} };\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to read ${WIDGET_CONFIG_FILE}: ${message}`);\n }\n\n return { path: configPath, config: parseWidgetConfigSource(source) };\n}\n\nexport async function writeWidgetConfig(\n projectDir: string,\n config: FluidWidgetConfig,\n): Promise<void> {\n await writeFile(\n resolveWidgetConfigPath(projectDir),\n formatWidgetConfig(config),\n \"utf-8\",\n );\n}\n\nexport function formatWidgetConfig(config: FluidWidgetConfig): string {\n const lines = [\n 'import type { FluidWidgetConfig } from \"@fluid-app/fluid-cli-widget\";',\n \"\",\n \"const config = {\",\n ];\n\n if (config.droplet) {\n lines.push(` droplet: ${JSON.stringify(config.droplet)},`);\n }\n\n lines.push(\n \"} satisfies FluidWidgetConfig;\",\n \"\",\n \"const widgetConfig: FluidWidgetConfig = config;\",\n \"\",\n \"export default config;\",\n \"export const droplet = widgetConfig.droplet;\",\n 'export { widgetPackage, widgetPackages } from \"./manifest\";',\n \"\",\n );\n return lines.join(\"\\n\");\n}\n\nexport function parseWidgetConfigSource(\n source: string,\n): Partial<FluidWidgetConfig> {\n const objectSource = extractConfigObjectLiteral(source);\n const config = parseConfigObjectProperties(objectSource);\n\n return config;\n}\n\nexport function mergeWidgetConfig(\n current: Partial<FluidWidgetConfig>,\n updates: Partial<FluidWidgetConfig>,\n): FluidWidgetConfig {\n const droplet =\n normalizeOptionalString(updates.droplet) ??\n normalizeOptionalString(current.droplet);\n\n return droplet ? { droplet } : {};\n}\n\nexport function validateDropletUuid(dropletUuid: string): string | undefined {\n if (!dropletUuid) return \"Droplet UUID is required.\";\n if (dropletUuid.length > MAX_DROPLET_UUID_LENGTH) {\n return `Droplet UUID must be ${MAX_DROPLET_UUID_LENGTH} characters or fewer.`;\n }\n if (!URL_SAFE_IDENTIFIER_PATTERN.test(dropletUuid)) {\n return (\n \"Droplet UUID must be URL-safe text: letters, numbers, \" +\n \"'_', '~', and '-' only.\"\n );\n }\n return undefined;\n}\n\nfunction extractConfigObjectLiteral(source: string): string {\n const configStart = /\\bconst\\s+config\\s*=\\s*\\{/.exec(source);\n if (!configStart) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} must declare \\`const config = { ... } satisfies FluidWidgetConfig\\`.`,\n );\n }\n\n const openBraceIndex = source.indexOf(\"{\", configStart.index);\n const closeBraceIndex = findMatchingBrace(source, openBraceIndex);\n const suffix = stripComments(source.slice(closeBraceIndex + 1));\n if (!/^\\s*(?:as\\s+const\\s+)?satisfies\\s+FluidWidgetConfig\\s*;/.test(suffix)) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config object must use \\`satisfies FluidWidgetConfig\\` or \\`as const satisfies FluidWidgetConfig\\`.`,\n );\n }\n\n return stripComments(source.slice(openBraceIndex + 1, closeBraceIndex));\n}\n\nfunction parseConfigObjectProperties(\n objectSource: string,\n): Partial<FluidWidgetConfig> {\n const config: { droplet?: string } = {};\n\n for (const member of splitTopLevelMembers(objectSource)) {\n const trimmedMember = member.trim();\n if (!trimmedMember) continue;\n\n const propertyMatch = /^(droplet)\\s*:\\s*([\\s\\S]+)$/.exec(trimmedMember);\n if (!propertyMatch) {\n const propertyName = /^([A-Za-z_$][\\w$]*)\\s*:/.exec(trimmedMember)?.[1];\n throw new WidgetConfigParseError(\n propertyName\n ? `${WIDGET_CONFIG_FILE} does not support config field ${propertyName}. Supported field is droplet.`\n : `${WIDGET_CONFIG_FILE} config fields must use optional droplet: \"...\" string literal.`,\n );\n }\n\n const propertyName = propertyMatch[1];\n if (propertyName !== \"droplet\") {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config field could not be parsed.`,\n );\n }\n const valueSource = propertyMatch[2]?.trim() ?? \"\";\n const value = parseStringLiteralValue(valueSource, propertyName);\n if (!value.trim()) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field ${propertyName} must be a non-empty string literal.`,\n );\n }\n\n if (config.droplet !== undefined) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field droplet must only be declared once.`,\n );\n }\n config.droplet = value;\n }\n\n return config;\n}\n\nfunction parseStringLiteralValue(\n valueSource: string,\n propertyName: string,\n): string {\n if (valueSource.startsWith('\"') && valueSource.endsWith('\"')) {\n try {\n const parsed = JSON.parse(valueSource) as unknown;\n if (typeof parsed === \"string\") return parsed;\n } catch {\n // Fall through to the actionable error below.\n }\n }\n\n if (valueSource.startsWith(\"'\") && valueSource.endsWith(\"'\")) {\n return parseSingleQuotedStringLiteral(valueSource);\n }\n\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field ${propertyName} must be a string literal (for example ${propertyName}: \"value\").`,\n );\n}\n\nfunction parseSingleQuotedStringLiteral(valueSource: string): string {\n let value = \"\";\n\n for (let index = 1; index < valueSource.length - 1; index += 1) {\n const char = valueSource[index];\n if (char !== \"\\\\\") {\n value += char;\n continue;\n }\n\n index += 1;\n const escaped = valueSource[index];\n switch (escaped) {\n case \"\\\\\":\n case \"'\":\n case '\"':\n value += escaped;\n break;\n case \"n\":\n value += \"\\n\";\n break;\n case \"r\":\n value += \"\\r\";\n break;\n case \"t\":\n value += \"\\t\";\n break;\n case \"b\":\n value += \"\\b\";\n break;\n case \"f\":\n value += \"\\f\";\n break;\n case \"v\":\n value += \"\\v\";\n break;\n default:\n value += escaped ?? \"\";\n break;\n }\n }\n\n return value;\n}\n\nfunction stripComments(source: string): string {\n let result = \"\";\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let lineComment = false;\n let blockComment = false;\n\n for (let index = 0; index < source.length; index += 1) {\n const char = source[index];\n const nextChar = source[index + 1];\n\n if (lineComment) {\n if (char === \"\\n\" || char === \"\\r\") {\n lineComment = false;\n result += char;\n } else {\n result += \" \";\n }\n continue;\n }\n\n if (blockComment) {\n if (char === \"*\" && nextChar === \"/\") {\n blockComment = false;\n result += \" \";\n index += 1;\n } else if (char === \"\\n\" || char === \"\\r\") {\n result += char;\n } else {\n result += \" \";\n }\n continue;\n }\n\n if (stringQuote) {\n result += char;\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === \"/\" && nextChar === \"/\") {\n lineComment = true;\n result += \" \";\n index += 1;\n continue;\n }\n\n if (char === \"/\" && nextChar === \"*\") {\n blockComment = true;\n result += \" \";\n index += 1;\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n }\n result += char;\n }\n\n return result;\n}\n\nfunction splitTopLevelMembers(objectSource: string): string[] {\n const members: string[] = [];\n let memberStart = 0;\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let nestedDepth = 0;\n\n for (let index = 0; index < objectSource.length; index += 1) {\n const char = objectSource[index];\n\n if (stringQuote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n continue;\n }\n\n if (char === \"{\" || char === \"[\" || char === \"(\") {\n nestedDepth += 1;\n continue;\n }\n if (char === \"}\" || char === \"]\" || char === \")\") {\n nestedDepth -= 1;\n continue;\n }\n\n if (char === \",\" && nestedDepth === 0) {\n members.push(objectSource.slice(memberStart, index));\n memberStart = index + 1;\n }\n }\n\n members.push(objectSource.slice(memberStart));\n return members;\n}\n\nfunction findMatchingBrace(source: string, openBraceIndex: number): number {\n let depth = 0;\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let lineComment = false;\n let blockComment = false;\n\n for (let index = openBraceIndex; index < source.length; index += 1) {\n const char = source[index];\n const nextChar = source[index + 1];\n\n if (lineComment) {\n if (char === \"\\n\" || char === \"\\r\") lineComment = false;\n continue;\n }\n\n if (blockComment) {\n if (char === \"*\" && nextChar === \"/\") {\n blockComment = false;\n index += 1;\n }\n continue;\n }\n\n if (stringQuote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === \"/\" && nextChar === \"/\") {\n lineComment = true;\n index += 1;\n continue;\n }\n\n if (char === \"/\" && nextChar === \"*\") {\n blockComment = true;\n index += 1;\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n continue;\n }\n\n if (char === \"{\") depth += 1;\n if (char === \"}\") {\n depth -= 1;\n if (depth === 0) return index;\n }\n }\n\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config object is missing a closing brace.`,\n );\n}\n\nfunction normalizeOptionalString(\n value: string | undefined,\n): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\ninterface NodeError extends Error {\n readonly code?: string;\n}\n\nfunction isNodeError(error: unknown): error is NodeError {\n return error instanceof Error && \"code\" in error;\n}\n\nconst MAX_DROPLET_UUID_LENGTH = 256;\nconst URL_SAFE_SEGMENT_SOURCE = \"[A-Za-z0-9][A-Za-z0-9_~-]*\";\nconst URL_SAFE_IDENTIFIER_PATTERN = new RegExp(`^${URL_SAFE_SEGMENT_SOURCE}$`);\n","export interface WidgetCliValidationError {\n readonly path?: string;\n readonly message: string;\n}\n\nexport function formatValidationErrors(\n errors: readonly WidgetCliValidationError[],\n): string {\n if (errors.length === 0) return \"Validation failed.\";\n\n return [\n \"Validation failed:\",\n ...errors.map((error) => {\n const location = error.path ? `${error.path}: ` : \"\";\n return ` - ${location}${error.message}`;\n }),\n ].join(\"\\n\");\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, rm, rmdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n loadSourceWidgetPackages,\n validateSingleSourceWidgetPackage,\n} from \"@fluid-app/fluid-cli-portal\";\nimport {\n WIDGET_CONFIG_FILE,\n loadWidgetConfig,\n validateDropletUuid,\n} from \"./config.js\";\nimport type {\n ValidatedWidgetPackageBuild,\n WidgetPackageValidationError,\n} from \"@fluid-app/fluid-cli-portal\";\nimport { formatValidationErrors } from \"./validation.js\";\n\nexport const DEFAULT_WIDGET_OUT_DIR = \".fluid/widget-dist\";\nexport const ROOT_WIDGET_CONFIG_FILE: string = WIDGET_CONFIG_FILE;\n\nconst SOURCE_CONFIG_CANDIDATES = [\n \"src/widgets.config.ts\",\n \"src/portal.config.ts\",\n \"portal.config.ts\",\n] as const;\n\nexport interface WidgetValidationResult {\n readonly projectDir: string;\n readonly sourceConfigPath?: string;\n readonly validated: ValidatedWidgetPackageBuild;\n}\n\nexport class WidgetValidationError extends Error {\n public readonly errors: readonly WidgetPackageValidationError[];\n\n constructor(errors: readonly WidgetPackageValidationError[]) {\n super(formatValidationErrors(errors));\n this.name = \"WidgetValidationError\";\n this.errors = errors;\n }\n}\n\nexport async function validateDropletWidgetProject(\n projectDir: string,\n packageKeyOverride?: string,\n): Promise<WidgetValidationResult> {\n const resolvedProjectDir = path.resolve(projectDir);\n const sourceConfig = resolveWidgetSourceConfig(resolvedProjectDir);\n if (!sourceConfig) {\n throw new WidgetValidationError([\n {\n code: \"NO_SOURCE_PACKAGE\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message:\n `No widget package config found. Create ${ROOT_WIDGET_CONFIG_FILE} ` +\n \"or src/widgets.config.ts that exports defineWidgetPackage(...).\",\n },\n ]);\n }\n\n const configErrors = await validateRootWidgetConfig(\n resolvedProjectDir,\n packageKeyOverride,\n );\n if (configErrors.length > 0) {\n throw new WidgetValidationError(configErrors);\n }\n\n const sourcePackages = await withRootWidgetConfigBridge(\n resolvedProjectDir,\n async () => {\n const loadResult = await loadSourceWidgetPackages(resolvedProjectDir);\n if (!loadResult.success) {\n throw new WidgetValidationError([\n {\n code: \"INVALID_SOURCE_PACKAGE\",\n path: sourceConfig.relativePath,\n message: appendDetails(\n loadResult.error.message,\n loadResult.error.details,\n ),\n },\n ]);\n }\n return loadResult.value;\n },\n packageKeyOverride,\n );\n\n const validation = validateSingleSourceWidgetPackage(sourcePackages, {\n owner: \"droplet\",\n });\n const errors = [\n ...validation.errors,\n ...validateDropletMetadata(sourcePackages),\n ];\n\n if (!validation.success || !validation.value || errors.length > 0) {\n throw new WidgetValidationError(errors);\n }\n\n return {\n projectDir: resolvedProjectDir,\n sourceConfigPath: sourceConfig.relativePath,\n validated: validation.value,\n };\n}\n\nexport async function withRootWidgetConfigBridge<T>(\n projectDir: string,\n callback: () => Promise<T>,\n packageKeyOverride?: string,\n): Promise<T> {\n const rootConfigPath = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (!existsSync(rootConfigPath) || resolvePortalSourceConfig(projectDir)) {\n return callback();\n }\n\n const packageKey =\n packageKeyOverride?.trim() ||\n (await loadWidgetConfig(projectDir)).config.droplet;\n if (!packageKey) {\n throw new Error(\n \"fluid.widget.config.ts must set droplet before validating, building, or publishing.\",\n );\n }\n\n const srcDir = path.join(projectDir, \"src\");\n const bridgePath = path.join(srcDir, \"widgets.config.ts\");\n const srcDirExisted = existsSync(srcDir);\n await mkdir(srcDir, { recursive: true });\n try {\n await writeFile(\n bridgePath,\n createRootWidgetConfigBridgeSource(packageKey),\n {\n encoding: \"utf-8\",\n flag: \"wx\",\n },\n );\n } catch (err) {\n if (isNodeError(err) && err.code === \"EEXIST\") {\n throw new Error(\n `${path.relative(projectDir, bridgePath)} already exists. ` +\n \"Remove this stale Fluid widget CLI bridge file and try again.\",\n );\n }\n throw err;\n }\n\n try {\n return await callback();\n } finally {\n await rm(bridgePath, { force: true }).catch(() => {});\n if (!srcDirExisted) await rmdir(srcDir).catch(() => {});\n }\n}\n\nfunction createRootWidgetConfigBridgeSource(packageKey: string): string {\n return `import { widgetPackage as sourceWidgetPackage } from \"../manifest\";\n\nconst packageKey = ${JSON.stringify(packageKey)};\nconst packageId = sourceWidgetPackage.scope + \".\" + packageKey;\n\nexport const widgetPackage = {\n ...sourceWidgetPackage,\n packageStableId: packageKey,\n packageId,\n};\n\nexport const widgetPackages = [widgetPackage] as const;\nexport default widgetPackage;\n`;\n}\n\nexport function resolveWidgetSourceConfig(\n projectDir: string,\n): { readonly path: string; readonly relativePath: string } | undefined {\n const rootConfig = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (existsSync(rootConfig)) {\n return { path: rootConfig, relativePath: ROOT_WIDGET_CONFIG_FILE };\n }\n\n return resolvePortalSourceConfig(projectDir);\n}\n\nexport function formatValidationSuccess(\n result: WidgetValidationResult,\n): string {\n return [\n \"Widget package is valid.\",\n `Config: ${result.sourceConfigPath ?? \"unknown\"}`,\n `Package: ${result.validated.packageId}`,\n `Version: ${result.validated.version}`,\n `Widgets: ${result.validated.widgets.length}`,\n ].join(\"\\n\");\n}\n\nasync function validateRootWidgetConfig(\n projectDir: string,\n packageKeyOverride?: string,\n): Promise<WidgetPackageValidationError[]> {\n const configPath = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (!existsSync(configPath)) return [];\n\n try {\n const loaded = await loadWidgetConfig(projectDir);\n const droplet = packageKeyOverride ?? loaded.config.droplet ?? \"\";\n const packageKeyError = validateDropletUuid(droplet);\n if (!packageKeyError) return [];\n\n return [\n {\n code: \"INVALID_PACKAGE_KEY\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message: packageKeyError,\n },\n ];\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return [\n {\n code: \"INVALID_SOURCE_PACKAGE\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message,\n },\n ];\n }\n}\n\nfunction validateDropletMetadata(\n sourcePackages: readonly unknown[],\n): WidgetPackageValidationError[] {\n if (sourcePackages.length !== 1) return [];\n\n const sourcePackage = sourcePackages[0];\n if (!isRecord(sourcePackage)) return [];\n\n const errors: WidgetPackageValidationError[] = [];\n if (sourcePackage[\"packageType\"] !== \"droplet\") {\n errors.push({\n code: \"UNSUPPORTED_OWNER\",\n path: \"packageType\",\n message:\n 'Droplet widget packages must set packageType: \"droplet\" in package metadata.',\n });\n }\n\n if (!isNonEmptyString(sourcePackage[\"packageStableId\"])) {\n errors.push({\n code: \"INVALID_PACKAGE_KEY\",\n path: \"packageStableId\",\n message:\n \"Droplet widget packages must set packageStableId so published widget types remain stable across builds.\",\n });\n }\n\n const widgets = sourcePackage[\"widgets\"];\n if (Array.isArray(widgets)) {\n widgets.forEach((widget, index) => {\n if (!isRecord(widget)) return;\n validateJsonSerializable(\n widget[\"propertySchema\"],\n `widgets[${index}].propertySchema`,\n errors,\n );\n validateJsonSerializable(\n widget[\"defaultProps\"],\n `widgets[${index}].defaultProps`,\n errors,\n );\n });\n }\n\n return errors;\n}\n\nfunction resolvePortalSourceConfig(\n projectDir: string,\n): { readonly path: string; readonly relativePath: string } | undefined {\n for (const relativePath of SOURCE_CONFIG_CANDIDATES) {\n const candidate = path.join(projectDir, relativePath);\n if (existsSync(candidate)) return { path: candidate, relativePath };\n }\n\n return undefined;\n}\n\nfunction validateJsonSerializable(\n value: unknown,\n pathLabel: string,\n errors: WidgetPackageValidationError[],\n): void {\n if (value === undefined) return;\n\n try {\n assertJsonSerializable(value, pathLabel);\n } catch (err) {\n errors.push({\n code: \"INVALID_WIDGET_METADATA\",\n path: pathLabel,\n message: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\nfunction assertJsonSerializable(value: unknown, pathLabel: string): void {\n if (value === null) return;\n\n const valueType = typeof value;\n if (valueType === \"string\" || valueType === \"boolean\") return;\n if (valueType === \"number\") {\n if (Number.isFinite(value)) return;\n throw new Error(`${pathLabel} must not contain NaN or Infinity.`);\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n assertJsonSerializable(item, `${pathLabel}[${index}]`);\n });\n return;\n }\n if (isRecord(value)) {\n for (const [key, item] of Object.entries(value)) {\n if (item === undefined) {\n throw new Error(`${pathLabel}.${key} must not be undefined.`);\n }\n assertJsonSerializable(item, `${pathLabel}.${key}`);\n }\n return;\n }\n\n throw new Error(`${pathLabel} must contain only JSON-serializable values.`);\n}\n\nfunction appendDetails(message: string, details: string | undefined): string {\n return details ? `${message}\\n${details}` : message;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\ninterface NodeError extends Error {\n readonly code?: string;\n}\n\nfunction isNodeError(error: unknown): error is NodeError {\n return error instanceof Error && \"code\" in error;\n}\n","import chalk from \"chalk\";\n\nexport async function runCliAction(action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (err) {\n console.error(chalk.red(\"Error:\") + \" \" + formatUnknownError(err));\n process.exit(1);\n }\n}\n\nexport function formatUnknownError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"bun\" | \"npm\";\n\nexport function getRunCommand(\n script: string,\n cwd: string = process.cwd(),\n): string {\n return `${detectPackageManager(cwd)} run ${script}`;\n}\n\nexport function getInstallCommand(cwd: string = process.cwd()): string {\n return `${detectPackageManager(cwd)} install`;\n}\n\nexport async function installDependencies(cwd: string): Promise<void> {\n const packageManager = detectPackageManager(cwd);\n await runPackageManager(packageManager, [\"install\"], cwd);\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n if (existsSync(path.join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(path.join(cwd, \"yarn.lock\"))) return \"yarn\";\n if (existsSync(path.join(cwd, \"bun.lockb\"))) return \"bun\";\n if (existsSync(path.join(cwd, \"package-lock.json\"))) return \"npm\";\n\n const invokingPackageManager = readInvokingPackageManager();\n if (invokingPackageManager) return invokingPackageManager;\n\n const declaredPackageManager = readDeclaredPackageManager(cwd);\n if (declaredPackageManager && isCommandAvailable(declaredPackageManager)) {\n return declaredPackageManager;\n }\n\n return findAvailablePackageManager() ?? \"pnpm\";\n}\n\nfunction runPackageManager(\n command: PackageManager,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, [...args], {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n\n child.once(\"error\", (error: Error) => {\n reject(error);\n });\n\n child.once(\"exit\", (code: number | null) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n `${command} ${args.join(\" \")} exited with code ${code ?? \"unknown\"}`,\n ),\n );\n });\n });\n}\n\nfunction readInvokingPackageManager(): PackageManager | undefined {\n const userAgent = process.env[\"npm_config_user_agent\"];\n if (!userAgent) return undefined;\n\n const name = userAgent.split(\"/\")[0];\n if (isPackageManager(name)) return name;\n return undefined;\n}\n\nfunction readDeclaredPackageManager(cwd: string): PackageManager | undefined {\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!existsSync(packageJsonPath)) return undefined;\n\n try {\n const packageJson = JSON.parse(\n readFileSync(packageJsonPath, \"utf-8\"),\n ) as unknown;\n if (!isRecord(packageJson)) return undefined;\n\n const packageManager = packageJson[\"packageManager\"];\n if (typeof packageManager !== \"string\") return undefined;\n\n const name = packageManager.split(\"@\")[0];\n if (isPackageManager(name)) return name;\n } catch {\n // Malformed package.json is reported by command paths that need to parse it.\n }\n\n return undefined;\n}\n\nfunction findAvailablePackageManager(): PackageManager | undefined {\n for (const packageManager of [\"pnpm\", \"yarn\", \"bun\", \"npm\"] as const) {\n if (isCommandAvailable(packageManager)) return packageManager;\n }\n return undefined;\n}\n\nfunction isCommandAvailable(command: PackageManager): boolean {\n const result = spawnSync(command, [\"--version\"], {\n shell: process.platform === \"win32\",\n stdio: \"ignore\",\n });\n return result.status === 0;\n}\n\nfunction isPackageManager(value: string | undefined): value is PackageManager {\n return (\n value === \"pnpm\" || value === \"yarn\" || value === \"bun\" || value === \"npm\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { detectPackageManager } from \"./package-manager.js\";\n\nexport interface PackageScriptRunResult {\n readonly ran: boolean;\n readonly command?: string;\n}\n\nexport async function runPackageScriptIfAvailable(options: {\n readonly projectDir: string;\n readonly scriptName: string;\n}): Promise<PackageScriptRunResult> {\n const packageJsonPath = path.join(options.projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return { ran: false };\n\n const packageJson = await readPackageJson(packageJsonPath);\n if (!hasPackageScript(packageJson, options.scriptName)) return { ran: false };\n\n const packageManager = detectPackageManager(options.projectDir);\n const args = [\"run\", options.scriptName];\n await runCommand(packageManager, args, options.projectDir);\n\n return {\n ran: true,\n command: `${packageManager} ${args.join(\" \")}`,\n };\n}\n\nfunction runCommand(\n command: string,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n env: process.env,\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `${command} ${args.join(\" \")} exited with signal ${signal}.`\n : `${command} ${args.join(\" \")} exited with code ${code ?? \"unknown\"}.`,\n ),\n );\n });\n });\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<unknown> {\n const source = await readFile(packageJsonPath, \"utf-8\");\n try {\n return JSON.parse(source) as unknown;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to parse package.json: ${message}`);\n }\n}\n\nfunction hasPackageScript(value: unknown, scriptName: string): boolean {\n if (!isRecord(value)) return false;\n const scripts = value[\"scripts\"];\n if (!isRecord(scripts)) return false;\n return typeof scripts[scriptName] === \"string\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Command } from \"commander\";\nimport {\n buildSharedWidgetPackage,\n validateWidgetPublishOutDir,\n} from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n DEFAULT_WIDGET_OUT_DIR,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n} from \"../utils/source-package.js\";\nimport { runCliAction } from \"../utils/command.js\";\nimport { runPackageScriptIfAvailable } from \"../utils/package-scripts.js\";\n\nexport interface BuildWidgetOptions {\n readonly outDir?: string;\n readonly skipTypecheck?: boolean;\n}\n\nexport interface BuildWidgetPackageOptions {\n readonly projectDir: string;\n readonly outDir: string;\n readonly skipTypecheck?: boolean;\n}\n\nexport interface BuildWidgetPackageResult {\n readonly outDir: string;\n readonly packageId: string;\n readonly version: string;\n}\n\nexport async function buildWidgetPackage(\n options: BuildWidgetPackageOptions,\n): Promise<BuildWidgetPackageResult> {\n await validateDropletWidgetProject(options.projectDir);\n\n if (options.skipTypecheck !== true) {\n await runPackageScriptIfAvailable({\n projectDir: options.projectDir,\n scriptName: \"typecheck\",\n });\n }\n\n const outDir = validateWidgetPublishOutDir(\n options.projectDir,\n options.outDir,\n );\n const buildResult = await withRootWidgetConfigBridge(options.projectDir, () =>\n buildSharedWidgetPackage({\n projectDir: options.projectDir,\n publishDir: outDir,\n owner: \"droplet\",\n }),\n );\n\n if (!buildResult.success) {\n const details = buildResult.error.details\n ? `\\n${buildResult.error.details}`\n : \"\";\n throw new Error(`${buildResult.error.message}${details}`);\n }\n\n return {\n outDir: buildResult.value.publishDir,\n packageId: buildResult.value.packageId,\n version: buildResult.value.version,\n };\n}\n\nexport const buildCommand: Command = new Command(\"build\")\n .description(\"Validate and build the current droplet widget package\")\n .option(\n \"-o, --out-dir <dir>\",\n \"Widget artifact output directory\",\n DEFAULT_WIDGET_OUT_DIR,\n )\n .option(\"--skip-typecheck\", \"Skip package typecheck script when present\")\n .action((options: BuildWidgetOptions) => {\n return runCliAction(async () => {\n const outDir = options.outDir ?? DEFAULT_WIDGET_OUT_DIR;\n console.log(chalk.blue.bold(\"Building Fluid widget package\"));\n console.log();\n\n const spinner = ora(\n \"Validating and building widget artifacts...\",\n ).start();\n const result = await buildWidgetPackage({\n projectDir: process.cwd(),\n outDir,\n skipTypecheck: options.skipTypecheck,\n });\n spinner.succeed(\"Built widget runtime artifacts\");\n\n console.log();\n console.log(chalk.gray(\"Package: \") + chalk.white(result.packageId));\n console.log(chalk.gray(\"Version: \") + chalk.white(result.version));\n console.log(chalk.gray(\"Output: \") + chalk.cyan(outDir));\n });\n });\n","import { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { WidgetTemplateVariables } from \"../types.js\";\n\nexport function getDefaultTemplatePath(): string {\n return path.join(findPackageRoot(), \"templates\", \"default\");\n}\n\nexport async function directoryExists(filePath: string): Promise<boolean> {\n try {\n const stats = await stat(filePath);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function copyWidgetTemplate(\n templatePath: string,\n targetPath: string,\n variables: WidgetTemplateVariables,\n): Promise<void> {\n const files = await getFiles(templatePath);\n\n for (const file of files) {\n const sourcePath = path.join(templatePath, file);\n const outputFile = getOutputFilename(file);\n const destinationPath = path.join(targetPath, outputFile);\n\n await mkdir(path.dirname(destinationPath), { recursive: true });\n\n const content = await readFile(sourcePath, \"utf-8\");\n const processed = renderTemplate(content, variables);\n await writeFile(destinationPath, processed, \"utf-8\");\n }\n}\n\nexport async function getPortalSdkVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"portal\", \"sdk\"], \"^0.1.0\", options);\n}\n\nexport async function getPortalCoreVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"portal\", \"core\"], \"^0.1.0\", options);\n}\n\nexport async function getCliVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"cli\", \"core\"], \"^0.1.0\", options);\n}\n\nexport async function getWidgetCliVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"cli\", \"widget\"], \"^0.1.0\", options);\n}\n\nasync function getWorkspacePackageVersion(\n packagePathSegments: readonly string[],\n fallback: string,\n options: { readonly local?: boolean; readonly targetPath?: string },\n): Promise<string> {\n try {\n const packageRoot = findPackageRoot();\n const packagesRoot = path.join(packageRoot, \"..\", \"..\");\n const targetPackageRoot = path.join(packagesRoot, ...packagePathSegments);\n\n if (options.local) {\n const linkPath = options.targetPath\n ? path.relative(options.targetPath, targetPackageRoot)\n : targetPackageRoot;\n return `file:${linkPath || \".\"}`;\n }\n\n const packageJsonPath = path.join(targetPackageRoot, \"package.json\");\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return `^${pkg.version ?? fallback.replace(/^\\^/, \"\")}`;\n } catch {\n return fallback;\n }\n}\n\nasync function getFiles(dir: string, baseDir = dir): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await getFiles(fullPath, baseDir)));\n } else {\n files.push(path.relative(baseDir, fullPath));\n }\n }\n\n return files;\n}\n\nfunction renderTemplate(\n content: string,\n variables: WidgetTemplateVariables,\n): string {\n return content.replace(/{{\\s*([a-zA-Z0-9_]+)\\s*}}/g, (match, key) => {\n if (isTemplateVariableKey(key)) return variables[key] ?? \"\";\n return match;\n });\n}\n\nfunction isTemplateVariableKey(\n key: string,\n): key is keyof WidgetTemplateVariables {\n return [\n \"projectName\",\n \"widgetScope\",\n \"widgetPackageVersion\",\n \"sdkVersion\",\n \"coreVersion\",\n \"fluidCliVersion\",\n \"widgetCliVersion\",\n \"droplet\",\n ].includes(key);\n}\n\nfunction getOutputFilename(filename: string): string {\n return filename.endsWith(\".template\")\n ? filename.slice(0, -\".template\".length)\n : filename;\n}\n\nfunction findPackageRoot(): string {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (!existsSync(path.join(dir, \"package.json\"))) {\n const parent = path.dirname(dir);\n if (parent === dir)\n throw new Error(\"Could not find widget CLI package root\");\n dir = parent;\n }\n return dir;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport path from \"node:path\";\nimport type { WidgetCreateOptions } from \"../types.js\";\nimport {\n copyWidgetTemplate,\n directoryExists,\n getCliVersion,\n getDefaultTemplatePath,\n getPortalCoreVersion,\n getPortalSdkVersion,\n getWidgetCliVersion,\n} from \"../utils/template.js\";\nimport {\n getInstallCommand,\n getRunCommand,\n installDependencies,\n} from \"../utils/package-manager.js\";\nimport {\n mergeWidgetConfig,\n validateDropletUuid,\n writeWidgetConfig,\n} from \"../utils/config.js\";\n\nconst DEFAULT_WIDGET_PACKAGE_VERSION = \"0.1.0\";\nconst DEFAULT_WIDGET_SCOPE = \"droplet\";\n\nexport const createCommand: Command = new Command(\"create\")\n .description(\"Create a standalone Fluid widget project\")\n .argument(\"<project-name>\", \"Name of the widget project to create\")\n .option(\"--skip-install\", \"Skip dependency installation\")\n .option(\n \"-o, --output-dir <dir>\",\n \"Directory to create the project in (defaults to cwd)\",\n )\n .option(\n \"--scope <scope>\",\n \"Widget package scope/namespace\",\n DEFAULT_WIDGET_SCOPE,\n )\n .option(\n \"--package-version <version>\",\n \"Initial widget package version\",\n DEFAULT_WIDGET_PACKAGE_VERSION,\n )\n .option(\n \"--local\",\n \"Use local monorepo packages via file: links (for development testing)\",\n )\n .option(\"--droplet <uuid>\", \"Existing droplet UUID that owns the package\")\n .action(async (projectName: string, options: WidgetCreateOptions) => {\n try {\n await createWidgetProject(projectName, options);\n } catch (err) {\n console.log();\n console.error(\n chalk.red(\"Error:\") +\n \" \" +\n (err instanceof Error ? err.message : String(err)),\n );\n console.log();\n process.exit(1);\n }\n });\n\nexport async function createWidgetProject(\n projectName: string,\n options: WidgetCreateOptions,\n): Promise<void> {\n console.log();\n console.log(chalk.bold(\"Creating a new Fluid widget project\"));\n console.log();\n\n const projectNameError = validateProjectName(projectName);\n if (projectNameError) throw new Error(projectNameError);\n\n const droplet = options.droplet?.trim();\n if (droplet) {\n const dropletError = validateDropletUuid(droplet);\n if (dropletError) throw new Error(dropletError);\n }\n\n const outputDir = path.resolve(options.outputDir ?? process.cwd());\n const targetPath = path.join(outputDir, projectName);\n if (await directoryExists(targetPath)) {\n throw new Error(`Directory already exists: ${targetPath}`);\n }\n\n const templatePath = getDefaultTemplatePath();\n if (!(await directoryExists(templatePath))) {\n throw new Error(\"Default widget template not found.\");\n }\n\n const config = mergeWidgetConfig({}, { droplet });\n const widgetScope = options.scope ?? DEFAULT_WIDGET_SCOPE;\n const localOptions = { local: options.local === true, targetPath };\n const variables = {\n projectName,\n droplet: config.droplet,\n widgetScope,\n widgetPackageVersion:\n options.packageVersion ?? DEFAULT_WIDGET_PACKAGE_VERSION,\n sdkVersion: await getPortalSdkVersion(localOptions),\n coreVersion: await getPortalCoreVersion(localOptions),\n fluidCliVersion: await getCliVersion(localOptions),\n widgetCliVersion: await getWidgetCliVersion(localOptions),\n };\n\n const spinner = ora(\"Copying widget template...\").start();\n try {\n await copyWidgetTemplate(templatePath, targetPath, variables);\n await writeWidgetConfig(targetPath, config);\n spinner.succeed(\"Copied widget template\");\n } catch (err) {\n spinner.fail(\"Failed to create widget project\");\n throw err;\n }\n\n const installCommand = getInstallCommand(targetPath);\n if (options.skipInstall !== true) {\n spinner.start(`Installing dependencies with ${installCommand}...`);\n try {\n await installDependencies(targetPath);\n spinner.succeed(\"Installed dependencies\");\n } catch {\n spinner.fail(\"Failed to install dependencies\");\n console.log();\n console.log(chalk.yellow(\"You can install dependencies manually:\"));\n console.log(chalk.cyan(` cd ${formatCdPath(targetPath)}`));\n console.log(chalk.cyan(` ${installCommand}`));\n }\n }\n\n console.log();\n console.log(\n chalk.green.bold(\"Success!\") + ` Created ${chalk.cyan(projectName)}`,\n );\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.cyan(` cd ${formatCdPath(targetPath)}`));\n if (options.skipInstall === true) {\n console.log(chalk.cyan(` ${installCommand}`));\n }\n if (!config.droplet) {\n console.log(chalk.cyan(\" fluid widget link\"));\n }\n console.log(chalk.cyan(` ${getRunCommand(\"dev\", targetPath)}`));\n console.log();\n console.log(\n \"Edit \" + chalk.cyan(\"manifest.ts\") + \" to customize your widget package.\",\n );\n console.log(\n chalk.dim(\n \"This command only creates local project files; it does not create a droplet.\",\n ),\n );\n console.log();\n}\n\nfunction validateProjectName(projectName: string): string | undefined {\n if (!projectName) return \"Project name is required.\";\n if (!/^[a-z0-9][a-z0-9-]*$/.test(projectName)) {\n return \"Project name must contain only lowercase letters, numbers, and hyphens.\";\n }\n return undefined;\n}\n\nfunction formatCdPath(targetPath: string): string {\n return path.relative(process.cwd(), targetPath) || \".\";\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport const DEFAULT_WIDGET_DEV_PORT = 5174;\n\nexport const WIDGET_DEV_ROUTES = [\n \"/\",\n \"/builder-preview\",\n \"/__manifests__\",\n \"/__preview__\",\n \"/__runtime-entry__\",\n] as const;\n\nexport interface WidgetDevOptions {\n readonly port?: string;\n readonly host?: boolean | string;\n readonly mode?: string;\n}\n\nexport interface WidgetDevProjectSummary {\n readonly projectDir: string;\n readonly packageName: string;\n readonly viteConfigPath: string;\n readonly localUrl: string;\n readonly target: string;\n readonly mode: string;\n readonly routes: readonly string[];\n}\n\nexport const devCommand: Command = new Command(\"dev\")\n .description(\"Start the local Fluid widget preview development server\")\n .option(\n \"-p, --port <port>\",\n \"Port to run the widget dev server on\",\n String(DEFAULT_WIDGET_DEV_PORT),\n )\n .option(\"--host [host]\", \"Expose the dev server to the network\")\n .option(\"--mode <mode>\", \"Vite mode to run\", \"development\")\n .action((options: WidgetDevOptions) => {\n return runCliAction(async () => {\n const projectDir = process.cwd();\n const summary = await resolveWidgetDevProject(projectDir, options);\n\n printWidgetDevSummary(summary);\n await runViteDevServer(projectDir, options);\n });\n });\n\nexport async function resolveWidgetDevProject(\n projectDir: string,\n options: WidgetDevOptions = {},\n): Promise<WidgetDevProjectSummary> {\n const resolvedProjectDir = path.resolve(projectDir);\n const packageJsonPath = path.join(resolvedProjectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n throw new Error(\n \"No package.json found. Run this command from a Fluid widget project directory.\",\n );\n }\n\n const packageJson = await readPackageJson(packageJsonPath);\n const packageName = readPackageName(packageJson) ?? path.basename(projectDir);\n\n const viteConfigPath = path.join(resolvedProjectDir, \"vite.config.ts\");\n if (!existsSync(viteConfigPath)) {\n throw new Error(\n \"No vite.config.ts found. Run this command from a Fluid widget project directory.\",\n );\n }\n\n const port = parsePort(options.port ?? String(DEFAULT_WIDGET_DEV_PORT));\n const host = normalizeHostOption(options.host);\n const mode = normalizeMode(options.mode);\n\n return {\n projectDir: resolvedProjectDir,\n packageName,\n viteConfigPath,\n localUrl: formatLocalUrl(port, host),\n target: packageName,\n mode,\n routes: WIDGET_DEV_ROUTES,\n };\n}\n\nexport function buildViteDevArgs(options: WidgetDevOptions = {}): string[] {\n const port = parsePort(options.port ?? String(DEFAULT_WIDGET_DEV_PORT));\n const host = normalizeHostOption(options.host);\n const mode = normalizeMode(options.mode);\n const args = [\"--port\", String(port), \"--mode\", mode];\n\n if (host) {\n args.push(\"--host\", host);\n }\n\n return args;\n}\n\nexport function printWidgetDevSummary(summary: WidgetDevProjectSummary): void {\n console.log();\n console.log(chalk.blue.bold(\"Fluid Widget Dev\"));\n console.log(chalk.gray(\"Local: \") + chalk.cyan(summary.localUrl));\n console.log(chalk.gray(\"Target: \") + chalk.white(summary.target));\n console.log(chalk.gray(\"Mode: \") + chalk.white(summary.mode));\n console.log(chalk.gray(\"Routes:\"));\n for (const route of summary.routes) {\n console.log(chalk.gray(\" - \") + chalk.cyan(route));\n }\n console.log();\n}\n\nexport async function runViteDevServer(\n projectDir: string,\n options: WidgetDevOptions = {},\n): Promise<void> {\n const viteCliPath = resolveViteCliPath(projectDir);\n if (!viteCliPath) {\n throw new Error(\n \"Unable to find Vite in node_modules. Run your package manager install command before starting widget dev.\",\n );\n }\n\n await runNodeScript(viteCliPath, buildViteDevArgs(options), projectDir);\n}\n\nfunction resolveViteCliPath(projectDir: string): string | undefined {\n const viteCliPath = path.join(\n projectDir,\n \"node_modules\",\n \"vite\",\n \"bin\",\n \"vite.js\",\n );\n return existsSync(viteCliPath) ? viteCliPath : undefined;\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(packageJsonPath, \"utf-8\")) as unknown;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to read package.json: ${message}`);\n }\n}\n\nfunction readPackageName(packageJson: unknown): string | undefined {\n if (!isRecord(packageJson)) return undefined;\n const name = packageJson[\"name\"];\n if (typeof name !== \"string\") return undefined;\n const trimmed = name.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction parsePort(value: string): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new Error(\"Port must be an integer between 1 and 65535.\");\n }\n return port;\n}\n\nfunction normalizeHostOption(\n host: WidgetDevOptions[\"host\"],\n): string | undefined {\n if (host === undefined || host === false) return undefined;\n if (host === true) return \"0.0.0.0\";\n\n const trimmed = host.trim();\n return trimmed.length > 0 ? trimmed : \"0.0.0.0\";\n}\n\nfunction normalizeMode(mode: string | undefined): string {\n const trimmed = mode?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : \"development\";\n}\n\nfunction formatLocalUrl(port: number, host: string | undefined): string {\n const displayHost = host && host !== \"0.0.0.0\" ? host : \"localhost\";\n return `http://${displayHost}:${port}`;\n}\n\nfunction runNodeScript(\n scriptPath: string,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, [scriptPath, ...args], {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n if (code === 0 || signal === \"SIGINT\" || signal === \"SIGTERM\") {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `Vite dev server exited with signal ${signal}.`\n : `Vite dev server exited with code ${code ?? \"unknown\"}.`,\n ),\n );\n });\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport type { FetchClient } from \"@fluid-app/fluid-cli\";\n\nexport interface AuthenticatedClientResult {\n readonly client: FetchClient;\n}\n\nexport function createAuthenticatedClient(): AuthenticatedClientResult {\n return { client: createAuthenticatedWidgetPackageClient() };\n}\n","import prompts from \"prompts\";\nimport type { FetchClient } from \"@fluid-app/fluid-cli\";\nimport type { Choice } from \"prompts\";\n\nexport interface DropletChoice {\n readonly uuid: string;\n readonly name: string;\n}\n\nexport async function promptForDroplet(\n client: FetchClient,\n): Promise<string | undefined> {\n const droplets = await listDroplets(client);\n\n if (droplets.length === 0) {\n throw new Error(\n \"No droplets were found for this account. Create a droplet in Fluid first, then run this command again.\",\n );\n }\n\n const response = await prompts({\n type: \"autocomplete\",\n name: \"droplet\",\n message: \"Select the droplet that owns this widget package\",\n choices: droplets.map((droplet) => ({\n title: `${droplet.name} (${droplet.uuid})`,\n value: droplet.uuid,\n })),\n suggest: (input: string, choices: Choice[]) =>\n Promise.resolve(\n input\n ? choices.filter((choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()),\n )\n : choices,\n ),\n });\n\n return response[\"droplet\"] as string | undefined;\n}\n\nexport async function listDroplets(\n client: FetchClient,\n): Promise<readonly DropletChoice[]> {\n try {\n const response = await client.get<unknown>(\"/api/droplets\");\n return normalizeDropletsResponse(response);\n } catch (err) {\n if (isApiLikeError(err)) {\n if (err.status === 401 || err.status === 403) {\n throw new Error(\n \"Your Fluid session has expired. Run `fluid login` and try again.\",\n );\n }\n throw new Error(\n `Could not fetch droplets from Fluid (HTTP ${err.status}). ${err.message}`,\n );\n }\n\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Could not fetch droplets from Fluid. ${message}`);\n }\n}\n\nfunction normalizeDropletsResponse(response: unknown): DropletChoice[] {\n const candidates = extractDropletArray(response);\n return candidates\n .map(normalizeDroplet)\n .filter((droplet): droplet is DropletChoice => droplet !== undefined);\n}\n\nfunction extractDropletArray(response: unknown): readonly unknown[] {\n if (Array.isArray(response)) return response;\n if (!isRecord(response)) return [];\n\n const directDroplets = response[\"droplets\"];\n if (Array.isArray(directDroplets)) return directDroplets;\n\n const data = response[\"data\"];\n if (Array.isArray(data)) return data;\n if (isRecord(data) && Array.isArray(data[\"droplets\"])) {\n return data[\"droplets\"];\n }\n\n return [];\n}\n\nfunction normalizeDroplet(value: unknown): DropletChoice | undefined {\n if (!isRecord(value)) return undefined;\n\n const uuid = readString(value, \"uuid\") ?? readString(value, \"id\");\n if (!uuid) return undefined;\n\n const name =\n readString(value, \"name\") ??\n readString(value, \"title\") ??\n readString(value, \"slug\") ??\n uuid;\n\n return { uuid, name };\n}\n\nfunction readString(\n record: Readonly<Record<string, unknown>>,\n key: string,\n): string | undefined {\n const value = record[key];\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction isApiLikeError(\n error: unknown,\n): error is { readonly status: number; readonly message: string } {\n return (\n error instanceof Error &&\n \"status\" in error &&\n typeof (error as { readonly status?: unknown }).status === \"number\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport type { WidgetLinkOptions } from \"../types.js\";\nimport { createAuthenticatedClient } from \"../utils/auth-client.js\";\nimport { promptForDroplet } from \"../utils/droplets.js\";\nimport {\n WIDGET_CONFIG_FILE,\n loadWidgetConfig,\n mergeWidgetConfig,\n validateDropletUuid,\n writeWidgetConfig,\n} from \"../utils/config.js\";\n\nexport const linkCommand: Command = new Command(\"link\")\n .description(\"Link this widget project to an existing Fluid droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .action(async (options: WidgetLinkOptions) => {\n try {\n const projectDir = process.cwd();\n const loaded = await loadWidgetConfig(projectDir);\n\n let droplet = options.droplet?.trim() || undefined;\n if (!droplet) {\n const spinner = ora(\"Fetching droplets...\").start();\n try {\n const { client } = createAuthenticatedClient();\n spinner.stop();\n droplet = await promptForDroplet(client);\n } catch (err) {\n spinner.fail(\"Unable to load droplets\");\n throw err;\n }\n\n if (!droplet) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n }\n\n const nextConfig = mergeWidgetConfig(loaded.config, { droplet });\n const nextDropletError = validateDropletUuid(nextConfig.droplet ?? \"\");\n if (nextDropletError) throw new Error(nextDropletError);\n\n await writeWidgetConfig(projectDir, nextConfig);\n\n console.log();\n console.log(chalk.green(\"Linked widget project.\"));\n console.log(\n chalk.gray(\"Config: \") +\n chalk.cyan(\n path.relative(projectDir, loaded.path) || WIDGET_CONFIG_FILE,\n ),\n );\n console.log(\n chalk.gray(\"Droplet: \") + chalk.white(nextConfig.droplet),\n );\n console.log(\n chalk.gray(\"Package key: \") +\n chalk.white(`${nextConfig.droplet} (derived from droplet)`),\n );\n console.log();\n } catch (err) {\n console.log();\n console.error(\n chalk.red(\"Error:\") +\n \" \" +\n (err instanceof Error ? err.message : String(err)),\n );\n console.log();\n process.exit(1);\n }\n });\n","import type { FetchClient } from \"@fluid-app/fluid-cli\";\n\nexport interface DropletWidgetVersionSummary {\n readonly packageKey?: string;\n readonly packageId?: string;\n readonly version?: string;\n readonly status?: string;\n readonly createdAt?: string;\n readonly updatedAt?: string;\n readonly artifactCount?: number;\n readonly raw: unknown;\n}\n\nexport interface DropletWidgetLogEntry {\n readonly timestamp?: string;\n readonly level?: string;\n readonly message: string;\n readonly raw: unknown;\n}\n\nexport async function fetchDropletWidgetStatus(options: {\n readonly client: FetchClient;\n readonly droplet: string;\n}): Promise<DropletWidgetVersionSummary[]> {\n const response = await options.client.get<unknown>(\n `/api/droplets/${encodeURIComponent(options.droplet)}/widget_package_versions`,\n );\n return extractArray(response).map(normalizeVersionSummary);\n}\n\nexport async function fetchDropletWidgetLogs(options: {\n readonly client: FetchClient;\n readonly droplet: string;\n readonly limit?: number;\n}): Promise<DropletWidgetLogEntry[]> {\n const response = await options.client.get<unknown>(\n `/api/droplets/${encodeURIComponent(options.droplet)}/widget_package_versions/logs`,\n options.limit ? { limit: options.limit } : undefined,\n );\n return extractArray(response).map(normalizeLogEntry);\n}\n\nexport function formatStatusRows(\n versions: readonly DropletWidgetVersionSummary[],\n): string {\n if (versions.length === 0) return \"No widget package versions found.\";\n\n return versions\n .map((version) => {\n const identity =\n version.packageId ?? version.packageKey ?? \"unknown-package\";\n const release = version.version ?? \"unknown-version\";\n const status = version.status ?? \"unknown\";\n const updated = version.updatedAt ?? version.createdAt ?? \"unknown time\";\n const artifacts =\n version.artifactCount === undefined\n ? \"unknown artifacts\"\n : `${version.artifactCount} artifact${version.artifactCount === 1 ? \"\" : \"s\"}`;\n return `${identity}@${release} — ${status} — ${artifacts} — ${updated}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatLogRows(logs: readonly DropletWidgetLogEntry[]): string {\n if (logs.length === 0) return \"No widget package logs found.\";\n\n return logs\n .map((entry) => {\n const timestamp = entry.timestamp ?? \"unknown time\";\n const level = entry.level ? entry.level.toUpperCase() : \"INFO\";\n return `[${timestamp}] ${level} ${entry.message}`;\n })\n .join(\"\\n\");\n}\n\nfunction normalizeVersionSummary(value: unknown): DropletWidgetVersionSummary {\n const record = unwrapKnownNestedRecord(value);\n const artifacts = readArray(record, \"artifacts\");\n return {\n packageKey: readFirstString(record, [\"package_key\", \"packageKey\"]),\n packageId: readFirstString(record, [\"package_id\", \"packageId\"]),\n version: readFirstString(record, [\"version\", \"name\"]),\n status: readFirstString(record, [\"status\", \"state\"]),\n createdAt: readFirstString(record, [\"created_at\", \"createdAt\"]),\n updatedAt: readFirstString(record, [\"updated_at\", \"updatedAt\"]),\n ...(artifacts ? { artifactCount: artifacts.length } : {}),\n raw: value,\n };\n}\n\nfunction normalizeLogEntry(value: unknown): DropletWidgetLogEntry {\n const record = unwrapKnownNestedRecord(value);\n return {\n timestamp: readFirstString(record, [\n \"timestamp\",\n \"created_at\",\n \"createdAt\",\n ]),\n level: readFirstString(record, [\"level\", \"severity\"]),\n message:\n readFirstString(record, [\"message\", \"event\", \"status\", \"state\"]) ??\n JSON.stringify(value),\n raw: value,\n };\n}\n\nfunction extractArray(value: unknown): unknown[] {\n if (Array.isArray(value)) return value;\n if (!isRecord(value)) return [];\n\n for (const key of [\n \"widget_package_versions\",\n \"widgetPackageVersions\",\n \"versions\",\n \"logs\",\n \"events\",\n \"data\",\n ] as const) {\n const nested = value[key];\n if (Array.isArray(nested)) return nested;\n }\n\n return [value];\n}\n\nfunction unwrapKnownNestedRecord(value: unknown): Record<string, unknown> {\n if (!isRecord(value)) return {};\n for (const key of [\n \"widget_package_version\",\n \"widgetPackageVersion\",\n \"version\",\n \"log\",\n \"event\",\n ] as const) {\n const nested = value[key];\n if (isRecord(nested)) return nested;\n }\n return value;\n}\n\nfunction readArray(\n record: Record<string, unknown>,\n key: string,\n): readonly unknown[] | undefined {\n const value = record[key];\n return Array.isArray(value) ? value : undefined;\n}\n\nfunction readFirstString(\n record: Record<string, unknown>,\n keys: readonly string[],\n): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim().length > 0) return value;\n if (typeof value === \"number\" && Number.isFinite(value))\n return String(value);\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Command } from \"commander\";\nimport { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport { fetchDropletWidgetLogs, formatLogRows } from \"../utils/droplet-api.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface LogsCommandOptions {\n readonly droplet?: string;\n readonly limit?: string;\n readonly json?: boolean;\n}\n\nexport const logsCommand: Command = new Command(\"logs\")\n .description(\"Show recent widget package publish logs for a Droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--limit <number>\", \"Maximum number of log entries to request\", \"50\")\n .option(\"--json\", \"Print raw log response as JSON\")\n .action((options: LogsCommandOptions) => {\n return runCliAction(async () => {\n const droplet = await resolveDroplet(process.cwd(), options.droplet);\n const limit = parseLimit(options.limit);\n const logs = await fetchDropletWidgetLogs({\n client: createAuthenticatedWidgetPackageClient(),\n droplet,\n limit,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n logs.map((entry) => entry.raw),\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.blue.bold(`Widget logs for droplet ${droplet}`));\n console.log();\n console.log(formatLogRows(logs));\n });\n });\n\nasync function resolveDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n\nfunction parseLimit(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number(value);\n if (Number.isInteger(parsed) && parsed > 0 && parsed <= 500) return parsed;\n throw new Error(\"--limit must be an integer between 1 and 500.\");\n}\n","import { Command } from \"commander\";\nimport {\n createAuthenticatedWidgetPackageClient,\n printDryRunSessionPayload,\n printRuntimeOnlyNotice,\n printWidgetPublishSummary,\n publishWidgetRuntimeArtifacts,\n} from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n DEFAULT_WIDGET_OUT_DIR,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n} from \"../utils/source-package.js\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport { runCliAction } from \"../utils/command.js\";\nimport { runPackageScriptIfAvailable } from \"../utils/package-scripts.js\";\n\nexport interface PublishWidgetPackageOptions {\n readonly projectDir: string;\n readonly outDir: string;\n readonly droplet?: string;\n readonly dryRun?: boolean;\n readonly skipTypecheck?: boolean;\n readonly client?: unknown;\n}\n\nexport interface PublishWidgetPackageResult {\n readonly dryRun: boolean;\n readonly uploaded: boolean;\n readonly outDir: string;\n readonly droplet?: string;\n}\n\nexport interface PublishWidgetPackageDependencies {\n readonly buildWidgetPackage: (options: {\n readonly projectDir: string;\n readonly outDir: string;\n }) => Promise<void>;\n readonly uploadWidgetPackage: (options: {\n readonly outDir: string;\n readonly droplet?: string;\n readonly client?: unknown;\n }) => Promise<void>;\n}\n\nexport async function publishWidgetPackage(\n options: PublishWidgetPackageOptions,\n dependencies?: PublishWidgetPackageDependencies,\n): Promise<PublishWidgetPackageResult> {\n if (dependencies) {\n await dependencies.buildWidgetPackage({\n projectDir: options.projectDir,\n outDir: options.outDir,\n });\n\n const dryRun = options.dryRun === true;\n if (dryRun) {\n return { dryRun, uploaded: false, outDir: options.outDir };\n }\n\n await dependencies.uploadWidgetPackage({\n outDir: options.outDir,\n droplet: options.droplet,\n client: options.client,\n });\n return { dryRun, uploaded: true, outDir: options.outDir };\n }\n\n const droplet = await resolvePublishDroplet(\n options.projectDir,\n options.droplet,\n );\n\n await validateDropletWidgetProject(options.projectDir, droplet);\n if (options.skipTypecheck !== true) {\n await runPackageScriptIfAvailable({\n projectDir: options.projectDir,\n scriptName: \"typecheck\",\n });\n }\n\n const dryRun = options.dryRun === true;\n await withRootWidgetConfigBridge(\n options.projectDir,\n () =>\n publishWidgetRuntimeArtifacts({\n projectDir: options.projectDir,\n outDir: options.outDir,\n buildOwner: \"droplet\",\n uploadOwner: { kind: \"droplet\", uuid: droplet },\n dryRun,\n ...(dryRun ? {} : { client: createAuthenticatedWidgetPackageClient() }),\n }),\n droplet,\n );\n\n return {\n dryRun,\n uploaded: !dryRun,\n outDir: options.outDir,\n droplet,\n };\n}\n\nexport interface PublishCommandOptions {\n readonly outDir?: string;\n readonly droplet?: string;\n readonly dryRun?: boolean;\n readonly skipTypecheck?: boolean;\n}\n\nexport const publishCommand: Command = new Command(\"publish\")\n .description(\"Publish a Fluid widget package\")\n .option(\n \"-o, --out-dir <dir>\",\n \"Widget artifact output directory\",\n DEFAULT_WIDGET_OUT_DIR,\n )\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--dry-run\", \"Build and validate without uploading\")\n .option(\"--skip-typecheck\", \"Skip package typecheck script when present\")\n .action((options: PublishCommandOptions) => {\n return runCliAction(async () => {\n const projectDir = process.cwd();\n const outDir = options.outDir ?? DEFAULT_WIDGET_OUT_DIR;\n const droplet = await resolvePublishDroplet(projectDir, options.droplet);\n const dryRun = options.dryRun === true;\n\n console.log();\n console.log(chalk.blue.bold(\"Fluid Widget Publish\"));\n console.log();\n printRuntimeOnlyNotice();\n console.log(chalk.gray(\"Droplet: \") + chalk.white(droplet));\n console.log(chalk.gray(\"Output: \") + chalk.cyan(outDir));\n if (dryRun) {\n console.log(chalk.yellow(\"Dry run: no upload will be created.\"));\n }\n console.log();\n\n const validateSpinner = ora(\"Validating widget package...\").start();\n await validateDropletWidgetProject(projectDir, droplet);\n validateSpinner.succeed(\"Validated widget package\");\n\n if (options.skipTypecheck !== true) {\n const typecheckSpinner = ora(\"Running package typecheck...\").start();\n const typecheck = await runPackageScriptIfAvailable({\n projectDir,\n scriptName: \"typecheck\",\n });\n if (typecheck.ran) {\n typecheckSpinner.succeed(\"Package typecheck passed\");\n } else {\n typecheckSpinner.info(\"No typecheck script found; skipping\");\n }\n }\n\n const publishSpinner = ora(\n dryRun\n ? \"Building and preparing dry-run upload payload...\"\n : \"Building and publishing widget artifacts...\",\n ).start();\n\n const result = await withRootWidgetConfigBridge(\n projectDir,\n () =>\n publishWidgetRuntimeArtifacts({\n projectDir,\n outDir,\n buildOwner: \"droplet\",\n uploadOwner: { kind: \"droplet\", uuid: droplet },\n dryRun,\n ...(dryRun\n ? {}\n : { client: createAuthenticatedWidgetPackageClient() }),\n }),\n droplet,\n );\n\n publishSpinner.succeed(\n dryRun ? \"Prepared dry-run upload payload\" : \"Published widget package\",\n );\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"Dry run complete — upload session was not requested.\"),\n );\n console.log();\n printDryRunSessionPayload(result);\n }\n\n printWidgetPublishSummary({\n title: dryRun ? \"Widget publish dry run\" : \"Widget publish\",\n ownerLabel: `droplet ${droplet}`,\n outDir,\n result,\n });\n });\n });\n\nasync function resolvePublishDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n","import { Command } from \"commander\";\nimport { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport {\n fetchDropletWidgetStatus,\n formatStatusRows,\n} from \"../utils/droplet-api.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface StatusCommandOptions {\n readonly droplet?: string;\n readonly json?: boolean;\n}\n\nexport const statusCommand: Command = new Command(\"status\")\n .description(\"Show published widget package status for a Droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--json\", \"Print raw status response as JSON\")\n .action((options: StatusCommandOptions) => {\n return runCliAction(async () => {\n const droplet = await resolveDroplet(process.cwd(), options.droplet);\n const versions = await fetchDropletWidgetStatus({\n client: createAuthenticatedWidgetPackageClient(),\n droplet,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n versions.map((version) => version.raw),\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.blue.bold(`Widget status for droplet ${droplet}`));\n console.log();\n console.log(formatStatusRows(versions));\n });\n });\n\nasync function resolveDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n formatValidationSuccess,\n validateDropletWidgetProject,\n} from \"../utils/source-package.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface ValidateWidgetOptions {\n readonly json?: boolean;\n}\n\nexport const validateCommand: Command = new Command(\"validate\")\n .description(\"Validate the current droplet widget package\")\n .option(\"--json\", \"Print machine-readable validation output\")\n .action((options: ValidateWidgetOptions) => {\n return runCliAction(async () => {\n const result = await validateDropletWidgetProject(process.cwd());\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n valid: true,\n config: result.sourceConfigPath,\n packageId: result.validated.packageId,\n version: result.validated.version,\n widgets: result.validated.widgets.map((widget) => ({\n name: widget.name,\n type: widget.type,\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.green(formatValidationSuccess(result)));\n });\n });\n","import { Command } from \"commander\";\nimport type { FluidPlugin, PluginContext } from \"@fluid-app/fluid-cli\";\nimport { buildCommand } from \"./commands/build.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { devCommand } from \"./commands/dev.js\";\nimport { linkCommand } from \"./commands/link.js\";\nimport { logsCommand } from \"./commands/logs.js\";\nimport { publishCommand } from \"./commands/publish.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { validateCommand } from \"./commands/validate.js\";\n\nexport const widgetCommand: Command = new Command(\"widget\")\n .description(\n \"Create, preview, link, validate, build, and publish standalone Fluid widgets\",\n )\n .addCommand(createCommand)\n .addCommand(devCommand)\n .addCommand(linkCommand)\n .addCommand(validateCommand)\n .addCommand(buildCommand)\n .addCommand(publishCommand)\n .addCommand(statusCommand)\n .addCommand(logsCommand);\n\nconst plugin: FluidPlugin = {\n name: \"@fluid-app/fluid-cli-widget\",\n version: \"0.1.0\",\n register(ctx: PluginContext) {\n const existingWidgetCommand = findCommand(ctx.program, \"widget\");\n if (existingWidgetCommand) {\n addCommandIfMissing(existingWidgetCommand, createCommand);\n addCommandIfMissing(existingWidgetCommand, devCommand);\n addCommandIfMissing(existingWidgetCommand, linkCommand);\n addCommandIfMissing(existingWidgetCommand, validateCommand);\n addCommandIfMissing(existingWidgetCommand, buildCommand);\n addCommandIfMissing(existingWidgetCommand, publishCommand);\n addCommandIfMissing(existingWidgetCommand, statusCommand);\n addCommandIfMissing(existingWidgetCommand, logsCommand);\n return;\n }\n\n ctx.program.addCommand(widgetCommand);\n },\n};\n\nexport default plugin;\n\nexport type {\n WidgetCommandOptions,\n WidgetCreateOptions,\n WidgetLinkOptions,\n WidgetTemplateVariables,\n} from \"./types.js\";\nexport { buildCommand, buildWidgetPackage } from \"./commands/build.js\";\nexport type {\n BuildWidgetOptions,\n BuildWidgetPackageOptions,\n BuildWidgetPackageResult,\n} from \"./commands/build.js\";\nexport { createCommand, createWidgetProject } from \"./commands/create.js\";\nexport {\n DEFAULT_WIDGET_DEV_PORT,\n WIDGET_DEV_ROUTES,\n buildViteDevArgs,\n devCommand,\n printWidgetDevSummary,\n resolveWidgetDevProject,\n runViteDevServer,\n} from \"./commands/dev.js\";\nexport type {\n WidgetDevOptions,\n WidgetDevProjectSummary,\n} from \"./commands/dev.js\";\nexport { linkCommand } from \"./commands/link.js\";\nexport { logsCommand } from \"./commands/logs.js\";\nexport type { LogsCommandOptions } from \"./commands/logs.js\";\nexport { publishCommand, publishWidgetPackage } from \"./commands/publish.js\";\nexport type {\n PublishCommandOptions,\n PublishWidgetPackageDependencies,\n PublishWidgetPackageOptions,\n PublishWidgetPackageResult,\n} from \"./commands/publish.js\";\nexport { statusCommand } from \"./commands/status.js\";\nexport type { StatusCommandOptions } from \"./commands/status.js\";\nexport { validateCommand } from \"./commands/validate.js\";\nexport type { ValidateWidgetOptions } from \"./commands/validate.js\";\nexport {\n WIDGET_CONFIG_FILE,\n formatWidgetConfig,\n loadWidgetConfig,\n mergeWidgetConfig,\n parseWidgetConfigSource,\n resolveWidgetConfigPath,\n validateDropletUuid,\n writeWidgetConfig,\n type FluidWidgetConfig,\n type LoadedWidgetConfig,\n} from \"./utils/config.js\";\nexport {\n DEFAULT_WIDGET_OUT_DIR,\n ROOT_WIDGET_CONFIG_FILE,\n WidgetValidationError,\n formatValidationSuccess,\n resolveWidgetSourceConfig,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n type WidgetValidationResult,\n} from \"./utils/source-package.js\";\nexport { formatValidationErrors } from \"./utils/validation.js\";\nexport type { WidgetCliValidationError } from \"./utils/validation.js\";\n\nfunction addCommandIfMissing(parent: Command, child: Command): void {\n if (findCommand(parent, child.name())) return;\n parent.addCommand(child);\n}\n\nfunction findCommand(parent: Command, name: string): Command | undefined {\n return parent.commands?.find((command) => command.name() === name);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["isNodeError","isRecord","isRecord","readPackageJson","isRecord","isRecord","isRecord","resolveDroplet"],"sources":["../src/utils/config.ts","../src/utils/validation.ts","../src/utils/source-package.ts","../src/utils/command.ts","../src/utils/package-manager.ts","../src/utils/package-scripts.ts","../src/commands/build.ts","../src/utils/template.ts","../src/commands/create.ts","../src/commands/dev.ts","../src/utils/auth-client.ts","../src/utils/droplets.ts","../src/commands/link.ts","../src/utils/droplet-api.ts","../src/commands/logs.ts","../src/commands/publish.ts","../src/commands/status.ts","../src/commands/validate.ts","../src/index.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const WIDGET_CONFIG_FILE = \"fluid.widget.config.ts\";\n\nexport interface FluidWidgetConfig {\n readonly droplet?: string;\n}\n\nexport interface LoadedWidgetConfig {\n readonly path: string;\n readonly config: Partial<FluidWidgetConfig>;\n}\n\nexport class WidgetConfigParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WidgetConfigParseError\";\n }\n}\n\nexport function resolveWidgetConfigPath(projectDir: string): string {\n return path.join(projectDir, WIDGET_CONFIG_FILE);\n}\n\nexport async function loadWidgetConfig(\n projectDir: string,\n): Promise<LoadedWidgetConfig> {\n const configPath = resolveWidgetConfigPath(projectDir);\n\n let source: string;\n try {\n source = await readFile(configPath, \"utf-8\");\n } catch (err) {\n if (isNodeError(err) && err.code === \"ENOENT\") {\n return { path: configPath, config: {} };\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to read ${WIDGET_CONFIG_FILE}: ${message}`);\n }\n\n return { path: configPath, config: parseWidgetConfigSource(source) };\n}\n\nexport async function writeWidgetConfig(\n projectDir: string,\n config: FluidWidgetConfig,\n): Promise<void> {\n await writeFile(\n resolveWidgetConfigPath(projectDir),\n formatWidgetConfig(config),\n \"utf-8\",\n );\n}\n\nexport function formatWidgetConfig(config: FluidWidgetConfig): string {\n const lines = [\n 'import type { FluidWidgetConfig } from \"@fluid-app/fluid-cli-widget\";',\n \"\",\n \"const config = {\",\n ];\n\n if (config.droplet) {\n lines.push(` droplet: ${JSON.stringify(config.droplet)},`);\n }\n\n lines.push(\n \"} satisfies FluidWidgetConfig;\",\n \"\",\n \"const widgetConfig: FluidWidgetConfig = config;\",\n \"\",\n \"export default config;\",\n \"export const droplet = widgetConfig.droplet;\",\n 'export { widgetPackage, widgetPackages } from \"./manifest\";',\n \"\",\n );\n return lines.join(\"\\n\");\n}\n\nexport function parseWidgetConfigSource(\n source: string,\n): Partial<FluidWidgetConfig> {\n const objectSource = extractConfigObjectLiteral(source);\n const config = parseConfigObjectProperties(objectSource);\n\n return config;\n}\n\nexport function mergeWidgetConfig(\n current: Partial<FluidWidgetConfig>,\n updates: Partial<FluidWidgetConfig>,\n): FluidWidgetConfig {\n const droplet =\n normalizeOptionalString(updates.droplet) ??\n normalizeOptionalString(current.droplet);\n\n return droplet ? { droplet } : {};\n}\n\nexport function validateDropletUuid(dropletUuid: string): string | undefined {\n if (!dropletUuid) return \"Droplet UUID is required.\";\n if (dropletUuid.length > MAX_DROPLET_UUID_LENGTH) {\n return `Droplet UUID must be ${MAX_DROPLET_UUID_LENGTH} characters or fewer.`;\n }\n if (!URL_SAFE_IDENTIFIER_PATTERN.test(dropletUuid)) {\n return (\n \"Droplet UUID must be URL-safe text: letters, numbers, \" +\n \"'_', '~', and '-' only.\"\n );\n }\n return undefined;\n}\n\nfunction extractConfigObjectLiteral(source: string): string {\n const configStart = /\\bconst\\s+config\\s*=\\s*\\{/.exec(source);\n if (!configStart) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} must declare \\`const config = { ... } satisfies FluidWidgetConfig\\`.`,\n );\n }\n\n const openBraceIndex = source.indexOf(\"{\", configStart.index);\n const closeBraceIndex = findMatchingBrace(source, openBraceIndex);\n const suffix = stripComments(source.slice(closeBraceIndex + 1));\n if (!/^\\s*(?:as\\s+const\\s+)?satisfies\\s+FluidWidgetConfig\\s*;/.test(suffix)) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config object must use \\`satisfies FluidWidgetConfig\\` or \\`as const satisfies FluidWidgetConfig\\`.`,\n );\n }\n\n return stripComments(source.slice(openBraceIndex + 1, closeBraceIndex));\n}\n\nfunction parseConfigObjectProperties(\n objectSource: string,\n): Partial<FluidWidgetConfig> {\n const config: { droplet?: string } = {};\n\n for (const member of splitTopLevelMembers(objectSource)) {\n const trimmedMember = member.trim();\n if (!trimmedMember) continue;\n\n const propertyMatch = /^(droplet)\\s*:\\s*([\\s\\S]+)$/.exec(trimmedMember);\n if (!propertyMatch) {\n const propertyName = /^([A-Za-z_$][\\w$]*)\\s*:/.exec(trimmedMember)?.[1];\n throw new WidgetConfigParseError(\n propertyName\n ? `${WIDGET_CONFIG_FILE} does not support config field ${propertyName}. Supported field is droplet.`\n : `${WIDGET_CONFIG_FILE} config fields must use optional droplet: \"...\" string literal.`,\n );\n }\n\n const propertyName = propertyMatch[1];\n if (propertyName !== \"droplet\") {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config field could not be parsed.`,\n );\n }\n const valueSource = propertyMatch[2]?.trim() ?? \"\";\n const value = parseStringLiteralValue(valueSource, propertyName);\n if (!value.trim()) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field ${propertyName} must be a non-empty string literal.`,\n );\n }\n\n if (config.droplet !== undefined) {\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field droplet must only be declared once.`,\n );\n }\n config.droplet = value;\n }\n\n return config;\n}\n\nfunction parseStringLiteralValue(\n valueSource: string,\n propertyName: string,\n): string {\n if (valueSource.startsWith('\"') && valueSource.endsWith('\"')) {\n try {\n const parsed = JSON.parse(valueSource) as unknown;\n if (typeof parsed === \"string\") return parsed;\n } catch {\n // Fall through to the actionable error below.\n }\n }\n\n if (valueSource.startsWith(\"'\") && valueSource.endsWith(\"'\")) {\n return parseSingleQuotedStringLiteral(valueSource);\n }\n\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} field ${propertyName} must be a string literal (for example ${propertyName}: \"value\").`,\n );\n}\n\nfunction parseSingleQuotedStringLiteral(valueSource: string): string {\n let value = \"\";\n\n for (let index = 1; index < valueSource.length - 1; index += 1) {\n const char = valueSource[index];\n if (char !== \"\\\\\") {\n value += char;\n continue;\n }\n\n index += 1;\n const escaped = valueSource[index];\n switch (escaped) {\n case \"\\\\\":\n case \"'\":\n case '\"':\n value += escaped;\n break;\n case \"n\":\n value += \"\\n\";\n break;\n case \"r\":\n value += \"\\r\";\n break;\n case \"t\":\n value += \"\\t\";\n break;\n case \"b\":\n value += \"\\b\";\n break;\n case \"f\":\n value += \"\\f\";\n break;\n case \"v\":\n value += \"\\v\";\n break;\n default:\n value += escaped ?? \"\";\n break;\n }\n }\n\n return value;\n}\n\nfunction stripComments(source: string): string {\n let result = \"\";\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let lineComment = false;\n let blockComment = false;\n\n for (let index = 0; index < source.length; index += 1) {\n const char = source[index];\n const nextChar = source[index + 1];\n\n if (lineComment) {\n if (char === \"\\n\" || char === \"\\r\") {\n lineComment = false;\n result += char;\n } else {\n result += \" \";\n }\n continue;\n }\n\n if (blockComment) {\n if (char === \"*\" && nextChar === \"/\") {\n blockComment = false;\n result += \" \";\n index += 1;\n } else if (char === \"\\n\" || char === \"\\r\") {\n result += char;\n } else {\n result += \" \";\n }\n continue;\n }\n\n if (stringQuote) {\n result += char;\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === \"/\" && nextChar === \"/\") {\n lineComment = true;\n result += \" \";\n index += 1;\n continue;\n }\n\n if (char === \"/\" && nextChar === \"*\") {\n blockComment = true;\n result += \" \";\n index += 1;\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n }\n result += char;\n }\n\n return result;\n}\n\nfunction splitTopLevelMembers(objectSource: string): string[] {\n const members: string[] = [];\n let memberStart = 0;\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let nestedDepth = 0;\n\n for (let index = 0; index < objectSource.length; index += 1) {\n const char = objectSource[index];\n\n if (stringQuote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n continue;\n }\n\n if (char === \"{\" || char === \"[\" || char === \"(\") {\n nestedDepth += 1;\n continue;\n }\n if (char === \"}\" || char === \"]\" || char === \")\") {\n nestedDepth -= 1;\n continue;\n }\n\n if (char === \",\" && nestedDepth === 0) {\n members.push(objectSource.slice(memberStart, index));\n memberStart = index + 1;\n }\n }\n\n members.push(objectSource.slice(memberStart));\n return members;\n}\n\nfunction findMatchingBrace(source: string, openBraceIndex: number): number {\n let depth = 0;\n let stringQuote: '\"' | \"'\" | \"`\" | undefined;\n let escaped = false;\n let lineComment = false;\n let blockComment = false;\n\n for (let index = openBraceIndex; index < source.length; index += 1) {\n const char = source[index];\n const nextChar = source[index + 1];\n\n if (lineComment) {\n if (char === \"\\n\" || char === \"\\r\") lineComment = false;\n continue;\n }\n\n if (blockComment) {\n if (char === \"*\" && nextChar === \"/\") {\n blockComment = false;\n index += 1;\n }\n continue;\n }\n\n if (stringQuote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === stringQuote) {\n stringQuote = undefined;\n }\n continue;\n }\n\n if (char === \"/\" && nextChar === \"/\") {\n lineComment = true;\n index += 1;\n continue;\n }\n\n if (char === \"/\" && nextChar === \"*\") {\n blockComment = true;\n index += 1;\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n stringQuote = char;\n continue;\n }\n\n if (char === \"{\") depth += 1;\n if (char === \"}\") {\n depth -= 1;\n if (depth === 0) return index;\n }\n }\n\n throw new WidgetConfigParseError(\n `${WIDGET_CONFIG_FILE} config object is missing a closing brace.`,\n );\n}\n\nfunction normalizeOptionalString(\n value: string | undefined,\n): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\ninterface NodeError extends Error {\n readonly code?: string;\n}\n\nfunction isNodeError(error: unknown): error is NodeError {\n return error instanceof Error && \"code\" in error;\n}\n\nconst MAX_DROPLET_UUID_LENGTH = 256;\nconst URL_SAFE_SEGMENT_SOURCE = \"[A-Za-z0-9][A-Za-z0-9_~-]*\";\nconst URL_SAFE_IDENTIFIER_PATTERN = new RegExp(`^${URL_SAFE_SEGMENT_SOURCE}$`);\n","export interface WidgetCliValidationError {\n readonly path?: string;\n readonly message: string;\n}\n\nexport function formatValidationErrors(\n errors: readonly WidgetCliValidationError[],\n): string {\n if (errors.length === 0) return \"Validation failed.\";\n\n return [\n \"Validation failed:\",\n ...errors.map((error) => {\n const location = error.path ? `${error.path}: ` : \"\";\n return ` - ${location}${error.message}`;\n }),\n ].join(\"\\n\");\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, rm, rmdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n loadSourceWidgetPackages,\n validateSingleSourceWidgetPackage,\n} from \"@fluid-app/fluid-cli-portal\";\nimport {\n WIDGET_CONFIG_FILE,\n loadWidgetConfig,\n validateDropletUuid,\n} from \"./config.js\";\nimport type {\n ValidatedWidgetPackageBuild,\n WidgetPackageValidationError,\n} from \"@fluid-app/fluid-cli-portal\";\nimport { formatValidationErrors } from \"./validation.js\";\n\nexport const DEFAULT_WIDGET_OUT_DIR = \".fluid/widget-dist\";\nexport const ROOT_WIDGET_CONFIG_FILE: string = WIDGET_CONFIG_FILE;\n\nconst SOURCE_CONFIG_CANDIDATES = [\n \"src/widgets.config.ts\",\n \"src/portal.config.ts\",\n \"portal.config.ts\",\n] as const;\n\nexport interface WidgetValidationResult {\n readonly projectDir: string;\n readonly sourceConfigPath?: string;\n readonly validated: ValidatedWidgetPackageBuild;\n}\n\nexport class WidgetValidationError extends Error {\n public readonly errors: readonly WidgetPackageValidationError[];\n\n constructor(errors: readonly WidgetPackageValidationError[]) {\n super(formatValidationErrors(errors));\n this.name = \"WidgetValidationError\";\n this.errors = errors;\n }\n}\n\nexport async function validateDropletWidgetProject(\n projectDir: string,\n packageKeyOverride?: string,\n): Promise<WidgetValidationResult> {\n const resolvedProjectDir = path.resolve(projectDir);\n const sourceConfig = resolveWidgetSourceConfig(resolvedProjectDir);\n if (!sourceConfig) {\n throw new WidgetValidationError([\n {\n code: \"NO_SOURCE_PACKAGE\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message:\n `No widget package config found. Create ${ROOT_WIDGET_CONFIG_FILE} ` +\n \"or src/widgets.config.ts that exports defineWidgetPackage(...).\",\n },\n ]);\n }\n\n const configErrors = await validateRootWidgetConfig(\n resolvedProjectDir,\n packageKeyOverride,\n );\n if (configErrors.length > 0) {\n throw new WidgetValidationError(configErrors);\n }\n\n const sourcePackages = await withRootWidgetConfigBridge(\n resolvedProjectDir,\n async () => {\n const loadResult = await loadSourceWidgetPackages(resolvedProjectDir);\n if (!loadResult.success) {\n throw new WidgetValidationError([\n {\n code: \"INVALID_SOURCE_PACKAGE\",\n path: sourceConfig.relativePath,\n message: appendDetails(\n loadResult.error.message,\n loadResult.error.details,\n ),\n },\n ]);\n }\n return loadResult.value;\n },\n packageKeyOverride,\n );\n\n const validation = validateSingleSourceWidgetPackage(sourcePackages, {\n owner: \"droplet\",\n });\n const errors = [\n ...validation.errors,\n ...validateDropletMetadata(sourcePackages),\n ];\n\n if (!validation.success || !validation.value || errors.length > 0) {\n throw new WidgetValidationError(errors);\n }\n\n return {\n projectDir: resolvedProjectDir,\n sourceConfigPath: sourceConfig.relativePath,\n validated: validation.value,\n };\n}\n\nexport async function withRootWidgetConfigBridge<T>(\n projectDir: string,\n callback: () => Promise<T>,\n packageKeyOverride?: string,\n): Promise<T> {\n const rootConfigPath = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (!existsSync(rootConfigPath) || resolvePortalSourceConfig(projectDir)) {\n return callback();\n }\n\n const packageKey =\n packageKeyOverride?.trim() ||\n (await loadWidgetConfig(projectDir)).config.droplet;\n if (!packageKey) {\n throw new Error(\n \"fluid.widget.config.ts must set droplet before validating, building, or publishing.\",\n );\n }\n\n const srcDir = path.join(projectDir, \"src\");\n const bridgePath = path.join(srcDir, \"widgets.config.ts\");\n const srcDirExisted = existsSync(srcDir);\n await mkdir(srcDir, { recursive: true });\n try {\n await writeFile(\n bridgePath,\n createRootWidgetConfigBridgeSource(packageKey),\n {\n encoding: \"utf-8\",\n flag: \"wx\",\n },\n );\n } catch (err) {\n if (isNodeError(err) && err.code === \"EEXIST\") {\n throw new Error(\n `${path.relative(projectDir, bridgePath)} already exists. ` +\n \"Remove this stale Fluid widget CLI bridge file and try again.\",\n );\n }\n throw err;\n }\n\n try {\n return await callback();\n } finally {\n await rm(bridgePath, { force: true }).catch(() => {});\n if (!srcDirExisted) await rmdir(srcDir).catch(() => {});\n }\n}\n\nfunction createRootWidgetConfigBridgeSource(packageKey: string): string {\n return `import { widgetPackage as sourceWidgetPackage } from \"../manifest\";\n\nconst packageKey = ${JSON.stringify(packageKey)};\nconst packageId = sourceWidgetPackage.scope + \".\" + packageKey;\n\nexport const widgetPackage = {\n ...sourceWidgetPackage,\n packageStableId: packageKey,\n packageId,\n};\n\nexport const widgetPackages = [widgetPackage] as const;\nexport default widgetPackage;\n`;\n}\n\nexport function resolveWidgetSourceConfig(\n projectDir: string,\n): { readonly path: string; readonly relativePath: string } | undefined {\n const rootConfig = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (existsSync(rootConfig)) {\n return { path: rootConfig, relativePath: ROOT_WIDGET_CONFIG_FILE };\n }\n\n return resolvePortalSourceConfig(projectDir);\n}\n\nexport function formatValidationSuccess(\n result: WidgetValidationResult,\n): string {\n return [\n \"Widget package is valid.\",\n `Config: ${result.sourceConfigPath ?? \"unknown\"}`,\n `Package: ${result.validated.packageId}`,\n `Version: ${result.validated.version}`,\n `Widgets: ${result.validated.widgets.length}`,\n ].join(\"\\n\");\n}\n\nasync function validateRootWidgetConfig(\n projectDir: string,\n packageKeyOverride?: string,\n): Promise<WidgetPackageValidationError[]> {\n const configPath = path.join(projectDir, ROOT_WIDGET_CONFIG_FILE);\n if (!existsSync(configPath)) return [];\n\n try {\n const loaded = await loadWidgetConfig(projectDir);\n const droplet = packageKeyOverride ?? loaded.config.droplet ?? \"\";\n const packageKeyError = validateDropletUuid(droplet);\n if (!packageKeyError) return [];\n\n return [\n {\n code: \"INVALID_PACKAGE_KEY\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message: packageKeyError,\n },\n ];\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return [\n {\n code: \"INVALID_SOURCE_PACKAGE\",\n path: ROOT_WIDGET_CONFIG_FILE,\n message,\n },\n ];\n }\n}\n\nfunction validateDropletMetadata(\n sourcePackages: readonly unknown[],\n): WidgetPackageValidationError[] {\n if (sourcePackages.length !== 1) return [];\n\n const sourcePackage = sourcePackages[0];\n if (!isRecord(sourcePackage)) return [];\n\n const errors: WidgetPackageValidationError[] = [];\n if (sourcePackage[\"packageType\"] !== \"droplet\") {\n errors.push({\n code: \"UNSUPPORTED_OWNER\",\n path: \"packageType\",\n message:\n 'Droplet widget packages must set packageType: \"droplet\" in package metadata.',\n });\n }\n\n if (!isNonEmptyString(sourcePackage[\"packageStableId\"])) {\n errors.push({\n code: \"INVALID_PACKAGE_KEY\",\n path: \"packageStableId\",\n message:\n \"Droplet widget packages must set packageStableId so published widget types remain stable across builds.\",\n });\n }\n\n const widgets = sourcePackage[\"widgets\"];\n if (Array.isArray(widgets)) {\n widgets.forEach((widget, index) => {\n if (!isRecord(widget)) return;\n validateJsonSerializable(\n widget[\"propertySchema\"],\n `widgets[${index}].propertySchema`,\n errors,\n );\n validateJsonSerializable(\n widget[\"defaultProps\"],\n `widgets[${index}].defaultProps`,\n errors,\n );\n });\n }\n\n return errors;\n}\n\nfunction resolvePortalSourceConfig(\n projectDir: string,\n): { readonly path: string; readonly relativePath: string } | undefined {\n for (const relativePath of SOURCE_CONFIG_CANDIDATES) {\n const candidate = path.join(projectDir, relativePath);\n if (existsSync(candidate)) return { path: candidate, relativePath };\n }\n\n return undefined;\n}\n\nfunction validateJsonSerializable(\n value: unknown,\n pathLabel: string,\n errors: WidgetPackageValidationError[],\n): void {\n if (value === undefined) return;\n\n try {\n assertJsonSerializable(value, pathLabel);\n } catch (err) {\n errors.push({\n code: \"INVALID_WIDGET_METADATA\",\n path: pathLabel,\n message: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\nfunction assertJsonSerializable(value: unknown, pathLabel: string): void {\n if (value === null) return;\n\n const valueType = typeof value;\n if (valueType === \"string\" || valueType === \"boolean\") return;\n if (valueType === \"number\") {\n if (Number.isFinite(value)) return;\n throw new Error(`${pathLabel} must not contain NaN or Infinity.`);\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n assertJsonSerializable(item, `${pathLabel}[${index}]`);\n });\n return;\n }\n if (isRecord(value)) {\n for (const [key, item] of Object.entries(value)) {\n if (item === undefined) {\n throw new Error(`${pathLabel}.${key} must not be undefined.`);\n }\n assertJsonSerializable(item, `${pathLabel}.${key}`);\n }\n return;\n }\n\n throw new Error(`${pathLabel} must contain only JSON-serializable values.`);\n}\n\nfunction appendDetails(message: string, details: string | undefined): string {\n return details ? `${message}\\n${details}` : message;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\ninterface NodeError extends Error {\n readonly code?: string;\n}\n\nfunction isNodeError(error: unknown): error is NodeError {\n return error instanceof Error && \"code\" in error;\n}\n","import chalk from \"chalk\";\n\nexport async function runCliAction(action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (err) {\n console.error(chalk.red(\"Error:\") + \" \" + formatUnknownError(err));\n process.exit(1);\n }\n}\n\nexport function formatUnknownError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"bun\" | \"npm\";\n\nexport function getRunCommand(\n script: string,\n cwd: string = process.cwd(),\n): string {\n return `${detectPackageManager(cwd)} run ${script}`;\n}\n\nexport function getInstallCommand(cwd: string = process.cwd()): string {\n return `${detectPackageManager(cwd)} install`;\n}\n\nexport async function installDependencies(cwd: string): Promise<void> {\n const packageManager = detectPackageManager(cwd);\n await runPackageManager(packageManager, [\"install\"], cwd);\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n if (existsSync(path.join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(path.join(cwd, \"yarn.lock\"))) return \"yarn\";\n if (existsSync(path.join(cwd, \"bun.lockb\"))) return \"bun\";\n if (existsSync(path.join(cwd, \"package-lock.json\"))) return \"npm\";\n\n const invokingPackageManager = readInvokingPackageManager();\n if (invokingPackageManager) return invokingPackageManager;\n\n const declaredPackageManager = readDeclaredPackageManager(cwd);\n if (declaredPackageManager && isCommandAvailable(declaredPackageManager)) {\n return declaredPackageManager;\n }\n\n return findAvailablePackageManager() ?? \"pnpm\";\n}\n\nfunction runPackageManager(\n command: PackageManager,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, [...args], {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n\n child.once(\"error\", (error: Error) => {\n reject(error);\n });\n\n child.once(\"exit\", (code: number | null) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n `${command} ${args.join(\" \")} exited with code ${code ?? \"unknown\"}`,\n ),\n );\n });\n });\n}\n\nfunction readInvokingPackageManager(): PackageManager | undefined {\n const userAgent = process.env[\"npm_config_user_agent\"];\n if (!userAgent) return undefined;\n\n const name = userAgent.split(\"/\")[0];\n if (isPackageManager(name)) return name;\n return undefined;\n}\n\nfunction readDeclaredPackageManager(cwd: string): PackageManager | undefined {\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!existsSync(packageJsonPath)) return undefined;\n\n try {\n const packageJson = JSON.parse(\n readFileSync(packageJsonPath, \"utf-8\"),\n ) as unknown;\n if (!isRecord(packageJson)) return undefined;\n\n const packageManager = packageJson[\"packageManager\"];\n if (typeof packageManager !== \"string\") return undefined;\n\n const name = packageManager.split(\"@\")[0];\n if (isPackageManager(name)) return name;\n } catch {\n // Malformed package.json is reported by command paths that need to parse it.\n }\n\n return undefined;\n}\n\nfunction findAvailablePackageManager(): PackageManager | undefined {\n for (const packageManager of [\"pnpm\", \"yarn\", \"bun\", \"npm\"] as const) {\n if (isCommandAvailable(packageManager)) return packageManager;\n }\n return undefined;\n}\n\nfunction isCommandAvailable(command: PackageManager): boolean {\n const result = spawnSync(command, [\"--version\"], {\n shell: process.platform === \"win32\",\n stdio: \"ignore\",\n });\n return result.status === 0;\n}\n\nfunction isPackageManager(value: string | undefined): value is PackageManager {\n return (\n value === \"pnpm\" || value === \"yarn\" || value === \"bun\" || value === \"npm\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { detectPackageManager } from \"./package-manager.js\";\n\nexport interface PackageScriptRunResult {\n readonly ran: boolean;\n readonly command?: string;\n}\n\nexport async function runPackageScriptIfAvailable(options: {\n readonly projectDir: string;\n readonly scriptName: string;\n}): Promise<PackageScriptRunResult> {\n const packageJsonPath = path.join(options.projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return { ran: false };\n\n const packageJson = await readPackageJson(packageJsonPath);\n if (!hasPackageScript(packageJson, options.scriptName)) return { ran: false };\n\n const packageManager = detectPackageManager(options.projectDir);\n const args = [\"run\", options.scriptName];\n await runCommand(packageManager, args, options.projectDir);\n\n return {\n ran: true,\n command: `${packageManager} ${args.join(\" \")}`,\n };\n}\n\nfunction runCommand(\n command: string,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n env: process.env,\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `${command} ${args.join(\" \")} exited with signal ${signal}.`\n : `${command} ${args.join(\" \")} exited with code ${code ?? \"unknown\"}.`,\n ),\n );\n });\n });\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<unknown> {\n const source = await readFile(packageJsonPath, \"utf-8\");\n try {\n return JSON.parse(source) as unknown;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to parse package.json: ${message}`);\n }\n}\n\nfunction hasPackageScript(value: unknown, scriptName: string): boolean {\n if (!isRecord(value)) return false;\n const scripts = value[\"scripts\"];\n if (!isRecord(scripts)) return false;\n return typeof scripts[scriptName] === \"string\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Command } from \"commander\";\nimport {\n buildSharedWidgetPackage,\n validateWidgetPublishOutDir,\n} from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n DEFAULT_WIDGET_OUT_DIR,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n} from \"../utils/source-package.js\";\nimport { runCliAction } from \"../utils/command.js\";\nimport { runPackageScriptIfAvailable } from \"../utils/package-scripts.js\";\n\nexport interface BuildWidgetOptions {\n readonly outDir?: string;\n readonly skipTypecheck?: boolean;\n}\n\nexport interface BuildWidgetPackageOptions {\n readonly projectDir: string;\n readonly outDir: string;\n readonly skipTypecheck?: boolean;\n}\n\nexport interface BuildWidgetPackageResult {\n readonly outDir: string;\n readonly packageId: string;\n readonly version: string;\n}\n\nexport async function buildWidgetPackage(\n options: BuildWidgetPackageOptions,\n): Promise<BuildWidgetPackageResult> {\n await validateDropletWidgetProject(options.projectDir);\n\n if (options.skipTypecheck !== true) {\n await runPackageScriptIfAvailable({\n projectDir: options.projectDir,\n scriptName: \"typecheck\",\n });\n }\n\n const outDir = validateWidgetPublishOutDir(\n options.projectDir,\n options.outDir,\n );\n const buildResult = await withRootWidgetConfigBridge(options.projectDir, () =>\n buildSharedWidgetPackage({\n projectDir: options.projectDir,\n publishDir: outDir,\n owner: \"droplet\",\n }),\n );\n\n if (!buildResult.success) {\n const details = buildResult.error.details\n ? `\\n${buildResult.error.details}`\n : \"\";\n throw new Error(`${buildResult.error.message}${details}`);\n }\n\n return {\n outDir: buildResult.value.publishDir,\n packageId: buildResult.value.packageId,\n version: buildResult.value.version,\n };\n}\n\nexport const buildCommand: Command = new Command(\"build\")\n .description(\"Validate and build the current droplet widget package\")\n .option(\n \"-o, --out-dir <dir>\",\n \"Widget artifact output directory\",\n DEFAULT_WIDGET_OUT_DIR,\n )\n .option(\"--skip-typecheck\", \"Skip package typecheck script when present\")\n .action((options: BuildWidgetOptions) => {\n return runCliAction(async () => {\n const outDir = options.outDir ?? DEFAULT_WIDGET_OUT_DIR;\n console.log(chalk.blue.bold(\"Building Fluid widget package\"));\n console.log();\n\n const spinner = ora(\n \"Validating and building widget artifacts...\",\n ).start();\n const result = await buildWidgetPackage({\n projectDir: process.cwd(),\n outDir,\n skipTypecheck: options.skipTypecheck,\n });\n spinner.succeed(\"Built widget runtime artifacts\");\n\n console.log();\n console.log(chalk.gray(\"Package: \") + chalk.white(result.packageId));\n console.log(chalk.gray(\"Version: \") + chalk.white(result.version));\n console.log(chalk.gray(\"Output: \") + chalk.cyan(outDir));\n });\n });\n","import { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { WidgetTemplateVariables } from \"../types.js\";\n\nexport function getDefaultTemplatePath(): string {\n return path.join(findPackageRoot(), \"templates\", \"default\");\n}\n\nexport async function directoryExists(filePath: string): Promise<boolean> {\n try {\n const stats = await stat(filePath);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function copyWidgetTemplate(\n templatePath: string,\n targetPath: string,\n variables: WidgetTemplateVariables,\n): Promise<void> {\n const files = await getFiles(templatePath);\n\n for (const file of files) {\n const sourcePath = path.join(templatePath, file);\n const outputFile = getOutputFilename(file);\n const destinationPath = path.join(targetPath, outputFile);\n\n await mkdir(path.dirname(destinationPath), { recursive: true });\n\n const content = await readFile(sourcePath, \"utf-8\");\n const processed = renderTemplate(content, variables);\n await writeFile(destinationPath, processed, \"utf-8\");\n }\n}\n\nexport async function getPortalSdkVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"portal\", \"sdk\"], \"^0.1.0\", options);\n}\n\nexport async function getPortalCoreVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"portal\", \"core\"], \"^0.1.0\", options);\n}\n\nexport async function getCliVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"cli\", \"core\"], \"^0.1.0\", options);\n}\n\nexport async function getWidgetCliVersion(\n options: {\n readonly local?: boolean;\n readonly targetPath?: string;\n } = {},\n): Promise<string> {\n return getWorkspacePackageVersion([\"cli\", \"widget\"], \"^0.1.0\", options);\n}\n\nasync function getWorkspacePackageVersion(\n packagePathSegments: readonly string[],\n fallback: string,\n options: { readonly local?: boolean; readonly targetPath?: string },\n): Promise<string> {\n try {\n const packageRoot = findPackageRoot();\n const packagesRoot = path.join(packageRoot, \"..\", \"..\");\n const targetPackageRoot = path.join(packagesRoot, ...packagePathSegments);\n\n if (options.local) {\n const linkPath = (\n options.targetPath\n ? path.relative(options.targetPath, targetPackageRoot)\n : targetPackageRoot\n ).replace(/\\\\/g, \"/\");\n return `link:${linkPath || \".\"}`;\n }\n\n const packageJsonPath = path.join(targetPackageRoot, \"package.json\");\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return `^${pkg.version ?? fallback.replace(/^\\^/, \"\")}`;\n } catch {\n return fallback;\n }\n}\n\nasync function getFiles(dir: string, baseDir = dir): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await getFiles(fullPath, baseDir)));\n } else {\n files.push(path.relative(baseDir, fullPath));\n }\n }\n\n return files;\n}\n\nfunction renderTemplate(\n content: string,\n variables: WidgetTemplateVariables,\n): string {\n const withConditionals = content.replace(\n /{{\\s*#if\\s+([a-zA-Z0-9_]+)\\s*}}([\\s\\S]*?){{\\s*\\/if\\s*}}/g,\n (match, key, block) => {\n if (!isTemplateVariableKey(key)) return match;\n return variables[key] ? String(block) : \"\";\n },\n );\n\n return withConditionals.replace(\n /{{\\s*([a-zA-Z0-9_]+)\\s*}}/g,\n (match, key) => {\n if (isTemplateVariableKey(key)) return variables[key] ?? \"\";\n return match;\n },\n );\n}\n\nfunction isTemplateVariableKey(\n key: string,\n): key is keyof WidgetTemplateVariables {\n return [\n \"projectName\",\n \"widgetScope\",\n \"widgetPackageVersion\",\n \"sdkVersion\",\n \"localCoreVersion\",\n \"fluidCliVersion\",\n \"widgetCliVersion\",\n \"droplet\",\n ].includes(key);\n}\n\nfunction getOutputFilename(filename: string): string {\n return filename.endsWith(\".template\")\n ? filename.slice(0, -\".template\".length)\n : filename;\n}\n\nfunction findPackageRoot(): string {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (!existsSync(path.join(dir, \"package.json\"))) {\n const parent = path.dirname(dir);\n if (parent === dir)\n throw new Error(\"Could not find widget CLI package root\");\n dir = parent;\n }\n return dir;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport path from \"node:path\";\nimport type { WidgetCreateOptions } from \"../types.js\";\nimport {\n copyWidgetTemplate,\n directoryExists,\n getCliVersion,\n getDefaultTemplatePath,\n getPortalCoreVersion,\n getPortalSdkVersion,\n getWidgetCliVersion,\n} from \"../utils/template.js\";\nimport {\n getInstallCommand,\n getRunCommand,\n installDependencies,\n} from \"../utils/package-manager.js\";\nimport {\n mergeWidgetConfig,\n validateDropletUuid,\n writeWidgetConfig,\n} from \"../utils/config.js\";\n\nconst DEFAULT_WIDGET_PACKAGE_VERSION = \"0.1.0\";\nconst DEFAULT_WIDGET_SCOPE = \"droplet\";\n\nexport const createCommand: Command = new Command(\"create\")\n .description(\"Create a standalone Fluid widget project\")\n .argument(\"<project-name>\", \"Name of the widget project to create\")\n .option(\"--skip-install\", \"Skip dependency installation\")\n .option(\n \"-o, --output-dir <dir>\",\n \"Directory to create the project in (defaults to cwd)\",\n )\n .option(\n \"--scope <scope>\",\n \"Widget package scope/namespace\",\n DEFAULT_WIDGET_SCOPE,\n )\n .option(\n \"--package-version <version>\",\n \"Initial widget package version\",\n DEFAULT_WIDGET_PACKAGE_VERSION,\n )\n .option(\n \"--local\",\n \"Use local monorepo packages via file: links (for development testing)\",\n )\n .option(\"--droplet <uuid>\", \"Existing droplet UUID that owns the package\")\n .action(async (projectName: string, options: WidgetCreateOptions) => {\n try {\n await createWidgetProject(projectName, options);\n } catch (err) {\n console.log();\n console.error(\n chalk.red(\"Error:\") +\n \" \" +\n (err instanceof Error ? err.message : String(err)),\n );\n console.log();\n process.exit(1);\n }\n });\n\nexport async function createWidgetProject(\n projectName: string,\n options: WidgetCreateOptions,\n): Promise<void> {\n console.log();\n console.log(chalk.bold(\"Creating a new Fluid widget project\"));\n console.log();\n\n const projectNameError = validateProjectName(projectName);\n if (projectNameError) throw new Error(projectNameError);\n\n const droplet = options.droplet?.trim();\n if (droplet) {\n const dropletError = validateDropletUuid(droplet);\n if (dropletError) throw new Error(dropletError);\n }\n\n const outputDir = path.resolve(options.outputDir ?? process.cwd());\n const targetPath = path.join(outputDir, projectName);\n if (await directoryExists(targetPath)) {\n throw new Error(`Directory already exists: ${targetPath}`);\n }\n\n const templatePath = getDefaultTemplatePath();\n if (!(await directoryExists(templatePath))) {\n throw new Error(\"Default widget template not found.\");\n }\n\n const config = mergeWidgetConfig({}, { droplet });\n const widgetScope = options.scope ?? DEFAULT_WIDGET_SCOPE;\n const localOptions = { local: options.local === true, targetPath };\n const variables = {\n projectName,\n droplet: config.droplet,\n widgetScope,\n widgetPackageVersion:\n options.packageVersion ?? DEFAULT_WIDGET_PACKAGE_VERSION,\n sdkVersion: await getPortalSdkVersion(localOptions),\n localCoreVersion: options.local\n ? await getPortalCoreVersion(localOptions)\n : undefined,\n fluidCliVersion: await getCliVersion(localOptions),\n widgetCliVersion: await getWidgetCliVersion(localOptions),\n };\n\n const spinner = ora(\"Copying widget template...\").start();\n try {\n await copyWidgetTemplate(templatePath, targetPath, variables);\n await writeWidgetConfig(targetPath, config);\n spinner.succeed(\"Copied widget template\");\n } catch (err) {\n spinner.fail(\"Failed to create widget project\");\n throw err;\n }\n\n const installCommand = getInstallCommand(targetPath);\n if (options.skipInstall !== true) {\n spinner.start(`Installing dependencies with ${installCommand}...`);\n try {\n await installDependencies(targetPath);\n spinner.succeed(\"Installed dependencies\");\n } catch {\n spinner.fail(\"Failed to install dependencies\");\n console.log();\n console.log(chalk.yellow(\"You can install dependencies manually:\"));\n console.log(chalk.cyan(` cd ${formatCdPath(targetPath)}`));\n console.log(chalk.cyan(` ${installCommand}`));\n }\n }\n\n console.log();\n console.log(\n chalk.green.bold(\"Success!\") + ` Created ${chalk.cyan(projectName)}`,\n );\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.cyan(` cd ${formatCdPath(targetPath)}`));\n if (options.skipInstall === true) {\n console.log(chalk.cyan(` ${installCommand}`));\n }\n if (!config.droplet) {\n console.log(chalk.cyan(\" fluid widget link\"));\n }\n console.log(chalk.cyan(` ${getRunCommand(\"dev\", targetPath)}`));\n console.log();\n console.log(\n \"Edit \" + chalk.cyan(\"manifest.ts\") + \" to customize your widget package.\",\n );\n console.log(\n chalk.dim(\n \"This command only creates local project files; it does not create a droplet.\",\n ),\n );\n console.log();\n}\n\nfunction validateProjectName(projectName: string): string | undefined {\n if (!projectName) return \"Project name is required.\";\n if (!/^[a-z0-9][a-z0-9-]*$/.test(projectName)) {\n return \"Project name must contain only lowercase letters, numbers, and hyphens.\";\n }\n return undefined;\n}\n\nfunction formatCdPath(targetPath: string): string {\n return path.relative(process.cwd(), targetPath) || \".\";\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport const DEFAULT_WIDGET_DEV_PORT = 5174;\n\nexport const WIDGET_DEV_ROUTES = [\n \"/\",\n \"/builder-preview\",\n \"/__manifests__\",\n \"/__preview__\",\n \"/__runtime-entry__\",\n] as const;\n\nexport interface WidgetDevOptions {\n readonly port?: string;\n readonly host?: boolean | string;\n readonly mode?: string;\n}\n\nexport interface WidgetDevProjectSummary {\n readonly projectDir: string;\n readonly packageName: string;\n readonly viteConfigPath: string;\n readonly localUrl: string;\n readonly target: string;\n readonly mode: string;\n readonly routes: readonly string[];\n}\n\nexport const devCommand: Command = new Command(\"dev\")\n .description(\"Start the local Fluid widget preview development server\")\n .option(\n \"-p, --port <port>\",\n \"Port to run the widget dev server on\",\n String(DEFAULT_WIDGET_DEV_PORT),\n )\n .option(\"--host [host]\", \"Expose the dev server to the network\")\n .option(\"--mode <mode>\", \"Vite mode to run\", \"development\")\n .action((options: WidgetDevOptions) => {\n return runCliAction(async () => {\n const projectDir = process.cwd();\n const summary = await resolveWidgetDevProject(projectDir, options);\n\n printWidgetDevSummary(summary);\n await runViteDevServer(projectDir, options);\n });\n });\n\nexport async function resolveWidgetDevProject(\n projectDir: string,\n options: WidgetDevOptions = {},\n): Promise<WidgetDevProjectSummary> {\n const resolvedProjectDir = path.resolve(projectDir);\n const packageJsonPath = path.join(resolvedProjectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n throw new Error(\n \"No package.json found. Run this command from a Fluid widget project directory.\",\n );\n }\n\n const packageJson = await readPackageJson(packageJsonPath);\n const packageName = readPackageName(packageJson) ?? path.basename(projectDir);\n\n const viteConfigPath = path.join(resolvedProjectDir, \"vite.config.ts\");\n if (!existsSync(viteConfigPath)) {\n throw new Error(\n \"No vite.config.ts found. Run this command from a Fluid widget project directory.\",\n );\n }\n\n const port = parsePort(options.port ?? String(DEFAULT_WIDGET_DEV_PORT));\n const host = normalizeHostOption(options.host);\n const mode = normalizeMode(options.mode);\n\n return {\n projectDir: resolvedProjectDir,\n packageName,\n viteConfigPath,\n localUrl: formatLocalUrl(port, host),\n target: packageName,\n mode,\n routes: WIDGET_DEV_ROUTES,\n };\n}\n\nexport function buildViteDevArgs(options: WidgetDevOptions = {}): string[] {\n const port = parsePort(options.port ?? String(DEFAULT_WIDGET_DEV_PORT));\n const host = normalizeHostOption(options.host);\n const mode = normalizeMode(options.mode);\n const args = [\"--port\", String(port), \"--mode\", mode];\n\n if (host) {\n args.push(\"--host\", host);\n }\n\n return args;\n}\n\nexport function printWidgetDevSummary(summary: WidgetDevProjectSummary): void {\n console.log();\n console.log(chalk.blue.bold(\"Fluid Widget Dev\"));\n console.log(chalk.gray(\"Local: \") + chalk.cyan(summary.localUrl));\n console.log(chalk.gray(\"Target: \") + chalk.white(summary.target));\n console.log(chalk.gray(\"Mode: \") + chalk.white(summary.mode));\n console.log(chalk.gray(\"Routes:\"));\n for (const route of summary.routes) {\n console.log(chalk.gray(\" - \") + chalk.cyan(route));\n }\n console.log();\n}\n\nexport async function runViteDevServer(\n projectDir: string,\n options: WidgetDevOptions = {},\n): Promise<void> {\n const viteCliPath = resolveViteCliPath(projectDir);\n if (!viteCliPath) {\n throw new Error(\n \"Unable to find Vite in node_modules. Run your package manager install command before starting widget dev.\",\n );\n }\n\n await runNodeScript(viteCliPath, buildViteDevArgs(options), projectDir);\n}\n\nfunction resolveViteCliPath(projectDir: string): string | undefined {\n const viteCliPath = path.join(\n projectDir,\n \"node_modules\",\n \"vite\",\n \"bin\",\n \"vite.js\",\n );\n return existsSync(viteCliPath) ? viteCliPath : undefined;\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(packageJsonPath, \"utf-8\")) as unknown;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Unable to read package.json: ${message}`);\n }\n}\n\nfunction readPackageName(packageJson: unknown): string | undefined {\n if (!isRecord(packageJson)) return undefined;\n const name = packageJson[\"name\"];\n if (typeof name !== \"string\") return undefined;\n const trimmed = name.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction parsePort(value: string): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new Error(\"Port must be an integer between 1 and 65535.\");\n }\n return port;\n}\n\nfunction normalizeHostOption(\n host: WidgetDevOptions[\"host\"],\n): string | undefined {\n if (host === undefined || host === false) return undefined;\n if (host === true) return \"0.0.0.0\";\n\n const trimmed = host.trim();\n return trimmed.length > 0 ? trimmed : \"0.0.0.0\";\n}\n\nfunction normalizeMode(mode: string | undefined): string {\n const trimmed = mode?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : \"development\";\n}\n\nfunction formatLocalUrl(port: number, host: string | undefined): string {\n const displayHost = host && host !== \"0.0.0.0\" ? host : \"localhost\";\n return `http://${displayHost}:${port}`;\n}\n\nfunction runNodeScript(\n scriptPath: string,\n args: readonly string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, [scriptPath, ...args], {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n if (code === 0 || signal === \"SIGINT\" || signal === \"SIGTERM\") {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `Vite dev server exited with signal ${signal}.`\n : `Vite dev server exited with code ${code ?? \"unknown\"}.`,\n ),\n );\n });\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport type { FetchClient } from \"@fluid-app/fluid-cli\";\n\nexport interface AuthenticatedClientResult {\n readonly client: FetchClient;\n}\n\nexport function createAuthenticatedClient(): AuthenticatedClientResult {\n return { client: createAuthenticatedWidgetPackageClient() };\n}\n","import prompts from \"prompts\";\nimport type { FetchClient } from \"@fluid-app/fluid-cli\";\nimport type { Choice } from \"prompts\";\n\nexport interface DropletChoice {\n readonly uuid: string;\n readonly name: string;\n}\n\nexport async function promptForDroplet(\n client: FetchClient,\n): Promise<string | undefined> {\n const droplets = await listDroplets(client);\n\n if (droplets.length === 0) {\n throw new Error(\n \"No droplets were found for this account. Create a droplet in Fluid first, then run this command again.\",\n );\n }\n\n const response = await prompts({\n type: \"autocomplete\",\n name: \"droplet\",\n message: \"Select the droplet that owns this widget package\",\n choices: droplets.map((droplet) => ({\n title: `${droplet.name} (${droplet.uuid})`,\n value: droplet.uuid,\n })),\n suggest: (input: string, choices: Choice[]) =>\n Promise.resolve(\n input\n ? choices.filter((choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()),\n )\n : choices,\n ),\n });\n\n return response[\"droplet\"] as string | undefined;\n}\n\nexport async function listDroplets(\n client: FetchClient,\n): Promise<readonly DropletChoice[]> {\n try {\n const response = await client.get<unknown>(\"/api/droplets\");\n return normalizeDropletsResponse(response);\n } catch (err) {\n if (isApiLikeError(err)) {\n if (err.status === 401 || err.status === 403) {\n throw new Error(\n \"Your Fluid session has expired. Run `fluid login` and try again.\",\n );\n }\n throw new Error(\n `Could not fetch droplets from Fluid (HTTP ${err.status}). ${err.message}`,\n );\n }\n\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Could not fetch droplets from Fluid. ${message}`);\n }\n}\n\nfunction normalizeDropletsResponse(response: unknown): DropletChoice[] {\n const candidates = extractDropletArray(response);\n return candidates\n .map(normalizeDroplet)\n .filter((droplet): droplet is DropletChoice => droplet !== undefined);\n}\n\nfunction extractDropletArray(response: unknown): readonly unknown[] {\n if (Array.isArray(response)) return response;\n if (!isRecord(response)) return [];\n\n const directDroplets = response[\"droplets\"];\n if (Array.isArray(directDroplets)) return directDroplets;\n\n const data = response[\"data\"];\n if (Array.isArray(data)) return data;\n if (isRecord(data) && Array.isArray(data[\"droplets\"])) {\n return data[\"droplets\"];\n }\n\n return [];\n}\n\nfunction normalizeDroplet(value: unknown): DropletChoice | undefined {\n if (!isRecord(value)) return undefined;\n\n const uuid = readString(value, \"uuid\") ?? readString(value, \"id\");\n if (!uuid) return undefined;\n\n const name =\n readString(value, \"name\") ??\n readString(value, \"title\") ??\n readString(value, \"slug\") ??\n uuid;\n\n return { uuid, name };\n}\n\nfunction readString(\n record: Readonly<Record<string, unknown>>,\n key: string,\n): string | undefined {\n const value = record[key];\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction isApiLikeError(\n error: unknown,\n): error is { readonly status: number; readonly message: string } {\n return (\n error instanceof Error &&\n \"status\" in error &&\n typeof (error as { readonly status?: unknown }).status === \"number\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport type { WidgetLinkOptions } from \"../types.js\";\nimport { createAuthenticatedClient } from \"../utils/auth-client.js\";\nimport { promptForDroplet } from \"../utils/droplets.js\";\nimport {\n WIDGET_CONFIG_FILE,\n loadWidgetConfig,\n mergeWidgetConfig,\n validateDropletUuid,\n writeWidgetConfig,\n} from \"../utils/config.js\";\n\nexport const linkCommand: Command = new Command(\"link\")\n .description(\"Link this widget project to an existing Fluid droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .action(async (options: WidgetLinkOptions) => {\n try {\n const projectDir = process.cwd();\n const loaded = await loadWidgetConfig(projectDir);\n\n let droplet = options.droplet?.trim() || undefined;\n if (!droplet) {\n const spinner = ora(\"Fetching droplets...\").start();\n try {\n const { client } = createAuthenticatedClient();\n spinner.stop();\n droplet = await promptForDroplet(client);\n } catch (err) {\n spinner.fail(\"Unable to load droplets\");\n throw err;\n }\n\n if (!droplet) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n }\n\n const nextConfig = mergeWidgetConfig(loaded.config, { droplet });\n const nextDropletError = validateDropletUuid(nextConfig.droplet ?? \"\");\n if (nextDropletError) throw new Error(nextDropletError);\n\n await writeWidgetConfig(projectDir, nextConfig);\n\n console.log();\n console.log(chalk.green(\"Linked widget project.\"));\n console.log(\n chalk.gray(\"Config: \") +\n chalk.cyan(\n path.relative(projectDir, loaded.path) || WIDGET_CONFIG_FILE,\n ),\n );\n console.log(\n chalk.gray(\"Droplet: \") + chalk.white(nextConfig.droplet),\n );\n console.log(\n chalk.gray(\"Package key: \") +\n chalk.white(`${nextConfig.droplet} (derived from droplet)`),\n );\n console.log();\n } catch (err) {\n console.log();\n console.error(\n chalk.red(\"Error:\") +\n \" \" +\n (err instanceof Error ? err.message : String(err)),\n );\n console.log();\n process.exit(1);\n }\n });\n","import type { FetchClient } from \"@fluid-app/fluid-cli\";\n\nexport interface DropletWidgetVersionSummary {\n readonly packageKey?: string;\n readonly packageId?: string;\n readonly version?: string;\n readonly status?: string;\n readonly createdAt?: string;\n readonly updatedAt?: string;\n readonly artifactCount?: number;\n readonly raw: unknown;\n}\n\nexport interface DropletWidgetLogEntry {\n readonly timestamp?: string;\n readonly level?: string;\n readonly message: string;\n readonly raw: unknown;\n}\n\nexport async function fetchDropletWidgetStatus(options: {\n readonly client: FetchClient;\n readonly droplet: string;\n}): Promise<DropletWidgetVersionSummary[]> {\n const response = await options.client.get<unknown>(\n `/api/droplets/${encodeURIComponent(options.droplet)}/widget_package_versions`,\n );\n return extractArray(response).map(normalizeVersionSummary);\n}\n\nexport async function fetchDropletWidgetLogs(options: {\n readonly client: FetchClient;\n readonly droplet: string;\n readonly limit?: number;\n}): Promise<DropletWidgetLogEntry[]> {\n const response = await options.client.get<unknown>(\n `/api/droplets/${encodeURIComponent(options.droplet)}/widget_package_versions/logs`,\n options.limit ? { limit: options.limit } : undefined,\n );\n return extractArray(response).map(normalizeLogEntry);\n}\n\nexport function formatStatusRows(\n versions: readonly DropletWidgetVersionSummary[],\n): string {\n if (versions.length === 0) return \"No widget package versions found.\";\n\n return versions\n .map((version) => {\n const identity =\n version.packageId ?? version.packageKey ?? \"unknown-package\";\n const release = version.version ?? \"unknown-version\";\n const status = version.status ?? \"unknown\";\n const updated = version.updatedAt ?? version.createdAt ?? \"unknown time\";\n const artifacts =\n version.artifactCount === undefined\n ? \"unknown artifacts\"\n : `${version.artifactCount} artifact${version.artifactCount === 1 ? \"\" : \"s\"}`;\n return `${identity}@${release} — ${status} — ${artifacts} — ${updated}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatLogRows(logs: readonly DropletWidgetLogEntry[]): string {\n if (logs.length === 0) return \"No widget package logs found.\";\n\n return logs\n .map((entry) => {\n const timestamp = entry.timestamp ?? \"unknown time\";\n const level = entry.level ? entry.level.toUpperCase() : \"INFO\";\n return `[${timestamp}] ${level} ${entry.message}`;\n })\n .join(\"\\n\");\n}\n\nfunction normalizeVersionSummary(value: unknown): DropletWidgetVersionSummary {\n const record = unwrapKnownNestedRecord(value);\n const artifacts = readArray(record, \"artifacts\");\n return {\n packageKey: readFirstString(record, [\"package_key\", \"packageKey\"]),\n packageId: readFirstString(record, [\"package_id\", \"packageId\"]),\n version: readFirstString(record, [\"version\", \"name\"]),\n status: readFirstString(record, [\"status\", \"state\"]),\n createdAt: readFirstString(record, [\"created_at\", \"createdAt\"]),\n updatedAt: readFirstString(record, [\"updated_at\", \"updatedAt\"]),\n ...(artifacts ? { artifactCount: artifacts.length } : {}),\n raw: value,\n };\n}\n\nfunction normalizeLogEntry(value: unknown): DropletWidgetLogEntry {\n const record = unwrapKnownNestedRecord(value);\n return {\n timestamp: readFirstString(record, [\n \"timestamp\",\n \"created_at\",\n \"createdAt\",\n ]),\n level: readFirstString(record, [\"level\", \"severity\"]),\n message:\n readFirstString(record, [\"message\", \"event\", \"status\", \"state\"]) ??\n JSON.stringify(value),\n raw: value,\n };\n}\n\nfunction extractArray(value: unknown): unknown[] {\n if (Array.isArray(value)) return value;\n if (!isRecord(value)) return [];\n\n for (const key of [\n \"widget_package_versions\",\n \"widgetPackageVersions\",\n \"versions\",\n \"logs\",\n \"events\",\n \"data\",\n ] as const) {\n const nested = value[key];\n if (Array.isArray(nested)) return nested;\n }\n\n return [value];\n}\n\nfunction unwrapKnownNestedRecord(value: unknown): Record<string, unknown> {\n if (!isRecord(value)) return {};\n for (const key of [\n \"widget_package_version\",\n \"widgetPackageVersion\",\n \"version\",\n \"log\",\n \"event\",\n ] as const) {\n const nested = value[key];\n if (isRecord(nested)) return nested;\n }\n return value;\n}\n\nfunction readArray(\n record: Record<string, unknown>,\n key: string,\n): readonly unknown[] | undefined {\n const value = record[key];\n return Array.isArray(value) ? value : undefined;\n}\n\nfunction readFirstString(\n record: Record<string, unknown>,\n keys: readonly string[],\n): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim().length > 0) return value;\n if (typeof value === \"number\" && Number.isFinite(value))\n return String(value);\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Command } from \"commander\";\nimport { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport { fetchDropletWidgetLogs, formatLogRows } from \"../utils/droplet-api.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface LogsCommandOptions {\n readonly droplet?: string;\n readonly limit?: string;\n readonly json?: boolean;\n}\n\nexport const logsCommand: Command = new Command(\"logs\")\n .description(\"Show recent widget package publish logs for a Droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--limit <number>\", \"Maximum number of log entries to request\", \"50\")\n .option(\"--json\", \"Print raw log response as JSON\")\n .action((options: LogsCommandOptions) => {\n return runCliAction(async () => {\n const droplet = await resolveDroplet(process.cwd(), options.droplet);\n const limit = parseLimit(options.limit);\n const logs = await fetchDropletWidgetLogs({\n client: createAuthenticatedWidgetPackageClient(),\n droplet,\n limit,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n logs.map((entry) => entry.raw),\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.blue.bold(`Widget logs for droplet ${droplet}`));\n console.log();\n console.log(formatLogRows(logs));\n });\n });\n\nasync function resolveDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n\nfunction parseLimit(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number(value);\n if (Number.isInteger(parsed) && parsed > 0 && parsed <= 500) return parsed;\n throw new Error(\"--limit must be an integer between 1 and 500.\");\n}\n","import { Command } from \"commander\";\nimport {\n createAuthenticatedWidgetPackageClient,\n printDryRunSessionPayload,\n printRuntimeOnlyNotice,\n printWidgetPublishSummary,\n publishWidgetRuntimeArtifacts,\n} from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n DEFAULT_WIDGET_OUT_DIR,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n} from \"../utils/source-package.js\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport { runCliAction } from \"../utils/command.js\";\nimport { runPackageScriptIfAvailable } from \"../utils/package-scripts.js\";\n\nexport interface PublishWidgetPackageOptions {\n readonly projectDir: string;\n readonly outDir: string;\n readonly droplet?: string;\n readonly dryRun?: boolean;\n readonly skipTypecheck?: boolean;\n readonly client?: unknown;\n}\n\nexport interface PublishWidgetPackageResult {\n readonly dryRun: boolean;\n readonly uploaded: boolean;\n readonly outDir: string;\n readonly droplet?: string;\n}\n\nexport interface PublishWidgetPackageDependencies {\n readonly buildWidgetPackage: (options: {\n readonly projectDir: string;\n readonly outDir: string;\n }) => Promise<void>;\n readonly uploadWidgetPackage: (options: {\n readonly outDir: string;\n readonly droplet?: string;\n readonly client?: unknown;\n }) => Promise<void>;\n}\n\nexport async function publishWidgetPackage(\n options: PublishWidgetPackageOptions,\n dependencies?: PublishWidgetPackageDependencies,\n): Promise<PublishWidgetPackageResult> {\n if (dependencies) {\n await dependencies.buildWidgetPackage({\n projectDir: options.projectDir,\n outDir: options.outDir,\n });\n\n const dryRun = options.dryRun === true;\n if (dryRun) {\n return { dryRun, uploaded: false, outDir: options.outDir };\n }\n\n await dependencies.uploadWidgetPackage({\n outDir: options.outDir,\n droplet: options.droplet,\n client: options.client,\n });\n return { dryRun, uploaded: true, outDir: options.outDir };\n }\n\n const droplet = await resolvePublishDroplet(\n options.projectDir,\n options.droplet,\n );\n\n await validateDropletWidgetProject(options.projectDir, droplet);\n if (options.skipTypecheck !== true) {\n await runPackageScriptIfAvailable({\n projectDir: options.projectDir,\n scriptName: \"typecheck\",\n });\n }\n\n const dryRun = options.dryRun === true;\n await withRootWidgetConfigBridge(\n options.projectDir,\n () =>\n publishWidgetRuntimeArtifacts({\n projectDir: options.projectDir,\n outDir: options.outDir,\n buildOwner: \"droplet\",\n uploadOwner: { kind: \"droplet\", uuid: droplet },\n dryRun,\n ...(dryRun ? {} : { client: createAuthenticatedWidgetPackageClient() }),\n }),\n droplet,\n );\n\n return {\n dryRun,\n uploaded: !dryRun,\n outDir: options.outDir,\n droplet,\n };\n}\n\nexport interface PublishCommandOptions {\n readonly outDir?: string;\n readonly droplet?: string;\n readonly dryRun?: boolean;\n readonly skipTypecheck?: boolean;\n}\n\nexport const publishCommand: Command = new Command(\"publish\")\n .description(\"Publish a Fluid widget package\")\n .option(\n \"-o, --out-dir <dir>\",\n \"Widget artifact output directory\",\n DEFAULT_WIDGET_OUT_DIR,\n )\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--dry-run\", \"Build and validate without uploading\")\n .option(\"--skip-typecheck\", \"Skip package typecheck script when present\")\n .action((options: PublishCommandOptions) => {\n return runCliAction(async () => {\n const projectDir = process.cwd();\n const outDir = options.outDir ?? DEFAULT_WIDGET_OUT_DIR;\n const droplet = await resolvePublishDroplet(projectDir, options.droplet);\n const dryRun = options.dryRun === true;\n\n console.log();\n console.log(chalk.blue.bold(\"Fluid Widget Publish\"));\n console.log();\n printRuntimeOnlyNotice();\n console.log(chalk.gray(\"Droplet: \") + chalk.white(droplet));\n console.log(chalk.gray(\"Output: \") + chalk.cyan(outDir));\n if (dryRun) {\n console.log(chalk.yellow(\"Dry run: no upload will be created.\"));\n }\n console.log();\n\n const validateSpinner = ora(\"Validating widget package...\").start();\n await validateDropletWidgetProject(projectDir, droplet);\n validateSpinner.succeed(\"Validated widget package\");\n\n if (options.skipTypecheck !== true) {\n const typecheckSpinner = ora(\"Running package typecheck...\").start();\n const typecheck = await runPackageScriptIfAvailable({\n projectDir,\n scriptName: \"typecheck\",\n });\n if (typecheck.ran) {\n typecheckSpinner.succeed(\"Package typecheck passed\");\n } else {\n typecheckSpinner.info(\"No typecheck script found; skipping\");\n }\n }\n\n const publishSpinner = ora(\n dryRun\n ? \"Building and preparing dry-run upload payload...\"\n : \"Building and publishing widget artifacts...\",\n ).start();\n\n const result = await withRootWidgetConfigBridge(\n projectDir,\n () =>\n publishWidgetRuntimeArtifacts({\n projectDir,\n outDir,\n buildOwner: \"droplet\",\n uploadOwner: { kind: \"droplet\", uuid: droplet },\n dryRun,\n ...(dryRun\n ? {}\n : { client: createAuthenticatedWidgetPackageClient() }),\n }),\n droplet,\n );\n\n publishSpinner.succeed(\n dryRun ? \"Prepared dry-run upload payload\" : \"Published widget package\",\n );\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"Dry run complete — upload session was not requested.\"),\n );\n console.log();\n printDryRunSessionPayload(result);\n }\n\n printWidgetPublishSummary({\n title: dryRun ? \"Widget publish dry run\" : \"Widget publish\",\n ownerLabel: `droplet ${droplet}`,\n outDir,\n result,\n });\n });\n });\n\nasync function resolvePublishDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n","import { Command } from \"commander\";\nimport { createAuthenticatedWidgetPackageClient } from \"@fluid-app/fluid-cli-portal\";\nimport chalk from \"chalk\";\nimport { loadWidgetConfig, validateDropletUuid } from \"../utils/config.js\";\nimport {\n fetchDropletWidgetStatus,\n formatStatusRows,\n} from \"../utils/droplet-api.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface StatusCommandOptions {\n readonly droplet?: string;\n readonly json?: boolean;\n}\n\nexport const statusCommand: Command = new Command(\"status\")\n .description(\"Show published widget package status for a Droplet\")\n .option(\"--droplet <uuid>\", \"Droplet UUID that owns the widget package\")\n .option(\"--json\", \"Print raw status response as JSON\")\n .action((options: StatusCommandOptions) => {\n return runCliAction(async () => {\n const droplet = await resolveDroplet(process.cwd(), options.droplet);\n const versions = await fetchDropletWidgetStatus({\n client: createAuthenticatedWidgetPackageClient(),\n droplet,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n versions.map((version) => version.raw),\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.blue.bold(`Widget status for droplet ${droplet}`));\n console.log();\n console.log(formatStatusRows(versions));\n });\n });\n\nasync function resolveDroplet(\n projectDir: string,\n override: string | undefined,\n): Promise<string> {\n const droplet =\n override?.trim() || (await loadWidgetConfig(projectDir)).config.droplet;\n if (droplet?.trim()) {\n const trimmedDroplet = droplet.trim();\n const dropletError = validateDropletUuid(trimmedDroplet);\n if (dropletError) throw new Error(dropletError);\n return trimmedDroplet;\n }\n\n throw new Error(\n \"Missing droplet UUID. Pass --droplet <uuid> or set droplet in fluid.widget.config.ts.\",\n );\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n formatValidationSuccess,\n validateDropletWidgetProject,\n} from \"../utils/source-package.js\";\nimport { runCliAction } from \"../utils/command.js\";\n\nexport interface ValidateWidgetOptions {\n readonly json?: boolean;\n}\n\nexport const validateCommand: Command = new Command(\"validate\")\n .description(\"Validate the current droplet widget package\")\n .option(\"--json\", \"Print machine-readable validation output\")\n .action((options: ValidateWidgetOptions) => {\n return runCliAction(async () => {\n const result = await validateDropletWidgetProject(process.cwd());\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n valid: true,\n config: result.sourceConfigPath,\n packageId: result.validated.packageId,\n version: result.validated.version,\n widgets: result.validated.widgets.map((widget) => ({\n name: widget.name,\n type: widget.type,\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(chalk.green(formatValidationSuccess(result)));\n });\n });\n","import { Command } from \"commander\";\nimport type { FluidPlugin, PluginContext } from \"@fluid-app/fluid-cli\";\nimport { buildCommand } from \"./commands/build.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { devCommand } from \"./commands/dev.js\";\nimport { linkCommand } from \"./commands/link.js\";\nimport { logsCommand } from \"./commands/logs.js\";\nimport { publishCommand } from \"./commands/publish.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { validateCommand } from \"./commands/validate.js\";\n\nexport const widgetCommand: Command = new Command(\"widget\")\n .description(\n \"Create, preview, link, validate, build, and publish standalone Fluid widgets\",\n )\n .addCommand(createCommand)\n .addCommand(devCommand)\n .addCommand(linkCommand)\n .addCommand(validateCommand)\n .addCommand(buildCommand)\n .addCommand(publishCommand)\n .addCommand(statusCommand)\n .addCommand(logsCommand);\n\nconst plugin: FluidPlugin = {\n name: \"@fluid-app/fluid-cli-widget\",\n version: \"0.1.0\",\n register(ctx: PluginContext) {\n const existingWidgetCommand = findCommand(ctx.program, \"widget\");\n if (existingWidgetCommand) {\n addCommandIfMissing(existingWidgetCommand, createCommand);\n addCommandIfMissing(existingWidgetCommand, devCommand);\n addCommandIfMissing(existingWidgetCommand, linkCommand);\n addCommandIfMissing(existingWidgetCommand, validateCommand);\n addCommandIfMissing(existingWidgetCommand, buildCommand);\n addCommandIfMissing(existingWidgetCommand, publishCommand);\n addCommandIfMissing(existingWidgetCommand, statusCommand);\n addCommandIfMissing(existingWidgetCommand, logsCommand);\n return;\n }\n\n ctx.program.addCommand(widgetCommand);\n },\n};\n\nexport default plugin;\n\nexport type {\n WidgetCommandOptions,\n WidgetCreateOptions,\n WidgetLinkOptions,\n WidgetTemplateVariables,\n} from \"./types.js\";\nexport { buildCommand, buildWidgetPackage } from \"./commands/build.js\";\nexport type {\n BuildWidgetOptions,\n BuildWidgetPackageOptions,\n BuildWidgetPackageResult,\n} from \"./commands/build.js\";\nexport { createCommand, createWidgetProject } from \"./commands/create.js\";\nexport {\n DEFAULT_WIDGET_DEV_PORT,\n WIDGET_DEV_ROUTES,\n buildViteDevArgs,\n devCommand,\n printWidgetDevSummary,\n resolveWidgetDevProject,\n runViteDevServer,\n} from \"./commands/dev.js\";\nexport type {\n WidgetDevOptions,\n WidgetDevProjectSummary,\n} from \"./commands/dev.js\";\nexport { linkCommand } from \"./commands/link.js\";\nexport { logsCommand } from \"./commands/logs.js\";\nexport type { LogsCommandOptions } from \"./commands/logs.js\";\nexport { publishCommand, publishWidgetPackage } from \"./commands/publish.js\";\nexport type {\n PublishCommandOptions,\n PublishWidgetPackageDependencies,\n PublishWidgetPackageOptions,\n PublishWidgetPackageResult,\n} from \"./commands/publish.js\";\nexport { statusCommand } from \"./commands/status.js\";\nexport type { StatusCommandOptions } from \"./commands/status.js\";\nexport { validateCommand } from \"./commands/validate.js\";\nexport type { ValidateWidgetOptions } from \"./commands/validate.js\";\nexport {\n WIDGET_CONFIG_FILE,\n formatWidgetConfig,\n loadWidgetConfig,\n mergeWidgetConfig,\n parseWidgetConfigSource,\n resolveWidgetConfigPath,\n validateDropletUuid,\n writeWidgetConfig,\n type FluidWidgetConfig,\n type LoadedWidgetConfig,\n} from \"./utils/config.js\";\nexport {\n DEFAULT_WIDGET_OUT_DIR,\n ROOT_WIDGET_CONFIG_FILE,\n WidgetValidationError,\n formatValidationSuccess,\n resolveWidgetSourceConfig,\n validateDropletWidgetProject,\n withRootWidgetConfigBridge,\n type WidgetValidationResult,\n} from \"./utils/source-package.js\";\nexport { formatValidationErrors } from \"./utils/validation.js\";\nexport type { WidgetCliValidationError } from \"./utils/validation.js\";\n\nfunction addCommandIfMissing(parent: Command, child: Command): void {\n if (findCommand(parent, child.name())) return;\n parent.addCommand(child);\n}\n\nfunction findCommand(parent: Command, name: string): Command | undefined {\n return parent.commands?.find((command) => command.name() === name);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-app/fluid-cli-widget",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Fluid CLI plugin for standalone widget package workflows",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"commander": "^12.0.0",
|
|
24
24
|
"ora": "^8.0.0",
|
|
25
25
|
"prompts": "^2.4.2",
|
|
26
|
-
"@fluid-app/fluid-cli-portal": "0.1.
|
|
27
|
-
"@fluid-app/fluid-cli": "0.1.
|
|
26
|
+
"@fluid-app/fluid-cli-portal": "0.1.30",
|
|
27
|
+
"@fluid-app/fluid-cli": "0.1.11"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^24",
|
|
@@ -13,19 +13,27 @@
|
|
|
13
13
|
"widget:publish": "fluid widget publish"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@fluid-app/portal-core": "{{coreVersion}}",
|
|
17
16
|
"@fluid-app/portal-sdk": "{{sdkVersion}}",
|
|
18
|
-
|
|
19
|
-
"
|
|
17
|
+
{{#if localCoreVersion}}
|
|
18
|
+
"@fluid-app/portal-core": "{{localCoreVersion}}",
|
|
19
|
+
{{/if}}
|
|
20
|
+
"@hookform/resolvers": "^5.2.2",
|
|
21
|
+
"@tanstack/react-query": "^5.90.11",
|
|
22
|
+
"lucide-react": "~0.575.0",
|
|
23
|
+
"react": "^19.2.4",
|
|
24
|
+
"react-dom": "^19.2.4",
|
|
25
|
+
"react-hook-form": "^7.64.0",
|
|
26
|
+
"zod": "4.3.5",
|
|
27
|
+
"zustand": "^5.0.9"
|
|
20
28
|
},
|
|
21
29
|
"devDependencies": {
|
|
22
30
|
"@fluid-app/fluid-cli": "{{fluidCliVersion}}",
|
|
23
31
|
"@vitejs/plugin-react": "^4.3.0",
|
|
24
32
|
"typescript": "^5.6.0",
|
|
25
|
-
"vite": "^6.
|
|
33
|
+
"vite": "^6.4.1",
|
|
26
34
|
"@fluid-app/fluid-cli-widget": "{{widgetCliVersion}}",
|
|
27
|
-
"@types/react": "^19.
|
|
28
|
-
"@types/react-dom": "^19.
|
|
35
|
+
"@types/react": "^19.2.13",
|
|
36
|
+
"@types/react-dom": "^19.2.3"
|
|
29
37
|
},
|
|
30
38
|
"engines": {
|
|
31
39
|
"node": ">=24.0.0"
|