@powerhousedao/shared 6.2.3-dev.50 → 6.2.3-dev.52

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 (53) hide show
  1. package/dist/clis/args/common-BXabdhiO.mjs.map +1 -1
  2. package/dist/clis/{build-config-CR5lvv_A.mjs → build-config-HbYUSZS1.mjs} +26 -5
  3. package/dist/clis/build-config-HbYUSZS1.mjs.map +1 -0
  4. package/dist/clis/build-config.d.mts +6 -0
  5. package/dist/clis/build-config.d.mts.map +1 -1
  6. package/dist/clis/build-config.mjs +1 -1
  7. package/dist/clis/build-pieces.d.mts +62 -2
  8. package/dist/clis/build-pieces.d.mts.map +1 -1
  9. package/dist/clis/build-pieces.mjs +189 -11
  10. package/dist/clis/build-pieces.mjs.map +1 -1
  11. package/dist/clis/constants.d.mts +2 -2
  12. package/dist/clis/constants.mjs +13 -2
  13. package/dist/clis/constants.mjs.map +1 -1
  14. package/dist/clis/index.d.mts +20 -1
  15. package/dist/clis/index.d.mts.map +1 -1
  16. package/dist/clis/index.mjs +355 -288
  17. package/dist/clis/index.mjs.map +1 -1
  18. package/dist/clis/{types-Cc_rB0Yx.d.mts → types-BZBiwi6I.d.mts} +17 -3
  19. package/dist/clis/types-BZBiwi6I.d.mts.map +1 -0
  20. package/dist/{config-loader-CXhzL512.js → config-loader-DpeoExZO.js} +3 -2
  21. package/dist/config-loader-DpeoExZO.js.map +1 -0
  22. package/dist/connect/config-loader.d.ts +1 -1
  23. package/dist/connect/config-loader.js +1 -1
  24. package/dist/connect/index.d.ts +6 -1
  25. package/dist/connect/index.d.ts.map +1 -1
  26. package/dist/connect/index.js +6 -1
  27. package/dist/connect/index.js.map +1 -1
  28. package/dist/{constants-C2K-m7pp.d.ts → constants-C6ket9Bn.d.ts} +2 -2
  29. package/dist/constants-C6ket9Bn.d.ts.map +1 -0
  30. package/dist/constants.d.ts +1 -1
  31. package/dist/constants.js +1 -0
  32. package/dist/constants.js.map +1 -1
  33. package/dist/document-drive/index.d.ts +3 -3
  34. package/dist/document-model/errors.d.ts +1 -1
  35. package/dist/document-model/index.d.ts +1 -1
  36. package/dist/document-model/index.js +1 -0
  37. package/dist/document-model/index.js.map +1 -1
  38. package/dist/{index-BhqNGLu9.d.ts → index-C3fD6cad.d.ts} +2 -2
  39. package/dist/{index-BhqNGLu9.d.ts.map → index-C3fD6cad.d.ts.map} +1 -1
  40. package/dist/index.d.ts +4 -4
  41. package/dist/processors/index.d.ts +1 -1
  42. package/dist/registry/index.d.ts +2 -2
  43. package/dist/registry/index.js.map +1 -1
  44. package/dist/registry/manifest-slim.d.ts +2 -2
  45. package/dist/{types-BTfv_ZzS.d.ts → types-CywupGpk.d.ts} +2 -2
  46. package/dist/{types-BTfv_ZzS.d.ts.map → types-CywupGpk.d.ts.map} +1 -1
  47. package/dist/{types-BRJfX8ck.d.ts → types-DDH6v2BE.d.ts} +8 -1
  48. package/dist/{types-BRJfX8ck.d.ts.map → types-DDH6v2BE.d.ts.map} +1 -1
  49. package/package.json +1 -1
  50. package/dist/clis/build-config-CR5lvv_A.mjs.map +0 -1
  51. package/dist/clis/types-Cc_rB0Yx.d.mts.map +0 -1
  52. package/dist/config-loader-CXhzL512.js.map +0 -1
  53. package/dist/constants-C2K-m7pp.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"common-BXabdhiO.mjs","names":["AGENTS","_AGENTS"],"sources":["../../../clis/constants.ts","../../../clis/file-system/get-config.ts","../../../clis/args/common.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Manifest } from \"../document-model/types.js\";\nimport type { PowerhouseConfig } from \"./types.js\";\n\nexport const SERVICE_ACTIONS = [\n \"start\",\n \"stop\",\n \"status\",\n \"setup\",\n \"restart\",\n] as const;\n\nexport const SECONDS_IN_DAY = 24 * 60 * 60;\nexport const DEFAULT_EXPIRY_DAYS = 7;\nexport const DEFAULT_EXPIRY_SECONDS = DEFAULT_EXPIRY_DAYS * SECONDS_IN_DAY;\n\nexport const DRIVES_PRESERVE_STRATEGIES = [\n \"preserve-all\",\n \"preserve-by-url-and-detach\",\n] as const;\n\nexport const LOG_LEVELS = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"verbose\",\n] as const;\n\nexport const DEFAULT_TIMEOUT = 300 as const;\n\nexport const DEFAULT_CONNECT_STUDIO_PORT = 3000 as const;\n\nexport const DEFAULT_VETRA_CONNECT_PORT = 3001 as const;\n\nexport const DEFAULT_CONNECT_PREVIEW_PORT = 4173 as const;\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport const DEFAULT_RENOWN_URL = \"https://www.renown.id\" as const;\n\nexport const DEFAULT_REGISTRY_URL = \"https://registry.vetra.io\" as const;\n\nexport const DEFAULT_SWITCHBOARD_PORT = 4001 as const;\n\n// Per-project dev-server port bands. `ph init` assigns each project a port\n// triple derived from its name, so two projects never collide and an agent's\n// MCP URL can be baked into .mcp.json before a session starts.\n//\n// Two hard constraints picked these bands, both below 10000:\n//\n// 1. Below the OS ephemeral range. Linux allocates outbound source ports\n// from 32768-60999 (`/proc/sys/net/ipv4/ip_local_port_range`); macOS and\n// Windows start at 49152. A listener parked in that window can lose a\n// race to a transient outbound socket, which would surface as a\n// `--strictPort` failure blaming a project conflict that does not exist.\n// 2. Below 10000, which is where ph-clint starts. ph-clint derives its own\n// per-CLI ports by hashing into 10000-59900, so staying under 10000\n// keeps the two schemes from ever contending.\n//\n// Within those limits the blocks were chosen by measuring which ports the\n// Powerhouse repos actually reference: 2000-2999 has none, 7000-7999 has one,\n// 6000-6999 has five. See PROJECT_PORT_DENYLIST in project-ports.ts for the\n// individual ports skipped inside them.\nexport const PROJECT_PORT_BAND_SIZE = 1000 as const;\nexport const PROJECT_PORT_BAND_SWITCHBOARD = 7000 as const;\nexport const PROJECT_PORT_BAND_STUDIO = 6000 as const;\nexport const PROJECT_PORT_BAND_VETRA_CONNECT = 2000 as const;\n\nexport const DEFAULT_VETRA_DRIVE_ID = \"vetra\" as const;\n\nexport const MINIMUM_NODE_VERSION = \"24.0.0\" as const;\nexport const PH_BIN = \"ph-cli-legacy\" as const;\nexport const POWERHOUSE_CONFIG_FILE = \"powerhouse.config.json\" as const;\nexport const PH_GLOBAL_DIR_NAME = \".ph\" as const;\n// Keep PH_GLOBAL_PROJECT_NAME for backwards compatibility\nexport const PH_GLOBAL_PROJECT_NAME = PH_GLOBAL_DIR_NAME;\n\nexport const HOME_DIR = homedir();\n\nexport const POWERHOUSE_GLOBAL_DIR = join(HOME_DIR, PH_GLOBAL_DIR_NAME);\n\n// Workspace packages that go in peerDependencies of every generated project.\nexport const VERSIONED_PEER_DEPENDENCIES = [\n \"document-model\",\n \"@powerhousedao/reactor-browser\",\n];\n\ntype PeerSpec = { peer: string; dev: string };\n\nexport const REACTOR_API_PACKAGE = \"@powerhousedao/reactor-api\";\nexport const ANALYTICS_ENGINE_CORE_PACKAGE =\n \"@powerhousedao/analytics-engine-core\";\nexport const GRAPHQL_PACKAGE = \"graphql\";\nexport const GRAPHQL_TAG_PACKAGE = \"graphql-tag\";\nexport const PIECES_FRAMEWORK_PACKAGE = \"@powerhousedao/pieces-framework\";\n\n// External peerDependencies of every generated project.\n// `peer` is the consumer-facing range; `dev` is the exact build-tested pin.\n// graphql / graphql-tag are always-on because the workspace packages pulled\n// in by every `ph init` project (codegen, reactor-api, reactor-browser,\n// vetra-packages) declare them as peers — even projects without subgraphs\n// need them in scope so pnpm hoists a single graphql instance.\nexport const PEER_EXTERNAL_DEPENDENCIES = {\n [GRAPHQL_PACKAGE]: { peer: \"^16\", dev: \"16.12.0\" },\n [GRAPHQL_TAG_PACKAGE]: { peer: \"^2\", dev: \"2.12.6\" },\n react: { peer: \"^19\", dev: \"19.2.6\" },\n \"react-dom\": { peer: \"^19\", dev: \"19.2.6\" },\n zod: { peer: \"^4\", dev: \"4.3.6\" },\n} as const satisfies Record<string, PeerSpec>;\n\n// Per-feature deps added dynamically by codegen when required. `devVersioned`\n// is for a workspace package the build inlines, which no consumer provides.\nexport const FEATURE_DEPENDENCIES = {\n analyticsProcessor: {\n peerVersioned: [ANALYTICS_ENGINE_CORE_PACKAGE],\n peerExternal: {},\n devVersioned: [],\n },\n // Each piece is bundled whole (build-pieces.mts), framework included, so the\n // framework is only ever needed to compile the piece's own source.\n piece: {\n peerVersioned: [],\n peerExternal: {},\n devVersioned: [PIECES_FRAMEWORK_PACKAGE],\n },\n} as const satisfies Record<\n string,\n {\n peerVersioned: readonly string[];\n peerExternal: Record<string, PeerSpec>;\n devVersioned: readonly string[];\n }\n>;\n\nexport const VERSIONED_DEPENDENCIES = [\n ...VERSIONED_PEER_DEPENDENCIES,\n ...FEATURE_DEPENDENCIES.analyticsProcessor.peerVersioned,\n];\n\n// Transitive dependencies whose postinstall scripts the generated project\n// trusts. Mirrors the `allowBuilds` map in the boilerplate's\n// pnpm-workspace.yaml and is also passed as `--allow-build` flags to\n// `pnpm dlx @powerhousedao/ph-cli init` so pnpm 11's strict-dep-builds\n// default doesn't prompt during the outer dlx download.\nexport const BOILERPLATE_ALLOWED_BUILDS = [\n \"@apollo/protobufjs\",\n \"@datadog/pprof\",\n \"@parcel/watcher\",\n \"@reown/appkit\",\n \"bufferutil\",\n \"esbuild\",\n \"keccak\",\n \"protobufjs\",\n \"utf-8-validate\",\n] as const;\n\n// Single-version pins the boilerplate enforces on generated projects,\n// avoiding duplicates from coexisting version ranges. Rendered as pnpm\n// `overrides` (pnpm-workspace.yaml) and as yarn v1 `resolutions`\n// (package.json). Generated-project only — never change the monorepo\n// catalog for this (a re-resolution there pulls a tsc-crashing TS6 beta).\nexport const BOILERPLATE_DEPENDENCY_OVERRIDES = {\n \"date-fns\": \"4.3.0\",\n vite: \"8.0.14\",\n rolldown: \"1.0.2\",\n} as const satisfies Record<string, string>;\n\nexport const VERSIONED_DEV_DEPENDENCIES = [\n \"@powerhousedao/ph-cli\",\n \"@powerhousedao/reactor\",\n \"@powerhousedao/shared\",\n \"@powerhousedao/connect\",\n \"@powerhousedao/design-system\",\n];\n\nexport const packageJsonExports = {\n \".\": {\n types: \"./dist/types/index.d.ts\",\n browser: \"./dist/browser/index.js\",\n node: \"./dist/node/index.mjs\",\n },\n \"./reactor\": {\n types: \"./dist/types/reactor/index.d.ts\",\n browser: \"./dist/browser/reactor/index.js\",\n },\n \"./document-models\": {\n types: \"./dist/types/document-models/index.d.ts\",\n browser: \"./dist/browser/document-models/index.js\",\n node: \"./dist/node/document-models/index.mjs\",\n },\n \"./document-models/*\": {\n types: \"./dist/types/document-models/*/index.d.ts\",\n browser: \"./dist/browser/document-models/*/index.js\",\n node: \"./dist/node/document-models/*/index.mjs\",\n },\n \"./editors\": {\n types: \"./dist/types/editors/index.d.ts\",\n browser: \"./dist/browser/editors/index.js\",\n node: \"./dist/node/editors/index.mjs\",\n },\n \"./editors/*\": {\n types: \"./dist/types/editors/*/editor.d.ts\",\n browser: \"./dist/browser/editors/*/editor.js\",\n node: \"./dist/node/editors/*/editor.mjs\",\n },\n \"./subgraphs\": {\n types: \"./dist/types/subgraphs/index.d.ts\",\n browser: \"./dist/browser/subgraphs/index.js\",\n node: \"./dist/node/subgraphs/index.mjs\",\n },\n \"./processors\": {\n types: \"./dist/types/processors/index.d.ts\",\n browser: \"./dist/browser/processors/index.js\",\n node: \"./dist/node/processors/index.mjs\",\n },\n // Node only, as the build is: a piece is loaded by a host process, never by\n // the browser. Without these a package can build a piece and still fail the\n // `packageName/pieces` import a host resolves it through.\n \"./pieces\": {\n types: \"./dist/types/pieces/index.d.ts\",\n node: \"./dist/node/pieces/index.mjs\",\n },\n \"./pieces/*\": {\n types: \"./dist/types/pieces/*/index.d.ts\",\n node: \"./dist/node/pieces/*/index.mjs\",\n },\n \"./manifest\": \"./dist/powerhouse.manifest.json\",\n \"./style.css\": \"./dist/style.css\",\n} as const;\n\nexport const packageScripts = {\n \"test:watch\": \"vitest\",\n lint: \"oxlint --type-aware --type-check\",\n \"lint:fix\": \"oxlint --type-aware --type-check --fix\",\n format: \"oxfmt\",\n \"format:check\": \"oxfmt --check\",\n tsc: \"tsc\",\n \"tsc:watch\": \"tsc --watch\",\n generate: \"ph-cli generate\",\n connect: \"ph-cli connect\",\n build: \"ph-cli build\",\n reactor: \"ph-cli reactor\",\n service: \"ph-cli service\",\n vetra: \"ph-cli vetra\",\n \"service-startup\":\n \"bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh\",\n \"service-unstartup\":\n \"bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh\",\n} as const;\n\nexport const externalDependencies = {} as const;\n\n// eslint/prettier devDependencies present in projects scaffolded before the oxc migration.\n// Stripped from package.json during `ph migrate`.\nexport const LEGACY_LINT_FORMAT_DEPENDENCIES = [\n \"@eslint/js\",\n \"eslint\",\n \"eslint-config-prettier\",\n \"eslint-plugin-prettier\",\n \"eslint-plugin-react\",\n \"eslint-plugin-react-hooks\",\n \"globals\",\n \"prettier\",\n \"typescript-eslint\",\n] as const;\n\n// Legacy lint/format config files written by eslint/prettier boilerplate.\n// Removed from the project root during `ph migrate`.\nexport const LEGACY_LINT_FORMAT_FILES = [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \"eslint.config.ts\",\n \".eslintrc\",\n \".eslintrc.js\",\n \".eslintrc.cjs\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n \".eslintignore\",\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yml\",\n \".prettierrc.yaml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n \".prettierignore\",\n] as const;\n\nexport const externalDevDependencies = {\n \"@electric-sql/pglite\": \"0.3.15\",\n \"@electric-sql/pglite-tools\": \"0.2.20\",\n \"@powerhousedao/document-engineering\": \"1.40.5\",\n \"@tailwindcss/cli\": \"^4.1.18\",\n \"@tailwindcss/vite\": \"^4.1.18\",\n \"@types/node\": \"^24.9.2\",\n \"@types/react\": \"^19.2.3\",\n \"@types/react-dom\": \"^19.2.3\",\n \"@vitejs/plugin-react\": \"^6.0.1\",\n \"@vitest/coverage-v8\": \"5.0.3\",\n oxfmt: \"0.68.0\",\n oxlint: \"1.70.0\",\n \"oxlint-tsgolint\": \"0.23.0\",\n tailwindcss: \"^4.1.16\",\n typescript: \"~7.0.2\",\n vite: \"^8.0.10\",\n \"vite-tsconfig-paths\": \"6.1.1\",\n vitest: \"5.0.3\",\n} as const;\n\nexport const defaultManifest: Manifest = {\n name: \"\",\n description: \"\",\n category: \"\",\n publisher: {\n name: \"\",\n url: \"\",\n },\n documentModels: [],\n editors: [],\n apps: [],\n subgraphs: [],\n processors: [],\n};\n\nconst DEFAULT_DOCUMENT_MODELS_DIR = \"./document-models\";\nconst DEFAULT_EDITORS_DIR = \"./editors\";\nconst DEFAULT_PROCESSORS_DIR = \"./processors\";\nconst DEFAULT_SUBGRAPHS_DIR = \"./subgraphs\";\nconst DEFAULT_IMPORT_SCRIPTS_DIR = \"./scripts\";\nconst DEFAULT_SKIP_FORMAT = false;\nconst DEFAULT_LOG_LEVEL = \"info\";\n\nexport const DEFAULT_CONFIG: PowerhouseConfig = {\n documentModelsDir: DEFAULT_DOCUMENT_MODELS_DIR,\n editorsDir: DEFAULT_EDITORS_DIR,\n processorsDir: DEFAULT_PROCESSORS_DIR,\n subgraphsDir: DEFAULT_SUBGRAPHS_DIR,\n importScriptsDir: DEFAULT_IMPORT_SCRIPTS_DIR,\n skipFormat: DEFAULT_SKIP_FORMAT,\n logLevel: DEFAULT_LOG_LEVEL,\n auth: {\n enabled: false,\n admins: [],\n },\n};\n","import { readFileSync } from \"node:fs\";\nimport { DEFAULT_CONFIG } from \"../constants.js\";\nimport type { PowerhouseConfig } from \"../types.js\";\n\nexport function getConfig(path = \"./powerhouse.config.json\") {\n let config: PowerhouseConfig = { ...DEFAULT_CONFIG };\n try {\n const configStr = readFileSync(path, \"utf-8\");\n const userConfig = JSON.parse(configStr) as PowerhouseConfig;\n config = { ...config, ...userConfig };\n } catch {\n // console.warn(\"No powerhouse.config.json found, using defaults\");\n }\n\n return config;\n}\n","import {\n array,\n boolean,\n command,\n flag,\n multioption,\n number,\n oneOf,\n option,\n optional,\n string,\n} from \"cmd-ts\";\n// Sub-path: avoids pulling the package-manager-detector runtime here,\n// which `oneOf(AGENTS)` below would force at module load.\nimport type { Agent } from \"package-manager-detector\";\nimport { AGENTS as _AGENTS } from \"package-manager-detector/constants\";\nimport {\n DEFAULT_TIMEOUT,\n DRIVES_PRESERVE_STRATEGIES,\n LOG_LEVELS,\n} from \"../constants.js\";\nimport { getConfig } from \"../file-system/get-config.js\";\n\nexport const AGENTS: Agent[] = _AGENTS;\n\nexport const debugArgs = {\n debug: flag({\n type: optional(boolean),\n long: \"debug\",\n description: \"Log arguments passed to this command\",\n }),\n};\n\nexport const buildArgs = {\n outDir: option({\n type: string,\n long: \"out-dir\",\n description: \"Where to output the bundled code\",\n defaultValue: () => \"dist\" as const,\n defaultValueIsSerializable: true,\n }),\n noSharedDeps: flag({\n type: boolean,\n long: \"no-shared-deps\",\n description:\n \"Bundle the shared dependency set instead of externalizing it (default: externalize)\",\n defaultValue: () => false as const,\n defaultValueIsSerializable: true,\n }),\n ignoreTypeErrors: flag({\n type: boolean,\n long: \"ignore-type-errors\",\n description:\n \"Unsafe: build even when tsc reports type errors, without asking. The package can load and still fail at runtime\",\n defaultValue: () => false as const,\n defaultValueIsSerializable: true,\n }),\n ...debugArgs,\n};\n\nexport const packageManagerArgs = {\n packageManager: option({\n type: optional(oneOf(AGENTS)),\n long: \"package-manager\",\n short: \"p\",\n description:\n \"Specify the package manager to use for your project. Can be one of: `npm`, `pnpm`, `yarn`, or `bun`. Defaults to your environment package manager.\",\n }),\n npm: flag({\n type: optional(boolean),\n long: \"npm\",\n description: \"Use 'npm' as package manager\",\n }),\n pnpm: flag({\n type: optional(boolean),\n long: \"pnpm\",\n description: \"Use 'pnpm' as package manager\",\n }),\n yarn: flag({\n type: optional(boolean),\n long: \"yarn\",\n description: \"Use 'yarn' as package manager\",\n }),\n bun: flag({\n type: optional(boolean),\n long: \"bun\",\n description: \"Use 'bun' as package manager\",\n }),\n};\nexport const getPackageManagerCommand = command({\n name: \"get-package-manager\",\n args: packageManagerArgs,\n handler: (args) => args,\n});\nexport const packages = option({\n type: optional(string),\n long: \"packages\",\n description: \"Comma-separated list of package names to load\",\n env: \"PH_PACKAGES\" as const,\n});\n\nexport const localPackage = option({\n type: optional(string),\n long: \"local-package\",\n description: \"Path to local package to load during development\",\n env: \"PH_LOCAL_PACKAGE\" as const,\n});\n\nexport const disableLocalPackages = flag({\n type: boolean,\n long: \"ignore-local\",\n description: \"Do not load local packages from this project\",\n defaultValue: () => false,\n});\n\nexport const httpsKeyFile = option({\n type: optional(string),\n long: \"https-key-file\",\n description: \"path to the ssl key file\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (https === undefined) return undefined;\n if (typeof https === \"boolean\") return undefined;\n return https.keyPath;\n },\n});\n\nexport const httpsCertFile = option({\n type: optional(string),\n long: \"https-cert-file\",\n description: \"path to the ssl cert file\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (https === undefined) return undefined;\n if (typeof https === \"boolean\") return undefined;\n return https.certPath;\n },\n});\n\nexport const https = flag({\n type: optional(boolean),\n long: \"https\",\n description: \"Use https\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (typeof https === \"boolean\") return https;\n return undefined;\n },\n});\n\nexport const vetraSwitchboardArgs = {\n https,\n httpsKeyFile,\n httpsCertFile,\n dev: flag({\n type: optional(boolean),\n long: \"dev\",\n description: \"enable development mode to load local packages\",\n }),\n remoteDrives: multioption({\n type: array(string),\n long: \"remote-drives\",\n description: \"Specify remote drive URLs to use\",\n defaultValue: () => [],\n }),\n disableLocalPackages,\n ...debugArgs,\n};\n\nexport const defaultDrivesUrl = option({\n type: optional(string),\n long: \"default-drives-url\",\n description: \"Comma-separated drive URLs to use as Connect's default drives.\",\n defaultValue: () => \"\",\n});\n\nexport const logLevel = option({\n type: oneOf(LOG_LEVELS),\n long: \"log-level\",\n description: \"Log level for the application\",\n defaultValue: () => \"info\" as const,\n defaultValueIsSerializable: true,\n env: \"PH_CONNECT_LOG_LEVEL\" as const,\n});\n\nexport const connectBasePath = option({\n long: \"base\",\n type: string,\n description: \"Base path for the app\",\n defaultValue: () => \"/\",\n});\n\nexport const renownNamespace = option({\n type: optional(string),\n long: \"renown-namespace\",\n description:\n \"Renown localStorage namespace; share it across Connects to share login.\",\n});\n\nexport const renownSwitchboardUrl = option({\n type: optional(string),\n long: \"renown-switchboard-url\",\n description:\n \"Override connect.renown.switchboardUrl. When set, enables in-page Renown sign-in.\",\n});\n\nexport const drivesPreserveStrategy = option({\n type: oneOf(DRIVES_PRESERVE_STRATEGIES),\n long: \"drive-preserve-strategy\",\n description: \"The preservation strategy to use on default drives\",\n defaultValue: () => \"preserve-by-url-and-detach\" as const,\n defaultValueIsSerializable: true,\n});\n\nexport const force = flag({\n type: optional(boolean),\n long: \"force\",\n description:\n \"Force dep pre-optimization regardless of whether deps have changed.\",\n});\n\nexport const commonArgs = {\n connectBasePath,\n logLevel,\n packages,\n localPackage,\n disableLocalPackages,\n defaultDrivesUrl,\n drivesPreserveStrategy,\n force,\n ...debugArgs,\n};\n\nexport const commonServerArgs = {\n host: option({\n type: optional(string),\n long: \"host\",\n description:\n \"Expose the server to the network. Pass an IP (e.g. 0.0.0.0) to bind to a specific address.\",\n }),\n open: flag({\n type: optional(boolean),\n long: \"open\",\n description: \"Open browser on startup\",\n }),\n cors: flag({\n type: optional(boolean),\n long: \"cors\",\n description: \"Enable CORS\",\n }),\n strictPort: flag({\n type: optional(boolean),\n long: \"strictPort\",\n description: \"Exit if specified port is already in use\",\n }),\n printUrls: flag({\n type: boolean,\n long: \"print-urls\",\n description: \"Print server urls\",\n defaultValue: () => true,\n defaultValueIsSerializable: true,\n }),\n bindCLIShortcuts: flag({\n type: boolean,\n long: \"bind-cli-shortcuts\",\n description: \"Bind CLI shortcuts\",\n defaultValue: () => true,\n defaultValueIsSerializable: true,\n }),\n watchTimeout: option({\n type: number,\n long: \"watch-timeout\",\n description: \"Amount of time to wait before a file is considered changed\",\n defaultValue: () => DEFAULT_TIMEOUT,\n defaultValueIsSerializable: true,\n }),\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"common-BXabdhiO.mjs","names":["AGENTS","_AGENTS"],"sources":["../../../clis/constants.ts","../../../clis/file-system/get-config.ts","../../../clis/args/common.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Manifest } from \"../document-model/types.js\";\nimport type { PowerhouseConfig } from \"./types.js\";\n\nexport const SERVICE_ACTIONS = [\n \"start\",\n \"stop\",\n \"status\",\n \"setup\",\n \"restart\",\n] as const;\n\nexport const SECONDS_IN_DAY = 24 * 60 * 60;\nexport const DEFAULT_EXPIRY_DAYS = 7;\nexport const DEFAULT_EXPIRY_SECONDS = DEFAULT_EXPIRY_DAYS * SECONDS_IN_DAY;\n\nexport const DRIVES_PRESERVE_STRATEGIES = [\n \"preserve-all\",\n \"preserve-by-url-and-detach\",\n] as const;\n\nexport const LOG_LEVELS = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"verbose\",\n] as const;\n\nexport const DEFAULT_TIMEOUT = 300 as const;\n\nexport const DEFAULT_CONNECT_STUDIO_PORT = 3000 as const;\n\nexport const DEFAULT_VETRA_CONNECT_PORT = 3001 as const;\n\nexport const DEFAULT_CONNECT_PREVIEW_PORT = 4173 as const;\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport const DEFAULT_RENOWN_URL = \"https://www.renown.id\" as const;\n\nexport const DEFAULT_REGISTRY_URL = \"https://registry.vetra.io\" as const;\n\nexport const DEFAULT_SWITCHBOARD_PORT = 4001 as const;\n\n// Per-project dev-server port bands. `ph init` assigns each project a port\n// triple derived from its name, so two projects never collide and an agent's\n// MCP URL can be baked into .mcp.json before a session starts.\n//\n// Two hard constraints picked these bands, both below 10000:\n//\n// 1. Below the OS ephemeral range. Linux allocates outbound source ports\n// from 32768-60999 (`/proc/sys/net/ipv4/ip_local_port_range`); macOS and\n// Windows start at 49152. A listener parked in that window can lose a\n// race to a transient outbound socket, which would surface as a\n// `--strictPort` failure blaming a project conflict that does not exist.\n// 2. Below 10000, which is where ph-clint starts. ph-clint derives its own\n// per-CLI ports by hashing into 10000-59900, so staying under 10000\n// keeps the two schemes from ever contending.\n//\n// Within those limits the blocks were chosen by measuring which ports the\n// Powerhouse repos actually reference: 2000-2999 has none, 7000-7999 has one,\n// 6000-6999 has five. See PROJECT_PORT_DENYLIST in project-ports.ts for the\n// individual ports skipped inside them.\nexport const PROJECT_PORT_BAND_SIZE = 1000 as const;\nexport const PROJECT_PORT_BAND_SWITCHBOARD = 7000 as const;\nexport const PROJECT_PORT_BAND_STUDIO = 6000 as const;\nexport const PROJECT_PORT_BAND_VETRA_CONNECT = 2000 as const;\n\n/**\n * Icon for the drives switchboard creates by default, inlined as a data URI.\n *\n * A remote URL is the wrong shape for this: the value is baked into the drive\n * document and rendered by every Connect that opens it, so the icon only\n * appears when that client can reach that host. A desktop or air-gapped install\n * cannot, and the ipfs.io gateway this previously pointed at now answers 403\n * regardless.\n *\n * The mark is drawn dark-on-light so it stays legible against either theme.\n */\nexport const DEFAULT_DRIVE_ICON =\n \"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='3'%20fill='%23F3F5F7'/%3E%3Cpath%20fill='%23343839'%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M10.0059%200L3.41636%205.45646C2.44979%206.25682%202.3795%207.71452%203.26456%208.60418L5.54425%2010.8957C6.21311%2011.568%206.35783%2012.6012%205.89944%2013.4314L4.48126%2016H2.13333C0.955126%2016%200%2015.0449%200%2013.8667V2.13333C0%200.955126%200.955126%200%202.13333%200H10.0059ZM11.2436%200L10.0128%202.24221C9.55899%203.06891%209.70183%204.09549%2010.3641%204.7669L12.7825%207.21868C13.6656%208.11402%2013.5866%209.57512%2012.612%2010.37L5.70922%2016H13.8667C15.0449%2016%2016%2015.0449%2016%2013.8667V2.13333C16%200.955126%2015.0449%200%2013.8667%200H11.2436Z'/%3E%3C/svg%3E\" as const;\n\nexport const DEFAULT_VETRA_DRIVE_ID = \"vetra\" as const;\n\nexport const MINIMUM_NODE_VERSION = \"24.0.0\" as const;\nexport const PH_BIN = \"ph-cli-legacy\" as const;\nexport const POWERHOUSE_CONFIG_FILE = \"powerhouse.config.json\" as const;\nexport const PH_GLOBAL_DIR_NAME = \".ph\" as const;\n// Keep PH_GLOBAL_PROJECT_NAME for backwards compatibility\nexport const PH_GLOBAL_PROJECT_NAME = PH_GLOBAL_DIR_NAME;\n\nexport const HOME_DIR = homedir();\n\nexport const POWERHOUSE_GLOBAL_DIR = join(HOME_DIR, PH_GLOBAL_DIR_NAME);\n\n// Workspace packages that go in peerDependencies of every generated project.\nexport const VERSIONED_PEER_DEPENDENCIES = [\n \"document-model\",\n \"@powerhousedao/reactor-browser\",\n];\n\ntype PeerSpec = { peer: string; dev: string };\n\nexport const REACTOR_API_PACKAGE = \"@powerhousedao/reactor-api\";\nexport const ANALYTICS_ENGINE_CORE_PACKAGE =\n \"@powerhousedao/analytics-engine-core\";\nexport const GRAPHQL_PACKAGE = \"graphql\";\nexport const GRAPHQL_TAG_PACKAGE = \"graphql-tag\";\nexport const PIECES_FRAMEWORK_PACKAGE = \"@powerhousedao/pieces-framework\";\n\n// External peerDependencies of every generated project.\n// `peer` is the consumer-facing range; `dev` is the exact build-tested pin.\n// graphql / graphql-tag are always-on because the workspace packages pulled\n// in by every `ph init` project (codegen, reactor-api, reactor-browser,\n// vetra-packages) declare them as peers — even projects without subgraphs\n// need them in scope so pnpm hoists a single graphql instance.\nexport const PEER_EXTERNAL_DEPENDENCIES = {\n [GRAPHQL_PACKAGE]: { peer: \"^16\", dev: \"16.12.0\" },\n [GRAPHQL_TAG_PACKAGE]: { peer: \"^2\", dev: \"2.12.6\" },\n react: { peer: \"^19\", dev: \"19.2.6\" },\n \"react-dom\": { peer: \"^19\", dev: \"19.2.6\" },\n zod: { peer: \"^4\", dev: \"4.3.6\" },\n} as const satisfies Record<string, PeerSpec>;\n\n// Per-feature deps added dynamically by codegen when required. `devVersioned`\n// is for a workspace package the build inlines, which no consumer provides.\nexport const FEATURE_DEPENDENCIES = {\n analyticsProcessor: {\n peerVersioned: [ANALYTICS_ENGINE_CORE_PACKAGE],\n peerExternal: {},\n devVersioned: [],\n },\n // Each piece is bundled whole (build-pieces.mts), framework included, so the\n // framework is only ever needed to compile the piece's own source.\n piece: {\n peerVersioned: [],\n peerExternal: {},\n devVersioned: [PIECES_FRAMEWORK_PACKAGE],\n },\n} as const satisfies Record<\n string,\n {\n peerVersioned: readonly string[];\n peerExternal: Record<string, PeerSpec>;\n devVersioned: readonly string[];\n }\n>;\n\nexport const VERSIONED_DEPENDENCIES = [\n ...VERSIONED_PEER_DEPENDENCIES,\n ...FEATURE_DEPENDENCIES.analyticsProcessor.peerVersioned,\n];\n\n// Transitive dependencies whose postinstall scripts the generated project\n// trusts. Mirrors the `allowBuilds` map in the boilerplate's\n// pnpm-workspace.yaml and is also passed as `--allow-build` flags to\n// `pnpm dlx @powerhousedao/ph-cli init` so pnpm 11's strict-dep-builds\n// default doesn't prompt during the outer dlx download.\nexport const BOILERPLATE_ALLOWED_BUILDS = [\n \"@apollo/protobufjs\",\n \"@datadog/pprof\",\n \"@parcel/watcher\",\n \"@reown/appkit\",\n \"bufferutil\",\n \"esbuild\",\n \"keccak\",\n \"protobufjs\",\n \"utf-8-validate\",\n] as const;\n\n// Single-version pins the boilerplate enforces on generated projects,\n// avoiding duplicates from coexisting version ranges. Rendered as pnpm\n// `overrides` (pnpm-workspace.yaml) and as yarn v1 `resolutions`\n// (package.json). Generated-project only — never change the monorepo\n// catalog for this (a re-resolution there pulls a tsc-crashing TS6 beta).\nexport const BOILERPLATE_DEPENDENCY_OVERRIDES = {\n \"date-fns\": \"4.3.0\",\n vite: \"8.0.14\",\n rolldown: \"1.0.2\",\n} as const satisfies Record<string, string>;\n\nexport const VERSIONED_DEV_DEPENDENCIES = [\n \"@powerhousedao/ph-cli\",\n \"@powerhousedao/reactor\",\n \"@powerhousedao/shared\",\n \"@powerhousedao/connect\",\n \"@powerhousedao/design-system\",\n];\n\nexport const packageJsonExports = {\n \".\": {\n types: \"./dist/types/index.d.ts\",\n browser: \"./dist/browser/index.js\",\n node: \"./dist/node/index.mjs\",\n },\n \"./reactor\": {\n types: \"./dist/types/reactor/index.d.ts\",\n browser: \"./dist/browser/reactor/index.js\",\n },\n \"./document-models\": {\n types: \"./dist/types/document-models/index.d.ts\",\n browser: \"./dist/browser/document-models/index.js\",\n node: \"./dist/node/document-models/index.mjs\",\n },\n \"./document-models/*\": {\n types: \"./dist/types/document-models/*/index.d.ts\",\n browser: \"./dist/browser/document-models/*/index.js\",\n node: \"./dist/node/document-models/*/index.mjs\",\n },\n \"./editors\": {\n types: \"./dist/types/editors/index.d.ts\",\n browser: \"./dist/browser/editors/index.js\",\n node: \"./dist/node/editors/index.mjs\",\n },\n \"./editors/*\": {\n types: \"./dist/types/editors/*/editor.d.ts\",\n browser: \"./dist/browser/editors/*/editor.js\",\n node: \"./dist/node/editors/*/editor.mjs\",\n },\n \"./subgraphs\": {\n types: \"./dist/types/subgraphs/index.d.ts\",\n node: \"./dist/node/subgraphs/index.mjs\",\n },\n \"./processors\": {\n types: \"./dist/types/processors/index.d.ts\",\n browser: \"./dist/browser/processors/index.js\",\n node: \"./dist/node/processors/index.mjs\",\n },\n // Node only, as the build is: a piece is loaded by a host process, never by\n // the browser. Without these a package can build a piece and still fail the\n // `packageName/pieces` import a host resolves it through.\n \"./pieces\": {\n types: \"./dist/types/pieces/index.d.ts\",\n node: \"./dist/node/pieces/index.mjs\",\n },\n \"./pieces/*\": {\n types: \"./dist/types/pieces/*/index.d.ts\",\n node: \"./dist/node/pieces/*/index.mjs\",\n },\n \"./manifest\": \"./dist/powerhouse.manifest.json\",\n \"./style.css\": \"./dist/style.css\",\n} as const;\n\nexport const packageScripts = {\n \"test:watch\": \"vitest\",\n lint: \"oxlint --type-aware --type-check\",\n \"lint:fix\": \"oxlint --type-aware --type-check --fix\",\n format: \"oxfmt\",\n \"format:check\": \"oxfmt --check\",\n tsc: \"tsc\",\n \"tsc:watch\": \"tsc --watch\",\n generate: \"ph-cli generate\",\n connect: \"ph-cli connect\",\n build: \"ph-cli build\",\n reactor: \"ph-cli reactor\",\n service: \"ph-cli service\",\n vetra: \"ph-cli vetra\",\n \"service-startup\":\n \"bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh\",\n \"service-unstartup\":\n \"bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh\",\n} as const;\n\nexport const externalDependencies = {} as const;\n\n// eslint/prettier devDependencies present in projects scaffolded before the oxc migration.\n// Stripped from package.json during `ph migrate`.\nexport const LEGACY_LINT_FORMAT_DEPENDENCIES = [\n \"@eslint/js\",\n \"eslint\",\n \"eslint-config-prettier\",\n \"eslint-plugin-prettier\",\n \"eslint-plugin-react\",\n \"eslint-plugin-react-hooks\",\n \"globals\",\n \"prettier\",\n \"typescript-eslint\",\n] as const;\n\n// Legacy lint/format config files written by eslint/prettier boilerplate.\n// Removed from the project root during `ph migrate`.\nexport const LEGACY_LINT_FORMAT_FILES = [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \"eslint.config.ts\",\n \".eslintrc\",\n \".eslintrc.js\",\n \".eslintrc.cjs\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n \".eslintignore\",\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yml\",\n \".prettierrc.yaml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n \".prettierignore\",\n] as const;\n\nexport const externalDevDependencies = {\n \"@electric-sql/pglite\": \"0.3.15\",\n \"@electric-sql/pglite-tools\": \"0.2.20\",\n \"@powerhousedao/document-engineering\": \"1.40.5\",\n \"@tailwindcss/cli\": \"^4.1.18\",\n \"@tailwindcss/vite\": \"^4.1.18\",\n \"@types/node\": \"^24.9.2\",\n \"@types/react\": \"^19.2.3\",\n \"@types/react-dom\": \"^19.2.3\",\n \"@vitejs/plugin-react\": \"^6.0.1\",\n \"@vitest/coverage-v8\": \"5.0.3\",\n oxfmt: \"0.68.0\",\n oxlint: \"1.70.0\",\n \"oxlint-tsgolint\": \"0.23.0\",\n tailwindcss: \"^4.1.16\",\n typescript: \"~7.0.2\",\n vite: \"^8.0.10\",\n \"vite-tsconfig-paths\": \"6.1.1\",\n vitest: \"5.0.3\",\n} as const;\n\nexport const defaultManifest: Manifest = {\n name: \"\",\n description: \"\",\n category: \"\",\n publisher: {\n name: \"\",\n url: \"\",\n },\n documentModels: [],\n editors: [],\n apps: [],\n subgraphs: [],\n processors: [],\n};\n\nconst DEFAULT_DOCUMENT_MODELS_DIR = \"./document-models\";\nconst DEFAULT_EDITORS_DIR = \"./editors\";\nconst DEFAULT_PROCESSORS_DIR = \"./processors\";\nconst DEFAULT_SUBGRAPHS_DIR = \"./subgraphs\";\nconst DEFAULT_IMPORT_SCRIPTS_DIR = \"./scripts\";\nconst DEFAULT_SKIP_FORMAT = false;\nconst DEFAULT_LOG_LEVEL = \"info\";\n\nexport const DEFAULT_CONFIG: PowerhouseConfig = {\n documentModelsDir: DEFAULT_DOCUMENT_MODELS_DIR,\n editorsDir: DEFAULT_EDITORS_DIR,\n processorsDir: DEFAULT_PROCESSORS_DIR,\n subgraphsDir: DEFAULT_SUBGRAPHS_DIR,\n importScriptsDir: DEFAULT_IMPORT_SCRIPTS_DIR,\n skipFormat: DEFAULT_SKIP_FORMAT,\n logLevel: DEFAULT_LOG_LEVEL,\n auth: {\n enabled: false,\n admins: [],\n },\n};\n","import { readFileSync } from \"node:fs\";\nimport { DEFAULT_CONFIG } from \"../constants.js\";\nimport type { PowerhouseConfig } from \"../types.js\";\n\nexport function getConfig(path = \"./powerhouse.config.json\") {\n let config: PowerhouseConfig = { ...DEFAULT_CONFIG };\n try {\n const configStr = readFileSync(path, \"utf-8\");\n const userConfig = JSON.parse(configStr) as PowerhouseConfig;\n config = { ...config, ...userConfig };\n } catch {\n // console.warn(\"No powerhouse.config.json found, using defaults\");\n }\n\n return config;\n}\n","import {\n array,\n boolean,\n command,\n flag,\n multioption,\n number,\n oneOf,\n option,\n optional,\n string,\n} from \"cmd-ts\";\n// Sub-path: avoids pulling the package-manager-detector runtime here,\n// which `oneOf(AGENTS)` below would force at module load.\nimport type { Agent } from \"package-manager-detector\";\nimport { AGENTS as _AGENTS } from \"package-manager-detector/constants\";\nimport {\n DEFAULT_TIMEOUT,\n DRIVES_PRESERVE_STRATEGIES,\n LOG_LEVELS,\n} from \"../constants.js\";\nimport { getConfig } from \"../file-system/get-config.js\";\n\nexport const AGENTS: Agent[] = _AGENTS;\n\nexport const debugArgs = {\n debug: flag({\n type: optional(boolean),\n long: \"debug\",\n description: \"Log arguments passed to this command\",\n }),\n};\n\nexport const buildArgs = {\n outDir: option({\n type: string,\n long: \"out-dir\",\n description: \"Where to output the bundled code\",\n defaultValue: () => \"dist\" as const,\n defaultValueIsSerializable: true,\n }),\n noSharedDeps: flag({\n type: boolean,\n long: \"no-shared-deps\",\n description:\n \"Bundle the shared dependency set instead of externalizing it (default: externalize)\",\n defaultValue: () => false as const,\n defaultValueIsSerializable: true,\n }),\n ignoreTypeErrors: flag({\n type: boolean,\n long: \"ignore-type-errors\",\n description:\n \"Unsafe: build even when tsc reports type errors, without asking. The package can load and still fail at runtime\",\n defaultValue: () => false as const,\n defaultValueIsSerializable: true,\n }),\n ...debugArgs,\n};\n\nexport const packageManagerArgs = {\n packageManager: option({\n type: optional(oneOf(AGENTS)),\n long: \"package-manager\",\n short: \"p\",\n description:\n \"Specify the package manager to use for your project. Can be one of: `npm`, `pnpm`, `yarn`, or `bun`. Defaults to your environment package manager.\",\n }),\n npm: flag({\n type: optional(boolean),\n long: \"npm\",\n description: \"Use 'npm' as package manager\",\n }),\n pnpm: flag({\n type: optional(boolean),\n long: \"pnpm\",\n description: \"Use 'pnpm' as package manager\",\n }),\n yarn: flag({\n type: optional(boolean),\n long: \"yarn\",\n description: \"Use 'yarn' as package manager\",\n }),\n bun: flag({\n type: optional(boolean),\n long: \"bun\",\n description: \"Use 'bun' as package manager\",\n }),\n};\nexport const getPackageManagerCommand = command({\n name: \"get-package-manager\",\n args: packageManagerArgs,\n handler: (args) => args,\n});\nexport const packages = option({\n type: optional(string),\n long: \"packages\",\n description: \"Comma-separated list of package names to load\",\n env: \"PH_PACKAGES\" as const,\n});\n\nexport const localPackage = option({\n type: optional(string),\n long: \"local-package\",\n description: \"Path to local package to load during development\",\n env: \"PH_LOCAL_PACKAGE\" as const,\n});\n\nexport const disableLocalPackages = flag({\n type: boolean,\n long: \"ignore-local\",\n description: \"Do not load local packages from this project\",\n defaultValue: () => false,\n});\n\nexport const httpsKeyFile = option({\n type: optional(string),\n long: \"https-key-file\",\n description: \"path to the ssl key file\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (https === undefined) return undefined;\n if (typeof https === \"boolean\") return undefined;\n return https.keyPath;\n },\n});\n\nexport const httpsCertFile = option({\n type: optional(string),\n long: \"https-cert-file\",\n description: \"path to the ssl cert file\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (https === undefined) return undefined;\n if (typeof https === \"boolean\") return undefined;\n return https.certPath;\n },\n});\n\nexport const https = flag({\n type: optional(boolean),\n long: \"https\",\n description: \"Use https\",\n defaultValue: () => {\n const baseConfig = getConfig();\n const https = baseConfig.reactor?.https;\n if (typeof https === \"boolean\") return https;\n return undefined;\n },\n});\n\nexport const vetraSwitchboardArgs = {\n https,\n httpsKeyFile,\n httpsCertFile,\n dev: flag({\n type: optional(boolean),\n long: \"dev\",\n description: \"enable development mode to load local packages\",\n }),\n remoteDrives: multioption({\n type: array(string),\n long: \"remote-drives\",\n description: \"Specify remote drive URLs to use\",\n defaultValue: () => [],\n }),\n disableLocalPackages,\n ...debugArgs,\n};\n\nexport const defaultDrivesUrl = option({\n type: optional(string),\n long: \"default-drives-url\",\n description: \"Comma-separated drive URLs to use as Connect's default drives.\",\n defaultValue: () => \"\",\n});\n\nexport const logLevel = option({\n type: oneOf(LOG_LEVELS),\n long: \"log-level\",\n description: \"Log level for the application\",\n defaultValue: () => \"info\" as const,\n defaultValueIsSerializable: true,\n env: \"PH_CONNECT_LOG_LEVEL\" as const,\n});\n\nexport const connectBasePath = option({\n long: \"base\",\n type: string,\n description: \"Base path for the app\",\n defaultValue: () => \"/\",\n});\n\nexport const renownNamespace = option({\n type: optional(string),\n long: \"renown-namespace\",\n description:\n \"Renown localStorage namespace; share it across Connects to share login.\",\n});\n\nexport const renownSwitchboardUrl = option({\n type: optional(string),\n long: \"renown-switchboard-url\",\n description:\n \"Override connect.renown.switchboardUrl. When set, enables in-page Renown sign-in.\",\n});\n\nexport const drivesPreserveStrategy = option({\n type: oneOf(DRIVES_PRESERVE_STRATEGIES),\n long: \"drive-preserve-strategy\",\n description: \"The preservation strategy to use on default drives\",\n defaultValue: () => \"preserve-by-url-and-detach\" as const,\n defaultValueIsSerializable: true,\n});\n\nexport const force = flag({\n type: optional(boolean),\n long: \"force\",\n description:\n \"Force dep pre-optimization regardless of whether deps have changed.\",\n});\n\nexport const commonArgs = {\n connectBasePath,\n logLevel,\n packages,\n localPackage,\n disableLocalPackages,\n defaultDrivesUrl,\n drivesPreserveStrategy,\n force,\n ...debugArgs,\n};\n\nexport const commonServerArgs = {\n host: option({\n type: optional(string),\n long: \"host\",\n description:\n \"Expose the server to the network. Pass an IP (e.g. 0.0.0.0) to bind to a specific address.\",\n }),\n open: flag({\n type: optional(boolean),\n long: \"open\",\n description: \"Open browser on startup\",\n }),\n cors: flag({\n type: optional(boolean),\n long: \"cors\",\n description: \"Enable CORS\",\n }),\n strictPort: flag({\n type: optional(boolean),\n long: \"strictPort\",\n description: \"Exit if specified port is already in use\",\n }),\n printUrls: flag({\n type: boolean,\n long: \"print-urls\",\n description: \"Print server urls\",\n defaultValue: () => true,\n defaultValueIsSerializable: true,\n }),\n bindCLIShortcuts: flag({\n type: boolean,\n long: \"bind-cli-shortcuts\",\n description: \"Bind CLI shortcuts\",\n defaultValue: () => true,\n defaultValueIsSerializable: true,\n }),\n watchTimeout: option({\n type: number,\n long: \"watch-timeout\",\n description: \"Amount of time to wait before a file is considered changed\",\n defaultValue: () => DEFAULT_TIMEOUT,\n defaultValueIsSerializable: true,\n }),\n};\n"],"mappings":";;;;;;AAKA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;AAMA,MAAa,6BAA6B,CACxC,gBACA,4BACF;AAEA,MAAa,aAAa;CACxB;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,8BAA8B;AAE3C,MAAa,6BAA6B;AAE1C,MAAa,+BAA+B;AAE5C,MAAa,yBAAyB;AAEtC,MAAa,qBAAqB;AAIlC,MAAa,2BAA2B;AAwCxC,MAAa,yBAAyB;AAStC,MAAa,WAAW,QAAQ;AAEK,KAAK,UAAA,KAA4B;AAGtE,MAAa,8BAA8B,CACzC,kBACA,gCACF;AA2BA,MAAa,uBAAuB;CAClC,oBAAoB;EAClB,eAAe,CAAC,sCAA6B;EAC7C,cAAc,CAAC;EACf,cAAc,CAAC;CACjB;CAGA,OAAO;EACL,eAAe,CAAC;EAChB,cAAc,CAAC;EACf,cAAc,CAAC,iCAAwB;CACzC;AACF;AASsC,CACpC,GAAG,6BACH,GAAG,qBAAqB,mBAAmB,aAC7C;AAsMA,MAAa,iBAAmC;CAC9C,mBAAmB;CACnB,YAAY;CACZ,eAAe;CACf,cAAc;CACd,kBAAkB;CAClB,YAAY;CACZ,UAAU;CACV,MAAM;EACJ,SAAS;EACT,QAAQ,CAAC;CACX;AACF;;;ACvWA,SAAgB,UAAU,OAAO,4BAA4B;CAC3D,IAAI,SAA2B,EAAE,GAAG,eAAe;CACnD,IAAI;EACF,MAAM,YAAY,aAAa,MAAM,OAAO;EAC5C,MAAM,aAAa,KAAK,MAAM,SAAS;EACvC,SAAS;GAAE,GAAG;GAAQ,GAAG;EAAW;CACtC,QAAQ,CAER;CAEA,OAAO;AACT;;;ACQA,MAAaA,WAAkBC;AAE/B,MAAa,YAAY,EACvB,OAAO,KAAK;CACV,MAAM,SAAS,OAAO;CACtB,MAAM;CACN,aAAa;AACf,CAAC,EACH;AAEA,MAAa,YAAY;CACvB,QAAQ,OAAO;EACb,MAAM;EACN,MAAM;EACN,aAAa;EACb,oBAAoB;EACpB,4BAA4B;CAC9B,CAAC;CACD,cAAc,KAAK;EACjB,MAAM;EACN,MAAM;EACN,aACE;EACF,oBAAoB;EACpB,4BAA4B;CAC9B,CAAC;CACD,kBAAkB,KAAK;EACrB,MAAM;EACN,MAAM;EACN,aACE;EACF,oBAAoB;EACpB,4BAA4B;CAC9B,CAAC;CACD,GAAG;AACL;AAEA,MAAa,qBAAqB;CAChC,gBAAgB,OAAO;EACrB,MAAM,SAAS,MAAMD,QAAM,CAAC;EAC5B,MAAM;EACN,OAAO;EACP,aACE;CACJ,CAAC;CACD,KAAK,KAAK;EACR,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,MAAM,KAAK;EACT,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,MAAM,KAAK;EACT,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,KAAK,KAAK;EACR,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;AACH;AACA,MAAa,2BAA2B,QAAQ;CAC9C,MAAM;CACN,MAAM;CACN,UAAU,SAAS;AACrB,CAAC;AACD,MAAa,WAAW,OAAO;CAC7B,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aAAa;CACb,KAAK;AACP,CAAC;AAED,MAAa,eAAe,OAAO;CACjC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aAAa;CACb,KAAK;AACP,CAAC;AAED,MAAa,uBAAuB,KAAK;CACvC,MAAM;CACN,MAAM;CACN,aAAa;CACb,oBAAoB;AACtB,CAAC;AAED,MAAa,eAAe,OAAO;CACjC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aAAa;CACb,oBAAoB;EAElB,MAAM,QADa,UACI,CAAC,CAAC,SAAS;EAClC,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAChC,IAAI,OAAO,UAAU,WAAW,OAAO,KAAA;EACvC,OAAO,MAAM;CACf;AACF,CAAC;AAED,MAAa,gBAAgB,OAAO;CAClC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aAAa;CACb,oBAAoB;EAElB,MAAM,QADa,UACI,CAAC,CAAC,SAAS;EAClC,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAChC,IAAI,OAAO,UAAU,WAAW,OAAO,KAAA;EACvC,OAAO,MAAM;CACf;AACF,CAAC;AAED,MAAa,QAAQ,KAAK;CACxB,MAAM,SAAS,OAAO;CACtB,MAAM;CACN,aAAa;CACb,oBAAoB;EAElB,MAAM,QADa,UACI,CAAC,CAAC,SAAS;EAClC,IAAI,OAAO,UAAU,WAAW,OAAO;CAEzC;AACF,CAAC;AAED,MAAa,uBAAuB;CAClC;CACA;CACA;CACA,KAAK,KAAK;EACR,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,cAAc,YAAY;EACxB,MAAM,MAAM,MAAM;EAClB,MAAM;EACN,aAAa;EACb,oBAAoB,CAAC;CACvB,CAAC;CACD;CACA,GAAG;AACL;AAEA,MAAa,mBAAmB,OAAO;CACrC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aAAa;CACb,oBAAoB;AACtB,CAAC;AAED,MAAa,WAAW,OAAO;CAC7B,MAAM,MAAM,UAAU;CACtB,MAAM;CACN,aAAa;CACb,oBAAoB;CACpB,4BAA4B;CAC5B,KAAK;AACP,CAAC;AAED,MAAa,kBAAkB,OAAO;CACpC,MAAM;CACN,MAAM;CACN,aAAa;CACb,oBAAoB;AACtB,CAAC;AAED,MAAa,kBAAkB,OAAO;CACpC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aACE;AACJ,CAAC;AAED,MAAa,uBAAuB,OAAO;CACzC,MAAM,SAAS,MAAM;CACrB,MAAM;CACN,aACE;AACJ,CAAC;AAED,MAAa,yBAAyB,OAAO;CAC3C,MAAM,MAAM,0BAA0B;CACtC,MAAM;CACN,aAAa;CACb,oBAAoB;CACpB,4BAA4B;AAC9B,CAAC;AAED,MAAa,QAAQ,KAAK;CACxB,MAAM,SAAS,OAAO;CACtB,MAAM;CACN,aACE;AACJ,CAAC;AAED,MAAa,aAAa;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,GAAG;AACL;AAEA,MAAa,mBAAmB;CAC9B,MAAM,OAAO;EACX,MAAM,SAAS,MAAM;EACrB,MAAM;EACN,aACE;CACJ,CAAC;CACD,MAAM,KAAK;EACT,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,MAAM,KAAK;EACT,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,YAAY,KAAK;EACf,MAAM,SAAS,OAAO;EACtB,MAAM;EACN,aAAa;CACf,CAAC;CACD,WAAW,KAAK;EACd,MAAM;EACN,MAAM;EACN,aAAa;EACb,oBAAoB;EACpB,4BAA4B;CAC9B,CAAC;CACD,kBAAkB,KAAK;EACrB,MAAM;EACN,MAAM;EACN,aAAa;EACb,oBAAoB;EACpB,4BAA4B;CAC9B,CAAC;CACD,cAAc,OAAO;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,oBAAA;EACA,4BAA4B;CAC9B,CAAC;AACH"}
