Skip to content

make SpaceRid and ProjectRid assignable to FolderRid - #303

Open
KuberSethi wants to merge 2 commits into
mainfrom
ksethi/rid-subtyping
Open

make SpaceRid and ProjectRid assignable to FolderRid#303
KuberSethi wants to merge 2 commits into
mainfrom
ksethi/rid-subtyping

Conversation

@KuberSethi

Copy link
Copy Markdown

Before this PR

In @osdk/foundry.filesystem, SpaceRid and ProjectRid are disjoint branded types from FolderRid, so users have to write a cast to call methods that accept any folder-typed rid:

await Folders.children(client, space.rid as FolderRid, { preview: true });

This is inconsistent with the documented domain — the same package defines:

export type FolderType = "FOLDER" | "SPACE" | "PROJECT";

A Space is a Folder, and a Project is a Folder. The type system should reflect that.

After this PR

A SpaceRid or ProjectRid is now assignable to FolderRid with no cast:

const { data: spaces } = await Spaces.list(client, { preview: true });
const { data: children } = await Folders.children(client, spaces[0].rid, { preview: true });

Sibling rids remain mutually non-assignable, plain strings still flow into all three (loose brand preserved), and FolderRid → SpaceRid is still a type error.

• encode the IS-A relationship in the platform-sdk-generator via a small RID_SUBTYPES table; when a parent rid is emitted, its LooselyBrandedString brand union is widened to include its declared children
• apply the resulting shape to FolderRid in @osdk/foundry.filesystem: `LooselyBrandedString<"FolderRid" | "SpaceRid" | "ProjectRid">`
• children (SpaceRid, ProjectRid) stay as single-brand LooselyBrandedString so siblings don't collapse into each other

Possible downsides?

This is strictly type-widening on FolderRid and behaviorally unchanged at runtime — the brand property is phantom (`__LOOSE_BRAND?: T` is never set on a runtime string). No existing code that compiled before should fail to compile.

a space and a project are both folders in the filesystem domain
(FolderType = "FOLDER" | "SPACE" | "PROJECT"), so generated SDK
callers no longer have to write `space.rid as FolderRid` to call
Folders.children, Folders.get, etc.

• encode the IS-A relationship in the platform-sdk-generator by widening a
  parent rid's LooselyBrandedString brand union to include its children
• regenerate FolderRid in @osdk/foundry.filesystem so it accepts SpaceRid
  and ProjectRid; siblings stay mutually non-assignable
…d only

• flip the table from `child → parents[]` to `parent → children[]` so the
  call site is a direct `?.[]` lookup instead of a reverse Object.entries scan
• drop the getChildBrandsOf helper (now one expression at the call site)
• only widen brand unions for rid-typed builtins; string-typed components
  keep their narrow single-brand emit, matching the table's intent
• tighten the JSDoc to describe just the mechanism (the domain motivation
  lives in the PR description and changeset)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant