everything-dev 1.33.7 → 1.35.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-contract.cjs +48 -68
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +48 -68
- package/dist/api-contract.mjs.map +1 -1
- package/dist/cli/init.cjs +67 -44
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +68 -45
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/sync.cjs +5 -0
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +5 -0
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +6 -3
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +6 -3
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/config.cjs +12 -4
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +12 -4
- package/dist/config.mjs.map +1 -1
- package/dist/contract.d.cts +44 -28
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +44 -28
- package/dist/contract.d.mts.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/merge.cjs +2 -5
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.d.cts +1 -1
- package/dist/merge.d.cts.map +1 -1
- package/dist/merge.d.mts +1 -1
- package/dist/merge.d.mts.map +1 -1
- package/dist/merge.mjs +2 -5
- package/dist/merge.mjs.map +1 -1
- package/dist/plugin.cjs +7 -3
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +65 -43
- package/dist/plugin.d.mts +65 -43
- package/dist/plugin.mjs +7 -3
- package/dist/plugin.mjs.map +1 -1
- package/dist/shared-deps.cjs +201 -0
- package/dist/shared-deps.cjs.map +1 -0
- package/dist/shared-deps.mjs +200 -0
- package/dist/shared-deps.mjs.map +1 -0
- package/dist/types.cjs +14 -12
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +88 -40
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +88 -40
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +14 -13
- package/dist/types.mjs.map +1 -1
- package/package.json +4 -4
- package/skills/extends-config/SKILL.md +7 -8
- package/skills/init-upgrade/SKILL.md +5 -2
- package/skills/publish-sync/SKILL.md +1 -1
- package/dist/shared.cjs +0 -155
- package/dist/shared.cjs.map +0 -1
- package/dist/shared.mjs +0 -154
- package/dist/shared.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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 hasLocalApiWorkspace = existsSync(join(opts.configDir, \"api\", \"src\"));\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 if (hasLocalApiWorkspace) {\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\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 interface ContractBridgeStatus {\n key: string;\n source: \"local\" | \"remote\" | \"skipped\" | \"failed\";\n url?: string;\n error?: string;\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 status: ContractBridgeStatus[];\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 const status: ContractBridgeStatus[] = [];\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 const excludedPluginKeys = new Set<string>();\n\n try {\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 status.push({\n key: \"api\",\n source: opts.runtimeConfig.api.source,\n url: opts.runtimeConfig.api.source !== \"local\" ? opts.apiBaseUrl : undefined,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve api contract: ${message}`);\n status.push({\n key: \"api\",\n source: \"failed\",\n url: opts.apiBaseUrl || undefined,\n error: message,\n });\n }\n\n if (opts.runtimeConfig.auth) {\n try {\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 status.push({\n key: \"auth\",\n source: opts.runtimeConfig.auth.source,\n url: opts.runtimeConfig.auth.source !== \"local\" ? opts.runtimeConfig.auth.url : undefined,\n });\n if (authSource.generatedPath) {\n generatedPath = authSource.generatedPath;\n }\n\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 } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve auth contract: ${message}`);\n status.push({\n key: \"auth\",\n source: \"failed\",\n url: opts.runtimeConfig.auth.url || undefined,\n error: message,\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 status.push({ key, source: \"skipped\" });\n excludedPluginKeys.add(key);\n continue;\n }\n try {\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 status.push({\n key,\n source: plugin.source,\n url: plugin.source !== \"local\" ? plugin.url : undefined,\n });\n if (source.generatedPath) {\n generatedPath = source.generatedPath;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve plugin \"${key}\": ${message}`);\n status.push({ key, source: \"failed\", url: plugin.url || undefined, error: message });\n excludedPluginKeys.add(key);\n }\n }\n\n const apiStatus = status.find((s) => s.key === \"api\");\n if (apiStatus?.source === \"failed\") {\n throw new Error(\n `Cannot generate contract types without api contract: ${apiStatus.error ?? \"unknown error\"}`,\n );\n }\n\n const allPluginKeys = pluginEntries\n .filter(([key]) => !excludedPluginKeys.has(key))\n .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 status,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"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 \" organization?: { activeOrganizationId?: string | null } | null;\",\n \" apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;\",\n \"};\",\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 writeContractBasedAuthTypesGen(targetPath: string, configDir: string) {\n const authExportRel = toImportPath(\n targetPath,\n join(configDir, \".bos\", \"generated\", \"auth\", \"auth-export.d.ts\"),\n );\n const contractRel = toImportPath(\n targetPath,\n join(configDir, \".bos\", \"generated\", \"auth\", \"contract.d.ts\"),\n );\n\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 \"${authExportRel}\";`,\n `import type { InferOutput, ContractType as AuthContract } from \"${contractRel}\";`,\n `import type { Auth as BaseAuth } from \"${authExportRel}\";`,\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 \" organization?: { activeOrganizationId?: string | null } | null;\",\n \" apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;\",\n \"};\",\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\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 hasLocalApiWorkspace = existsSync(join(opts.configDir, \"api\", \"src\"));\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 if (hasLocalApiWorkspace) {\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\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 writeContractBasedAuthTypesGen(authTypesPath, opts.configDir);\n }\n }\n\n return uiContractPath;\n}\n\nexport interface ContractBridgeStatus {\n key: string;\n source: \"local\" | \"remote\" | \"skipped\" | \"failed\";\n url?: string;\n error?: string;\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 status: ContractBridgeStatus[];\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 const status: ContractBridgeStatus[] = [];\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 const excludedPluginKeys = new Set<string>();\n\n try {\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 status.push({\n key: \"api\",\n source: opts.runtimeConfig.api.source,\n url: opts.runtimeConfig.api.source !== \"local\" ? opts.apiBaseUrl : undefined,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve api contract: ${message}`);\n status.push({\n key: \"api\",\n source: \"failed\",\n url: opts.apiBaseUrl || undefined,\n error: message,\n });\n }\n\n if (opts.runtimeConfig.auth) {\n try {\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 status.push({\n key: \"auth\",\n source: opts.runtimeConfig.auth.source,\n url: opts.runtimeConfig.auth.source !== \"local\" ? opts.runtimeConfig.auth.url : undefined,\n });\n if (authSource.generatedPath) {\n generatedPath = authSource.generatedPath;\n }\n\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 } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve auth contract: ${message}`);\n status.push({\n key: \"auth\",\n source: \"failed\",\n url: opts.runtimeConfig.auth.url || undefined,\n error: message,\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 status.push({ key, source: \"skipped\" });\n excludedPluginKeys.add(key);\n continue;\n }\n try {\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 status.push({\n key,\n source: plugin.source,\n url: plugin.source !== \"local\" ? plugin.url : undefined,\n });\n if (source.generatedPath) {\n generatedPath = source.generatedPath;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve plugin \"${key}\": ${message}`);\n status.push({ key, source: \"failed\", url: plugin.url || undefined, error: message });\n excludedPluginKeys.add(key);\n }\n }\n\n const apiStatus = status.find((s) => s.key === \"api\");\n if (apiStatus?.source === \"failed\") {\n throw new Error(\n `Cannot generate contract types without api contract: ${apiStatus.error ?? \"unknown error\"}`,\n );\n }\n\n const allPluginKeys = pluginEntries\n .filter(([key]) => !excludedPluginKeys.has(key))\n .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 status,\n };\n}\n"],"mappings":"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"}
|
package/dist/cli/init.cjs
CHANGED
|
@@ -423,17 +423,16 @@ async function personalizeConfig(destination, opts) {
|
|
|
423
423
|
} else continue;
|
|
424
424
|
stripProductionFields(pluginObj);
|
|
425
425
|
}
|
|
426
|
-
if (Object.keys(plugins).length === 0)
|
|
426
|
+
if (Object.keys(plugins).length === 0) config.plugins = {};
|
|
427
427
|
}
|
|
428
|
-
} else
|
|
428
|
+
} else config.plugins = {};
|
|
429
429
|
if (opts.mode === "sync" && opts.existingConfig) {
|
|
430
430
|
const managedRootKeys = new Set([
|
|
431
431
|
"extends",
|
|
432
432
|
"account",
|
|
433
433
|
"domain",
|
|
434
434
|
"app",
|
|
435
|
-
"plugins"
|
|
436
|
-
"shared"
|
|
435
|
+
"plugins"
|
|
437
436
|
]);
|
|
438
437
|
const preservedRootKeys = new Set([
|
|
439
438
|
...managedRootKeys,
|
|
@@ -550,14 +549,37 @@ async function personalizeConfig(destination, opts) {
|
|
|
550
549
|
(0, node_fs.writeFileSync)(pluginsClientGenPath, `import type { ContractRouterClient, AnyContractRouter } from "@orpc/contract";\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\nexport type PluginsClient = Record<string, never>;\n`);
|
|
551
550
|
}
|
|
552
551
|
}
|
|
553
|
-
const authTypesContent = generateAuthTypesTemplate();
|
|
554
552
|
const authTypesPaths = [];
|
|
555
553
|
if (has("ui")) authTypesPaths.push((0, node_path.join)(destination, "ui", "src", "lib", "auth-types.gen.ts"));
|
|
556
554
|
if (has("api")) authTypesPaths.push((0, node_path.join)(destination, "api", "src", "lib", "auth-types.gen.ts"));
|
|
557
555
|
if (has("host") && (0, node_fs.existsSync)((0, node_path.join)(destination, "host", "src"))) authTypesPaths.push((0, node_path.join)(destination, "host", "src", "lib", "auth-types.gen.ts"));
|
|
558
556
|
for (const authTypesGenPath of authTypesPaths) if (!(0, node_fs.existsSync)(authTypesGenPath)) {
|
|
559
557
|
(0, node_fs.mkdirSync)((0, node_path.dirname)(authTypesGenPath), { recursive: true });
|
|
560
|
-
(0, node_fs.writeFileSync)(authTypesGenPath,
|
|
558
|
+
(0, node_fs.writeFileSync)(authTypesGenPath, generateAuthTypesContent(authTypesGenPath, destination));
|
|
559
|
+
}
|
|
560
|
+
if (authTypesPaths.length > 0) {
|
|
561
|
+
const authDir = (0, node_path.join)(destination, ".bos", "generated", "auth");
|
|
562
|
+
if (!(0, node_fs.existsSync)(authDir)) (0, node_fs.mkdirSync)(authDir, { recursive: true });
|
|
563
|
+
const authExportStubPath = (0, node_path.join)(authDir, "auth-export.d.ts");
|
|
564
|
+
if (!(0, node_fs.existsSync)(authExportStubPath)) (0, node_fs.writeFileSync)(authExportStubPath, `export type Auth = any;
|
|
565
|
+
export type AuthOrganizationContext = any;
|
|
566
|
+
export type AuthOrganization = any;
|
|
567
|
+
export type AuthOrganizationSummary = any;
|
|
568
|
+
export type AuthOrganizationMember = any;
|
|
569
|
+
export type AuthApiKey = any;
|
|
570
|
+
export type AuthInvitation = any;
|
|
571
|
+
export type GetActiveMemberInput = any;
|
|
572
|
+
export type GetOrganizationInput = any;
|
|
573
|
+
export type ListMembersInput = any;
|
|
574
|
+
export type ListInvitationsInput = any;
|
|
575
|
+
export type ListApiKeysInput = any;
|
|
576
|
+
export type AuthServices = any;
|
|
577
|
+
export type createAuthInstance = any;
|
|
578
|
+
`);
|
|
579
|
+
const contractStubPath = (0, node_path.join)(authDir, "contract.d.ts");
|
|
580
|
+
if (!(0, node_fs.existsSync)(contractStubPath)) (0, node_fs.writeFileSync)(contractStubPath, `export type ContractType = any;
|
|
581
|
+
export type InferOutput<_TRoute extends string> = any;
|
|
582
|
+
`);
|
|
561
583
|
}
|
|
562
584
|
if (has("plugins")) for (const plugin of opts.plugins ?? []) {
|
|
563
585
|
const pluginSrcDir = (0, node_path.join)(destination, "plugins", plugin, "src");
|
|
@@ -568,56 +590,57 @@ async function personalizeConfig(destination, opts) {
|
|
|
568
590
|
(0, node_fs.writeFileSync)(pluginClientGenPath, "export type PluginsClient = Record<string, never>;\n");
|
|
569
591
|
}
|
|
570
592
|
}
|
|
571
|
-
function
|
|
572
|
-
|
|
573
|
-
export type {
|
|
574
|
-
|
|
593
|
+
function generateAuthTypesContent(targetPath, configDir) {
|
|
594
|
+
const authExportRel = toRelativeImportPath((0, node_path.join)(configDir, ".bos", "generated", "auth", "auth-export.d.ts"), targetPath);
|
|
595
|
+
return `export type {
|
|
596
|
+
Auth,
|
|
597
|
+
AuthOrganizationContext,
|
|
598
|
+
AuthOrganization,
|
|
599
|
+
AuthOrganizationSummary,
|
|
600
|
+
AuthOrganizationMember,
|
|
601
|
+
AuthApiKey,
|
|
602
|
+
AuthInvitation,
|
|
603
|
+
GetActiveMemberInput,
|
|
604
|
+
GetOrganizationInput,
|
|
605
|
+
ListMembersInput,
|
|
606
|
+
ListInvitationsInput,
|
|
607
|
+
ListApiKeysInput,
|
|
608
|
+
AuthServices,
|
|
609
|
+
createAuthInstance,
|
|
610
|
+
} from "${authExportRel}";
|
|
611
|
+
import type { InferOutput, ContractType as AuthContract } from "${toRelativeImportPath((0, node_path.join)(configDir, ".bos", "generated", "auth", "contract.d.ts"), targetPath)}";
|
|
612
|
+
import type { Auth as BaseAuth } from "${authExportRel}";
|
|
613
|
+
|
|
614
|
+
type RawAuthSession = InferOutput<"getSession">;
|
|
615
|
+
type RawAuthRequestContext = InferOutput<"getContext">;
|
|
616
|
+
type RawAuthActiveMember = InferOutput<"getActiveMember">;
|
|
617
|
+
|
|
618
|
+
export type AuthSessionUser = NonNullable<RawAuthSession["user"]> & {
|
|
575
619
|
role?: string | null;
|
|
576
620
|
isAnonymous?: boolean | null;
|
|
577
621
|
walletAddress?: string | null;
|
|
578
622
|
banned?: boolean | null;
|
|
579
623
|
};
|
|
580
|
-
export type AuthSessionData = NonNullable<
|
|
624
|
+
export type AuthSessionData = NonNullable<RawAuthSession["session"]> & {
|
|
581
625
|
activeOrganizationId?: string | null;
|
|
582
626
|
};
|
|
583
627
|
export type AuthSession = {
|
|
584
628
|
user: AuthSessionUser | null;
|
|
585
629
|
session: AuthSessionData | null;
|
|
586
630
|
};
|
|
587
|
-
export
|
|
588
|
-
activeOrganizationId
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
export interface AuthRequestContext {
|
|
595
|
-
user: AuthSessionUser | null;
|
|
596
|
-
userId: string | null;
|
|
597
|
-
isAuthenticated: boolean;
|
|
598
|
-
authMethod: "session" | "apiKey" | "anonymous" | "none";
|
|
599
|
-
near: {
|
|
600
|
-
primaryAccountId: string | null;
|
|
601
|
-
linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;
|
|
602
|
-
hasNearAccount: boolean;
|
|
603
|
-
};
|
|
604
|
-
organization: AuthOrganizationContext;
|
|
605
|
-
organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;
|
|
606
|
-
}
|
|
607
|
-
export type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };
|
|
608
|
-
export type AuthOrganization = NonNullable<AuthOrganizationContext["organization"]>;
|
|
609
|
-
export type AuthOrganizationMember = NonNullable<AuthOrganizationContext["member"]>;
|
|
610
|
-
export type AuthOrganizationSummary = NonNullable<AuthRequestContext["organizations"]>[number];
|
|
611
|
-
export type AuthBaseSession = Auth["$Infer"]["Session"];
|
|
612
|
-
export type createAuthInstance = never;
|
|
613
|
-
export interface AuthServices {
|
|
614
|
-
auth: Auth;
|
|
615
|
-
db: unknown;
|
|
616
|
-
driver: { close(): Promise<void> };
|
|
617
|
-
handler: (req: Request) => Promise<Response>;
|
|
618
|
-
}
|
|
631
|
+
export type AuthRequestContext = RawAuthRequestContext & {
|
|
632
|
+
organization?: { activeOrganizationId?: string | null } | null;
|
|
633
|
+
apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;
|
|
634
|
+
};
|
|
635
|
+
export type AuthActiveMember = RawAuthActiveMember;
|
|
636
|
+
export type AuthBaseSession = BaseAuth["$Infer"]["Session"];
|
|
637
|
+
export type AuthContractType = AuthContract;
|
|
619
638
|
`;
|
|
620
639
|
}
|
|
640
|
+
function toRelativeImportPath(fromPath, toPath) {
|
|
641
|
+
const rel = (0, node_path.relative)((0, node_path.dirname)(toPath), fromPath);
|
|
642
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
643
|
+
}
|
|
621
644
|
async function runBunInstall(destination, spinner) {
|
|
622
645
|
await runWithProgress("bun", ["install", "--ignore-scripts"], destination, spinner, "Installing dependencies");
|
|
623
646
|
}
|
|
@@ -728,7 +751,7 @@ async function scaffoldMinimalProject(destination, parentConfig, opts) {
|
|
|
728
751
|
}
|
|
729
752
|
}
|
|
730
753
|
config.plugins = plugins;
|
|
731
|
-
}
|
|
754
|
+
} else if (has("plugins")) config.plugins = {};
|
|
732
755
|
await require_save_config.saveBosConfig(destination, config);
|
|
733
756
|
const workspacePackages = [];
|
|
734
757
|
for (const section of opts.overrides) workspacePackages.push(...OVERRIDE_WORKSPACE_MAP[section]);
|