feat(connector-openapi): resolve providerConfig.spec from a package-relative file path (#3016)#3024
Merged
Merged
Conversation
…elative file path (#3016) ADR-0096 follow-up: complete the spec union (inline object | file path | remote URL) for the declarative openapi provider. - spec: ConnectorProviderContext gains an optional host-injected loadPackageFile capability (pure type) - service-automation: packageRoot option + createPackageFileLoader with a root-confinement guard (rejects absolute and ..-escaping paths; lazy node:fs/node:path imports); capability injected into every provider ctx; failures follow the reconcile policy (fatal at boot, soft on reload) - connector-openapi: non-URL string specs are read via ctx.loadPackageFile and parsed as OpenAPI JSON with clear errors - cli: serve/dev anchor packageRoot to the objectstack.config.ts directory - tests: file-path happy path, missing file (fatal at boot / skipped on reload), traversal rejection; ADR-0096 scope-boundary note updated Closes #3016 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016eY7byWABTUPtJG7R2AEFU
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 4 package(s): 105 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
- spec: providerConfig describe/TSDoc now documents the spec union (inline object | package-relative file path | http(s) URL) so the auto-generated references pick it up - showcase: StatusOpenApiConnector — a provider: 'openapi' declarative instance whose OpenAPI document is referenced as a package-relative file path (src/system/connectors/status-openapi.json), materialized at boot by an option-less ConnectorOpenApiPlugin; getHealth dispatches GET /api/v1/health against the running server itself - coverage notes + stale connectors: comment updated (the collection has held provider-bound instances since ADR-0096, not only descriptors) Verified: booted the showcase (--fresh, random port); GET /api/v1/automation/connectors lists showcase_status_openapi (origin: declarative) with the getHealth action. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016eY7byWABTUPtJG7R2AEFU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3016(ADR-0096 后续项,承接 #2977 / #2994 / #3001)
背景
ADR-0096 的典型示例把 OpenAPI 实例写成
providerConfig: { spec: './billing-openapi.json' },但已落地的openapiprovider 工厂只接受内联文档对象或 http(s) URL,文件路径会被直接拒绝。本 PR 补全 spec 联合形态:内联对象 | 文件路径 | 远程 URL。设计
文件系统访问不放进 connector 包,而是由宿主注入能力(与 ADR-0096「provider 工厂只依赖
@objectstack/spec纯类型」的结构保持一致):@objectstack/spec—ConnectorProviderContext新增可选的loadPackageFile(relativePath)能力(纯类型,Prime Directive ✨ Set up Copilot instructions #2):按声明该 connector 的 stack/package 根目录解析相对路径并读取 UTF-8 文本;无文件系统的宿主(edge/browser)为undefined。另更新providerConfig的 describe/TSDoc,自动生成的 references 文档会带上 spec 三种形态。@objectstack/service-automation— 新增packageRoot插件选项(相对文件引用的解析基准,默认process.cwd())与导出的createPackageFileLoader(packageRoot):实现根目录约束(拒绝绝对路径与..逃逸路径,含 Windows 盘符形式);node:fs/node:path在闭包内懒加载,非 Node 宿主只有真正解引用文件时才会失败。materializeDeclaredConnectors将该能力注入每个 provider 工厂的 ctx。读取/解析失败沿用既有 reconcile 策略:启动时 fatal,reload 时跳过该条目(旧连接器继续服务)。@objectstack/connector-openapi— 非 URL 的字符串spec现在经ctx.loadPackageFile读取并按 OpenAPI JSON 解析;文件缺失/不可读、JSON 不可解析、宿主无文件访问能力各有清晰报错。@objectstack/cli—serve/dev把项目目录(objectstack.config.ts所在目录)作为 automation 服务的packageRoot传入,与 standalone sqlite 默认库的锚定方式一致。Showcase 示例(第二个提交)
新增
StatusOpenApiConnector:provider: 'openapi'声明式实例,OpenAPI 文档以包相对路径引用(src/system/connectors/status-openapi.json),由无参ConnectorOpenApiPlugin(只贡献 provider 工厂)在启动时物化;getHealth指向运行中的服务器自身GET /api/v1/health,零外部依赖。与既有rest内联实例(StatusApiConnector)互补,并同步修正了connectors:集合还是「纯 descriptor」时代的过期注释与 coverage 说明。实机验证:
--fresh随机端口启动 showcase,GET /api/v1/automation/connectors列出showcase_status_openapi(origin: declarative,actiongetHealth)。测试
connector-openapi/openapi-provider.test.ts:文件路径 happy path(经注入的 loader)、loader 失败透传、JSON 不可解析、宿主无文件访问;既有内联/URL 用例不变。service-automation/connector-materialization.test.ts:createPackageFileLoader单测(happy path、绝对路径拒绝、..逃逸拒绝、缺失文件报错含解析后路径);物化策略集成测试(工厂收到可用的loadPackageFile、缺失文件启动 fatal、逃逸路径启动 fatal、reload 软失败且旧连接器继续服务)。pnpm turbo test(spec / service-automation / connector-openapi / example-showcase)全绿;@objectstack/clibuild 通过。其他
🤖 Generated with Claude Code
https://claude.ai/code/session_016eY7byWABTUPtJG7R2AEFU