@@ -93,12 +93,15 @@ const entry = [
93
93
  "editors/index.ts",
94
94
  "editors/*/index.ts",
95
95
  "editors/*/module.ts",
96
+ "processors/index.ts"
97
+ ];
98
+ const nodeEntry = [
99
+ ...entry,
100
+ "processors/*/index.ts",
96
101
  "subgraphs/index.ts",
97
102
  "subgraphs/*/index.ts",
98
- "processors/index.ts",
99
- "processors/*/index.ts"
103
+ "pieces/index.ts"
100
104
  ];
101
- const nodeEntry = [...entry, "pieces/index.ts"];
102
105
  const PIECE_ENTRY_GLOB = "pieces/*/index.ts";
103
106
  const browserEntry = [...entry, "reactor/index.ts"];
104
107
  const alwaysBundle = ["**"];
@@ -140,6 +143,20 @@ const clean = true;
140
143
  const dts = false;
141
144
  const sourcemap = true;
142
145
  const sharedNeverBundle = EXTERNALIZABLE_SHARED_SPECIFIERS.map((s) => new RegExp(`^${s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(/.*)?$`));
146
+ const SWITCHBOARD_PROCESSORS_STUB = "\0powerhouse:switchboard-processors";
147
+ function switchboardProcessorsStub() {
148
+ return {
149
+ name: "powerhouse:switchboard-processors-stub",
150
+ resolveId(source, importer) {
151
+ if (!importer || !/^\.\/switchboard(\.[cm]?[jt]s)?$/.test(source)) return null;
152
+ const path = importer.replaceAll("\\", "/");
153
+ return /(^|\/)processors\/factory\.[cm]?[jt]s$/.test(path) && !path.includes("/node_modules/") ? SWITCHBOARD_PROCESSORS_STUB : null;
154
+ },
155
+ load(id) {
156
+ return id === SWITCHBOARD_PROCESSORS_STUB ? "export const processorFactoryBuilders = [];" : null;
157
+ }
158
+ };
159
+ }
143
160
  const baseBrowserConfig = {
144
161
  entry: browserEntry,
145
162
  platform: "browser",
@@ -151,13 +168,15 @@ const baseBrowserConfig = {
151
168
  plugins: [esmExternalRequirePlugin({
152
169
  external: reactExternals,
153
170
  skipDuplicateCheck: true
154
- })],
171
+ }), switchboardProcessorsStub()],
155
172
  inputOptions: { experimental: { resolveNewUrlToAsset: true } }
