Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/production-spec-global-volumes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@runpod/typescript-api-sdk': minor
---

Resync the vendored production spec and regenerate the types. Adds the global-volume operations (`/v2/global-volumes` list, create, get, update, delete) and `GET /v2/organization`, `global` mounts on pods, `mounts` on endpoints, and the `pagination` block on the cluster and network-volume list responses. All additive upstream, so existing calls keep their current types. `listClusters` and `listNetworkVolumes` now return one page (default `limit` 1000) instead of every resource; follow `pagination.nextCursor` until `hasNextPage` is false.
36 changes: 30 additions & 6 deletions scripts/fix_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,17 @@ def ignore_aliases(self, data):
return True


# Characters YAML reads as line breaks besides \n. Unescaped in a plain,
# single-quoted or block scalar they fold to a space on reload (the 2026-10
# global-volume `name` pattern ends in a raw U+0085), so such strings are
# double-quoted, where the emitter escapes them as \N, \L and \P.
YAML_EXTRA_BREAKS = re.compile("[\x85\u2028\u2029]")


def represent_str(dumper, value):
"""Multi-line text stays readable; ambiguous scalars get quoted."""
if YAML_EXTRA_BREAKS.search(value):
return dumper.represent_scalar(STR_TAG, value, style='"')
if "\n" in value.rstrip("\n"):
# Author-chosen line breaks (bullet lists, PATCH-semantics blocks).
return dumper.represent_scalar(STR_TAG, value, style="|")
Expand Down Expand Up @@ -403,14 +412,29 @@ def name_enum_constants(spec: dict) -> int:
# external API consumers; the contract half is what callers need.
(
("components", "schemas", "Mounts", "description"),
"At-most-one of `persistent` or\n`network` may be set today (mutually exclusive, enforced at the\n"
"handler with 400 if both are present). The `network` field is an\n"
"array for forward compatibility with eventual multi-network-volume\n"
"support, but `maxItems` is 1 today.",
"At most one of `persistent` or\n`network` may be set: sending both is rejected with 400. The\n"
"`network` field is an array for forward compatibility with\n"
"`persistent` is mutually exclusive\nwith both `network` and `global` (enforced at the handler with 400 if\n"
"combined). The `network` field is an array for forward compatibility\n"
"with eventual multi-network-volume support, but `maxItems` is 1 today.",
"`persistent` is mutually exclusive\nwith both `network` and `global`: combining them is rejected with 400.\n"
"The `network` field is an array for forward compatibility with\n"
"multi-network-volume support; `maxItems` is 1.",
),
(
("components", "schemas", "BaseMounts", "description"),
"At-most-one\nof `persistent` or `network` may be set today (mutually exclusive,\n"
"enforced at the handler with 400 if both are present). The `network`\n"
"field is an array for forward compatibility with eventual\n"
"multi-network-volume support, but `maxItems` is 1 today. Left open so\n"
"that concrete schemas can extend it and close themselves.",
"At most one\nof `persistent` or `network` may be set: combining them is rejected\n"
"with 400. The `network` field is an array for forward compatibility\n"
"with multi-network-volume support; `maxItems` is 1.",
),
(
("components", "schemas", "EndpointMount", "description"),
"always at `/runpod-volume`. Custom\npaths are not supported yet.",
"always at `/runpod-volume`.",
),
(
("components", "schemas", "TemplateMounts", "description"),
"Templates support only a\nsingle persistent mount today; any `network` property is rejected\n"
Expand Down
19 changes: 19 additions & 0 deletions scripts/test_fix_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ def test_yaml_11_boolean_strings_survive_a_round_trip(self):
)
self.assertEqual(reloaded, spec)

def test_extra_yaml_line_breaks_survive_a_round_trip(self):
# The 2026-10 global-volume `name` pattern ends in a raw U+0085. YAML
# reads NEL, LS and PS as line breaks, so unescaped they fold to a
# space on reload and the pattern silently changes.
pattern = "[^\\p{Z}\\t-\\r\x85]"
spec = {
"openapi": "3.1.0",
"paths": {},
"components": {
"schemas": {
"Name": {"type": "string", "pattern": pattern},
"Prose": {"description": "a\u2028b\u2029c"},
}
},
}
text = dump_spec(spec)
for reader in (SpecLoader, yaml.SafeLoader):
self.assertEqual(yaml.load(text, Loader=reader), spec, reader.__name__)

def test_stock_pyyaml_shows_why_the_loader_is_needed(self):
# The bug this guards against, spelled out: plain `OFF` is false in 1.1.
self.assertIs(yaml.safe_load("enum: [OFF]")["enum"][0], False)
Expand Down
Loading
Loading