Repository navigation
feat(portal): build a portal from the spec folders APIMATIC-META.json merges - #435
Merged
Merged
Conversation
… merges `portal generate` and `portal serve` read only the documents at the top of `src/spec`, so the layout the platform merges several APIs from, a folder to each API and an `APIMATIC-META.json` beside them, failed with "No OpenAPI 3.x document found". When `APIMATIC-META.json` turns on `MergeApis`, the portal now reads the folders it merges, in the order `MergeOrderOfDirectories` lists them or else every folder by name, one OpenAPI document to a folder and a section named after the folder. Refused, each with its own message: a merged folder with no document to read (empty, missing or outside `src/spec`), a merged folder with two OpenAPI documents, and an `APIMATIC-META.json` that is not JSON. Only the exact name `APIMATIC-META.json` is read. Warned, and built: - several documents at the top of `src/spec` that nothing merges, as the SDKs are built from one; - an API definition left at the top of `src/spec` while its folders are merged, which the portal and the SDKs leave out; - an operation that more than one definition declares: its SDK samples are left out, since the samples hold one per method and path and would show another API's call. The `portal generate` and `portal serve` help, the README and the Live preview note describe the layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows the review of the merged spec folders: - An operation that one spec declares twice, as a path item's own method beside its `$ref` does, no longer counts as shared: a single-spec project kept losing its SDK sample. Pages sharing an address and specs sharing an operation are now one `Shared` type and one grouping. - `APIMATIC-META.json` is read as the platform reads it: setting names in any case, and `MergeApis` as `true` or `"true"`. - A merged folder with more than one OpenAPI document at its top is still refused, now with where to move shared parts: the platform builds the folder from the first file by name, which may be the shared parts. Shared parts at the top of `src/spec` are no longer warned as left out. - Hidden files such as `.gitkeep` are never read as API definitions. - A merged folder the platform would not find is refused: `.` (`src/spec` itself), and a name in another case than the folder's on disk. - `portal serve` reloads on any change in `src/spec`, so shared parts in a folder of their own reload the preview too. - A metadata file that merges where `src/spec` has no folders is its own problem, and the sentence about `MergeOrderOfDirectories` lives once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A merged folder counts every file with a version key as a candidate definition, as the platform does, so a Swagger or other definition beside the OpenAPI 3.x document is refused too. The conversion advice says to move the converted file up in place of the original, which would otherwise be such a second definition. - Two ideas named apart on `OpenApiDocument`: `namesApiFormat` (what the platform may take as a folder's definition) and `declaresOperations` (paths, webhooks or channels). The left-out warning needs both, so an AsyncAPI or webhooks-only definition at the top of `src/spec` is named again. - Folders `MergeOrderOfDirectories` names that the platform would not find (missing, in another case, outside `src/spec`, or `.`) are their own problem, checked where the order is read; `emptyMergedFolders` keeps the folders that are there and hold nothing. - `APIMATIC-META.json` prefers a setting's exact name over one in another case. - `DirectoryPath.contains` takes a folder named `..v2` for one inside, not a step up. - An operation one spec declares twice is read once where its endpoints are collected, and `shared()` is a plain grouping again. - The preview reloads only for `.json`, `.yaml` and `.yml` files in `src/spec`, by a list a test holds to the CLI's; `SPEC_EXTENSIONS` lives in `src/types/project-layout.ts`. - `severalSpecsInFolder` carries its folder; a read document is a spec yet to be given its slug; one helper gives a page's slugs and address; no restating comments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…docs The advice to merge folders, in the error for a `src/spec` with only folders, the warning for several specs nothing merges, and the `portal generate` help, no longer links the docs. It names the setting by its place in `APIMATIC-META.json`, `MergeConfiguration.MergeApis`, which the link was left to say: a `MergeApis` at the top of the file merges nothing. `MERGE_SETTINGS` gains `configuration`, which the file reader uses too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
mrafnadeem-apimatic
approved these changes
Oct 14, 2026
Merged
|
🎉 This PR is included in version 2.0.0-beta.6 🎉 The release is available on: Your semantic-release bot 📦🚀 |
saeedjamshaid
added a commit
that referenced
this pull request
Oct 16, 2026
…ec-errors #435 rewrote the same spec reading. Its folder discovery is kept, and every file it reads goes through this branch's reader, so the documents of a merged folder get the `$ref` checks and the reasons. #435's check for an operation declared twice moves into `SpecBundle.endpoints()`, with a test there, and the `specDirectory` both branches added is kept once. Serve's warnings now hold when `APIMATIC-META.json` changes which folders merge: the documents are named by their path from `spec/` and said to be "now read" or "no longer read", and a refused specification says the preview "shows what it can still read". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.