156
173
  };
174
+ const pluginList = (plugins) => plugins === void 0 ? [] : Array.isArray(plugins) ? plugins : [plugins];
157
175
  function buildBrowserBuildConfig(options = {}) {
158
176
  const sharedDeps = options.sharedDeps ?? true;
159
177
  return {
160
178
  ...baseBrowserConfig,
179
+ plugins: [...baseBrowserConfig.plugins, ...pluginList(options.plugins)],
161
180
  deps: {
162
181
  alwaysBundle,
163
182
  neverBundle: [...browserNeverBundle, ...sharedDeps ? sharedNeverBundle : []]
@@ -192,6 +211,7 @@ function buildNodeBuildConfig(options = {}) {
192
211
  neverBundle: [...nodeNeverBundle, ...sharedDeps ? sharedNeverBundle : []]
193
212
  },
194
213
  platform: "node",
214
+ ...options.plugins ? { plugins: options.plugins } : {},
195
215
  config,
196
216
  clean,
197
217
  dts,
@@ -212,6 +232,7 @@ function buildPieceBuildConfig(options) {
212
232
  entry: { index: options.entry },
213
233
  outDir: options.outDir,
214
234
  platform: "node",
235
+ ...options.plugins ? { plugins: options.plugins } : {},
215
236
  deps: {
216
237
  alwaysBundle,
217
238
  neverBundle: [],
@@ -228,4 +249,4 @@ function buildPieceBuildConfig(options) {
228
249
  //#endregion
229
250
  export { buildNodeBuildConfig as a, nodeBuildConfig as c, buildBrowserBuildConfig as i, browserBuildConfig as n, buildPieceBuildConfig as o, browserEntry as r, findBundledSharedDeps as s, PIECE_ENTRY_GLOB as t };
230
251
 
231
- //# sourceMappingURL=build-config-CR5lvv_A.mjs.map
252
+ //# sourceMappingURL=build-config-HbYUSZS1.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-config-HbYUSZS1.mjs","names":[],"sources":["../../connect/shared-deps.ts","../../clis/build-config.mts"],"sourcesContent":["import { satisfies, validRange } from \"semver\";\n\nexport type SharedDep = { specifier: string; package: string };\n\n/**\n * The dependency set Connect and loaded packages share via the import map.\n * `@powerhousedao/connect` is deliberately absent: it is the Connect app\n * itself (no importable exports), so there is nothing to share.\n */\nexport const SHARED_DEPS: readonly SharedDep[] = [\n { specifier: \"document-model\", package: \"document-model\" },\n {\n specifier: \"@powerhousedao/document-engineering\",\n package: \"@powerhousedao/document-engineering\",\n },\n { specifier: \"@powerhousedao/shared\", package: \"@powerhousedao/shared\" },\n {\n specifier: \"@powerhousedao/shared/registry/urls\",\n package: \"@powerhousedao/shared\",\n },\n {\n specifier: \"@powerhousedao/design-system/connect\",\n package: \"@powerhousedao/design-system\",\n },\n {\n specifier: \"@powerhousedao/reactor-browser\",\n package: \"@powerhousedao/reactor-browser\",\n },\n // Connect already vendors zod (it is in DEFAULT_VENDOR_INCLUDE, so the\n // import map publishes an entry for it) and every generated project already\n // declares it as a peerDependency -- yet it was missing from this set, so\n // each package inlined a private copy anyway. It is the single biggest\n // dependency left in a minimal package.\n { specifier: \"zod\", package: \"zod\" },\n];\n\nexport const SHARED_DEP_SPECIFIERS: readonly string[] = SHARED_DEPS.map(\n (d) => d.specifier,\n);\n\n/**\n * The `@powerhousedao/shared` subpaths the production vendor bundles. The\n * bare root is deliberately absent: its type barrel references node-only\n * modules (`clis/`), which the current vite/rolldown cannot bundle for the\n * browser — vendoring the root fails the build (a pre-existing latent\n * issue). A package that imports the bare root is simply not shared; it\n * bundles its own copy.\n */\nexport const SHARED_SUBPATHS: readonly string[] = [\n \"connect\",\n \"document-model\",\n \"processors\",\n \"document-drive\",\n \"registry\",\n \"registry/urls\",\n \"registry/manifest-slim\",\n];\n\n/**\n * The specifiers a package build may safely externalize onto the host's\n * import map — i.e. the ones the vendor actually publishes an entry for.\n *\n * `@powerhousedao/shared` is narrowed to SHARED_SUBPATHS rather than taken as\n * a prefix: the bare root is never vendored (see SHARED_SUBPATHS), and\n * neither are its other subpaths (`analytics`, `constants`, `clis`, ...).\n * Externalizing those would leave a bare specifier in the package's output\n * that nothing in the import map resolves, so the package would fail to load\n * at runtime instead of simply bundling its own copy.\n */\nexport const EXTERNALIZABLE_SHARED_SPECIFIERS: readonly string[] = [\n ...new Set([\n ...SHARED_DEP_SPECIFIERS.filter((s) => s !== \"@powerhousedao/shared\"),\n ...SHARED_SUBPATHS.map((s) => `@powerhousedao/shared/${s}`),\n ]),\n];\n\n/** Split a specifier into its package name and subpath (\"\" for a root). */\nexport function parseDepSpec(spec: string): { pkg: string; sub: string } {\n if (spec.startsWith(\"@\")) {\n const parts = spec.split(\"/\");\n return { pkg: parts.slice(0, 2).join(\"/\"), sub: parts.slice(2).join(\"/\") };\n }\n const i = spec.indexOf(\"/\");\n return i === -1\n ? { pkg: spec, sub: \"\" }\n : { pkg: spec.slice(0, i), sub: spec.slice(i + 1) };\n}\n\nfunction isSharedSpecifier(spec: string, specs: readonly string[]): boolean {\n return specs.some((s) => spec === s || spec.startsWith(s + \"/\"));\n}\n\n/**\n * Return the import/export specifiers in `source` that are a shared\n * specifier (or a subpath of one), sorted. Heuristic: only statement\n * positions are scanned (`from \"x\"`, `import \"x\"`, `import(\"x\")`;\n * `export … from \"x\"` is covered by the `from` pattern), so import-like\n * text inside comments or strings can be reported too. That errs toward\n * over-reporting, which is the safe direction for the advisory build\n * warning.\n */\nexport function findSharedImports(\n source: string,\n specs: readonly string[] = SHARED_DEP_SPECIFIERS,\n): string[] {\n const found = new Set<string>();\n const patterns = [\n /\\bfrom\\s+[\"']([^\"'\\\\]+)[\"']/g,\n /\\bimport\\s+[\"']([^\"'\\\\]+)[\"']/g,\n /\\bimport\\s*\\(\\s*[\"']([^\"'\\\\]+)[\"']\\s*\\)/g,\n ];\n for (const re of patterns) {\n for (const m of source.matchAll(re)) {\n const spec = m[1];\n if (isSharedSpecifier(spec, specs)) found.add(spec);\n }\n }\n return [...found].sort();\n}\n\n/**\n * Rewrite a package source for blob import in a worker context (import maps\n * don't apply there): shared specifiers become their mapped URLs, and\n * relative (`./`, `../`) specifiers become absolute against `sourceUrl`\n * (a blob URL has no directory to resolve against). `#` subpath imports are\n * deliberately left alone: they resolve via the package's own\n * `package.json` \"imports\" field, which the rewrite cannot reproduce.\n * Returns the input unchanged when nothing matched.\n */\nexport function rewritePackageSource(\n source: string,\n sourceUrl: string,\n imports: Record<string, string>,\n): string {\n if (!Object.keys(imports).length) return source;\n const base = new URL(sourceUrl);\n const map = (spec: string): string | null => {\n const mapped = imports[spec];\n if (mapped) return mapped;\n if (spec.startsWith(\"./\") || spec.startsWith(\"../\")) {\n return new URL(spec, base).href;\n }\n return null;\n };\n let out = source;\n // The quote character is captured and reused: a source that quotes its\n // specifiers with ' would otherwise never match the replacement and be\n // left un-rewritten — silently, since the specifier still maps.\n for (const re of [\n /\\bfrom\\s+([\"'])([^\"'\\\\]+)\\1/g,\n /\\bimport\\s+([\"'])([^\"'\\\\]+)\\1/g,\n /\\bimport\\s*\\(\\s*([\"'])([^\"'\\\\]+)\\1\\s*\\)/g,\n ]) {\n out = out.replace(re, (match, quote: string, spec: string) => {\n // The match contains the quoted specifier exactly once and the\n // captured group has no quotes/backslashes ([^\"'\\\\]), so a literal\n // replace is safe.\n const mapped = map(spec);\n return mapped\n ? match.replace(`${quote}${spec}${quote}`, `${quote}${mapped}${quote}`)\n : match;\n });\n }\n return out;\n}\n\nexport type SharedDepMismatch = {\n package: string;\n required: string;\n provided: string;\n};\n\nexport type PackageDeps = {\n dependencies?: Record<string, unknown>;\n peerDependencies?: Record<string, unknown>;\n};\n\n/**\n * Compare a package's declared ranges against the host's version table.\n * `hostVersions` defines the checked set (only deps present in it are\n * checked). `*`, non-semver protocols (workspace:, file:, git:, npm:, URLs)\n * and unparseable ranges never mismatch.\n */\nexport function checkSharedDeps(\n pkgJson: PackageDeps,\n hostVersions: Record<string, string>,\n): SharedDepMismatch[] {\n const out: SharedDepMismatch[] = [];\n const entries = [\n ...Object.entries(pkgJson.dependencies ?? {}),\n ...Object.entries(pkgJson.peerDependencies ?? {}),\n ];\n for (const [dep, range] of entries) {\n const provided = hostVersions[dep];\n if (provided === undefined || typeof range !== \"string\") continue;\n if (range === \"*\" || /^[a-z]+:/i.test(range)) continue;\n if (!validRange(range)) continue;\n if (!satisfies(provided, range, { includePrerelease: true })) {\n out.push({ package: dep, required: range, provided });\n }\n }\n return out;\n}\n\nexport function formatSharedDepWarnings(\n mismatches: SharedDepMismatch[],\n): string[] {\n return mismatches.map(\n (m) =>\n `${m.package}: requires ${m.required}, Connect provides ${m.provided}`,\n );\n}\n\n/**\n * Stable filename for a local package's worker model bundle under\n * `__reactor_worker__/packages/`. Shared by the tab (URL computation via the\n * manifest) and the production prebuild (emitted entry names), so the two can\n * never drift. Scoped names flatten (`@scope/name` -> `scope__name`).\n */\nexport function workerPackageFileName(packageName: string): string {\n return `${packageName.replace(/^@/, \"\").replace(/[^\\w.-]+/g, \"__\")}.js`;\n}\n","import { esmExternalRequirePlugin } from \"rolldown/plugins\";\nimport type { InlineConfig } from \"tsdown\";\nimport {\n EXTERNALIZABLE_SHARED_SPECIFIERS,\n findSharedImports,\n} from \"../connect/shared-deps.js\";\n\nconst entry = [\n \"index.ts\",\n \"document-models/index.ts\",\n \"document-models/*/index.ts\",\n \"document-models/*/module.ts\",\n \"editors/index.ts\",\n \"editors/*/index.ts\",\n \"editors/*/module.ts\",\n \"processors/index.ts\",\n];\n\n// ./pieces is node-only for the same reason ./reactor is browser-only: a piece\n// is loaded and run by a host process, never by the browser. Only the list of\n// pieces builds here; each piece is its own build (buildPieceBuildConfig), so\n// two pieces never share a chunk and each ships as one self-contained module.\nconst nodeEntry = [\n ...entry,\n // Node-only: Connect reaches processors through processors/index.ts, and\n // subgraphs only over GraphQL.\n \"processors/*/index.ts\",\n \"subgraphs/index.ts\",\n \"subgraphs/*/index.ts\",\n \"pieces/index.ts\",\n];\n\n// Where a package's pieces live, one directory per piece, as the node entry\n// glob spells it; `ph build` expands it against the project to find them.\nexport const PIECE_ENTRY_GLOB = \"pieces/*/index.ts\";\n\n// ./reactor is browser-only: the SharedWorker needs it, the node build does not.\nexport const browserEntry = [...entry, \"reactor/index.ts\"];\n\nconst alwaysBundle = [\"**\"];\n\n// React must be external so `import ... from \"react\"` stays a bare import and\n// resolves to the host's React at runtime; bundled, a chunk would carry a second\n// React. In the browser build the externals below belong to esmExternalRequirePlugin\n// alone: rolldown converts a CommonJS `require(\"react\")` into an import only for\n// externals the plugin owns, and listed in neverBundle too the top-level external\n// wins, leaving a browser bundle with a require it cannot serve. use-sync-external-store\n// under zustand, and so under @xyflow/react, is the case that found this.\nconst reactExternals = [\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react-dom/client\",\n];\n\nconst nodeNeverBundle = [\n // we know that we don't want connect inside connect\n \"@powerhousedao/connect\",\n // published code would never need the cli\n \"@powerhousedao/ph-cli\",\n // the reactor-api host must provide a single class identity for\n // BaseSubgraph/BaseProcessor — inlining a copy here breaks the\n // prototype-chain check the package loader uses to detect subgraphs.\n \"@powerhousedao/reactor-api\",\n // react is resolved from esm.sh\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react-dom/client\",\n // build tools\n \"tailwindcss\",\n \"vitest\",\n \"tsdown\",\n \"@tailwindcss/cli\",\n \"@vitejs/plugin-react\",\n // testing tools\n \"@testing-library/jest-dom\",\n \"@testing-library/react\",\n \"@testing-library/user-event\",\n // types\n \"@types/node\",\n \"@types/react\",\n \"@types/react-dom\",\n // exclude pglite wasm/data chunks\n \"@electric-sql/pglite\",\n \"@electric-sql/pglite-tools\",\n];\n\n// The node build keeps React in neverBundle: node has createRequire, so a\n// CommonJS require of an external resolves there without the plugin.\nconst browserNeverBundle = nodeNeverBundle.filter(\n (spec) => typeof spec !== \"string\" || !reactExternals.includes(spec),\n);\n\nconst copy = [{ from: \"powerhouse.manifest.json\", to: \"dist\" }];\n\nconst config = false;\nconst clean = true;\n// types are emitted via a separate tsc command\nconst dts = false;\nconst sourcemap = true;\n\n// Shared deps are externalized from every package build: the host (Connect)\n// resolves them to one bundled copy via the import map, so a package must\n// not inline its own copy (two instances of the same dep break identity\n// checks and double the download). One regexp per specifier covers the root\n// and every subpath (rolldown `external` accepts strings and regexps, not\n// function matchers, in this toolchain).\n//\n// Only the specifiers the vendor publishes are externalized — see\n// EXTERNALIZABLE_SHARED_SPECIFIERS. Externalizing one the import map has no\n// entry for would leave an unresolvable bare specifier in the output.\nconst sharedNeverBundle = EXTERNALIZABLE_SHARED_SPECIFIERS.map(\n (s) => new RegExp(`^${s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}(/.*)?$`),\n);\n\ntype Plugin = NonNullable<InlineConfig[\"plugins\"]>;\n\nconst SWITCHBOARD_PROCESSORS_STUB = \"\\0powerhouse:switchboard-processors\";\n\n// Connect runs processors with processorApp \"connect\", so the generated\n// factory's import of ./switchboard gets an empty list in the browser build.\nfunction switchboardProcessorsStub(): Plugin {\n return {\n name: \"powerhouse:switchboard-processors-stub\",\n resolveId(source, importer) {\n if (!importer || !/^\\.\\/switchboard(\\.[cm]?[jt]s)?$/.test(source)) {\n return null;\n }\n const path = importer.replaceAll(\"\\\\\", \"/\");\n const isFactory =\n /(^|\\/)processors\\/factory\\.[cm]?[jt]s$/.test(path) &&\n !path.includes(\"/node_modules/\");\n return isFactory ? SWITCHBOARD_PROCESSORS_STUB : null;\n },\n load(id) {\n return id === SWITCHBOARD_PROCESSORS_STUB\n ? \"export const processorFactoryBuilders = [];\"\n : null;\n },\n };\n}\n\nconst baseBrowserConfig = {\n entry: browserEntry,\n platform: \"browser\" as const,\n copy,\n config,\n clean,\n dts,\n sourcemap,\n plugins: [\n esmExternalRequirePlugin({\n external: reactExternals,\n skipDuplicateCheck: true,\n }),\n switchboardProcessorsStub(),\n ],\n inputOptions: {\n experimental: { resolveNewUrlToAsset: true },\n },\n};\n\nconst pluginList = (plugins: InlineConfig[\"plugins\"]) =>\n plugins === undefined ? [] : Array.isArray(plugins) ? plugins : [plugins];\n\nexport type BrowserBuildConfigOptions = {\n /** Externalize the shared dependency set (default: true). */\n sharedDeps?: boolean;\n /** Extra bundler plugins, such as the external dependency guard. */\n plugins?: InlineConfig[\"plugins\"];\n};\n\nexport function buildBrowserBuildConfig(\n options: BrowserBuildConfigOptions = {},\n): InlineConfig {\n const sharedDeps = options.sharedDeps ?? true;\n return {\n ...baseBrowserConfig,\n plugins: [...baseBrowserConfig.plugins, ...pluginList(options.plugins)],\n deps: {\n alwaysBundle,\n neverBundle: [\n ...browserNeverBundle,\n ...(sharedDeps ? sharedNeverBundle : []),\n ],\n },\n };\n}\n\n// Kept for existing callers: the default (shared deps externalized).\nexport const browserBuildConfig = buildBrowserBuildConfig();\n\n/**\n * Shared specs a source imports but the built output no longer references as\n * bare imports — the bundler inlined them, which is exactly what the\n * external set is meant to prevent.\n */\nexport function findBundledSharedDeps(\n importedSpecs: string[],\n outputs: readonly { path: string; content: string }[],\n): string[] {\n return importedSpecs.filter(\n (spec) =>\n !outputs.some((f) => findSharedImports(f.content, [spec]).includes(spec)),\n );\n}\n\nexport type NodeBuildConfigOptions = {\n /** Externalize the shared dependency set (default: true). */\n sharedDeps?: boolean;\n /** Extra bundler plugins, such as the external dependency detector. */\n plugins?: InlineConfig[\"plugins\"];\n};\n\n/**\n * The node build externalizes the same shared set as the browser build, for\n * the same reason the `@powerhousedao/reactor-api` entry in `nodeNeverBundle`\n * already gives: the host provides these, and a package carrying its own copy\n * is a second class identity as well as dead weight. What differs is only how\n * the import is resolved at runtime -- Connect's import map in the browser,\n * ordinary node resolution here, which works because these are declared for\n * the consumer to provide (`document-model`, `@powerhousedao/reactor-browser`\n * and `zod` are peerDependencies of every generated project).\n */\nexport function buildNodeBuildConfig(\n options: NodeBuildConfigOptions = {},\n): InlineConfig {\n const sharedDeps = options.sharedDeps ?? true;\n return {\n entry: nodeEntry,\n deps: {\n alwaysBundle,\n neverBundle: [\n ...nodeNeverBundle,\n ...(sharedDeps ? sharedNeverBundle : []),\n ],\n },\n platform: \"node\",\n ...(options.plugins ? { plugins: options.plugins } : {}),\n config,\n clean,\n dts,\n sourcemap,\n };\n}\n\n// Kept for existing callers: the default (shared deps externalized).\nexport const nodeBuildConfig: InlineConfig = buildNodeBuildConfig();\n\nexport type PieceBuildConfigOptions = {\n /** The piece's source entry, relative to the project: `pieces/<dir>/index.ts`. */\n entry: string;\n /** Where the piece lands: `<outDir>/node/pieces/<dir>`. */\n outDir: string;\n /** Extra bundler plugins, such as the external dependency detector. */\n plugins?: InlineConfig[\"plugins\"];\n};\n\n/**\n * One piece, bundled whole. A piece runs in a forked worker with no\n * node_modules beside it, so nothing the piece imports can be left to the\n * host: the framework, its dependencies and the shared set that every other\n * module kind externalizes are all inlined here, and only node built-ins stay\n * external. Code splitting is off for the same reason, so a dynamic import is\n * inlined too and the piece directory holds exactly one module.\n */\nexport function buildPieceBuildConfig(\n options: PieceBuildConfigOptions,\n): InlineConfig {\n return {\n entry: { index: options.entry },\n outDir: options.outDir,\n platform: \"node\",\n ...(options.plugins ? { plugins: options.plugins } : {}),\n deps: {\n alwaysBundle,\n neverBundle: [],\n // Inlining dependencies is the point here, so tsdown's hint about it\n // would only be noise on every piece.\n onlyBundle: false,\n },\n outputOptions: { codeSplitting: false },\n // The worker runs without source maps, so a map would only be shipped twice\n minify: true,\n config,\n clean,\n dts,\n sourcemap: false,\n };\n}\n"],"mappings":"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"}
@@ -5,6 +5,8 @@ export declare const browserEntry: string[];
5
5
  export type BrowserBuildConfigOptions = {
6
6
  /** Externalize the shared dependency set (default: true). */
7
7
  sharedDeps?: boolean;
8
+ /** Extra bundler plugins, such as the external dependency guard. */
9
+ plugins?: InlineConfig["plugins"];
8
10
  };
9
11
  export declare function buildBrowserBuildConfig(options?: BrowserBuildConfigOptions): InlineConfig;
10
12
  export declare const browserBuildConfig: InlineConfig;
@@ -20,6 +22,8 @@ export declare function findBundledSharedDeps(importedSpecs: string[], outputs:
20
22
  export type NodeBuildConfigOptions = {
21
23
  /** Externalize the shared dependency set (default: true). */
22
24
  sharedDeps?: boolean;
25
+ /** Extra bundler plugins, such as the external dependency detector. */
26
+ plugins?: InlineConfig["plugins"];
23
27
  };
24
28
  /**
25
29
  * The node build externalizes the same shared set as the browser build, for
@@ -38,6 +42,8 @@ export type PieceBuildConfigOptions = {
38
42
  entry: string;
39
43
  /** Where the piece lands: `<outDir>/node/pieces/<dir>`. */
40
44
  outDir: string;
45
+ /** Extra bundler plugins, such as the external dependency detector. */
46
+ plugins?: InlineConfig["plugins"];
41
47
  };
42
48
  /**
43
49
  * One piece, bundled whole. A piece runs in a forked worker with no
@@ -1 +1 @@
1
- {"version":3,"file":"build-config.d.mts","names":[],"sources":["../../clis/build-config.mts"],"mappings":";;qBA6Ba;qBAGA;YAkGD;;EAEV;;wBAGc,wBACd,UAAS,4BACR;qBAeU,oBAAkB;;;;;;wBAOf,sBACd,yBACA;EAAoB;EAAc;;YAQxB;;EAEV;;;;;;;;;;;;wBAac,qBACd,UAAS,yBACR;qBAoBU,iBAAiB;YAElB;;EAEV;;EAEA;;;;;;;;;;wBAWc,sBACd,SAAS,0BACR"}
1
+ {"version":3,"file":"build-config.d.mts","names":[],"sources":["../../clis/build-config.mts"],"mappings":";;qBAkCa;qBAGA;YAiID;;EAEV;;EAEA,UAAU;;wBAGI,wBACd,UAAS,4BACR;qBAgBU,oBAAkB;;;;;;wBAOf,sBACd,yBACA;EAAoB;EAAc;;YAQxB;;EAEV;;EAEA,UAAU;;;;;;;;;;;;wBAaI,qBACd,UAAS,yBACR;qBAqBU,iBAAiB;YAElB;;EAEV;;EAEA;;EAEA,UAAU;;;;;;;;;;wBAWI,sBACd,SAAS,0BACR"}
@@ -1,2 +1,2 @@
1
- import { a as buildNodeBuildConfig, c as nodeBuildConfig, i as buildBrowserBuildConfig, n as browserBuildConfig, o as buildPieceBuildConfig, r as browserEntry, s as findBundledSharedDeps, t as PIECE_ENTRY_GLOB } from "./build-config-CR5lvv_A.mjs";
1
+ import { a as buildNodeBuildConfig, c as nodeBuildConfig, i as buildBrowserBuildConfig, n as browserBuildConfig, o as buildPieceBuildConfig, r as browserEntry, s as findBundledSharedDeps, t as PIECE_ENTRY_GLOB } from "./build-config-HbYUSZS1.mjs";
2
2
  export { PIECE_ENTRY_GLOB, browserBuildConfig, browserEntry, buildBrowserBuildConfig, buildNodeBuildConfig, buildPieceBuildConfig, findBundledSharedDeps, nodeBuildConfig };
@@ -1,5 +1,60 @@
1
1
  import { t as InlineConfig } from "./index-6CZwrmQi.mjs";
2
- import { t as Manifest } from "./types-Cc_rB0Yx.mjs";
2
+ import { t as Manifest } from "./types-BZBiwi6I.mjs";
3
+ //#region clis/external-deps.d.mts
4
+ /** The files one module needs at run time, and why each was included. */
5
+ type FileTrace = {
6
+ /** Absolute paths. */
7
+ fileList: Set<string>;
8
+ /** Absolute path -> the absolute paths of the files that pulled it in. */
9
+ reasons: Map<string, {
10
+ parents: Set<string>;
11
+ }>;
12
+ };
13
+ /** Traces one file: @vercel/nft's nodeFileTrace, handed in by the CLI. */
14
+ type TraceFiles = (file: string) => Promise<FileTrace>;
15
+ /** A file the bundle cannot carry: a native addon or a WebAssembly module. */
16
+ type RequiredFile = {
17
+ file: string;
18
+ kind: "native" | "wasm";
19
+ };
20
+ type ExternalDependency = RequiredFile & {
21
+ name: string;
22
+ version: string;
23
+ /** The first of the package's own files seen importing it. */
24
+ importer?: string;
25
+ };
26
+ /** What one `ph build` learns about packages, shared by all of its builds. */
27
+ type DetectionCache = {
28
+ files: Map<string, Promise<RequiredFile | undefined>>;
29
+ wasm: Map<string, string | undefined>;
30
+ };
31
+ export declare const createDetectionCache: () => DetectionCache;
32
+ type ExternalDepsPluginOptions = {
33
+ /** The project root the dirs below are relative to. */
34
+ root?: string;
35
+ /** Browser build: a native package fails it; WebAssembly is bundled. */
36
+ browser?: boolean;
37
+ /** Dirs whose imports the bundler handles as usual: code no host runs. */
38
+ ignoreDirs?: string[];
39
+ /** Dirs that may not import a native or WebAssembly package. */
40
+ forbidDirs?: string[];
41
+ cache?: DetectionCache;
42
+ };
43
+ type Plugin = NonNullable<InlineConfig["plugins"]>;
44
+ /** `file` relative to `root`, with forward slashes on every platform. */
45
+ export declare function projectPath(root: string, file: string): string;
46
+ /** The first file `entry` cannot load without that a bundle cannot carry. */
47
+ export declare function findRequiredFile(entry: string, trace: TraceFiles, cache?: DetectionCache): Promise<RequiredFile | undefined>;
48
+ /** Keeps each package the code imports that needs such a file out of the bundle. */
49
+ export declare function externalDepsPlugin(trace: TraceFiles, found: Map<string, ExternalDependency>, options?: ExternalDepsPluginOptions): Plugin;
50
+ /**
51
+ * The detected packages `pkg` does not install for its consumers: anything
52
+ * outside dependencies, optionalDependencies and peerDependencies.
53
+ */
54
+ export declare function undeclaredExternalDependencies(found: Iterable<ExternalDependency>, pkg: Partial<Record<"dependencies" | "optionalDependencies" | "peerDependencies", Partial<Record<string, string>>>>): ExternalDependency[];
55
+ /** name -> version, sorted by name. */
56
+ export declare function externalDependencyVersions(found: Iterable<ExternalDependency>): Record<string, string>;
57
+ //#endregion
3
58
  //#region clis/build-pieces.d.mts
4
59
  export type PiecePlan = {
5
60
  /** The directory under pieces/, and so under <outDir>/node/pieces. */
@@ -55,6 +110,9 @@ export type PackageIdentity = {
55
110
  export type PieceBuildOptions = {
56
111
  /** The bundler: tsdown's `build`, handed in so this module never loads it. */
57
112
  bundle: (config: InlineConfig) => Promise<unknown>;
113
+ /** Traces a module's run-time files; without it nothing is kept external. */
114
+ trace?: TraceFiles;
115
+ cache?: DetectionCache;
58
116
  };
59
117
  export declare function statSafe(p: string): import("node:fs").Stats | null;
60
118
  export declare function expandEntryGlobs(root: string, globs: string[]): string[];
@@ -86,6 +144,7 @@ export declare function piecePackageJson(options: {
86
144
  description?: string;
87
145
  main: string;
88
146
  license?: string;
147
+ dependencies?: Record<string, string>;
89
148
  }): Record<string, unknown>;
90
149
  export declare function bundlePackageJson(dir: string, version: string): Record<string, unknown>;
91
150
  export declare function pieceDescriptor(piece: PackagePiece, version: string, metadata: PieceMetadata): Record<string, unknown>;
@@ -94,7 +153,8 @@ export declare function enrichManifestPieces(manifest: Manifest, built: BuiltPie
94
153
  unbuilt: string[];
95
154
  };
96
155
  export declare function buildPieces(target: PieceBuildTarget, pkg: PackageIdentity, options: PieceBuildOptions): Promise<BuiltPiece[]>;
97
- export declare function syncDistManifest(target: PieceBuildTarget, built: BuiltPiece[]): string | undefined;
156
+ export declare function syncDistManifest(target: PieceBuildTarget, built: BuiltPiece[], externalDependencies?: Record<string, string>): string | undefined;
98
157
  //#endregion
158
+ export type { DetectionCache, ExternalDependency, ExternalDepsPluginOptions, FileTrace, TraceFiles };
99
159
  export {};
100
160
  //# sourceMappingURL=build-pieces.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-pieces.d.mts","names":[],"sources":["../../clis/build-pieces.mts"],"mappings":";;;YA4BY;;EAEV;;EAEA;;EAEA;;YAKU;EACV;EACA;EACA,QAAQ;;YAKE;EACV;EACA;EACA;;YAKU,gBAAgB;EAC1B;EACA;EACA,UAAU;EACV,WAAW;;YAGD;EACV;EACA,UAAU;;YAGA;EACV,MAAM;EACN,QAAQ;EACR;IAAU;IAAc;;;YAGd;EACV;EACA;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;;YAGU;;EAEV,SAAS,QAAQ,iBAAiB;;wBAKpB,SAAS,8BAAS;wBAUlB,iBAAiB,cAAc;wBA4B/B,WAAW,qBAAqB,iBAAiB;wBAejD,uBAAkB,eAEK,cAAc;qBAiBxC;qBAiEA;wBAsFG,eACd,qBACA,mBACC;YA0BS;;EAEV;;EAEA;EACA;;wBAKc,qBACd,OAAO,cACP,qBACA,iBACC;wBAmCa,cAAc;EAC5B;EACA;;wBAac,mBAAmB;EACjC;EACA,QAAQ;;wBAWM,mBACd,OAAO,cACP,KAAK;wBAWS,iBAAiB;EAC/B;EACA;EACA;EACA;EACA;IACE;wBAeY,kBACd,aACA,kBACC;wBASa,gBACd,OAAO,cACP,iBACA,UAAU,gBACT;wBAUa,qBACd,UAAU,UACV,OAAO;EACJ,UAAU;EAAU;;wBAkCH,YACpB,QAAQ,kBACR,KAAK,iBACL,SAAS,oBACR,QAAQ;wBA0GK,iBACd,QAAQ,kBACR,OAAO"}
1
+ {"version":3,"file":"build-pieces.d.mts","names":[],"sources":["../../clis/external-deps.mts","../../clis/build-pieces.mts"],"mappings":";;;;KAQY;;EAEV,UAAU;;EAEV,SAAS;IAAc,SAAS;;;;KAItB,cAAc,iBAAiB,QAAQ;;KAGvC;EAAiB;EAAc;;KAE/B,qBAAqB;EAC/B;EACA;;EAEA;;;KAIU;EACV,OAAO,YAAY,QAAQ;EAC3B,MAAM;;qBAGK,4BAA2B;KAK5B;;EAEV;;EAEA;;EAEA;;EAEA;EACA,QAAQ;;KAGL,SAAS,YAAY;;wBAaV,YAAY,cAAc;;wBAwEpB,iBACpB,eACA,OAAO,YACP,QAAQ,iBACP,QAAQ;;wBAmDK,mBACd,OAAO,YACP,OAAO,YAAY,qBACnB,UAAS,4BACR;;;;;wBA8Da,+BACd,OAAO,SAAS,qBAChB,KAAK,QACH,qEAEE,QAAQ,4BAGX;;wBAUa,2BACd,OAAO,SAAS,sBACf;;;YCjOS;;EAEV;;EAEA;;EAEA;;YAKU;EACV;EACA;EACA,QAAQ;;YAKE;EACV;EACA;EACA;;YAKU,gBAAgB;EAC1B;EACA;EACA,UAAU;EACV,WAAW;;YAGD;EACV;EACA,UAAU;;YAGA;EACV,MAAM;EACN,QAAQ;EACR;IAAU;IAAc;;;YAGd;EACV;EACA;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;;YAGU;;EAEV,SAAS,QAAQ,iBAAiB;;EAElC,QAAQ;EACR,QAAQ;;wBAKM,SAAS,8BAAS;wBAUlB,iBAAiB,cAAc;wBA4B/B,WAAW,qBAAqB,iBAAiB;wBAejD,uBAAkB,eAEK,cAAc;qBAiBxC;qBAiEA;wBAsFG,eACd,qBACA,mBACC;YA0BS;;EAEV;;EAEA;EACA;;wBAKc,qBACd,OAAO,cACP,qBACA,iBACC;wBAmCa,cAAc;EAC5B;EACA;;wBAac,mBAAmB;EACjC;EACA,QAAQ;;wBAWM,mBACd,OAAO,cACP,KAAK;wBAWS,iBAAiB;EAC/B;EACA;EACA;EACA;EACA;EACA,eAAe;IACb;wBAeY,kBACd,aACA,kBACC;wBASa,gBACd,OAAO,cACP,iBACA,UAAU,gBACT;wBAUa,qBACd,UAAU,UACV,OAAO;EACJ,UAAU;EAAU;;wBAkCH,YACpB,QAAQ,kBACR,KAAK,iBACL,SAAS,oBACR,QAAQ;wBAgIK,iBACd,QAAQ,kBACR,OAAO,cACP,uBAAsB"}