everything-dev 1.33.6 → 1.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/api-contract.cjs +48 -68
  2. package/dist/api-contract.cjs.map +1 -1
  3. package/dist/api-contract.mjs +48 -68
  4. package/dist/api-contract.mjs.map +1 -1
  5. package/dist/cli/init.cjs +64 -41
  6. package/dist/cli/init.cjs.map +1 -1
  7. package/dist/cli/init.d.cts.map +1 -1
  8. package/dist/cli/init.d.mts.map +1 -1
  9. package/dist/cli/init.mjs +65 -42
  10. package/dist/cli/init.mjs.map +1 -1
  11. package/dist/cli/sync.cjs +5 -0
  12. package/dist/cli/sync.cjs.map +1 -1
  13. package/dist/cli/sync.mjs +5 -0
  14. package/dist/cli/sync.mjs.map +1 -1
  15. package/dist/cli/upgrade.cjs +6 -3
  16. package/dist/cli/upgrade.cjs.map +1 -1
  17. package/dist/cli/upgrade.mjs +6 -3
  18. package/dist/cli/upgrade.mjs.map +1 -1
  19. package/dist/config.cjs +12 -4
  20. package/dist/config.cjs.map +1 -1
  21. package/dist/config.d.cts.map +1 -1
  22. package/dist/config.d.mts.map +1 -1
  23. package/dist/config.mjs +12 -4
  24. package/dist/config.mjs.map +1 -1
  25. package/dist/contract.d.cts +62 -46
  26. package/dist/contract.d.cts.map +1 -1
  27. package/dist/contract.d.mts +62 -46
  28. package/dist/contract.d.mts.map +1 -1
  29. package/dist/index.cjs +1 -0
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.mts +2 -2
  32. package/dist/index.mjs +2 -2
  33. package/dist/merge.cjs +1 -2
  34. package/dist/merge.cjs.map +1 -1
  35. package/dist/merge.d.cts +1 -1
  36. package/dist/merge.d.cts.map +1 -1
  37. package/dist/merge.d.mts +1 -1
  38. package/dist/merge.d.mts.map +1 -1
  39. package/dist/merge.mjs +1 -2
  40. package/dist/merge.mjs.map +1 -1
  41. package/dist/near-cli.cjs +0 -23
  42. package/dist/near-cli.cjs.map +1 -1
  43. package/dist/near-cli.mjs +0 -23
  44. package/dist/near-cli.mjs.map +1 -1
  45. package/dist/plugin.cjs +9 -3
  46. package/dist/plugin.cjs.map +1 -1
  47. package/dist/plugin.d.cts +72 -50
  48. package/dist/plugin.d.mts +72 -50
  49. package/dist/plugin.mjs +9 -3
  50. package/dist/plugin.mjs.map +1 -1
  51. package/dist/shared-deps.cjs +201 -0
  52. package/dist/shared-deps.cjs.map +1 -0
  53. package/dist/shared-deps.mjs +200 -0
  54. package/dist/shared-deps.mjs.map +1 -0
  55. package/dist/types.cjs +14 -12
  56. package/dist/types.cjs.map +1 -1
  57. package/dist/types.d.cts +88 -40
  58. package/dist/types.d.cts.map +1 -1
  59. package/dist/types.d.mts +88 -40
  60. package/dist/types.d.mts.map +1 -1
  61. package/dist/types.mjs +14 -13
  62. package/dist/types.mjs.map +1 -1
  63. package/package.json +4 -4
  64. package/skills/extends-config/SKILL.md +7 -8
  65. package/skills/init-upgrade/SKILL.md +5 -2
  66. package/skills/publish-sync/SKILL.md +1 -1
  67. package/dist/shared.cjs +0 -155
  68. package/dist/shared.cjs.map +0 -1
  69. package/dist/shared.mjs +0 -154
  70. package/dist/shared.mjs.map +0 -1
@@ -136,7 +136,10 @@ function writeAuthTypesGen(targetPath, authExportPath) {
136
136
  " user: AuthSessionUser | null;",
137
137
  " session: AuthSessionData | null;",
138
138
  "};",
139
- "export type AuthRequestContext = RawAuthRequestContext;",
139
+ "export type AuthRequestContext = RawAuthRequestContext & {",
140
+ " organization?: { activeOrganizationId?: string | null } | null;",
141
+ " apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;",
142
+ "};",
140
143
  "export type AuthActiveMember = RawAuthActiveMember;",
141
144
  "export type AuthBaseSession = BaseAuth[\"$Infer\"][\"Session\"];",
142
145
  "export type AuthContractType = AuthContract;",
@@ -145,76 +148,53 @@ function writeAuthTypesGen(targetPath, authExportPath) {
145
148
  (0, node_fs.mkdirSync)((0, node_path.dirname)(targetPath), { recursive: true });
146
149
  writeFileIfChanged(targetPath, content);
147
150
  }
148
- function writeFallbackAuthTypesGen(targetPath) {
151
+ function writeContractBasedAuthTypesGen(targetPath, configDir) {
152
+ const authExportRel = toImportPath(targetPath, (0, node_path.join)(configDir, ".bos", "generated", "auth", "auth-export.d.ts"));
153
+ const contractRel = toImportPath(targetPath, (0, node_path.join)(configDir, ".bos", "generated", "auth", "contract.d.ts"));
149
154
  const content = [
150
- "import type { Auth } from \"better-auth\";",
151
- "export type { Auth } from \"better-auth\";",
152
- "export type AuthSession = Auth[\"$Infer\"][\"Session\"];",
153
- "export type AuthSessionData = AuthSession;",
154
- "export type AuthSessionUser = NonNullable<AuthSession[\"user\"]>;",
155
- "export interface AuthOrganizationContext {",
156
- " activeOrganizationId: string | null;",
157
- " organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;",
158
- " member: { id: string; role: string } | null;",
159
- " isPersonal: boolean;",
160
- " hasOrganization: boolean;",
161
- "}",
162
- "export interface AuthRequestContext {",
163
- " user: AuthSessionUser | null;",
164
- " userId: string | null;",
165
- " isAuthenticated: boolean;",
166
- " authMethod: \"session\" | \"apiKey\" | \"anonymous\" | \"none\";",
167
- " near: {",
168
- " primaryAccountId: string | null;",
169
- " linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;",
170
- " hasNearAccount: boolean;",
171
- " };",
172
- " organization: AuthOrganizationContext;",
173
- " organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;",
174
- "}",
175
- "export type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };",
176
- "export type AuthOrganization = {",
177
- " id: string;",
178
- " name: string;",
179
- " slug: string;",
180
- " logo?: string | null;",
181
- " metadata?: Record<string, unknown> | null;",
182
- " createdAt: Date;",
155
+ `export type {`,
156
+ ` Auth,`,
157
+ ` AuthOrganizationContext,`,
158
+ ` AuthOrganization,`,
159
+ ` AuthOrganizationSummary,`,
160
+ ` AuthOrganizationMember,`,
161
+ ` AuthApiKey,`,
162
+ ` AuthInvitation,`,
163
+ ` GetActiveMemberInput,`,
164
+ ` GetOrganizationInput,`,
165
+ ` ListMembersInput,`,
166
+ ` ListInvitationsInput,`,
167
+ ` ListApiKeysInput,`,
168
+ ` AuthServices,`,
169
+ ` createAuthInstance,`,
170
+ `} from "${authExportRel}";`,
171
+ `import type { InferOutput, ContractType as AuthContract } from "${contractRel}";`,
172
+ `import type { Auth as BaseAuth } from "${authExportRel}";`,
173
+ "",
174
+ "type RawAuthSession = InferOutput<\"getSession\">;",
175
+ "type RawAuthRequestContext = InferOutput<\"getContext\">;",
176
+ "type RawAuthActiveMember = InferOutput<\"getActiveMember\">;",
177
+ "",
178
+ "export type AuthSessionUser = NonNullable<RawAuthSession[\"user\"]> & {",
179
+ " role?: string | null;",
180
+ " isAnonymous?: boolean | null;",
181
+ " walletAddress?: string | null;",
182
+ " banned?: boolean | null;",
183
183
  "};",
184
- "export type AuthOrganizationSummary = NonNullable<AuthOrganizationContext[\"organization\"]>;",
185
- "export type AuthOrganizationMember = NonNullable<AuthOrganizationContext[\"member\"]>;",
186
- "export type AuthApiKey = {",
187
- " id: string;",
188
- " name: string | null;",
189
- " prefix: string | null;",
190
- " start: string | null;",
191
- " expiresAt: Date | null;",
192
- " createdAt: Date;",
193
- " updatedAt: Date;",
194
- " metadata: unknown | null;",
195
- " permissions: Record<string, string[]> | null;",
184
+ "export type AuthSessionData = NonNullable<RawAuthSession[\"session\"]> & {",
185
+ " activeOrganizationId?: string | null;",
196
186
  "};",
197
- "export type AuthInvitation = {",
198
- " id: string;",
199
- " organizationId: string;",
200
- " email: string;",
201
- " role: string | null;",
202
- " status: string;",
203
- " expiresAt: Date;",
204
- " inviterId: string;",
187
+ "export type AuthSession = {",
188
+ " user: AuthSessionUser | null;",
189
+ " session: AuthSessionData | null;",
205
190
  "};",
206
- "export type GetActiveMemberInput = { organizationId?: string };",
207
- "export type GetOrganizationInput = { id: string };",
208
- "export type ListMembersInput = { organizationId: string };",
209
- "export type ListInvitationsInput = { organizationId: string };",
210
- "export type ListApiKeysInput = { organizationId?: string };",
211
- "export type createAuthInstance = never;",
212
- "export interface AuthServices {",
213
- " auth: Auth;",
214
- " db: unknown;",
215
- " driver: { close(): Promise<void> };",
216
- " handler: (req: Request) => Promise<Response>;",
217
- "}",
191
+ "export type AuthRequestContext = RawAuthRequestContext & {",
192
+ " organization?: { activeOrganizationId?: string | null } | null;",
193
+ " apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;",
194
+ "};",
195
+ "export type AuthActiveMember = RawAuthActiveMember;",
196
+ "export type AuthBaseSession = BaseAuth[\"$Infer\"][\"Session\"];",
197
+ "export type AuthContractType = AuthContract;",
218
198
  ""
219
199
  ].join("\n");
220
200
  (0, node_fs.mkdirSync)((0, node_path.dirname)(targetPath), { recursive: true });
@@ -315,7 +295,7 @@ function writeGeneratedFiles(opts) {
315
295
  const hostLibDir = (0, node_path.join)(opts.configDir, "host", "src", "lib");
316
296
  if ((0, node_fs.existsSync)((0, node_path.join)(opts.configDir, "host", "src"))) authTypeTargets.push((0, node_path.join)(hostLibDir, "auth-types.gen.ts"));
317
297
  if (opts.authExportPath) for (const authTypesPath of authTypeTargets) writeAuthTypesGen(authTypesPath, opts.authExportPath);
318
- else if (opts.authSource) for (const authTypesPath of authTypeTargets) writeFallbackAuthTypesGen(authTypesPath);
298
+ else if (opts.authSource) for (const authTypesPath of authTypeTargets) writeContractBasedAuthTypesGen(authTypesPath, opts.configDir);
319
299
  return uiContractPath;
320
300
  }
321
301
  async function syncApiContractBridge(opts) {
@@ -1 +1 @@
1
- {"version":3,"file":"api-contract.cjs","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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qB,KAAK,YAAY,QAAQ,mBAAmB;AACvE,+CAAkB,cAAc,EAAE,EAAE,WAAW,MAAM,CAAC;AACtD,oBAAmB,eAAe,QAAQ;AAE1C,QAAO;;AAGT,SAAS,kBAAkB,YAAoB,gBAAwB;CACrE,MAAM,mBAAmB,aAAa,YAAY,eAAe;CACjE,MAAM,UAAU;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW,iBAAiB;EAC5B,mEAAmE,aAAa,uDAAyB,eAAe,EAAE,gBAAgB,CAAC,CAAC;EAC5I,0CAA0C,iBAAiB;EAC3D;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;AACZ,+CAAkB,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,oBAAmB,YAAY,QAAQ;;AAGzC,SAAS,0BAA0B,YAAoB;CACrD,MAAM,UAAU;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;AACZ,+CAAkB,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,oBAAmB,YAAY,QAAQ;;AAGzC,eAAe,sBAAsB,MAQT;AAC1B,KAAI,KAAK,QAAQ,OAAO;EACtB,MAAM,YAAY,KAAK,UAAU,eAAe,KAAK,SAAS,KAAK,OAAO,YAAY;AACtF,MAAI,aAAa,QAAQ,cAAc,GACrC,QAAO;GACL,KAAK,KAAK;GACV,YAAY;GACZ,oCAAqB,WA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"}
1
+ {"version":3,"file":"api-contract.cjs","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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"}
@@ -135,7 +135,10 @@ function writeAuthTypesGen(targetPath, authExportPath) {
135
135
  " user: AuthSessionUser | null;",
136
136
  " session: AuthSessionData | null;",
137
137
  "};",
138
- "export type AuthRequestContext = RawAuthRequestContext;",
138
+ "export type AuthRequestContext = RawAuthRequestContext & {",
139
+ " organization?: { activeOrganizationId?: string | null } | null;",
140
+ " apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;",
141
+ "};",
139
142
  "export type AuthActiveMember = RawAuthActiveMember;",
140
143
  "export type AuthBaseSession = BaseAuth[\"$Infer\"][\"Session\"];",
141
144
  "export type AuthContractType = AuthContract;",
@@ -144,76 +147,53 @@ function writeAuthTypesGen(targetPath, authExportPath) {
144
147
  mkdirSync(dirname(targetPath), { recursive: true });
145
148
  writeFileIfChanged(targetPath, content);
146
149
  }
147
- function writeFallbackAuthTypesGen(targetPath) {
150
+ function writeContractBasedAuthTypesGen(targetPath, configDir) {
151
+ const authExportRel = toImportPath(targetPath, join(configDir, ".bos", "generated", "auth", "auth-export.d.ts"));
152
+ const contractRel = toImportPath(targetPath, join(configDir, ".bos", "generated", "auth", "contract.d.ts"));
148
153
  const content = [
149
- "import type { Auth } from \"better-auth\";",
150
- "export type { Auth } from \"better-auth\";",
151
- "export type AuthSession = Auth[\"$Infer\"][\"Session\"];",
152
- "export type AuthSessionData = AuthSession;",
153
- "export type AuthSessionUser = NonNullable<AuthSession[\"user\"]>;",
154
- "export interface AuthOrganizationContext {",
155
- " activeOrganizationId: string | null;",
156
- " organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;",
157
- " member: { id: string; role: string } | null;",
158
- " isPersonal: boolean;",
159
- " hasOrganization: boolean;",
160
- "}",
161
- "export interface AuthRequestContext {",
162
- " user: AuthSessionUser | null;",
163
- " userId: string | null;",
164
- " isAuthenticated: boolean;",
165
- " authMethod: \"session\" | \"apiKey\" | \"anonymous\" | \"none\";",
166
- " near: {",
167
- " primaryAccountId: string | null;",
168
- " linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;",
169
- " hasNearAccount: boolean;",
170
- " };",
171
- " organization: AuthOrganizationContext;",
172
- " organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;",
173
- "}",
174
- "export type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };",
175
- "export type AuthOrganization = {",
176
- " id: string;",
177
- " name: string;",
178
- " slug: string;",
179
- " logo?: string | null;",
180
- " metadata?: Record<string, unknown> | null;",
181
- " createdAt: Date;",
154
+ `export type {`,
155
+ ` Auth,`,
156
+ ` AuthOrganizationContext,`,
157
+ ` AuthOrganization,`,
158
+ ` AuthOrganizationSummary,`,
159
+ ` AuthOrganizationMember,`,
160
+ ` AuthApiKey,`,
161
+ ` AuthInvitation,`,
162
+ ` GetActiveMemberInput,`,
163
+ ` GetOrganizationInput,`,
164
+ ` ListMembersInput,`,
165
+ ` ListInvitationsInput,`,
166
+ ` ListApiKeysInput,`,
167
+ ` AuthServices,`,
168
+ ` createAuthInstance,`,
169
+ `} from "${authExportRel}";`,
170
+ `import type { InferOutput, ContractType as AuthContract } from "${contractRel}";`,
171
+ `import type { Auth as BaseAuth } from "${authExportRel}";`,
172
+ "",
173
+ "type RawAuthSession = InferOutput<\"getSession\">;",
174
+ "type RawAuthRequestContext = InferOutput<\"getContext\">;",
175
+ "type RawAuthActiveMember = InferOutput<\"getActiveMember\">;",
176
+ "",
177
+ "export type AuthSessionUser = NonNullable<RawAuthSession[\"user\"]> & {",
178
+ " role?: string | null;",
179
+ " isAnonymous?: boolean | null;",
180
+ " walletAddress?: string | null;",
181
+ " banned?: boolean | null;",
182
182
  "};",
183
- "export type AuthOrganizationSummary = NonNullable<AuthOrganizationContext[\"organization\"]>;",
184
- "export type AuthOrganizationMember = NonNullable<AuthOrganizationContext[\"member\"]>;",
185
- "export type AuthApiKey = {",
186
- " id: string;",
187
- " name: string | null;",
188
- " prefix: string | null;",
189
- " start: string | null;",
190
- " expiresAt: Date | null;",
191
- " createdAt: Date;",
192
- " updatedAt: Date;",
193
- " metadata: unknown | null;",
194
- " permissions: Record<string, string[]> | null;",
183
+ "export type AuthSessionData = NonNullable<RawAuthSession[\"session\"]> & {",
184
+ " activeOrganizationId?: string | null;",
195
185
  "};",
196
- "export type AuthInvitation = {",
197
- " id: string;",
198
- " organizationId: string;",
199
- " email: string;",
200
- " role: string | null;",
201
- " status: string;",
202
- " expiresAt: Date;",
203
- " inviterId: string;",
186
+ "export type AuthSession = {",
187
+ " user: AuthSessionUser | null;",
188
+ " session: AuthSessionData | null;",
204
189
  "};",
205
- "export type GetActiveMemberInput = { organizationId?: string };",
206
- "export type GetOrganizationInput = { id: string };",
207
- "export type ListMembersInput = { organizationId: string };",
208
- "export type ListInvitationsInput = { organizationId: string };",
209
- "export type ListApiKeysInput = { organizationId?: string };",
210
- "export type createAuthInstance = never;",
211
- "export interface AuthServices {",
212
- " auth: Auth;",
213
- " db: unknown;",
214
- " driver: { close(): Promise<void> };",
215
- " handler: (req: Request) => Promise<Response>;",
216
- "}",
190
+ "export type AuthRequestContext = RawAuthRequestContext & {",
191
+ " organization?: { activeOrganizationId?: string | null } | null;",
192
+ " apiKey?: { id: string; permissions?: Record<string, string[]> | null } | null;",
193
+ "};",
194
+ "export type AuthActiveMember = RawAuthActiveMember;",
195
+ "export type AuthBaseSession = BaseAuth[\"$Infer\"][\"Session\"];",
196
+ "export type AuthContractType = AuthContract;",
217
197
  ""
218
198
  ].join("\n");
219
199
  mkdirSync(dirname(targetPath), { recursive: true });
@@ -314,7 +294,7 @@ function writeGeneratedFiles(opts) {
314
294
  const hostLibDir = join(opts.configDir, "host", "src", "lib");
315
295
  if (existsSync(join(opts.configDir, "host", "src"))) authTypeTargets.push(join(hostLibDir, "auth-types.gen.ts"));
316
296
  if (opts.authExportPath) for (const authTypesPath of authTypeTargets) writeAuthTypesGen(authTypesPath, opts.authExportPath);
317
- else if (opts.authSource) for (const authTypesPath of authTypeTargets) writeFallbackAuthTypesGen(authTypesPath);
297
+ else if (opts.authSource) for (const authTypesPath of authTypeTargets) writeContractBasedAuthTypesGen(authTypesPath, opts.configDir);
318
298
  return uiContractPath;
319
299
  }
320
300
  async function syncApiContractBridge(opts) {