@stigmer/sdk 3.25.0 → 3.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/iam-principal.test.d.ts +2 -0
- package/__tests__/iam-principal.test.d.ts.map +1 -0
- package/__tests__/iam-principal.test.js +65 -0
- package/__tests__/iam-principal.test.js.map +1 -0
- package/authorization-config.d.ts +28 -0
- package/authorization-config.d.ts.map +1 -1
- package/authorization-config.js +26 -1
- package/authorization-config.js.map +1 -1
- package/execution/transcript.d.ts +5 -6
- package/execution/transcript.d.ts.map +1 -1
- package/execution/transcript.js +5 -6
- package/execution/transcript.js.map +1 -1
- package/gen/authorization-config.d.ts +11 -0
- package/gen/authorization-config.d.ts.map +1 -1
- package/gen/authorization-config.js +23 -0
- package/gen/authorization-config.js.map +1 -1
- package/gen/client.d.ts +4 -0
- package/gen/client.d.ts.map +1 -1
- package/gen/client.js +4 -0
- package/gen/client.js.map +1 -1
- package/gen/resource-availability.d.ts.map +1 -1
- package/gen/resource-availability.js +1 -0
- package/gen/resource-availability.js.map +1 -1
- package/gen/team.d.ts +49 -0
- package/gen/team.d.ts.map +1 -0
- package/gen/team.js +119 -0
- package/gen/team.js.map +1 -0
- package/iam-principal.d.ts +30 -0
- package/iam-principal.d.ts.map +1 -0
- package/iam-principal.js +73 -0
- package/iam-principal.js.map +1 -0
- package/index.d.ts +3 -1
- package/index.d.ts.map +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/iam-principal.test.ts +82 -0
- package/src/authorization-config.ts +48 -1
- package/src/execution/transcript.ts +5 -6
- package/src/gen/authorization-config.ts +24 -0
- package/src/gen/client.ts +5 -0
- package/src/gen/resource-availability.ts +1 -0
- package/src/gen/team.ts +132 -0
- package/src/iam-principal.ts +92 -0
- package/src/index.ts +17 -0
package/src/gen/team.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Code generated by stigmer-codegen. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
import { wrapError } from "./errors.js";
|
|
4
|
+
import { stripUndefined } from "./proto-utils.js";
|
|
5
|
+
import { type DeleteResourceInput, type ResourceRef } from "./types.js";
|
|
6
|
+
import { create } from "@bufbuild/protobuf";
|
|
7
|
+
import { createClient, type Client, type Transport } from "@connectrpc/connect";
|
|
8
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
9
|
+
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
10
|
+
import { ApiResourceIdSchema, ApiResourceReferenceSchema, ApiResourceDeleteInputSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
|
|
11
|
+
import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
|
|
12
|
+
import { TeamSchema, type Team } from "@stigmer/protos/ai/stigmer/iam/team/v1/api_pb";
|
|
13
|
+
import { TeamCommandController } from "@stigmer/protos/ai/stigmer/iam/team/v1/command_pb";
|
|
14
|
+
import { ListTeamsByOrgInputSchema, TeamsSchema, type ListTeamsByOrgInput, type Teams } from "@stigmer/protos/ai/stigmer/iam/team/v1/io_pb";
|
|
15
|
+
import { TeamQueryController } from "@stigmer/protos/ai/stigmer/iam/team/v1/query_pb";
|
|
16
|
+
import { TeamSpecSchema } from "@stigmer/protos/ai/stigmer/iam/team/v1/spec_pb";
|
|
17
|
+
|
|
18
|
+
/** Provides operations on team resources. */
|
|
19
|
+
export class TeamClient {
|
|
20
|
+
private readonly command: Client<typeof TeamCommandController>;
|
|
21
|
+
private readonly query: Client<typeof TeamQueryController>;
|
|
22
|
+
|
|
23
|
+
constructor(transport: Transport) {
|
|
24
|
+
this.command = createClient(TeamCommandController, transport);
|
|
25
|
+
this.query = createClient(TeamQueryController, transport);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async create(input: TeamInput): Promise<Team> {
|
|
29
|
+
try {
|
|
30
|
+
return await this.command.create(buildTeamProto(input));
|
|
31
|
+
} catch (e) { throw wrapError(e); }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async update(input: TeamInput): Promise<Team> {
|
|
35
|
+
try {
|
|
36
|
+
return await this.command.update(buildTeamProto(input));
|
|
37
|
+
} catch (e) { throw wrapError(e); }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async delete(input: DeleteResourceInput): Promise<Team> {
|
|
41
|
+
try {
|
|
42
|
+
return await this.command.delete(create(ApiResourceDeleteInputSchema, {
|
|
43
|
+
resourceId: input.resourceId,
|
|
44
|
+
versionMessage: input.versionMessage,
|
|
45
|
+
force: input.force,
|
|
46
|
+
}));
|
|
47
|
+
} catch (e) { throw wrapError(e); }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async get(id: string): Promise<Team> {
|
|
51
|
+
try {
|
|
52
|
+
return await this.query.get(create(ApiResourceIdSchema, { value: id }));
|
|
53
|
+
} catch (e) { throw wrapError(e); }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getByReference(ref: ResourceRef): Promise<Team> {
|
|
57
|
+
try {
|
|
58
|
+
return await this.query.getByReference(create(ApiResourceReferenceSchema, { ...ref, kind: ApiResourceKind.team }));
|
|
59
|
+
} catch (e) { throw wrapError(e); }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async listByOrg(input: ListTeamsByOrgInput): Promise<Teams> {
|
|
63
|
+
try {
|
|
64
|
+
return await this.query.listByOrg(input);
|
|
65
|
+
} catch (e) { throw wrapError(e); }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Input for creating/updating a Team. */
|
|
70
|
+
export interface TeamInput {
|
|
71
|
+
/**
|
|
72
|
+
* The resource's `metadata.id`, for exact update addressing when set
|
|
73
|
+
* from a loaded resource. Required for updates to platform-scoped
|
|
74
|
+
* (org-less) kinds, where the org+slug fallback cannot match. On
|
|
75
|
+
* create, the cloud server stamps its own id regardless; the OSS
|
|
76
|
+
* server honors a caller-supplied id (existing apply semantics).
|
|
77
|
+
*/
|
|
78
|
+
id?: string;
|
|
79
|
+
name: string;
|
|
80
|
+
slug?: string;
|
|
81
|
+
org: string;
|
|
82
|
+
labels?: Record<string, string>;
|
|
83
|
+
visibility?: ApiResourceVisibility;
|
|
84
|
+
description?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function buildTeamProto(input: TeamInput): Team {
|
|
88
|
+
return Object.assign(create(TeamSchema), {
|
|
89
|
+
apiVersion: "iam.stigmer.ai/v1",
|
|
90
|
+
kind: "Team",
|
|
91
|
+
metadata: Object.assign(create(ApiResourceMetadataSchema), {
|
|
92
|
+
...(input.id && { id: input.id }),
|
|
93
|
+
name: input.name,
|
|
94
|
+
org: input.org,
|
|
95
|
+
...(input.slug && { slug: input.slug }),
|
|
96
|
+
...(input.labels && { labels: input.labels }),
|
|
97
|
+
...(input.visibility && { visibility: input.visibility }),
|
|
98
|
+
}),
|
|
99
|
+
spec: Object.assign(create(TeamSpecSchema), stripUndefined({
|
|
100
|
+
description: input.description,
|
|
101
|
+
})),
|
|
102
|
+
}) as Team;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Maps a fetched {@link Team} to a complete {@link TeamInput} for `update()`.
|
|
107
|
+
*
|
|
108
|
+
* The update RPC replaces the ENTIRE spec — spread this mapper's output
|
|
109
|
+
* and override only the fields you edit (spread nested objects the same
|
|
110
|
+
* way):
|
|
111
|
+
*
|
|
112
|
+
* await client.update({ ...toTeamUpdateInput(res), description: next });
|
|
113
|
+
*
|
|
114
|
+
* Proto3 defaults normalize to `undefined`; resource references keep
|
|
115
|
+
* `version` (pinned refs) and `kind`.
|
|
116
|
+
*/
|
|
117
|
+
export function toTeamUpdateInput(resource: Team): TeamInput {
|
|
118
|
+
const meta = resource.metadata;
|
|
119
|
+
const spec = resource.spec ?? create(TeamSpecSchema);
|
|
120
|
+
return {
|
|
121
|
+
// Exact update addressing (id-first in the update pipeline) — for
|
|
122
|
+
// platform-scoped (org-less) kinds the org+slug fallback cannot
|
|
123
|
+
// match, so the id is the ONLY working address.
|
|
124
|
+
id: meta?.id || undefined,
|
|
125
|
+
name: meta?.name ?? "",
|
|
126
|
+
slug: meta?.slug || undefined,
|
|
127
|
+
org: meta?.org ?? "",
|
|
128
|
+
labels: meta?.labels && Object.keys(meta.labels).length > 0 ? { ...meta.labels } : undefined,
|
|
129
|
+
visibility: meta?.visibility || undefined,
|
|
130
|
+
description: spec.description || undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who an IAM policy grants a role to: a person or a team, in one shape a
|
|
3
|
+
* client builds grants from and reads access lists back into.
|
|
4
|
+
*
|
|
5
|
+
* The wire spells a grantee as an `ApiResourceRef`: a person is
|
|
6
|
+
* `identity_account:<id>` with no relation qualifier, a team is
|
|
7
|
+
* `team:<id>#member` (every member of the team holds the grant). This
|
|
8
|
+
* module is the one place in the SDK that knows that spelling, so no caller
|
|
9
|
+
* writes the qualifier by hand and no caller can drop it.
|
|
10
|
+
*
|
|
11
|
+
* Reading goes through the same module: `granteeFromView` turns an access
|
|
12
|
+
* list entry back into a `Grantee` and answers `undefined` for anything it
|
|
13
|
+
* does not recognise (another kind, a team with a qualifier other than
|
|
14
|
+
* `member`), so a client never acts on a principal it would misname. A
|
|
15
|
+
* revoke built from the returned grantee names the exact row the list
|
|
16
|
+
* showed, because the server's revoke matches the qualifier exactly.
|
|
17
|
+
*/
|
|
18
|
+
import { create } from "@bufbuild/protobuf";
|
|
19
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
20
|
+
import type { ApiResourceRefView } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
|
|
21
|
+
import {
|
|
22
|
+
type ApiResourceRef,
|
|
23
|
+
ApiResourceRefSchema,
|
|
24
|
+
} from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
|
|
25
|
+
|
|
26
|
+
const PERSON_KIND = ApiResourceKind[ApiResourceKind.identity_account];
|
|
27
|
+
const TEAM_KIND = ApiResourceKind[ApiResourceKind.team];
|
|
28
|
+
|
|
29
|
+
/** The relation that makes every member of a team the grantee. */
|
|
30
|
+
const TEAM_MEMBERS_RELATION = "member";
|
|
31
|
+
|
|
32
|
+
/** A person or a team an IAM policy can grant a role to. */
|
|
33
|
+
export type Grantee =
|
|
34
|
+
| { readonly kind: "identity_account"; readonly id: string }
|
|
35
|
+
| { readonly kind: "team"; readonly id: string };
|
|
36
|
+
|
|
37
|
+
/** The kind of a {@link Grantee}. */
|
|
38
|
+
export type GranteeKind = Grantee["kind"];
|
|
39
|
+
|
|
40
|
+
/** A person, by identity account id (`ida_...`). */
|
|
41
|
+
export function personGrantee(id: string): Grantee {
|
|
42
|
+
return { kind: "identity_account", id };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A team, by team id (`tm_...`). */
|
|
46
|
+
export function teamGrantee(id: string): Grantee {
|
|
47
|
+
return { kind: "team", id };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The `ApiResourceRef` an IAM policy spec names the grantee with: a person
|
|
52
|
+
* unqualified, a team as its members.
|
|
53
|
+
*/
|
|
54
|
+
export function granteeRef(grantee: Grantee): ApiResourceRef {
|
|
55
|
+
switch (grantee.kind) {
|
|
56
|
+
case "identity_account":
|
|
57
|
+
return create(ApiResourceRefSchema, { kind: PERSON_KIND, id: grantee.id });
|
|
58
|
+
case "team":
|
|
59
|
+
return create(ApiResourceRefSchema, {
|
|
60
|
+
kind: TEAM_KIND,
|
|
61
|
+
id: grantee.id,
|
|
62
|
+
relation: TEAM_MEMBERS_RELATION,
|
|
63
|
+
});
|
|
64
|
+
default: {
|
|
65
|
+
const unreachable: never = grantee;
|
|
66
|
+
return unreachable;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The grantee an access-list entry names, or `undefined` when the entry
|
|
73
|
+
* is not a person or a team's members (a structural principal, a kind this
|
|
74
|
+
* SDK does not know, or a team qualifier other than `member`).
|
|
75
|
+
*/
|
|
76
|
+
export function granteeFromView(
|
|
77
|
+
view: Pick<ApiResourceRefView, "kind" | "id" | "relation">,
|
|
78
|
+
): Grantee | undefined {
|
|
79
|
+
if (!view.id) return undefined;
|
|
80
|
+
if (view.kind === PERSON_KIND && view.relation === "") {
|
|
81
|
+
return personGrantee(view.id);
|
|
82
|
+
}
|
|
83
|
+
if (view.kind === TEAM_KIND && view.relation === TEAM_MEMBERS_RELATION) {
|
|
84
|
+
return teamGrantee(view.id);
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** A stable key for a grantee: its kind and id. */
|
|
90
|
+
export function granteeKey(grantee: Grantee): string {
|
|
91
|
+
return `${grantee.kind}:${grantee.id}`;
|
|
92
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -77,7 +77,19 @@ export {
|
|
|
77
77
|
getGrantableRoles,
|
|
78
78
|
hasGrantableRoles,
|
|
79
79
|
isRoleGrantable,
|
|
80
|
+
getTeamGrantableRoles,
|
|
81
|
+
hasTeamGrantableRoles,
|
|
82
|
+
isRoleTeamGrantable,
|
|
80
83
|
} from "./authorization-config.js";
|
|
84
|
+
export {
|
|
85
|
+
type Grantee,
|
|
86
|
+
type GranteeKind,
|
|
87
|
+
personGrantee,
|
|
88
|
+
teamGrantee,
|
|
89
|
+
granteeRef,
|
|
90
|
+
granteeFromView,
|
|
91
|
+
granteeKey,
|
|
92
|
+
} from "./iam-principal.js";
|
|
81
93
|
export {
|
|
82
94
|
iamRoleToString,
|
|
83
95
|
iamRoleFromString,
|
|
@@ -244,6 +256,11 @@ export {
|
|
|
244
256
|
toIdentityProviderUpdateInput,
|
|
245
257
|
type IdentityProviderInput,
|
|
246
258
|
} from "./gen/identityprovider.js";
|
|
259
|
+
export {
|
|
260
|
+
TeamClient,
|
|
261
|
+
toTeamUpdateInput,
|
|
262
|
+
type TeamInput,
|
|
263
|
+
} from "./gen/team.js";
|
|
247
264
|
export {
|
|
248
265
|
OAuthAppClient,
|
|
249
266
|
toOAuthAppUpdateInput,
|