The problem
To build SDKs from several APIs, the platform wants a folder to each API in
src/specand anAPIMATIC-META.jsonbeside the folders whoseMergeConfigurationturns onMergeApis.sdk generateworks with that layout, butportal generateandportal serveread only the documents at the top ofsrc/spec. With the metadata file the only file there, both stopped with:So one input could not give both the SDKs and the portal. Flattening the specs into
src/speclet the portal build, but then nothing merges them, and the SDKs and their code samples cover one of the specs only, without a word.Tracked in apimatic-io issue 2297.
What changes
src/spec/APIMATIC-META.jsonturns onMergeApis(setting names in any case, andtrueor"true", as the platform accepts them), the portal reads the folders it merges:MergeOrderOfDirectorieslists, in its order, or every folder by name when it lists none (an empty list included, as on the platform); a folder listed twice is read once;$reffiles anywhere. Any file there with a version key counts as a candidate, in whatever format, as on the platform; files below the top, the folder's own metadata file and hidden files such as.gitkeepdo not;orders.v2becomesorders-v2). The sidebar lists sections by name;content/api/nav.jsonreorders them, as it already did.APIMATIC-META.jsonis read. Other names the platform also accepts are treated as any other file.MergeOrderOfDirectoriesnames that the platform would not find: missing, named in another case than on disk, outsidesrc/spec, orsrc/specitself (.);APIMATIC-META.jsonthat is not JSON;src/spechas no folders.src/specthat nothing merges, since the SDKs are built from one of them;src/specwhile its folders are merged, which the platform leaves out of the SDKs and the portal leaves out too; shared parts kept there are not named;$ref, counts once.portal servereloads on any change to a.json,.yamlor.ymlfile insrc/spec, so parts a merged folder refers to in a folder of their own reload the preview too.portal.config.jsoncarriesspecDirfor it.api transformis told to write beside it, in a merged folder as at the top ofsrc/spec; the converted file is moved up in place of the original. An unreadable document is named by its path.portal generatedescribes the layout, andportal serve, its Live preview note and the README say that changing which foldersAPIMATIC-META.jsonmerges needs the preview restarted, as changing the documents insrc/specdoes.Sharedtype and one grouping;FileName.isEqualreplaces threecompare(...) === 0;FileName.slugified,FileName.isHidden,DirectoryPath.compare,DirectoryPath.isAncestorOf,Endpoint.isEqual,OpenApiDocument.namesApiFormat/declaresOperationsandFileService.directorySpelledOnDiskare new;DirectoryPath.containsno longer takes a folder named..v2for a step up; the "list these files in a sentence" idiom insrc/prompts/portal/source.tsis onelisted()helper instead of seven copies;METADATA_FILE_NAMEandSPEC_EXTENSIONSlive insrc/types/project-layout.ts.What it prints
How the platform reads a merged folder
Probed with
apimatic sdk generatefrom this branch, withspec/alphaholding:components.yaml(an OpenAPI document of shared parts) andopenapi.jsoncomponents.yamlopenapi.jsonandzparts.json, orZparts.jsonopenapi.jsoncomponents.jsonwith no version key, andopenapi.jsonopenapi.jsona.jsonandb.json, both full APIsa.json;b.jsonis dropped without a warningcommon/components.json(shared parts, in a folder sorting first) andopenapi.jsonopenapi.jsonMergeOrderOfDirectories: ["Alpha"]with a folder namedalphamergeConfiguration/mergeApisin lower case, or"MergeApis": "true"MergeOrderOfDirectories: []MergeOrderOfDirectoriesTesting
pnpm test: 1853 passing, 67 pending, ESLint clean. New tests cover the metadata file, discovery of merged folders and every refusal and warning, the messages, the samples left off shared operations, the preview's reload, and the new value-object methods.APIMATIC_E2E=1: 65 build and 2 serve cases passing. A new fixture merges two folders that both declareGET /status, one of them keeping a schema in a file of its own folder. It checks a section and a page per operation, each API's own sample and server, no SDK sample on either/statuspage (this case fails with the filter taken out), and the schema read from the other file.portal generateruns against the platform, with the CLI built from this branch:GET /status: the warning, no SDK call on either/statuspage, and the other operations' samples in place;"true", shared parts in a folder inside a merged folder, and a single spec with a method beside its path item's$ref: each builds, with samples on every page and no warning about the specs;.folders, a metadata file merging no folders, a flat two-spec project and a spec left at the top beside merged folders: each prints what is shown above.portal serveon a merged fixture whose spec refers tospec/common/pet.json: a.DS_Storewritten intospec/sent the open preview nothing, and savingpet.jsonsent it a full reload.Not in this PR
🤖 Generated with Claude Code