@sanity/workbench-cli 2.0.2 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +1 -1
  2. package/dist/_exports/_internal_render.d.ts +12 -0
  3. package/dist/_exports/_internal_render.js +3 -0
  4. package/dist/_exports/_internal_render.js.map +1 -0
  5. package/dist/_exports/build.d.ts +4 -4
  6. package/dist/_exports/build.js +2 -1
  7. package/dist/_exports/build.js.map +1 -1
  8. package/dist/_exports/defineApp-DldjQwq6.d.ts +375 -0
  9. package/dist/_exports/deploy.d.ts +10 -9
  10. package/dist/_exports/deploy.js +1 -0
  11. package/dist/_exports/deploy.js.map +1 -1
  12. package/dist/_exports/dev.d.ts +1 -1
  13. package/dist/_exports/index.d.ts +23 -16
  14. package/dist/_exports/index.js +2 -1
  15. package/dist/_exports/index.js.map +1 -1
  16. package/dist/_exports/preview.d.ts +1 -1
  17. package/dist/_exports/{registry-DI7hnTof.d.ts → registry-HE_dEHFa.d.ts} +38 -15
  18. package/dist/_exports/resolveWorkbenchConfig-6iznHbED.d.ts +60 -0
  19. package/dist/_exports/{summarizeInterfaces-DBGiAwNT.d.ts → summarizeInterfaces-CjkeWwkY.d.ts} +20 -17
  20. package/dist/_exports/undeploy.d.ts +12 -9
  21. package/dist/actions/build/artifact.js +1 -1
  22. package/dist/actions/build/artifact.js.map +1 -1
  23. package/dist/actions/build/views/artifact.js +1 -1
  24. package/dist/actions/build/views/artifact.js.map +1 -1
  25. package/dist/actions/build/vite/optimize-deps.js +3 -3
  26. package/dist/actions/build/vite/optimize-deps.js.map +1 -1
  27. package/dist/actions/build/vite/plugins/plugin-module-federation.js +8 -17
  28. package/dist/actions/build/vite/plugins/plugin-module-federation.js.map +1 -1
  29. package/dist/actions/build/vite/plugins/plugin-sanity-federation-runtime.js +1 -1
  30. package/dist/actions/build/vite/plugins/plugin-sanity-federation-runtime.js.map +1 -1
  31. package/dist/actions/build/vite/workbench-vite-plugins.js +1 -1
  32. package/dist/actions/build/vite/workbench-vite-plugins.js.map +1 -1
  33. package/dist/actions/deploy/deployPayload.js +0 -3
  34. package/dist/actions/deploy/deployPayload.js.map +1 -1
  35. package/dist/actions/deploy/deployWorkbenchApp.js +46 -4
  36. package/dist/actions/deploy/deployWorkbenchApp.js.map +1 -1
  37. package/dist/actions/deploy/getWorkbench.js +4 -5
  38. package/dist/actions/deploy/getWorkbench.js.map +1 -1
  39. package/dist/actions/deploy/summarizeInterfaces.js +14 -10
  40. package/dist/actions/deploy/summarizeInterfaces.js.map +1 -1
  41. package/dist/actions/deploy/viewDeployment.js +17 -5
  42. package/dist/actions/deploy/viewDeployment.js.map +1 -1
  43. package/dist/actions/dev/deriveConfigs.js +9 -6
  44. package/dist/actions/dev/deriveConfigs.js.map +1 -1
  45. package/dist/actions/dev/exposesSetId.js +2 -2
  46. package/dist/actions/dev/exposesSetId.js.map +1 -1
  47. package/dist/actions/dev/registry.js +31 -25
  48. package/dist/actions/dev/registry.js.map +1 -1
  49. package/dist/actions/dev/startDevManifestWatcher.js.map +1 -1
  50. package/dist/actions/dev/startDevServerRegistration.js +35 -60
  51. package/dist/actions/dev/startDevServerRegistration.js.map +1 -1
  52. package/dist/actions/dev/startWorkbenchDevServer.js +15 -33
  53. package/dist/actions/dev/startWorkbenchDevServer.js.map +1 -1
  54. package/dist/actions/dev/writeWorkbenchRuntime.js +2 -2
  55. package/dist/actions/dev/writeWorkbenchRuntime.js.map +1 -1
  56. package/dist/actions/preview/serveBuiltApplication.js +1 -1
  57. package/dist/actions/preview/serveBuiltApplication.js.map +1 -1
  58. package/dist/actions/preview/startWorkbenchPreview.js +1 -1
  59. package/dist/actions/preview/startWorkbenchPreview.js.map +1 -1
  60. package/dist/actions/undeploy/workbenchUndeployAdapter.js +24 -33
  61. package/dist/actions/undeploy/workbenchUndeployAdapter.js.map +1 -1
  62. package/dist/appId.js +13 -9
  63. package/dist/appId.js.map +1 -1
  64. package/dist/applicationReference.js +12 -0
  65. package/dist/applicationReference.js.map +1 -0
  66. package/dist/contract.js +69 -31
  67. package/dist/contract.js.map +1 -1
  68. package/dist/defineApp.js +53 -63
  69. package/dist/defineApp.js.map +1 -1
  70. package/dist/defineView.js +3 -3
  71. package/dist/defineView.js.map +1 -1
  72. package/dist/deriveInterfaces.js +45 -19
  73. package/dist/deriveInterfaces.js.map +1 -1
  74. package/dist/renderDashboard.js +63 -0
  75. package/dist/renderDashboard.js.map +1 -0
  76. package/dist/resolveWorkbenchApp.js +13 -9
  77. package/dist/resolveWorkbenchApp.js.map +1 -1
  78. package/dist/resolveWorkbenchConfig.js +30 -0
  79. package/dist/resolveWorkbenchConfig.js.map +1 -0
  80. package/dist/services/applications.js +7 -1
  81. package/dist/services/applications.js.map +1 -1
  82. package/package.json +12 -6
  83. package/dist/_exports/contract-DyG11fQ7.d.ts +0 -45
  84. package/dist/_exports/defineApp-r_CmoZfS.d.ts +0 -169
  85. package/dist/_exports/resolveWorkbenchApp-DqFqET9E.d.ts +0 -41
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n\n if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application')\n const inlinedId = await readInlinedAppId(outDir)\n const configs = await deriveConfigs(cliConfig.app)\n const id = inlinedId ?? (await buildAppId(workbench))\n const registration = registerDevServer({\n configs,\n host: remote.host,\n id,\n interfaces: deriveInterfaces(cliConfig.app, {isApp}),\n manifest: await extractManifest({configPath, workDir}),\n manifestUpdatedAt: new Date().toISOString(),\n port: remote.port,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n closers.push(async () => registration.release())\n } catch (err) {\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n output.log(\n `Workbench preview server started at ${styleText(['blue', 'underline'], workbenchUrl)} (serving build on port ${remote.port})`,\n )\n } else {\n const remoteUrl = `http://${toDisplayHost(remote.host)}:${remote.port}`\n output.log(`Serving build at ${styleText(['blue', 'underline'], remoteUrl)}`)\n }\n\n installSignalHandlers()\n\n return {close}\n}\n\n/** The id the build inlined into its bundle, or undefined when absent. */\nasync function readInlinedAppId(outDir: string): Promise<string | undefined> {\n try {\n return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined\n } catch {\n return undefined\n }\n}\n"],"names":["readFile","path","styleText","findProjectRoot","buildAppId","SANITY_APP_ID_FILE","deriveInterfaces","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","registerDevServer","startWorkbenchDevServer","serveBuiltApplication","startWorkbenchPreview","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","outDir","output","reactStrictMode","workDir","close","closers","installSignalHandlers","workbench","mode","push","remotePort","workbenchAvailable","workbenchPort","remote","catch","err","configPath","Error","inlinedId","readInlinedAppId","configs","app","id","registration","host","interfaces","manifest","manifestUpdatedAt","Date","toISOString","port","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n\n if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application')\n const inlinedId = await readInlinedAppId(outDir)\n const configs = await deriveConfigs(cliConfig)\n const id = inlinedId ?? (await buildAppId(workbench))\n const registration = registerDevServer({\n configs,\n host: remote.host,\n id,\n interfaces: deriveInterfaces(cliConfig.app, {isApp}),\n manifest: await extractManifest({configPath, workDir}),\n manifestUpdatedAt: new Date().toISOString(),\n port: remote.port,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n closers.push(async () => registration.release())\n } catch (err) {\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n output.log(\n `Workbench preview server started at ${styleText(['blue', 'underline'], workbenchUrl)} (serving build on port ${remote.port})`,\n )\n } else {\n const remoteUrl = `http://${toDisplayHost(remote.host)}:${remote.port}`\n output.log(`Serving build at ${styleText(['blue', 'underline'], remoteUrl)}`)\n }\n\n installSignalHandlers()\n\n return {close}\n}\n\n/** The id the build inlined into its bundle, or undefined when absent. */\nasync function readInlinedAppId(outDir: string): Promise<string | undefined> {\n try {\n return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined\n } catch {\n return undefined\n }\n}\n"],"names":["readFile","path","styleText","findProjectRoot","buildAppId","SANITY_APP_ID_FILE","deriveInterfaces","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","registerDevServer","startWorkbenchDevServer","serveBuiltApplication","startWorkbenchPreview","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","outDir","output","reactStrictMode","workDir","close","closers","installSignalHandlers","workbench","mode","push","remotePort","workbenchAvailable","workbenchPort","remote","catch","err","configPath","Error","inlinedId","readInlinedAppId","configs","id","registration","host","interfaces","app","manifest","manifestUpdatedAt","Date","toISOString","port","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"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"}
@@ -3,29 +3,29 @@ import { deleteConfig, listConfigs } from '../../services/installations.js';
3
3
  import { resolveInstallationId, summarizeConfig } from '../deploy/deployConfig.js';
