Documentation
¶
Overview ¶
Package monolith splits a single consolidated Jamf Pro OpenAPI document (e.g. the one served at /api/schema/) into per-resource spec files that match the layout expected by the rest of the generator pipeline.
Routing strategy: for each path in the monolith, look up the spec filename that currently owns it in specsDir. If found, route the path into that bucket. Otherwise fall back to a filename derived from the operation's first tag (with manual overrides in overrides.go).
Output: a shared library file (_MonolithLibrary.yaml) plus one file per bucket. For each component referenced by the monolith, the splitter counts how many buckets reach it transitively:
- Exclusive (1 bucket): inlined into that bucket's components block so the parser's resource.Schemas map contains it. Heuristics that scan declared schemas (e.g. detectNameField) see the same field set an upstream per-file spec would expose.
- Shared (2+ buckets): emitted to the library file; bucket refs to it are rewritten to external `_MonolithLibrary.yaml#/...` form.
This replicates the original per-file + shared-library layout used upstream, where each resource spec declared its own primary schemas locally and imported cross-resource definitions via external $refs.
Index ¶
Constants ¶
const AppInstallerSubtree = "/v1/app-installers"
AppInstallerSubtree is the path subtree ExtractSubtree derives the App Installer specs from, and AppInstallerSpecs routes its four families into one spec file each.
One tag covers all 23 operations upstream ("app-installers"), so tag-based routing cannot separate them, and the parser's own splitByPathFamilies is no help either: it fires only on sibling collection paths that each have a /{param} child, which titles and deployments have and global-settings does not — it would emit two resources named after their paths and drop the other two families' operations entirely. Hence an explicit route per family, whose filenames are the command names this CLI has shipped since the endpoints were reverse-engineered.
A path under the subtree that no route owns is an error, not a warning: a new family is a spec file whose name is a judgement call, and dropping it would lose the endpoint with nothing to notice.
const LibraryFilename = "_MonolithLibrary.yaml"
LibraryFilename is the shared components file emitted by Split. Contains "Library" so the parser's non-resource file skip logic ignores it during resource extraction.
Variables ¶
var AppInstallerSpecs = []SubtreeSpec{
{
Prefix: "/v1/app-installers",
Filename: "AppInstallers.yaml",
Title: "Jamf Pro API - App Installers",
Description: "Reports whether the App Installers feature is available on this instance, and which App Installer features the Cloud Services Connection enables.",
},
{
Prefix: "/v1/app-installers/titles",
Filename: "AppInstallerTitles.yaml",
Title: "Jamf Pro API - App Installer Titles",
Description: "Browse the Jamf App Catalog of available App Installer titles and their versions. Titles are read-only catalog entries provided by Jamf.",
},
{
Prefix: "/v1/app-installers/deployments",
Filename: "AppInstallerDeployments.yaml",
Title: "Jamf Pro API - App Installer Deployments",
Description: "Deploy App Installer titles to computers, manage each deployment's version and update behaviour, and read per-computer installation state.",
},
{
Prefix: "/v1/app-installers/global-settings",
Filename: "AppInstallerGlobalSettings.yaml",
Title: "Jamf Pro API - App Installer Global Settings",
Description: "Global settings for App Installer deployments, controlling end-user experience notifications and deployment process controls.",
},
}
var DroppedTags = map[string]bool{ "mobile-device-extension-attributes-preview": true, "devices": true, "user-session-preview": true, }
DroppedTags lists tags whose paths must never be emitted, even if present in the monolith. Used for legacy/preview endpoints that would collide with canonical resources.
var PreservedSpecs = map[string]bool{ "AppInstallers.yaml": true, "AppInstallerDeployments.yaml": true, "AppInstallerGlobalSettings.yaml": true, "AppInstallerTitles.yaml": true, }
PreservedSpecs lists spec filenames (relative to specs/) that the splitter must not touch. Their paths are also treated as invisible to the splitter: any matching path in the monolith is dropped in favour of the preserved file's hand-maintained definition.
Use this for specs sourced outside the public monolith (e.g. private or preview endpoints that only ship in internal documentation).
var TagFilenameOverrides = map[string]string{}
TagFilenameOverrides maps an OpenAPI tag to the spec filename that should be produced for it when a matching path is NOT already present in the existing specs/ layout. This only fires for **new** tags/paths that the path-based layout cannot place automatically.
Keyed by tag name (kebab form, as it appears in the monolith spec). Value is the basename (with .yaml extension) that the splitter should write.
Leave empty until an upstream rename or genuinely new tag requires an explicit mapping. Most tags map cleanly to a PascalCase-singular filename derived from the tag itself.
Functions ¶
func ExtractSubtree ¶ added in v1.28.0
func ExtractSubtree(source, specsDir, subtree string, specs []SubtreeSpec) ([]string, []string, error)
ExtractSubtree derives per-resource spec files for one subtree of a consolidated Jamf Pro OpenAPI document, leaving every other file in specsDir alone.
This exists because one Jamf Pro surface is published only on the gateway. App Installers sits under hiddenapi/ in jamf/jss, so the jss bundle and the instance's own /api/schema/ monolith both exclude it, and the specs this repo generated its commands from were reverse-engineered for exactly that reason. public-apis-oas#430 published all 23 operations into the gateway's Jamf Pro API spec on 2026-09-03, which is the SDK's api/pro_api.json — the same file gateway coverage is derived from. So the authoritative spec now arrives with the coverage sync, and these files are derived from it rather than maintained by hand.
It is deliberately not Split. Split owns the whole of specsDir: it wipes every root *.yaml, routes every path in the document, and partitions components into a shared _MonolithLibrary.yaml. Handing it pro_api.json would regenerate all 164 specs from the gateway's version-filtered view of the Pro API and delete the commands that view has withdrawn. This walks one subtree, writes only the files it is given, and inlines each bucket's whole component closure so the files are self-contained — a shared library would entangle them with Split's wipe-and-regenerate contract, and PreservedSpecs' $ref scan with it.
Three transforms turn a gateway-published operation into a Pro-direct one. Each is a property of the publication rather than of the endpoint, so it is applied here rather than corrected by hand afterwards:
- Header parameters are dropped. The gateway declares X-Tenant-Id on every operation; it is the scope this CLI's own client stamps on a request (client.setScopeHeader), never a flag a user supplies, and the parser turns a declared parameter into one.
- x-required-privileges-legacy is promoted over x-required-privileges. A Pro command's jamf:privileges annotation speaks Jamf Pro API-role prose ("Read Mac Applications"); the gateway spec's x-required-privileges is the GA capability vocabulary ("applications:read"), which reaches the same command through specs/gateway/coverage.json as jamf:gateway-privileges. Publishing the slug as the Pro privilege would send an operator to a console where that grant does not exist — the same class of wrong answer the two-vocabulary split in internal/privileges exists to prevent.
- x-action is stamped on any operation whose path is deeper than its collection path and whose terminal segment is a literal. jss carries x-action and the gateway publication drops it, and the parser needs it to name an operation after its verb: without it POST .../version-update, POST .../installation-retry (both forms) and POST .../deployments all infer "create" and collide, and GET .../titles/{id}/versions collides with the canonical get. Precedent for a GET carrying it is in the repo's own specs (ComputerPrestageScopeV2, PatchSoftwareTitleConfigurations).
Returns the files written (sorted) and any warnings — an operation with no legacy privilege list is reported rather than silently published with the gateway's slug.
func Split ¶
Split reads an OpenAPI monolith (JSON or YAML) from monolithSource and writes per-resource spec files into specsDir. monolithSource may be a local file path OR an http(s):// URL; URLs are fetched anonymously. Existing *.yaml files at the root of specsDir are removed; subdirectories (classic/) are left untouched. Files listed in PreservedSpecs (and any library files they depend on) are also left in place.
Returns the list of written file paths (sorted) and any routing warnings encountered (e.g. new paths that did not match the existing layout).
Types ¶
type SubtreeSpec ¶ added in v1.28.0
SubtreeSpec routes one branch of a path subtree into its own per-resource spec file. Prefix is the collection path the file owns; the longest matching prefix wins, so a parent and its children can both be declared.