/** * Build a diagnostic spec (wire graph + schema hash) from the project's * `defineDomain` definition. This mirrors what the codegen'd worker assembles — * but only for inspection / `/meta` provenance. The live install bundle is * always produced by the worker at request time, so a failure here is non-fatal * for dev/deploy (the CLI logs and continues) and fatal only for * `astrale-domain build`, where the spec IS the product. * * The modules (`schema` / `methods` / `views` / `functions`) come straight off * the definition — the SAME values the author wired into `defineDomain`, which * the adapter codegen also assembles. One source, no second filesystem probe to * drift from it. */ import type { Schema } from '@astrale-os/kernel-dsl' import { hashInstallGraph } from '@astrale-os/kernel-core/domain' import type { DomainDefinition } from '../config/define-domain.js' import type { RemoteDomainConfig } from '../domain/index.js' import { buildInstallGraph, defineRemoteDomain } from '../domain/index.js' export async function buildProjectSpec( def: DomainDefinition, url: string, ): Promise<{ wire: Record; schemaHash: string }> { // The definition's module values are untyped against `RemoteDomainConfig` by // nature (deps/schema generics erased on `DomainDefinition`); funnel them // through ONE cast into the config shape `defineRemoteDomain` validates. const config = { schema: def.schema, methods: def.methods, ...(def.core ? { core: def.core } : {}), ...(def.views ? { views: def.views } : {}), ...(def.functions ? { remoteFunctions: def.functions } : {}), ...(def.path ? { path: def.path } : {}), } as RemoteDomainConfig const domain = defineRemoteDomain()(config) const wire = buildInstallGraph(domain, url) const schemaHash = await hashInstallGraph(wire) return { wire: wire as unknown as Record, schemaHash } }