4
4
  import { summarizeInterfaces } from '../deploy/summarizeInterfaces.js';
5
5
  /**
6
- * The undeploy adapter for workbench apps, mirroring what a workbench deploy
7
- * creates: apps that expose interfaces delete their Brett application (the
8
- * server soft-deletes its deployments and refuses singletons with active
9
- * installations); a singleton without interfaces — the media library — deletes
10
- * its installation's config snapshots instead.
6
+ * The undeploy adapter for workbench apps and configs, mirroring what a
7
+ * workbench deploy creates: an app that exposes interfaces deletes its Brett
8
+ * application (the server soft-deletes its deployments and refuses singletons
9
+ * with active installations); a config — the media library — deletes its
10
+ * installation's config snapshots instead. The two are severed at the source,
11
+ * so exactly one of `workbench`/`config` is supplied and the brand decides the path.
11
12
  */ export function createWorkbenchUndeployAdapter(options) {
12
- const { appId, organizationId, type, workbench } = options;
13
- // Keyed on singleton-ness, not on a locally declared config, so an undeploy
14
- // still reaches the server's config snapshots after the fields are removed
15
- // from sanity.cli.ts.
16
- const configOnly = !!workbench.isSingleton && !workbench.hasInterfaces;
13
+ const { appId, config, organizationId, type, workbench } = options;
17
14
  // Workbench-internal, so kept off the reported target; resolveTarget stashes it for the delete.
18
15
  let installationId;
19
16
  return {
20
17
  resolveTarget: async ()=>{
21
- if (!configOnly) return resolveApplicationTarget({
22
- appId,
23
- type,
24
- workbench
25
- });
18
+ if (!config) {
19
+ if (!workbench) throw new Error('No workbench app or config to undeploy');
20
+ return resolveApplicationTarget({
21
+ appId,
22
+ type,
23
+ workbench
24
+ });
25
+ }
26
26
  const resolved = await resolveConfigTarget({
27
- organizationId,
28
- workbench
27
+ config,
28
+ organizationId
29
29
  });
30
30
  installationId = resolved.installationId;
31
31
  return resolved.resolution;
@@ -71,12 +71,7 @@ async function resolveApplicationTarget({ appId, type, workbench }) {
71
71
  views
72
72
  },
73
73
  services,
74
- summary: [
75
- ...lines,
76
- ...workbench.isSingleton === undefined ? [] : [
77
- `Singleton: ${workbench.isSingleton}`
78
- ]
79
- ],
74
+ summary: lines,
80
75
  title: application.title,
81
76
  type,
82
77
  url: getApplicationUrl({
@@ -88,10 +83,8 @@ async function resolveApplicationTarget({ appId, type, workbench }) {
88
83
  type: 'found'
89
84
  };
90
85
  }
91
- async function resolveConfigTarget({ organizationId, workbench }) {
92
- const config = workbench.config;
93
- const appType = config?.appType ?? workbench.applicationType;
94
- if (!appType) throw new Error('The app declares no app type to resolve its installation');
86
+ async function resolveConfigTarget({ config, organizationId }) {
87
+ const { appType } = config;
95
88
  if (!organizationId) {
96
89
  throw new Error('sanity.cli.ts does not contain an organization identifier ("app.organizationId"), which is required to resolve the installation');
97
90
  }
@@ -126,15 +119,13 @@ async function resolveConfigTarget({ organizationId, workbench }) {
126
119
  id: null,
127
120
  payload: {
128
121
  appId: null,
129
- ...config ? {
130
- config: summarizeConfig(config)
131
- } : {},
122
+ config: summarizeConfig(config),
132
123
  type: 'coreApp'
133
124
  },
134
- summary: config ? [
125
+ summary: [
135
126
  summarizeConfig(config)
136
- ] : [],
137
- title: workbench.slug,
127
+ ],
128
+ title: appType,
138
129
  type: 'coreApp',
139
130
  url: getWorkbenchUrl(organizationId)
140
131
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/undeploy/workbenchUndeployAdapter.ts"],"sourcesContent":["import {\n type UndeployAdapter,\n type UndeployApplicationTarget,\n type UndeployConfigTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\n\nimport {\n deleteApplication,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n} from '../../services/applications.js'\nimport {type ConfigSnapshot, deleteConfig, listConfigs} from '../../services/installations.js'\nimport {resolveInstallationId, summarizeConfig} from '../deploy/deployConfig.js'\nimport {type DeployableWorkbenchApp} from '../deploy/getWorkbench.js'\nimport {type DeployedInterface, summarizeInterfaces} from '../deploy/summarizeInterfaces.js'\n\n/** The workbench extension of the shared target; serializes into `--json` as-is. */\nexport type WorkbenchUndeployTarget =\n | (UndeployApplicationTarget & {\n services: DeployedInterface[]\n views: DeployedInterface[]\n })\n | (UndeployConfigTarget & {\n configs: ConfigSnapshot[]\n })\n\n/**\n * The undeploy adapter for workbench apps, mirroring what a workbench deploy\n * creates: apps that expose interfaces delete their Brett application (the\n * server soft-deletes its deployments and refuses singletons with active\n * installations); a singleton without interfaces — the media library — deletes\n * its installation's config snapshots instead.\n */\nexport function createWorkbenchUndeployAdapter(options: {\n appId: string | undefined\n organizationId: string | undefined\n type: 'coreApp' | 'studio'\n workbench: DeployableWorkbenchApp\n}): UndeployAdapter<WorkbenchUndeployTarget> {\n const {appId, organizationId, type, workbench} = options\n // Keyed on singleton-ness, not on a locally declared config, so an undeploy\n // still reaches the server's config snapshots after the fields are removed\n // from sanity.cli.ts.\n const configOnly = !!workbench.isSingleton && !workbench.hasInterfaces\n // Workbench-internal, so kept off the reported target; resolveTarget stashes it for the delete.\n let installationId: string | undefined\n\n return {\n resolveTarget: async () => {\n if (!configOnly) return resolveApplicationTarget({appId, type, workbench})\n const resolved = await resolveConfigTarget({organizationId, workbench})\n installationId = resolved.installationId\n return resolved.resolution\n },\n type,\n async undeploy(target) {\n if (target.deletes === 'config') {\n if (!installationId) throw new Error('No installation resolved for the config undeploy')\n for (const snapshot of target.configs) {\n await deleteConfig(installationId, snapshot.id)\n }\n return\n }\n await deleteApplication(target.id)\n },\n }\n}\n\nasync function resolveApplicationTarget({\n appId,\n type,\n workbench,\n}: {\n appId: string | undefined\n type: 'coreApp' | 'studio'\n workbench: DeployableWorkbenchApp\n}): Promise<UndeployTargetResolution<WorkbenchUndeployTarget>> {\n if (!appId) {\n return {\n message: 'No `deployment.appId` configured',\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n type: 'none',\n }\n }\n\n const application = await getApplication(appId)\n if (!application) {\n return {message: 'Application with the given ID does not exist', type: 'none'}\n }\n\n const {lines, services, views} = summarizeInterfaces(workbench)\n return {\n target: {\n application,\n deletes: 'application',\n id: application.id,\n payload: {appId: application.id, services, type, views},\n services,\n summary: [\n ...lines,\n ...(workbench.isSingleton === undefined ? [] : [`Singleton: ${workbench.isSingleton}`]),\n ],\n title: application.title,\n type,\n url: getApplicationUrl({...application, type}),\n views,\n },\n type: 'found',\n }\n}\n\nasync function resolveConfigTarget({\n organizationId,\n workbench,\n}: {\n organizationId: string | undefined\n workbench: DeployableWorkbenchApp\n}): Promise<{\n installationId?: string\n resolution: UndeployTargetResolution<WorkbenchUndeployTarget>\n}> {\n const config = workbench.config\n const appType = config?.appType ?? workbench.applicationType\n if (!appType) throw new Error('The app declares no app type to resolve its installation')\n if (!organizationId) {\n throw new Error(\n 'sanity.cli.ts does not contain an organization identifier (\"app.organizationId\"), which is required to resolve the installation',\n )\n }\n\n const installationId = await resolveInstallationId({appType, organizationId})\n if (!installationId) {\n return {\n resolution: {\n message: `No active \"${appType}\" installation for organization \"${organizationId}\"`,\n type: 'none',\n },\n }\n }\n\n const configs = await listConfigs(installationId)\n if (configs.length === 0) {\n return {\n installationId,\n resolution: {\n message: `No deployed config for the \"${appType}\" installation`,\n type: 'none',\n },\n }\n }\n\n return {\n installationId,\n resolution: {\n target: {\n configs,\n deletes: 'config',\n id: null,\n payload: {\n appId: null,\n ...(config ? {config: summarizeConfig(config)} : {}),\n type: 'coreApp',\n },\n summary: config ? [summarizeConfig(config)] : [],\n title: workbench.slug,\n type: 'coreApp',\n url: getWorkbenchUrl(organizationId),\n },\n type: 'found',\n },\n }\n}\n"],"names":["deleteApplication","getApplication","getApplicationUrl","getWorkbenchUrl","deleteConfig","listConfigs","resolveInstallationId","summarizeConfig","summarizeInterfaces","createWorkbenchUndeployAdapter","options","appId","organizationId","type","workbench","configOnly","isSingleton","hasInterfaces","installationId","resolveTarget","resolveApplicationTarget","resolved","resolveConfigTarget","resolution","undeploy","target","deletes","Error","snapshot","configs","id","message","solution","application","lines","services","views","payload","summary","undefined","title","url","config","appType","applicationType","length","slug"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/undeploy/workbenchUndeployAdapter.ts"],"sourcesContent":["import {\n type UndeployAdapter,\n type UndeployApplicationTarget,\n type UndeployConfigTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\n\nimport {type ResolvedMediaLibraryConfig} from '../../resolveWorkbenchConfig.js'\nimport {\n deleteApplication,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n} from '../../services/applications.js'\nimport {type ConfigSnapshot, deleteConfig, listConfigs} from '../../services/installations.js'\nimport {resolveInstallationId, summarizeConfig} from '../deploy/deployConfig.js'\nimport {type DeployableWorkbenchApp} from '../deploy/getWorkbench.js'\nimport {\n type DeployedView,\n type DeployedWebWorker,\n summarizeInterfaces,\n} from '../deploy/summarizeInterfaces.js'\n\n/** The workbench extension of the shared target; serializes into `--json` as-is. */\nexport type WorkbenchUndeployTarget =\n | (UndeployApplicationTarget & {\n services: DeployedWebWorker[]\n views: DeployedView[]\n })\n | (UndeployConfigTarget & {\n configs: ConfigSnapshot[]\n })\n\n/**\n * The undeploy adapter for workbench apps and configs, mirroring what a\n * workbench deploy creates: an app that exposes interfaces deletes its Brett\n * application (the server soft-deletes its deployments and refuses singletons\n * with active installations); a config — the media library — deletes its\n * installation's config snapshots instead. The two are severed at the source,\n * so exactly one of `workbench`/`config` is supplied and the brand decides the path.\n */\nexport function createWorkbenchUndeployAdapter(options: {\n appId: string | undefined\n config?: ResolvedMediaLibraryConfig\n organizationId: string | undefined\n type: 'coreApp' | 'studio'\n workbench?: DeployableWorkbenchApp\n}): UndeployAdapter<WorkbenchUndeployTarget> {\n const {appId, config, organizationId, type, workbench} = options\n // Workbench-internal, so kept off the reported target; resolveTarget stashes it for the delete.\n let installationId: string | undefined\n\n return {\n resolveTarget: async () => {\n if (!config) {\n if (!workbench) throw new Error('No workbench app or config to undeploy')\n return resolveApplicationTarget({appId, type, workbench})\n }\n const resolved = await resolveConfigTarget({config, organizationId})\n installationId = resolved.installationId\n return resolved.resolution\n },\n type,\n async undeploy(target) {\n if (target.deletes === 'config') {\n if (!installationId) throw new Error('No installation resolved for the config undeploy')\n for (const snapshot of target.configs) {\n await deleteConfig(installationId, snapshot.id)\n }\n return\n }\n await deleteApplication(target.id)\n },\n }\n}\n\nasync function resolveApplicationTarget({\n appId,\n type,\n workbench,\n}: {\n appId: string | undefined\n type: 'coreApp' | 'studio'\n workbench: DeployableWorkbenchApp\n}): Promise<UndeployTargetResolution<WorkbenchUndeployTarget>> {\n if (!appId) {\n return {\n message: 'No `deployment.appId` configured',\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n type: 'none',\n }\n }\n\n const application = await getApplication(appId)\n if (!application) {\n return {message: 'Application with the given ID does not exist', type: 'none'}\n }\n\n const {lines, services, views} = summarizeInterfaces(workbench)\n return {\n target: {\n application,\n deletes: 'application',\n id: application.id,\n payload: {appId: application.id, services, type, views},\n services,\n summary: lines,\n title: application.title,\n type,\n url: getApplicationUrl({...application, type}),\n views,\n },\n type: 'found',\n }\n}\n\nasync function resolveConfigTarget({\n config,\n organizationId,\n}: {\n config: ResolvedMediaLibraryConfig\n organizationId: string | undefined\n}): Promise<{\n installationId?: string\n resolution: UndeployTargetResolution<WorkbenchUndeployTarget>\n}> {\n const {appType} = config\n if (!organizationId) {\n throw new Error(\n 'sanity.cli.ts does not contain an organization identifier (\"app.organizationId\"), which is required to resolve the installation',\n )\n }\n\n const installationId = await resolveInstallationId({appType, organizationId})\n if (!installationId) {\n return {\n resolution: {\n message: `No active \"${appType}\" installation for organization \"${organizationId}\"`,\n type: 'none',\n },\n }\n }\n\n const configs = await listConfigs(installationId)\n if (configs.length === 0) {\n return {\n installationId,\n resolution: {\n message: `No deployed config for the \"${appType}\" installation`,\n type: 'none',\n },\n }\n }\n\n return {\n installationId,\n resolution: {\n target: {\n configs,\n deletes: 'config',\n id: null,\n payload: {\n appId: null,\n config: summarizeConfig(config),\n type: 'coreApp',\n },\n summary: [summarizeConfig(config)],\n title: appType,\n type: 'coreApp',\n url: getWorkbenchUrl(organizationId),\n },\n type: 'found',\n },\n }\n}\n"],"names":["deleteApplication","getApplication","getApplicationUrl","getWorkbenchUrl","deleteConfig","listConfigs","resolveInstallationId","summarizeConfig","summarizeInterfaces","createWorkbenchUndeployAdapter","options","appId","config","organizationId","type","workbench","installationId","resolveTarget","Error","resolveApplicationTarget","resolved","resolveConfigTarget","resolution","undeploy","target","deletes","snapshot","configs","id","message","solution","application","lines","services","views","payload","summary","title","url","appType","length"],"mappings":"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"}
package/dist/appId.js CHANGED
@@ -9,18 +9,22 @@
9
9
  * advertised by `sanity start` resolve to the same id. `sanity deploy` resolves
10
10
  * its own id from the applications API.
11
11
  */ export async function buildAppId(app) {
12
- const canonical = (interfaces)=>(interfaces ?? []).map((i)=>[
13
- i.type,
14
- i.name,
15
- i.src
16
- ]).toSorted();
17
12
  const shape = JSON.stringify({
18
- config: app.config ?? null,
19
13
  entry: app.entry ?? null,
14
+ // Identity, not address: the id keys on `name` (which defaults to `slug`). The
15
+ // address (`slug`) is deliberately absent, so renaming it never shifts the id.
16
+ name: app.name,
20
17
  organizationId: app.organizationId,
21
- services: canonical(app.services),
22
- slug: app.slug,
23
- views: canonical(app.views)
18
+ services: app.webWorkers.map((webWorker)=>[
19
+ webWorker.type,
20
+ webWorker.name,
21
+ webWorker.src
22
+ ]).toSorted(),
23
+ views: app.views.map((view)=>[
24
+ view.surface,
25
+ view.name,
26
+ view.src
27
+ ]).toSorted()
24
28
  });
25
29
  // eslint-disable-next-line n/no-unsupported-features/node-builtins -- the Web Crypto global is available on our Node target and in the browser
26
30
  const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(shape));
package/dist/appId.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/appId.ts"],"sourcesContent":["import {type ResolvedWorkbenchApp} from './resolveWorkbenchApp.js'\n\n/**\n * File the build writes into its output, carrying the id compiled into the\n * bundle. `sanity start` serves a build without recompiling, so it reads this\n * instead of recomputing — a deploy inlines the API id, not the shape hash.\n */\nexport const SANITY_APP_ID_FILE = 'sanity-app-id.txt'\n\n/**\n * The `build`/`start` id — a hash of the app's declared shape (its identity, not\n * its code), so the bundle inlined by `sanity build` and the registry entry\n * advertised by `sanity start` resolve to the same id. `sanity deploy` resolves\n * its own id from the applications API.\n */\nexport async function buildAppId(app: ResolvedWorkbenchApp): Promise<string> {\n const canonical = (\n interfaces: ReadonlyArray<{name: string; src: string; type: string}> | undefined,\n ): Array<[string, string, string]> =>\n (interfaces ?? []).map((i): [string, string, string] => [i.type, i.name, i.src]).toSorted()\n const shape = JSON.stringify({\n config: app.config ?? null,\n entry: app.entry ?? null,\n organizationId: app.organizationId,\n services: canonical(app.services),\n slug: app.slug,\n views: canonical(app.views),\n })\n // eslint-disable-next-line n/no-unsupported-features/node-builtins -- the Web Crypto global is available on our Node target and in the browser\n const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(shape))\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n"],"names":["SANITY_APP_ID_FILE","buildAppId","app","canonical","interfaces","map","i","type","name","src","toSorted","shape","JSON","stringify","config","entry","organizationId","services","slug","views","digest","globalThis","crypto","subtle","TextEncoder","encode","Array","from","Uint8Array","byte","toString","padStart","join"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,MAAMA,qBAAqB,oBAAmB;AAErD;;;;;CAKC,GACD,OAAO,eAAeC,WAAWC,GAAyB;IACxD,MAAMC,YAAY,CAChBC,aAEA,AAACA,CAAAA,cAAc,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC,IAAgC;gBAACA,EAAEC,IAAI;gBAAED,EAAEE,IAAI;gBAAEF,EAAEG,GAAG;aAAC,EAAEC,QAAQ;IAC3F,MAAMC,QAAQC,KAAKC,SAAS,CAAC;QAC3BC,QAAQZ,IAAIY,MAAM,IAAI;QACtBC,OAAOb,IAAIa,KAAK,IAAI;QACpBC,gBAAgBd,IAAIc,cAAc;QAClCC,UAAUd,UAAUD,IAAIe,QAAQ;QAChCC,MAAMhB,IAAIgB,IAAI;QACdC,OAAOhB,UAAUD,IAAIiB,KAAK;IAC5B;IACA,+IAA+I;IAC/I,MAAMC,SAAS,MAAMC,WAAWC,MAAM,CAACC,MAAM,CAACH,MAAM,CAAC,WAAW,IAAII,cAAcC,MAAM,CAACd;IACzF,OAAOe,MAAMC,IAAI,CAAC,IAAIC,WAAWR,SAAS,CAACS,OAASA,KAAKC,QAAQ,CAAC,IAAIC,QAAQ,CAAC,GAAG,MAAMC,IAAI,CAAC;AAC/F"}
1
+ {"version":3,"sources":["../src/appId.ts"],"sourcesContent":["import {type ResolvedWorkbenchApp} from './resolveWorkbenchApp.js'\n\n/**\n * File the build writes into its output, carrying the id compiled into the\n * bundle. `sanity start` serves a build without recompiling, so it reads this\n * instead of recomputing — a deploy inlines the API id, not the shape hash.\n */\nexport const SANITY_APP_ID_FILE = 'sanity-app-id.txt'\n\n/**\n * The `build`/`start` id — a hash of the app's declared shape (its identity, not\n * its code), so the bundle inlined by `sanity build` and the registry entry\n * advertised by `sanity start` resolve to the same id. `sanity deploy` resolves\n * its own id from the applications API.\n */\nexport async function buildAppId(app: ResolvedWorkbenchApp): Promise<string> {\n const shape = JSON.stringify({\n entry: app.entry ?? null,\n // Identity, not address: the id keys on `name` (which defaults to `slug`). The\n // address (`slug`) is deliberately absent, so renaming it never shifts the id.\n name: app.name,\n organizationId: app.organizationId,\n services: app.webWorkers\n .map((webWorker): [string, string, string] => [webWorker.type, webWorker.name, webWorker.src])\n .toSorted(),\n views: app.views\n .map((view): [string, string, string] => [view.surface, view.name, view.src])\n .toSorted(),\n })\n // eslint-disable-next-line n/no-unsupported-features/node-builtins -- the Web Crypto global is available on our Node target and in the browser\n const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(shape))\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n"],"names":["SANITY_APP_ID_FILE","buildAppId","app","shape","JSON","stringify","entry","name","organizationId","services","webWorkers","map","webWorker","type","src","toSorted","views","view","surface","digest","globalThis","crypto","subtle","TextEncoder","encode","Array","from","Uint8Array","byte","toString","padStart","join"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,MAAMA,qBAAqB,oBAAmB;AAErD;;;;;CAKC,GACD,OAAO,eAAeC,WAAWC,GAAyB;IACxD,MAAMC,QAAQC,KAAKC,SAAS,CAAC;QAC3BC,OAAOJ,IAAII,KAAK,IAAI;QACpB,+EAA+E;QAC/E,+EAA+E;QAC/EC,MAAML,IAAIK,IAAI;QACdC,gBAAgBN,IAAIM,cAAc;QAClCC,UAAUP,IAAIQ,UAAU,CACrBC,GAAG,CAAC,CAACC,YAAwC;gBAACA,UAAUC,IAAI;gBAAED,UAAUL,IAAI;gBAAEK,UAAUE,GAAG;aAAC,EAC5FC,QAAQ;QACXC,OAAOd,IAAIc,KAAK,CACbL,GAAG,CAAC,CAACM,OAAmC;gBAACA,KAAKC,OAAO;gBAAED,KAAKV,IAAI;gBAAEU,KAAKH,GAAG;aAAC,EAC3EC,QAAQ;IACb;IACA,+IAA+I;IAC/I,MAAMI,SAAS,MAAMC,WAAWC,MAAM,CAACC,MAAM,CAACH,MAAM,CAAC,WAAW,IAAII,cAAcC,MAAM,CAACrB;IACzF,OAAOsB,MAAMC,IAAI,CAAC,IAAIC,WAAWR,SAAS,CAACS,OAASA,KAAKC,QAAQ,CAAC,IAAIC,QAAQ,CAAC,GAAG,MAAMC,IAAI,CAAC;AAC/F"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The qualified, globally-unique handle for an application: `sanity/<name>` for
3
+ * singletons (always Sanity-owned), `<organizationId>/<name>` otherwise. Mirrors
4
+ * brett's server-side composition so a locally served app carries the same
5
+ * reference the deployed one would — the CLI is the authority for local apps,
6
+ * which never reach brett.
7
+ * @public
8
+ */ export function applicationReference(app) {
9
+ return `${app.isSingleton ? 'sanity' : app.organizationId}/${app.name}`;
10
+ }
11
+
12
+ //# sourceMappingURL=applicationReference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/applicationReference.ts"],"sourcesContent":["/**\n * The qualified, globally-unique handle for an application: `sanity/<name>` for\n * singletons (always Sanity-owned), `<organizationId>/<name>` otherwise. Mirrors\n * brett's server-side composition so a locally served app carries the same\n * reference the deployed one would — the CLI is the authority for local apps,\n * which never reach brett.\n * @public\n */\nexport function applicationReference(app: {\n isSingleton: boolean\n name: string\n organizationId: string\n}): string {\n return `${app.isSingleton ? 'sanity' : app.organizationId}/${app.name}`\n}\n"],"names":["applicationReference","app","isSingleton","organizationId","name"],"mappings":"AAAA;;;;;;;CAOC,GACD,OAAO,SAASA,qBAAqBC,GAIpC;IACC,OAAO,GAAGA,IAAIC,WAAW,GAAG,WAAWD,IAAIE,cAAc,CAAC,CAAC,EAAEF,IAAIG,IAAI,EAAE;AACzE"}
package/dist/contract.js CHANGED
@@ -5,11 +5,8 @@ import { z } from 'zod/mini';
5
5
  /** @internal */ export const VIEW_CONTRACT_VERSION = 1;
6
6
  /** @internal */ export const SERVICE_CONTRACT_VERSION = 1;
7
7
  /** @internal */ export const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1;
8
- /**
9
- * Component slots each interface type exposes, in render order. Source of truth
10
- * for {@link InterfaceType} and the build; add a type by registering it here.
11
- * @internal
12
- */ export const VIEW_COMPONENTS = {
8
+ /** Component slots per view surface; windows load outside the component artifact path. @internal */ export const VIEW_COMPONENTS = {
9
+ app: [],
13
10
  asset_source: [
14
11
  'asset_source'
15
12
  ],
@@ -32,22 +29,25 @@ import { z } from 'zod/mini';
32
29
  'large',
33
30
  'banner'
34
31
  ]);
35
- /**
36
- * The `app` interface's dock-placement metadata. Interface metadata is
37
- * discriminated on `type`; `app` is the only type with a shape so far.
38
- * @internal
39
- */ export const AppInterfaceMetadataSchema = z.object({
40
- group: z.optional(z.string()),
41
- priority: z.optional(z.number())
32
+ const DockGroupSchema = z.enum([
33
+ 'dock.system',
34
+ 'dock.applications',
35
+ 'dock.user'
36
+ ]);
37
+ /** @internal */ export const DockSchema = z.object({
38
+ group: z.optional(DockGroupSchema),
39
+ order: z.optional(z.number())
40
+ });
41
+ /** @internal */ export const ViewPlacementMetadataSchema = z.object({
42
+ dock: DockSchema
42
43
  });
43
44
  /**
44
- * A tile's interface metadata: its footprint `size` and an optional `priority`
45
+ * A tile's interface metadata: its footprint `size` and an optional `order`
45
46
  * the dashboard sorts on, ascending. Both are authored as top-level view fields
46
47
  * (see {@link InterfaceDeclarationSchema}) but stored on the record as metadata.
47
- * Mirrors `app`'s dock metadata; tile is the first view type to carry any.
48
48
  * @internal
49
49
  */ export const TileInterfaceMetadataSchema = z.object({
50
- priority: z.optional(z.number()),
50
+ order: z.optional(z.number()),
51
51
  size: TileSizeSchema
52
52
  });
53
53
  /**
@@ -61,16 +61,16 @@ import { z } from 'zod/mini';
61
61
  tile: VIEW_CONTRACT_VERSION,
62
62
  worker: SERVICE_CONTRACT_VERSION
63
63
  };
64
- /** @internal */ export function interfaceContractVersion(type) {
65
- const version = INTERFACE_CONTRACT_VERSIONS[type];
64
+ /** @internal */ export function interfaceContractVersion(kind) {
65
+ const version = INTERFACE_CONTRACT_VERSIONS[kind];
66
66
  return version === undefined ? undefined : String(version);
67
67
  }
68
68
  /**
69
69
  * The module-federation id a build exposes an interface at. Dev stamps the same
70
70
  * id a deploy would, so the workbench loads a local interface like a deployed one.
71
71
  * @internal
72
- */ export function interfaceModuleId(type, name) {
73
- switch(type){
72
+ */ export function interfaceModuleId(kind, name) {
73
+ switch(kind){
74
74
  case 'app':
75
75
  {
76
76
  return 'App';
@@ -87,7 +87,7 @@ import { z } from 'zod/mini';
87
87
  }
88
88
  default:
89
89
  {
90
- throw new Error(`Cannot derive a moduleId for unknown interface type: ${type}`);
90
+ throw new Error(`Cannot derive a moduleId for unknown interface kind: ${kind}`);
91
91
  }
92
92
  }
93
93
  }
@@ -99,7 +99,7 @@ function extensionDeclarationFields(kind) {
99
99
  src: z.string()
100
100
  };
101
101
  }
102
- // Every interface (view, service) shares `name` + `src` + a display `title`,
102
+ // Every interface shares `name` + `src` + a display `title`,
103
103
  // which Brett requires on the record each becomes.
104
104
  function interfaceDeclarationFields(kind) {
105
105
  return {
@@ -108,30 +108,67 @@ function interfaceDeclarationFields(kind) {
108
108
  };
109
109
  }
110
110
  const PanelViewSchema = z.object({
111
- type: z.literal('panel'),
112
- ...interfaceDeclarationFields('View')
111
+ surface: z.literal('panel'),
112
+ ...interfaceDeclarationFields('View'),
113
+ dock: z.optional(DockSchema)
114
+ });
115
+ /** @public */ export function definePanelView(view) {
116
+ return {
117
+ ...view,
118
+ surface: 'panel'
119
+ };
120
+ }
121
+ const WindowViewSchema = z.object({
122
+ surface: z.literal('app'),
123
+ ...interfaceDeclarationFields('View'),
124
+ dock: z.optional(DockSchema)
113
125
  });
126
+ /** @public */ export function defineWindowView(view) {
127
+ return {
128
+ ...view,
129
+ surface: 'app'
130
+ };
131
+ }
114
132
  const AssetSourceViewSchema = z.object({
115
- type: z.literal('asset_source'),
133
+ surface: z.literal('asset_source'),
116
134
  ...interfaceDeclarationFields('View')
117
135
  });
136
+ /** @public */ export function defineAssetSourceView(view) {
137
+ return {
138
+ ...view,
139
+ surface: 'asset_source'
140
+ };
141
+ }
118
142
  const TileViewSchema = z.object({
119
- type: z.literal('tile'),
143
+ surface: z.literal('tile'),
120
144
  ...interfaceDeclarationFields('View'),
121
- /** Sort position within its layout track, ascending. Optional. */ priority: z.optional(z.number()),
145
+ /** Sort position within its layout track, ascending. Optional. */ order: z.optional(z.number()),
122
146
  /** Footprint family the dashboard lays the tile out by. */ size: TileSizeSchema
123
147
  });
124
- /** @internal */ export const InterfaceDeclarationSchema = z.discriminatedUnion('type', [
148
+ /** @public */ export function defineTileView(view) {
149
+ return {
150
+ ...view,
151
+ surface: 'tile'
152
+ };
153
+ }
154
+ /** @internal */ export const InterfaceDeclarationSchema = z.discriminatedUnion('surface', [
155
+ WindowViewSchema,
125
156
  PanelViewSchema,
126
157
  AssetSourceViewSchema,
127
158
  TileViewSchema
128
159
  ]);
129
- const WorkerServiceSchema = z.object({
160
+ const WebWorkerSchema = z.object({
130
161
  type: z.literal('worker'),
131
- ...interfaceDeclarationFields('Service')
162
+ ...interfaceDeclarationFields('Web worker')
132
163
  });
164
+ /** @public */ export function defineWebWorker(webWorker) {
165
+ return {
166
+ ...webWorker,
167
+ type: 'worker'
168
+ };
169
+ }
133
170
  /** @internal */ export const ServiceDeclarationSchema = z.discriminatedUnion('type', [
134
- WorkerServiceSchema
171
+ WebWorkerSchema
135
172
  ]);
136
173
  const MediaLibraryFieldSchema = z.object({
137
174
  ...extensionDeclarationFields('Field'),
@@ -148,7 +185,8 @@ const MediaLibraryConfigSchema = z.object({
148
185
  fields: z.array(MediaLibraryFieldSchema).check(z.refine((fields)=>new Set(fields.map((field)=>field.name)).size === fields.length, 'Field `name` must be unique within a media library'))
149
186
  });
150
187
  /**
151
- * An app's optional config, keyed by `appType`; deploys as a versioned snapshot, not an interface.
188
+ * A workbench config's built value, keyed by `appType`; deploys as a versioned
189
+ * snapshot, not an interface.
152
190
  * @internal
153
191
  */ export const ConfigSchema = z.discriminatedUnion('appType', [
154
192
  MediaLibraryConfigSchema
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/contract.ts"],"sourcesContent":["import {z} from 'zod/mini'\n\n// Shared module-federation extension contract: interface (view/service) and\n// config declaration schemas, plus the versions the build stamps.\n// `zod/mini` keeps the bundle small.\n\n/** @internal */\nexport const VIEW_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const SERVICE_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1\n\n/**\n * A view component. The return is opaque so the runtime helpers carry no React\n * dependency — the generated artifact renders it with the app's own React.\n * @public\n */\nexport type ViewComponent<TProps> = (props: TProps) => unknown\n\n/** @public */\nexport interface ViewComponentBaseProps<TView> {\n view: TView\n}\n\n/**\n * Component slots each interface type exposes, in render order. Source of truth\n * for {@link InterfaceType} and the build; add a type by registering it here.\n * @internal\n */\nexport const VIEW_COMPONENTS = {\n asset_source: ['asset_source'],\n panel: ['title', 'panel'],\n tile: ['tile'],\n} as const satisfies Record<string, readonly string[]>\n\n/** @public */\nexport type InterfaceType = keyof typeof VIEW_COMPONENTS\n\n/**\n * A tile's footprint family — the shape it occupies on the dashboard. Modelled\n * on iOS WidgetKit families, not a linear scale: `banner` is full-width and\n * shallow, which a `small`→`large` magnitude can't express. The host maps a\n * family to a layout slot; the component reads it to render per footprint.\n * @public\n */\nexport const TileSizeSchema = z.enum(['small', 'large', 'banner'])\n\n/** @public */\nexport type TileSize = z.infer<typeof TileSizeSchema>\n\n/** @public */\nexport type ServiceType = 'worker'\n\n/**\n * The `app` interface's dock-placement metadata. Interface metadata is\n * discriminated on `type`; `app` is the only type with a shape so far.\n * @internal\n */\nexport const AppInterfaceMetadataSchema = z.object({\n group: z.optional(z.string()),\n priority: z.optional(z.number()),\n})\n\n/** @internal */\nexport type AppInterfaceMetadata = z.infer<typeof AppInterfaceMetadataSchema>\n\n/**\n * A tile's interface metadata: its footprint `size` and an optional `priority`\n * the dashboard sorts on, ascending. Both are authored as top-level view fields\n * (see {@link InterfaceDeclarationSchema}) but stored on the record as metadata.\n * Mirrors `app`'s dock metadata; tile is the first view type to carry any.\n * @internal\n */\nexport const TileInterfaceMetadataSchema = z.object({\n priority: z.optional(z.number()),\n size: TileSizeSchema,\n})\n\n/** @internal */\nexport type TileInterfaceMetadata = z.infer<typeof TileInterfaceMetadataSchema>\n\n/**\n * The contract version each interface type advertises, so the host can check it\n * renders/runs what it expects.\n * @internal\n */\nconst INTERFACE_CONTRACT_VERSIONS = {\n app: undefined,\n asset_source: VIEW_CONTRACT_VERSION,\n panel: VIEW_CONTRACT_VERSION,\n tile: VIEW_CONTRACT_VERSION,\n worker: SERVICE_CONTRACT_VERSION,\n} as const\n\n/** Every interface type an app exposes — an `app` view, a view, or a service. */\nexport type InterfaceKind = keyof typeof INTERFACE_CONTRACT_VERSIONS\n\n/** @internal */\nexport function interfaceContractVersion(type: InterfaceKind): string | undefined {\n const version = INTERFACE_CONTRACT_VERSIONS[type]\n return version === undefined ? undefined : String(version)\n}\n\n/**\n * The module-federation id a build exposes an interface at. Dev stamps the same\n * id a deploy would, so the workbench loads a local interface like a deployed one.\n * @internal\n */\nexport function interfaceModuleId(type: string, name: string): string {\n switch (type) {\n case 'app': {\n return 'App'\n }\n case 'asset_source':\n case 'panel':\n case 'tile': {\n return `views/${name}`\n }\n case 'worker': {\n return `services/${name}`\n }\n default: {\n throw new Error(`Cannot derive a moduleId for unknown interface type: ${type}`)\n }\n }\n}\n\n// Shared `name` + `src`; `kind` only tailors the validation message.\nfunction extensionDeclarationFields(kind: 'Field' | 'Service' | 'View') {\n const pattern = /^[a-zA-Z0-9_-]+$/\n return {\n name: z.string().check(z.regex(pattern, `${kind} \\`name\\` must match ${pattern}`)),\n src: z.string(),\n }\n}\n\n// Every interface (view, service) shares `name` + `src` + a display `title`,\n// which Brett requires on the record each becomes.\nfunction interfaceDeclarationFields(kind: 'Service' | 'View') {\n return {\n ...extensionDeclarationFields(kind),\n title: z.string(`${kind} \\`title\\` is required`),\n }\n}\n\nconst PanelViewSchema = z.object({\n type: z.literal('panel'),\n ...interfaceDeclarationFields('View'),\n})\n\nconst AssetSourceViewSchema = z.object({\n type: z.literal('asset_source'),\n ...interfaceDeclarationFields('View'),\n})\n\nconst TileViewSchema = z.object({\n type: z.literal('tile'),\n ...interfaceDeclarationFields('View'),\n /** Sort position within its layout track, ascending. Optional. */\n priority: z.optional(z.number()),\n /** Footprint family the dashboard lays the tile out by. */\n size: TileSizeSchema,\n})\n\n/** @internal */\nexport const InterfaceDeclarationSchema = z.discriminatedUnion('type', [\n PanelViewSchema,\n AssetSourceViewSchema,\n TileViewSchema,\n])\n\nconst WorkerServiceSchema = z.object({\n type: z.literal('worker'),\n ...interfaceDeclarationFields('Service'),\n})\n\n/** @internal */\nexport const ServiceDeclarationSchema = z.discriminatedUnion('type', [WorkerServiceSchema])\n\nconst MediaLibraryFieldSchema = z.object({\n ...extensionDeclarationFields('Field'),\n public: z.optional(z.boolean()),\n title: z.string(),\n})\n\n/**\n * Stamped where the config crosses a boundary so the authoring model doesn't carry a constant discriminator.\n * @internal\n */\nexport const INSTALLATION_CONFIG_TYPE = 'installation_config'\n\n// `appType` is stamped by `unstable_defineMediaLibrary`, never authored.\nconst MediaLibraryConfigSchema = z.object({\n appType: z.literal('media-library'),\n fields: z\n .array(MediaLibraryFieldSchema)\n .check(\n z.refine(\n (fields) => new Set(fields.map((field) => field.name)).size === fields.length,\n 'Field `name` must be unique within a media library',\n ),\n ),\n})\n\n/**\n * An app's optional config, keyed by `appType`; deploys as a versioned snapshot, not an interface.\n * @internal\n */\nexport const ConfigSchema = z.discriminatedUnion('appType', [MediaLibraryConfigSchema])\n"],"names":["z","VIEW_CONTRACT_VERSION","SERVICE_CONTRACT_VERSION","MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION","VIEW_COMPONENTS","asset_source","panel","tile","TileSizeSchema","enum","AppInterfaceMetadataSchema","object","group","optional","string","priority","number","TileInterfaceMetadataSchema","size","INTERFACE_CONTRACT_VERSIONS","app","undefined","worker","interfaceContractVersion","type","version","String","interfaceModuleId","name","Error","extensionDeclarationFields","kind","pattern","check","regex","src","interfaceDeclarationFields","title","PanelViewSchema","literal","AssetSourceViewSchema","TileViewSchema","InterfaceDeclarationSchema","discriminatedUnion","WorkerServiceSchema","ServiceDeclarationSchema","MediaLibraryFieldSchema","public","boolean","INSTALLATION_CONFIG_TYPE","MediaLibraryConfigSchema","appType","fields","array","refine","Set","map","field","length","ConfigSchema"],"mappings":"AAAA,SAAQA,CAAC,QAAO,WAAU;AAE1B,4EAA4E;AAC5E,kEAAkE;AAClE,qCAAqC;AAErC,cAAc,GACd,OAAO,MAAMC,wBAAwB,EAAC;AAEtC,cAAc,GACd,OAAO,MAAMC,2BAA2B,EAAC;AAEzC,cAAc,GACd,OAAO,MAAMC,wCAAwC,EAAC;AActD;;;;CAIC,GACD,OAAO,MAAMC,kBAAkB;IAC7BC,cAAc;QAAC;KAAe;IAC9BC,OAAO;QAAC;QAAS;KAAQ;IACzBC,MAAM;QAAC;KAAO;AAChB,EAAsD;AAKtD;;;;;;CAMC,GACD,OAAO,MAAMC,iBAAiBR,EAAES,IAAI,CAAC;IAAC;IAAS;IAAS;CAAS,EAAC;AAQlE;;;;CAIC,GACD,OAAO,MAAMC,6BAA6BV,EAAEW,MAAM,CAAC;IACjDC,OAAOZ,EAAEa,QAAQ,CAACb,EAAEc,MAAM;IAC1BC,UAAUf,EAAEa,QAAQ,CAACb,EAAEgB,MAAM;AAC/B,GAAE;AAKF;;;;;;CAMC,GACD,OAAO,MAAMC,8BAA8BjB,EAAEW,MAAM,CAAC;IAClDI,UAAUf,EAAEa,QAAQ,CAACb,EAAEgB,MAAM;IAC7BE,MAAMV;AACR,GAAE;AAKF;;;;CAIC,GACD,MAAMW,8BAA8B;IAClCC,KAAKC;IACLhB,cAAcJ;IACdK,OAAOL;IACPM,MAAMN;IACNqB,QAAQpB;AACV;AAKA,cAAc,GACd,OAAO,SAASqB,yBAAyBC,IAAmB;IAC1D,MAAMC,UAAUN,2BAA2B,CAACK,KAAK;IACjD,OAAOC,YAAYJ,YAAYA,YAAYK,OAAOD;AACpD;AAEA;;;;CAIC,GACD,OAAO,SAASE,kBAAkBH,IAAY,EAAEI,IAAY;IAC1D,OAAQJ;QACN,KAAK;YAAO;gBACV,OAAO;YACT;QACA,KAAK;QACL,KAAK;QACL,KAAK;YAAQ;gBACX,OAAO,CAAC,MAAM,EAAEI,MAAM;YACxB;QACA,KAAK;YAAU;gBACb,OAAO,CAAC,SAAS,EAAEA,MAAM;YAC3B;QACA;YAAS;gBACP,MAAM,IAAIC,MAAM,CAAC,qDAAqD,EAAEL,MAAM;YAChF;IACF;AACF;AAEA,qEAAqE;AACrE,SAASM,2BAA2BC,IAAkC;IACpE,MAAMC,UAAU;IAChB,OAAO;QACLJ,MAAM5B,EAAEc,MAAM,GAAGmB,KAAK,CAACjC,EAAEkC,KAAK,CAACF,SAAS,GAAGD,KAAK,qBAAqB,EAAEC,SAAS;QAChFG,KAAKnC,EAAEc,MAAM;IACf;AACF;AAEA,6EAA6E;AAC7E,mDAAmD;AACnD,SAASsB,2BAA2BL,IAAwB;IAC1D,OAAO;QACL,GAAGD,2BAA2BC,KAAK;QACnCM,OAAOrC,EAAEc,MAAM,CAAC,GAAGiB,KAAK,sBAAsB,CAAC;IACjD;AACF;AAEA,MAAMO,kBAAkBtC,EAAEW,MAAM,CAAC;IAC/Ba,MAAMxB,EAAEuC,OAAO,CAAC;IAChB,GAAGH,2BAA2B,OAAO;AACvC;AAEA,MAAMI,wBAAwBxC,EAAEW,MAAM,CAAC;IACrCa,MAAMxB,EAAEuC,OAAO,CAAC;IAChB,GAAGH,2BAA2B,OAAO;AACvC;AAEA,MAAMK,iBAAiBzC,EAAEW,MAAM,CAAC;IAC9Ba,MAAMxB,EAAEuC,OAAO,CAAC;IAChB,GAAGH,2BAA2B,OAAO;IACrC,gEAAgE,GAChErB,UAAUf,EAAEa,QAAQ,CAACb,EAAEgB,MAAM;IAC7B,yDAAyD,GACzDE,MAAMV;AACR;AAEA,cAAc,GACd,OAAO,MAAMkC,6BAA6B1C,EAAE2C,kBAAkB,CAAC,QAAQ;IACrEL;IACAE;IACAC;CACD,EAAC;AAEF,MAAMG,sBAAsB5C,EAAEW,MAAM,CAAC;IACnCa,MAAMxB,EAAEuC,OAAO,CAAC;IAChB,GAAGH,2BAA2B,UAAU;AAC1C;AAEA,cAAc,GACd,OAAO,MAAMS,2BAA2B7C,EAAE2C,kBAAkB,CAAC,QAAQ;IAACC;CAAoB,EAAC;AAE3F,MAAME,0BAA0B9C,EAAEW,MAAM,CAAC;IACvC,GAAGmB,2BAA2B,QAAQ;IACtCiB,QAAQ/C,EAAEa,QAAQ,CAACb,EAAEgD,OAAO;IAC5BX,OAAOrC,EAAEc,MAAM;AACjB;AAEA;;;CAGC,GACD,OAAO,MAAMmC,2BAA2B,sBAAqB;AAE7D,yEAAyE;AACzE,MAAMC,2BAA2BlD,EAAEW,MAAM,CAAC;IACxCwC,SAASnD,EAAEuC,OAAO,CAAC;IACnBa,QAAQpD,EACLqD,KAAK,CAACP,yBACNb,KAAK,CACJjC,EAAEsD,MAAM,CACN,CAACF,SAAW,IAAIG,IAAIH,OAAOI,GAAG,CAAC,CAACC,QAAUA,MAAM7B,IAAI,GAAGV,IAAI,KAAKkC,OAAOM,MAAM,EAC7E;AAGR;AAEA;;;CAGC,GACD,OAAO,MAAMC,eAAe3D,EAAE2C,kBAAkB,CAAC,WAAW;IAACO;CAAyB,EAAC"}
1
+ {"version":3,"sources":["../src/contract.ts"],"sourcesContent":["import {z} from 'zod/mini'\n\n// Shared module-federation extension contract: interface (view/service) and\n// config declaration schemas, plus the versions the build stamps.\n// `zod/mini` keeps the bundle small.\n\n/** @internal */\nexport const VIEW_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const SERVICE_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1\n\n/**\n * A view component. The return is opaque so the runtime helpers carry no React\n * dependency — the generated artifact renders it with the app's own React.\n * @public\n */\nexport type ViewComponent<TProps> = (props: TProps) => unknown\n\n/** @public */\nexport interface ViewComponentBaseProps<TView> {\n view: TView\n}\n\n/** Component slots per view surface; windows load outside the component artifact path. @internal */\nexport const VIEW_COMPONENTS = {\n app: [],\n asset_source: ['asset_source'],\n panel: ['title', 'panel'],\n tile: ['tile'],\n} as const satisfies Record<string, readonly string[]>\n\n/** @public */\nexport type ViewSurface = keyof typeof VIEW_COMPONENTS\n\n/**\n * A tile's footprint family — the shape it occupies on the dashboard. Modelled\n * on iOS WidgetKit families, not a linear scale: `banner` is full-width and\n * shallow, which a `small`→`large` magnitude can't express. The host maps a\n * family to a layout slot; the component reads it to render per footprint.\n * @public\n */\nexport const TileSizeSchema = z.enum(['small', 'large', 'banner'])\n\n/** @public */\nexport type TileSize = z.infer<typeof TileSizeSchema>\n\n/** @public */\nexport type ServiceType = 'worker'\n\nconst DockGroupSchema = z.enum(['dock.system', 'dock.applications', 'dock.user'])\n\n/** @public */\nexport type DockGroup = z.output<typeof DockGroupSchema>\n\n/** @internal */\nexport const DockSchema = z.object({\n group: z.optional(DockGroupSchema),\n order: z.optional(z.number()),\n})\n\n/** @internal */\nexport type Dock = z.infer<typeof DockSchema>\n\n/** @internal */\nexport const ViewPlacementMetadataSchema = z.object({dock: DockSchema})\n\n/** @internal */\nexport type ViewPlacementMetadata = z.infer<typeof ViewPlacementMetadataSchema>\n\n/**\n * A tile's interface metadata: its footprint `size` and an optional `order`\n * the dashboard sorts on, ascending. Both are authored as top-level view fields\n * (see {@link InterfaceDeclarationSchema}) but stored on the record as metadata.\n * @internal\n */\nexport const TileInterfaceMetadataSchema = z.object({\n order: z.optional(z.number()),\n size: TileSizeSchema,\n})\n\n/** @internal */\nexport type TileInterfaceMetadata = z.infer<typeof TileInterfaceMetadataSchema>\n\n/**\n * The contract version each interface type advertises, so the host can check it\n * renders/runs what it expects.\n * @internal\n */\nconst INTERFACE_CONTRACT_VERSIONS = {\n app: undefined,\n asset_source: VIEW_CONTRACT_VERSION,\n panel: VIEW_CONTRACT_VERSION,\n tile: VIEW_CONTRACT_VERSION,\n worker: SERVICE_CONTRACT_VERSION,\n} as const\n\n/** Every interface type an app exposes — an `app` view, a view, or a service. */\nexport type InterfaceKind = keyof typeof INTERFACE_CONTRACT_VERSIONS\n\n/** @internal */\nexport function interfaceContractVersion(kind: InterfaceKind): string | undefined {\n const version = INTERFACE_CONTRACT_VERSIONS[kind]\n return version === undefined ? undefined : String(version)\n}\n\n/**\n * The module-federation id a build exposes an interface at. Dev stamps the same\n * id a deploy would, so the workbench loads a local interface like a deployed one.\n * @internal\n */\nexport function interfaceModuleId(kind: string, name: string): string {\n switch (kind) {\n case 'app': {\n return 'App'\n }\n case 'asset_source':\n case 'panel':\n case 'tile': {\n return `views/${name}`\n }\n case 'worker': {\n return `services/${name}`\n }\n default: {\n throw new Error(`Cannot derive a moduleId for unknown interface kind: ${kind}`)\n }\n }\n}\n\n// Shared `name` + `src`; `kind` only tailors the validation message.\nfunction extensionDeclarationFields(kind: 'Field' | 'View' | 'Web worker') {\n const pattern = /^[a-zA-Z0-9_-]+$/\n return {\n name: z.string().check(z.regex(pattern, `${kind} \\`name\\` must match ${pattern}`)),\n src: z.string(),\n }\n}\n\n// Every interface shares `name` + `src` + a display `title`,\n// which Brett requires on the record each becomes.\nfunction interfaceDeclarationFields(kind: 'View' | 'Web worker') {\n return {\n ...extensionDeclarationFields(kind),\n title: z.string(`${kind} \\`title\\` is required`),\n }\n}\n\nconst PanelViewSchema = z.object({\n surface: z.literal('panel'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type PanelView = z.output<typeof PanelViewSchema>\n\n/** @public */\nexport type DefinePanelViewInput = Omit<PanelView, 'surface'>\n\n/** @public */\nexport function definePanelView(view: DefinePanelViewInput): PanelView {\n return {...view, surface: 'panel'}\n}\n\nconst WindowViewSchema = z.object({\n surface: z.literal('app'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type WindowView = z.output<typeof WindowViewSchema>\n\n/** @public */\nexport type DefineWindowViewInput = Omit<WindowView, 'surface'>\n\n/** @public */\nexport function defineWindowView(view: DefineWindowViewInput): WindowView {\n return {...view, surface: 'app'}\n}\n\nconst AssetSourceViewSchema = z.object({\n surface: z.literal('asset_source'),\n ...interfaceDeclarationFields('View'),\n})\n\n/** @public */\nexport type AssetSourceView = z.output<typeof AssetSourceViewSchema>\n\n/** @public */\nexport type DefineAssetSourceViewInput = Omit<AssetSourceView, 'surface'>\n\n/** @public */\nexport function defineAssetSourceView(view: DefineAssetSourceViewInput): AssetSourceView {\n return {...view, surface: 'asset_source'}\n}\n\nconst TileViewSchema = z.object({\n surface: z.literal('tile'),\n ...interfaceDeclarationFields('View'),\n /** Sort position within its layout track, ascending. Optional. */\n order: z.optional(z.number()),\n /** Footprint family the dashboard lays the tile out by. */\n size: TileSizeSchema,\n})\n\n/** @public */\nexport type TileView = z.output<typeof TileViewSchema>\n\n/** @public */\nexport type DefineTileViewInput = Omit<TileView, 'surface'>\n\n/** @public */\nexport function defineTileView(view: DefineTileViewInput): TileView {\n return {...view, surface: 'tile'}\n}\n\n/** @internal */\nexport const InterfaceDeclarationSchema = z.discriminatedUnion('surface', [\n WindowViewSchema,\n PanelViewSchema,\n AssetSourceViewSchema,\n TileViewSchema,\n])\n\n/** @public */\nexport type ViewDeclaration = z.output<typeof InterfaceDeclarationSchema>\n\nconst WebWorkerSchema = z.object({\n type: z.literal('worker'),\n ...interfaceDeclarationFields('Web worker'),\n})\n\n/** @public */\nexport type WebWorker = z.output<typeof WebWorkerSchema>\n\n/** @public */\nexport type DefineWebWorkerInput = Omit<WebWorker, 'type'>\n\n/** @public */\nexport function defineWebWorker(webWorker: DefineWebWorkerInput): WebWorker {\n return {...webWorker, type: 'worker'}\n}\n\n/** @internal */\nexport const ServiceDeclarationSchema = z.discriminatedUnion('type', [WebWorkerSchema])\n\nconst MediaLibraryFieldSchema = z.object({\n ...extensionDeclarationFields('Field'),\n public: z.optional(z.boolean()),\n title: z.string(),\n})\n\n/**\n * Stamped where the config crosses a boundary so the authoring model doesn't carry a constant discriminator.\n * @internal\n */\nexport const INSTALLATION_CONFIG_TYPE = 'installation_config'\n\n// `appType` is stamped by `unstable_defineMediaLibrary`, never authored.\nconst MediaLibraryConfigSchema = z.object({\n appType: z.literal('media-library'),\n fields: z\n .array(MediaLibraryFieldSchema)\n .check(\n z.refine(\n (fields) => new Set(fields.map((field) => field.name)).size === fields.length,\n 'Field `name` must be unique within a media library',\n ),\n ),\n})\n\n/**\n * A workbench config's built value, keyed by `appType`; deploys as a versioned\n * snapshot, not an interface.\n * @internal\n */\nexport const ConfigSchema = z.discriminatedUnion('appType', [MediaLibraryConfigSchema])\n\n/**\n * The `{appType, fields}` config value the build expands into a federation\n * remote and the deploy summarizes.\n * @internal\n */\nexport type WorkbenchConfigValue = z.output<typeof ConfigSchema>\n"],"names":["z","VIEW_CONTRACT_VERSION","SERVICE_CONTRACT_VERSION","MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION","VIEW_COMPONENTS","app","asset_source","panel","tile","TileSizeSchema","enum","DockGroupSchema","DockSchema","object","group","optional","order","number","ViewPlacementMetadataSchema","dock","TileInterfaceMetadataSchema","size","INTERFACE_CONTRACT_VERSIONS","undefined","worker","interfaceContractVersion","kind","version","String","interfaceModuleId","name","Error","extensionDeclarationFields","pattern","string","check","regex","src","interfaceDeclarationFields","title","PanelViewSchema","surface","literal","definePanelView","view","WindowViewSchema","defineWindowView","AssetSourceViewSchema","defineAssetSourceView","TileViewSchema","defineTileView","InterfaceDeclarationSchema","discriminatedUnion","WebWorkerSchema","type","defineWebWorker","webWorker","ServiceDeclarationSchema","MediaLibraryFieldSchema","public","boolean","INSTALLATION_CONFIG_TYPE","MediaLibraryConfigSchema","appType","fields","array","refine","Set","map","field","length","ConfigSchema"],"mappings":"AAAA,SAAQA,CAAC,QAAO,WAAU;AAE1B,4EAA4E;AAC5E,kEAAkE;AAClE,qCAAqC;AAErC,cAAc,GACd,OAAO,MAAMC,wBAAwB,EAAC;AAEtC,cAAc,GACd,OAAO,MAAMC,2BAA2B,EAAC;AAEzC,cAAc,GACd,OAAO,MAAMC,wCAAwC,EAAC;AActD,kGAAkG,GAClG,OAAO,MAAMC,kBAAkB;IAC7BC,KAAK,EAAE;IACPC,cAAc;QAAC;KAAe;IAC9BC,OAAO;QAAC;QAAS;KAAQ;IACzBC,MAAM;QAAC;KAAO;AAChB,EAAsD;AAKtD;;;;;;CAMC,GACD,OAAO,MAAMC,iBAAiBT,EAAEU,IAAI,CAAC;IAAC;IAAS;IAAS;CAAS,EAAC;AAQlE,MAAMC,kBAAkBX,EAAEU,IAAI,CAAC;IAAC;IAAe;IAAqB;CAAY;AAKhF,cAAc,GACd,OAAO,MAAME,aAAaZ,EAAEa,MAAM,CAAC;IACjCC,OAAOd,EAAEe,QAAQ,CAACJ;IAClBK,OAAOhB,EAAEe,QAAQ,CAACf,EAAEiB,MAAM;AAC5B,GAAE;AAKF,cAAc,GACd,OAAO,MAAMC,8BAA8BlB,EAAEa,MAAM,CAAC;IAACM,MAAMP;AAAU,GAAE;AAKvE;;;;;CAKC,GACD,OAAO,MAAMQ,8BAA8BpB,EAAEa,MAAM,CAAC;IAClDG,OAAOhB,EAAEe,QAAQ,CAACf,EAAEiB,MAAM;IAC1BI,MAAMZ;AACR,GAAE;AAKF;;;;CAIC,GACD,MAAMa,8BAA8B;IAClCjB,KAAKkB;IACLjB,cAAcL;IACdM,OAAON;IACPO,MAAMP;IACNuB,QAAQtB;AACV;AAKA,cAAc,GACd,OAAO,SAASuB,yBAAyBC,IAAmB;IAC1D,MAAMC,UAAUL,2BAA2B,CAACI,KAAK;IACjD,OAAOC,YAAYJ,YAAYA,YAAYK,OAAOD;AACpD;AAEA;;;;CAIC,GACD,OAAO,SAASE,kBAAkBH,IAAY,EAAEI,IAAY;IAC1D,OAAQJ;QACN,KAAK;YAAO;gBACV,OAAO;YACT;QACA,KAAK;QACL,KAAK;QACL,KAAK;YAAQ;gBACX,OAAO,CAAC,MAAM,EAAEI,MAAM;YACxB;QACA,KAAK;YAAU;gBACb,OAAO,CAAC,SAAS,EAAEA,MAAM;YAC3B;QACA;YAAS;gBACP,MAAM,IAAIC,MAAM,CAAC,qDAAqD,EAAEL,MAAM;YAChF;IACF;AACF;AAEA,qEAAqE;AACrE,SAASM,2BAA2BN,IAAqC;IACvE,MAAMO,UAAU;IAChB,OAAO;QACLH,MAAM9B,EAAEkC,MAAM,GAAGC,KAAK,CAACnC,EAAEoC,KAAK,CAACH,SAAS,GAAGP,KAAK,qBAAqB,EAAEO,SAAS;QAChFI,KAAKrC,EAAEkC,MAAM;IACf;AACF;AAEA,6DAA6D;AAC7D,mDAAmD;AACnD,SAASI,2BAA2BZ,IAA2B;IAC7D,OAAO;QACL,GAAGM,2BAA2BN,KAAK;QACnCa,OAAOvC,EAAEkC,MAAM,CAAC,GAAGR,KAAK,sBAAsB,CAAC;IACjD;AACF;AAEA,MAAMc,kBAAkBxC,EAAEa,MAAM,CAAC;IAC/B4B,SAASzC,EAAE0C,OAAO,CAAC;IACnB,GAAGJ,2BAA2B,OAAO;IACrCnB,MAAMnB,EAAEe,QAAQ,CAACH;AACnB;AAQA,YAAY,GACZ,OAAO,SAAS+B,gBAAgBC,IAA0B;IACxD,OAAO;QAAC,GAAGA,IAAI;QAAEH,SAAS;IAAO;AACnC;AAEA,MAAMI,mBAAmB7C,EAAEa,MAAM,CAAC;IAChC4B,SAASzC,EAAE0C,OAAO,CAAC;IACnB,GAAGJ,2BAA2B,OAAO;IACrCnB,MAAMnB,EAAEe,QAAQ,CAACH;AACnB;AAQA,YAAY,GACZ,OAAO,SAASkC,iBAAiBF,IAA2B;IAC1D,OAAO;QAAC,GAAGA,IAAI;QAAEH,SAAS;IAAK;AACjC;AAEA,MAAMM,wBAAwB/C,EAAEa,MAAM,CAAC;IACrC4B,SAASzC,EAAE0C,OAAO,CAAC;IACnB,GAAGJ,2BAA2B,OAAO;AACvC;AAQA,YAAY,GACZ,OAAO,SAASU,sBAAsBJ,IAAgC;IACpE,OAAO;QAAC,GAAGA,IAAI;QAAEH,SAAS;IAAc;AAC1C;AAEA,MAAMQ,iBAAiBjD,EAAEa,MAAM,CAAC;IAC9B4B,SAASzC,EAAE0C,OAAO,CAAC;IACnB,GAAGJ,2BAA2B,OAAO;IACrC,gEAAgE,GAChEtB,OAAOhB,EAAEe,QAAQ,CAACf,EAAEiB,MAAM;IAC1B,yDAAyD,GACzDI,MAAMZ;AACR;AAQA,YAAY,GACZ,OAAO,SAASyC,eAAeN,IAAyB;IACtD,OAAO;QAAC,GAAGA,IAAI;QAAEH,SAAS;IAAM;AAClC;AAEA,cAAc,GACd,OAAO,MAAMU,6BAA6BnD,EAAEoD,kBAAkB,CAAC,WAAW;IACxEP;IACAL;IACAO;IACAE;CACD,EAAC;AAKF,MAAMI,kBAAkBrD,EAAEa,MAAM,CAAC;IAC/ByC,MAAMtD,EAAE0C,OAAO,CAAC;IAChB,GAAGJ,2BAA2B,aAAa;AAC7C;AAQA,YAAY,GACZ,OAAO,SAASiB,gBAAgBC,SAA+B;IAC7D,OAAO;QAAC,GAAGA,SAAS;QAAEF,MAAM;IAAQ;AACtC;AAEA,cAAc,GACd,OAAO,MAAMG,2BAA2BzD,EAAEoD,kBAAkB,CAAC,QAAQ;IAACC;CAAgB,EAAC;AAEvF,MAAMK,0BAA0B1D,EAAEa,MAAM,CAAC;IACvC,GAAGmB,2BAA2B,QAAQ;IACtC2B,QAAQ3D,EAAEe,QAAQ,CAACf,EAAE4D,OAAO;IAC5BrB,OAAOvC,EAAEkC,MAAM;AACjB;AAEA;;;CAGC,GACD,OAAO,MAAM2B,2BAA2B,sBAAqB;AAE7D,yEAAyE;AACzE,MAAMC,2BAA2B9D,EAAEa,MAAM,CAAC;IACxCkD,SAAS/D,EAAE0C,OAAO,CAAC;IACnBsB,QAAQhE,EACLiE,KAAK,CAACP,yBACNvB,KAAK,CACJnC,EAAEkE,MAAM,CACN,CAACF,SAAW,IAAIG,IAAIH,OAAOI,GAAG,CAAC,CAACC,QAAUA,MAAMvC,IAAI,GAAGT,IAAI,KAAK2C,OAAOM,MAAM,EAC7E;AAGR;AAEA;;;;CAIC,GACD,OAAO,MAAMC,eAAevE,EAAEoD,kBAAkB,CAAC,WAAW;IAACU;CAAyB,EAAC"}