{"version":3,"file":"api-contract.mjs","names":[],"sources":["../src/api-contract.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport type { RuntimeConfig, RuntimePluginConfig } from \"./types\";\n\nconst REMOTE_FETCH_TIMEOUT_MS = 10_000;\n\nexport interface ApiPluginManifest {\n  schemaVersion: 1;\n  kind: \"every-plugin/manifest\";\n  plugin: {\n    name: string;\n    version: string;\n  };\n  runtime: {\n    remoteEntry: string;\n  };\n  contract?: {\n    kind: \"orpc\";\n    types: {\n      path: string;\n      exportName: string;\n      typeName: string;\n      sha256?: string;\n    };\n  };\n  additionalExports?: Array<{\n    path: string;\n    exports: string[];\n    sha256?: string;\n  }>;\n}\n\ninterface ContractSource {\n  key: string;\n  importName: string;\n  sourceFilePath: string;\n  generatedPath?: string;\n}\n\nfunction sha256(input: string): string {\n  return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction trimTrailingSlash(input: string): string {\n  return input.replace(/\\/$/, \"\");\n}\n\nfunction sanitizeIdentifier(input: string): string {\n  return input.replace(/[^A-Za-z0-9_]/g, \"_\").replace(/^[^A-Za-z_]+/, \"_\");\n}\n\nfunction toImportPath(fromFile: string, targetFile: string): string {\n  const rel = relative(dirname(fromFile), targetFile).replace(/\\\\/g, \"/\");\n  return rel.startsWith(\".\") ? rel : `./${rel}`;\n}\n\nfunction writeFileIfChanged(filePath: string, content: string) {\n  try {\n    if (readFileSync(filePath, \"utf8\") === content) return false;\n  } catch {\n    // file does not exist yet\n  }\n\n  writeFileSync(filePath, content);\n  return true;\n}\n\nfunction getApiPluginManifestUrl(apiBaseUrl: string): string {\n  return `${trimTrailingSlash(apiBaseUrl)}/plugin.manifest.json`;\n}\n\nasync function fetchWithTimeout(url: string): Promise<Response> {\n  const controller = new AbortController();\n  const timeout = setTimeout(() => controller.abort(), REMOTE_FETCH_TIMEOUT_MS);\n\n  try {\n    return await fetch(url, { signal: controller.signal });\n  } catch (error) {\n    if (error instanceof Error && error.name === \"AbortError\") {\n      throw new Error(`Timed out fetching ${url} after ${REMOTE_FETCH_TIMEOUT_MS}ms`);\n    }\n    throw error;\n  } finally {\n    clearTimeout(timeout);\n  }\n}\n\nasync function fetchApiPluginManifest(apiBaseUrl: string): Promise<ApiPluginManifest> {\n  const response = await fetchWithTimeout(getApiPluginManifestUrl(apiBaseUrl));\n  if (!response.ok) {\n    throw new Error(\n      `Failed to fetch API plugin manifest: ${response.status} ${response.statusText}`,\n    );\n  }\n\n  const manifest = (await response.json()) as ApiPluginManifest;\n  if (manifest.schemaVersion !== 1 || manifest.kind !== \"every-plugin/manifest\") {\n    throw new Error(\"Unsupported API plugin manifest format\");\n  }\n\n  return manifest;\n}\n\nfunction localApiContractSource(configDir: string): ContractSource {\n  const sourcePath = join(configDir, \"api\", \"src\", \"contract.ts\");\n  return {\n    key: \"api\",\n    importName: \"BaseApiContract\",\n    sourceFilePath: sourcePath,\n  };\n}\n\nfunction localAuthContractSource(configDir: string): ContractSource {\n  const sourcePath = join(configDir, \"plugins\", \"auth\", \"src\", \"contract.ts\");\n  return {\n    key: \"auth\",\n    importName: \"authContract\",\n    sourceFilePath: sourcePath,\n  };\n}\n\nasync function remoteContractSource(opts: {\n  configDir: string;\n  runtimeDir: string;\n  name: string;\n  baseUrl: string;\n  generatedSubdir: string;\n}): Promise<ContractSource> {\n  const manifest = await fetchApiPluginManifest(opts.baseUrl);\n  if (!manifest.contract) {\n    throw new Error(\n      `Plugin manifest for ${manifest.plugin.name} does not advertise contract types`,\n    );\n  }\n\n  const contractUrl = `${trimTrailingSlash(opts.baseUrl)}/${manifest.contract.types.path.replace(/^\\.\\//, \"\")}`;\n  const contractResponse = await fetchWithTimeout(contractUrl);\n  if (!contractResponse.ok) {\n    throw new Error(\n      `Failed to fetch contract types: ${contractResponse.status} ${contractResponse.statusText}`,\n    );\n  }\n\n  const contractTypes = await contractResponse.text();\n  if (manifest.contract.types.sha256 && manifest.contract.types.sha256 !== sha256(contractTypes)) {\n    throw new Error(\"Fetched contract types failed checksum verification\");\n  }\n\n  const generatedPath = join(opts.runtimeDir, opts.generatedSubdir, \"contract.d.ts\");\n  mkdirSync(dirname(generatedPath), { recursive: true });\n  writeFileIfChanged(generatedPath, contractTypes);\n\n  return {\n    key: opts.name,\n    importName: `${sanitizeIdentifier(opts.name)}Contract`,\n    sourceFilePath: generatedPath,\n    generatedPath,\n  };\n}\n\nasync function fetchAuthExportTypes(opts: {\n  baseUrl: string;\n  runtimeDir: string;\n  manifest: ApiPluginManifest;\n}): Promise<string | null> {\n  if (!opts.manifest.additionalExports || opts.manifest.additionalExports.length === 0) {\n    return null;\n  }\n\n  const authExportEntry = opts.manifest.additionalExports.find(\n    (entry) => entry.path.includes(\"auth-export\") || entry.path.endsWith(\"auth-export.d.ts\"),\n  );\n\n  if (!authExportEntry) {\n    return null;\n  }\n\n  const exportUrl = `${trimTrailingSlash(opts.baseUrl)}/${authExportEntry.path.replace(/^\\.\\//, \"\")}`;\n  const response = await fetchWithTimeout(exportUrl);\n  if (!response.ok) {\n    console.warn(`[API Contract] Failed to fetch auth export types: ${response.status}`);\n    return null;\n  }\n\n  const content = await response.text();\n  if (authExportEntry.sha256 && authExportEntry.sha256 !== sha256(content)) {\n    console.warn(\"[API Contract] Auth export types checksum mismatch\");\n    return null;\n  }\n\n  const generatedPath = join(opts.runtimeDir, \"auth\", \"auth-export.d.ts\");\n  mkdirSync(dirname(generatedPath), { recursive: true });\n  writeFileIfChanged(generatedPath, content);\n\n  return generatedPath;\n}\n\nfunction writeAuthTypesGen(targetPath: string, authExportPath: string) {\n  const exportImportPath = toImportPath(targetPath, authExportPath);\n  const content = [\n    `export type {`,\n    `  Auth,`,\n    `  AuthOrganizationContext,`,\n    `  AuthOrganization,`,\n    `  AuthOrganizationSummary,`,\n    `  AuthOrganizationMember,`,\n    `  AuthApiKey,`,\n    `  AuthInvitation,`,\n    `  GetActiveMemberInput,`,\n    `  GetOrganizationInput,`,\n    `  ListMembersInput,`,\n    `  ListInvitationsInput,`,\n    `  ListApiKeysInput,`,\n    `  AuthServices,`,\n    `  createAuthInstance,`,\n    `} from \"${exportImportPath}\";`,\n    `import type { InferOutput, ContractType as AuthContract } from \"${toImportPath(targetPath, join(dirname(authExportPath), \"contract.d.ts\"))}\";`,\n    `import type { Auth as BaseAuth } from \"${exportImportPath}\";`,\n    \"\",\n    'type RawAuthSession = InferOutput<\"getSession\">;',\n    'type RawAuthRequestContext = InferOutput<\"getContext\">;',\n    'type RawAuthActiveMember = InferOutput<\"getActiveMember\">;',\n    \"\",\n    'export type AuthSessionUser = NonNullable<RawAuthSession[\"user\"]> & {',\n    \"  role?: string | null;\",\n    \"  isAnonymous?: boolean | null;\",\n    \"  walletAddress?: string | null;\",\n    \"  banned?: boolean | null;\",\n    \"};\",\n    'export type AuthSessionData = NonNullable<RawAuthSession[\"session\"]> & {',\n    \"  activeOrganizationId?: string | null;\",\n    \"};\",\n    \"export type AuthSession = {\",\n    \"  user: AuthSessionUser | null;\",\n    \"  session: AuthSessionData | null;\",\n    \"};\",\n    \"export type AuthRequestContext = RawAuthRequestContext;\",\n    \"export type AuthActiveMember = RawAuthActiveMember;\",\n    'export type AuthBaseSession = BaseAuth[\"$Infer\"][\"Session\"];',\n    \"export type AuthContractType = AuthContract;\",\n    \"\",\n  ].join(\"\\n\");\n  mkdirSync(dirname(targetPath), { recursive: true });\n  writeFileIfChanged(targetPath, content);\n}\n\nfunction writeFallbackAuthTypesGen(targetPath: string) {\n  const content = [\n    'import type { Auth } from \"better-auth\";',\n    'export type { Auth } from \"better-auth\";',\n    'export type AuthSession = Auth[\"$Infer\"][\"Session\"];',\n    \"export type AuthSessionData = AuthSession;\",\n    'export type AuthSessionUser = NonNullable<AuthSession[\"user\"]>;',\n    \"export interface AuthOrganizationContext {\",\n    \"  activeOrganizationId: string | null;\",\n    \"  organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;\",\n    \"  member: { id: string; role: string } | null;\",\n    \"  isPersonal: boolean;\",\n    \"  hasOrganization: boolean;\",\n    \"}\",\n    \"export interface AuthRequestContext {\",\n    \"  user: AuthSessionUser | null;\",\n    \"  userId: string | null;\",\n    \"  isAuthenticated: boolean;\",\n    '  authMethod: \"session\" | \"apiKey\" | \"anonymous\" | \"none\";',\n    \"  near: {\",\n    \"    primaryAccountId: string | null;\",\n    \"    linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;\",\n    \"    hasNearAccount: boolean;\",\n    \"  };\",\n    \"  organization: AuthOrganizationContext;\",\n    \"  organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;\",\n    \"}\",\n    \"export type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };\",\n    \"export type AuthOrganization = {\",\n    \"  id: string;\",\n    \"  name: string;\",\n    \"  slug: string;\",\n    \"  logo?: string | null;\",\n    \"  metadata?: Record<string, unknown> | null;\",\n    \"  createdAt: Date;\",\n    \"};\",\n    'export type AuthOrganizationSummary = NonNullable<AuthOrganizationContext[\"organization\"]>;',\n    'export type AuthOrganizationMember = NonNullable<AuthOrganizationContext[\"member\"]>;',\n    \"export type AuthApiKey = {\",\n    \"  id: string;\",\n    \"  name: string | null;\",\n    \"  prefix: string | null;\",\n    \"  start: string | null;\",\n    \"  expiresAt: Date | null;\",\n    \"  createdAt: Date;\",\n    \"  updatedAt: Date;\",\n    \"  metadata: unknown | null;\",\n    \"  permissions: Record<string, string[]> | null;\",\n    \"};\",\n    \"export type AuthInvitation = {\",\n    \"  id: string;\",\n    \"  organizationId: string;\",\n    \"  email: string;\",\n    \"  role: string | null;\",\n    \"  status: string;\",\n    \"  expiresAt: Date;\",\n    \"  inviterId: string;\",\n    \"};\",\n    \"export type GetActiveMemberInput = { organizationId?: string };\",\n    \"export type GetOrganizationInput = { id: string };\",\n    \"export type ListMembersInput = { organizationId: string };\",\n    \"export type ListInvitationsInput = { organizationId: string };\",\n    \"export type ListApiKeysInput = { organizationId?: string };\",\n    \"export type createAuthInstance = never;\",\n    \"export interface AuthServices {\",\n    \"  auth: Auth;\",\n    \"  db: unknown;\",\n    \"  driver: { close(): Promise<void> };\",\n    \"  handler: (req: Request) => Promise<Response>;\",\n    \"}\",\n    \"\",\n  ].join(\"\\n\");\n  mkdirSync(dirname(targetPath), { recursive: true });\n  writeFileIfChanged(targetPath, content);\n}\n\nasync function resolveContractSource(opts: {\n  configDir: string;\n  runtimeDir: string;\n  key: string;\n  source: RuntimePluginConfig | { url: string; localPath?: string; name: string } | null;\n  baseUrl: string;\n  generatedSubdir: string;\n  localSourceFactory?: (configDir: string) => ContractSource;\n}): Promise<ContractSource> {\n  if (opts.key === \"api\") {\n    const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n    if (localPath != null && localPath !== \"\") {\n      return {\n        key: opts.key,\n        importName: \"BaseApiContract\",\n        sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n      };\n    }\n\n    if (!opts.baseUrl) {\n      return localApiContractSource(opts.configDir);\n    }\n  }\n\n  if (opts.key === \"auth\" && opts.localSourceFactory) {\n    const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n    if (localPath != null && localPath !== \"\") {\n      return {\n        key: opts.key,\n        importName: \"authContract\",\n        sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n      };\n    }\n\n    if (!opts.baseUrl) {\n      return opts.localSourceFactory(opts.configDir);\n    }\n  }\n\n  if (\n    opts.source &&\n    \"localPath\" in opts.source &&\n    opts.source.localPath != null &&\n    opts.source.localPath !== \"\"\n  ) {\n    return {\n      key: opts.key,\n      importName: `${sanitizeIdentifier(opts.key)}Contract`,\n      sourceFilePath: join(opts.source.localPath, \"src\", \"contract.ts\"),\n    };\n  }\n\n  return remoteContractSource({\n    configDir: opts.configDir,\n    runtimeDir: opts.runtimeDir,\n    name: opts.key,\n    baseUrl: opts.baseUrl,\n    generatedSubdir: opts.generatedSubdir,\n  });\n}\n\nfunction writeGeneratedFiles(opts: {\n  configDir: string;\n  sources: ContractSource[];\n  pluginKeys: string[];\n  authSource: ContractSource | null;\n  authExportPath?: string | null;\n}) {\n  const baseSource = opts.sources.find((source) => source.key === \"api\");\n  const pluginSources = opts.pluginKeys\n    .map((key) => opts.sources.find((entry) => entry.key === key))\n    .filter((source): source is ContractSource => Boolean(source));\n\n  if (!baseSource) {\n    throw new Error(\"API contract source is required to generate the aggregate contract\");\n  }\n\n  // --- Generate ui/src/lib/api-types.gen.ts ---\n  const uiContractPath = join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\");\n  const uiLines: string[] = [];\n\n  for (const source of opts.sources) {\n    const importPath = toImportPath(uiContractPath, source.sourceFilePath);\n    uiLines.push(`import type { ContractType as ${source.importName} } from \"${importPath}\";`);\n  }\n\n  uiLines.push(\"\");\n\n  const compositeParts: string[] = [];\n  if (opts.authSource) {\n    compositeParts.push(`auth: ${opts.authSource.importName}`);\n  }\n  for (const source of pluginSources) {\n    const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key) ? source.key : JSON.stringify(source.key);\n    compositeParts.push(`${key}: ${source.importName}`);\n  }\n\n  if (compositeParts.length === 0) {\n    uiLines.push(`export type ApiContract = ${baseSource.importName};`);\n  } else {\n    uiLines.push(`export type ApiContract = ${baseSource.importName} & {`);\n    for (const part of compositeParts) {\n      uiLines.push(`  ${part};`);\n    }\n    uiLines.push(\"};\");\n  }\n  mkdirSync(dirname(uiContractPath), { recursive: true });\n  writeFileIfChanged(uiContractPath, `${uiLines.join(\"\\n\")}\\n`);\n\n  // --- Generate api/src/lib/plugins-types.gen.ts ---\n  // Includes both plugin contracts AND auth as a unified PluginsClient type\n  const pluginsClientPath = join(opts.configDir, \"api\", \"src\", \"lib\", \"plugins-types.gen.ts\");\n  const pluginsClientLines: string[] = [];\n\n  for (const source of pluginSources) {\n    const importPath = toImportPath(pluginsClientPath, source.sourceFilePath);\n    pluginsClientLines.push(\n      `import type { ContractType as ${source.importName} } from \"${importPath}\";`,\n    );\n  }\n\n  if (opts.authSource) {\n    const authImportPath = toImportPath(pluginsClientPath, opts.authSource.sourceFilePath);\n    pluginsClientLines.push(\n      `import type { ContractType as ${opts.authSource.importName} } from \"${authImportPath}\";`,\n    );\n  }\n\n  pluginsClientLines.push(\n    'import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";',\n  );\n  pluginsClientLines.push(\n    \"type ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\",\n  );\n  pluginsClientLines.push(\"\");\n\n  const allPluginSources = [...pluginSources];\n  if (opts.authSource) {\n    allPluginSources.push({ ...opts.authSource, key: \"auth\" });\n  }\n\n  if (allPluginSources.length === 0) {\n    pluginsClientLines.push(\"export type PluginsClient = Record<string, never>;\");\n  } else {\n    pluginsClientLines.push(\"export type PluginsClient = {\");\n    for (const source of allPluginSources) {\n      const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key)\n        ? source.key\n        : JSON.stringify(source.key);\n      pluginsClientLines.push(`  ${key}: ClientFactory<${source.importName}>;`);\n    }\n    pluginsClientLines.push(\"};\");\n  }\n\n  mkdirSync(dirname(pluginsClientPath), { recursive: true });\n  writeFileIfChanged(pluginsClientPath, `${pluginsClientLines.join(\"\\n\")}\\n`);\n\n  // --- Generate */src/lib/auth-types.gen.ts ---\n  const authTypeTargets = [join(opts.configDir, \"ui\", \"src\", \"lib\", \"auth-types.gen.ts\")];\n  const apiLibDir = join(opts.configDir, \"api\", \"src\", \"lib\");\n  if (existsSync(apiLibDir)) {\n    authTypeTargets.push(join(apiLibDir, \"auth-types.gen.ts\"));\n  }\n  const hostLibDir = join(opts.configDir, \"host\", \"src\", \"lib\");\n  if (existsSync(join(opts.configDir, \"host\", \"src\"))) {\n    authTypeTargets.push(join(hostLibDir, \"auth-types.gen.ts\"));\n  }\n\n  if (opts.authExportPath) {\n    for (const authTypesPath of authTypeTargets) {\n      writeAuthTypesGen(authTypesPath, opts.authExportPath);\n    }\n  } else if (opts.authSource) {\n    for (const authTypesPath of authTypeTargets) {\n      writeFallbackAuthTypesGen(authTypesPath);\n    }\n  }\n\n  return uiContractPath;\n}\n\nexport async function syncApiContractBridge(opts: {\n  configDir: string;\n  runtimeConfig: RuntimeConfig;\n  apiBaseUrl: string;\n}): Promise<{\n  bridgePath: string;\n  generatedPath: string | null;\n  manifest: ApiPluginManifest | null;\n  source: \"local\" | \"remote\";\n}> {\n  const runtimeDir = join(opts.configDir, \".bos\", \"generated\");\n  const pluginEntries = Object.entries(opts.runtimeConfig.plugins ?? {}).sort(([a], [b]) =>\n    a.localeCompare(b),\n  );\n  const sources: ContractSource[] = [];\n  let manifest: ApiPluginManifest | null = null;\n  let generatedPath: string | null = null;\n  let authSource: ContractSource | null = null;\n  let authExportPath: string | null = null;\n\n  const baseSource = await resolveContractSource({\n    configDir: opts.configDir,\n    runtimeDir,\n    key: \"api\",\n    source: opts.runtimeConfig.api,\n    baseUrl: opts.apiBaseUrl,\n    generatedSubdir: \"api\",\n  });\n  sources.push(baseSource);\n\n  if (opts.runtimeConfig.auth) {\n    authSource = await resolveContractSource({\n      configDir: opts.configDir,\n      runtimeDir,\n      key: \"auth\",\n      source: opts.runtimeConfig.auth,\n      baseUrl: opts.runtimeConfig.auth.url,\n      generatedSubdir: \"auth\",\n      localSourceFactory: localAuthContractSource,\n    });\n    sources.push(authSource);\n    if (authSource.generatedPath) {\n      generatedPath = authSource.generatedPath;\n    }\n\n    // Fetch auth additional exports (auth-export.d.ts) for remote auth\n    if (opts.runtimeConfig.auth.url && opts.runtimeConfig.auth.source !== \"local\") {\n      try {\n        const authManifest = await fetchApiPluginManifest(opts.runtimeConfig.auth.url);\n        const fetchedAuthExportPath = await fetchAuthExportTypes({\n          baseUrl: opts.runtimeConfig.auth.url,\n          runtimeDir,\n          manifest: authManifest,\n        });\n        if (fetchedAuthExportPath) {\n          authExportPath = fetchedAuthExportPath;\n        }\n      } catch (error) {\n        console.warn(\n          `[API Contract] Failed to fetch auth additional exports: ${error instanceof Error ? error.message : String(error)}`,\n        );\n      }\n    }\n\n    if (!authExportPath) {\n      const localAuthExport = join(opts.configDir, \"plugins\", \"auth\", \"src\", \"auth-export.ts\");\n      if (existsSync(localAuthExport)) {\n        authExportPath = localAuthExport;\n      } else {\n        const generatedAuthExport = join(runtimeDir, \"auth\", \"auth-export.d.ts\");\n        if (existsSync(generatedAuthExport)) {\n          authExportPath = generatedAuthExport;\n        }\n      }\n    }\n  }\n\n  for (const [key, plugin] of pluginEntries) {\n    if (!plugin.url && !plugin.localPath) {\n      console.warn(\n        `[API Contract] Skipping plugin \"${key}\" — no URL resolved (local path missing and no production URL configured)`,\n      );\n      continue;\n    }\n    const source = await resolveContractSource({\n      configDir: opts.configDir,\n      runtimeDir,\n      key,\n      source: plugin,\n      baseUrl: plugin.url,\n      generatedSubdir: `plugins/${key}`,\n    });\n    sources.push(source);\n    if (source.generatedPath) {\n      generatedPath = source.generatedPath;\n    }\n  }\n\n  const allPluginKeys = pluginEntries.map(([key]) => key);\n\n  writeGeneratedFiles({\n    configDir: opts.configDir,\n    sources,\n    pluginKeys: allPluginKeys,\n    authSource,\n    authExportPath,\n  });\n\n  if (opts.runtimeConfig.api.source !== \"local\") {\n    manifest = await fetchApiPluginManifest(opts.apiBaseUrl);\n  }\n\n  return {\n    bridgePath: join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\"),\n    generatedPath,\n    manifest,\n    source: opts.runtimeConfig.api.source,\n  };\n}\n"],"mappings":"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"}