@lucern/sdk 0.3.0-alpha.16 → 0.3.0-alpha.2
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/CHANGELOG.md +0 -8
- package/README.md +4 -110
- package/dist/adminClient.d.ts +8 -10
- package/dist/adminClient.js +39 -260
- package/dist/adminClient.js.map +1 -1
- package/dist/answersClient.d.ts +0 -2
- package/dist/answersClient.js +11 -239
- package/dist/answersClient.js.map +1 -1
- package/dist/audience/index.d.ts +1 -2
- package/dist/audience/index.js +3 -1
- package/dist/audience/index.js.map +1 -1
- package/dist/audiencesClient.d.ts +16 -18
- package/dist/audiencesClient.js +90 -315
- package/dist/audiencesClient.js.map +1 -1
- package/dist/auditClient.d.ts +0 -2
- package/dist/auditClient.js +15 -245
- package/dist/auditClient.js.map +1 -1
- package/dist/beliefs/index.d.ts +5 -27
- package/dist/beliefs/index.js +1177 -3842
- package/dist/beliefs/index.js.map +1 -1
- package/dist/beliefsClient.d.ts +2 -4
- package/dist/beliefsClient.js +26 -248
- package/dist/beliefsClient.js.map +1 -1
- package/dist/client-B6aWUUwp.d.ts +2552 -0
- package/dist/client.d.ts +27 -3041
- package/dist/client.js +1177 -3842
- package/dist/client.js.map +1 -1
- package/dist/contextClient.d.ts +3 -6
- package/dist/contextClient.js +30 -270
- package/dist/contextClient.js.map +1 -1
- package/dist/contextFacade.js +16 -25
- package/dist/contextFacade.js.map +1 -1
- package/dist/contextPackCompiler.js +30 -19
- package/dist/contextPackCompiler.js.map +1 -1
- package/dist/contextPackPolicy.js +17 -7
- package/dist/contextPackPolicy.js.map +1 -1
- package/dist/contextTypes.d.ts +0 -2
- package/dist/contracts/api-enums.contract.d.ts +2 -2
- package/dist/contracts/api-enums.contract.js +1 -6
- package/dist/contracts/api-enums.contract.js.map +1 -1
- package/dist/contracts/auth-session.contract.d.ts +1 -1
- package/dist/contracts/auth-session.contract.js +1 -13
- package/dist/contracts/auth-session.contract.js.map +1 -1
- package/dist/contracts/index.d.ts +0 -1
- package/dist/contracts/index.js +6 -133
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/lens-filter.contract.js +3 -4
- package/dist/contracts/lens-filter.contract.js.map +1 -1
- package/dist/contracts/lens-workflow.contract.js +3 -4
- package/dist/contracts/lens-workflow.contract.js.map +1 -1
- package/dist/contracts/lensFilter.js +3 -4
- package/dist/contracts/lensFilter.js.map +1 -1
- package/dist/contracts/lensWorkflow.js +3 -4
- package/dist/contracts/lensWorkflow.js.map +1 -1
- package/dist/contracts/mcpTools.d.ts +1 -46
- package/dist/contracts/mcpTools.js +0 -108
- package/dist/contracts/mcpTools.js.map +1 -1
- package/dist/contradictions/index.d.ts +4 -26
- package/dist/contradictions/index.js +1177 -3842
- package/dist/contradictions/index.js.map +1 -1
- package/dist/coreClient.d.ts +2 -28
- package/dist/coreClient.js +14 -240
- package/dist/coreClient.js.map +1 -1
- package/dist/decisions/index.d.ts +14 -36
- package/dist/decisions/index.js +1177 -3842
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisionsClient.d.ts +12 -6
- package/dist/decisionsClient.js +37 -253
- package/dist/decisionsClient.js.map +1 -1
- package/dist/edges/index.d.ts +87 -49
- package/dist/edges/index.js +1177 -3842
- package/dist/edges/index.js.map +1 -1
- package/dist/events.js +3 -6
- package/dist/events.js.map +1 -1
- package/dist/eventsCore.d.ts +1 -3
- package/dist/eventsCore.js +14 -240
- package/dist/eventsCore.js.map +1 -1
- package/dist/evidence/index.d.ts +4 -26
- package/dist/evidence/index.js +1177 -3842
- package/dist/evidence/index.js.map +1 -1
- package/dist/evidenceClient.d.ts +0 -2
- package/dist/evidenceClient.js +14 -240
- package/dist/evidenceClient.js.map +1 -1
- package/dist/facade/context.d.ts +1 -2
- package/dist/facade/context.js +16 -25
- package/dist/facade/context.js.map +1 -1
- package/dist/gatewayFacades.d.ts +46 -90
- package/dist/gatewayFacades.js +128 -609
- package/dist/gatewayFacades.js.map +1 -1
- package/dist/graphClient.d.ts +13 -8
- package/dist/graphClient.js +45 -262
- package/dist/graphClient.js.map +1 -1
- package/dist/harnessClient.d.ts +24 -15
- package/dist/harnessClient.js +42 -253
- package/dist/harnessClient.js.map +1 -1
- package/dist/identityClient.d.ts +11 -115
- package/dist/identityClient.js +33 -555
- package/dist/identityClient.js.map +1 -1
- package/dist/index.d.ts +6 -32
- package/dist/index.js +2580 -5825
- package/dist/index.js.map +1 -1
- package/dist/learningClient.d.ts +6 -8
- package/dist/learningClient.js +44 -270
- package/dist/learningClient.js.map +1 -1
- package/dist/lenses/index.d.ts +38 -78
- package/dist/lenses/index.js +1177 -3842
- package/dist/lenses/index.js.map +1 -1
- package/dist/nodes/index.d.ts +21 -65
- package/dist/nodes/index.js +1177 -3842
- package/dist/nodes/index.js.map +1 -1
- package/dist/ontologies/index.d.ts +32 -55
- package/dist/ontologies/index.js +1177 -3842
- package/dist/ontologies/index.js.map +1 -1
- package/dist/ontologyClient.d.ts +25 -19
- package/dist/ontologyClient.js +40 -276
- package/dist/ontologyClient.js.map +1 -1
- package/dist/packsClient.d.ts +23 -11
- package/dist/packsClient.js +46 -252
- package/dist/packsClient.js.map +1 -1
- package/dist/policyClient.d.ts +10 -13
- package/dist/policyClient.js +25 -261
- package/dist/policyClient.js.map +1 -1
- package/dist/questions/index.d.ts +4 -26
- package/dist/questions/index.js +1177 -3842
- package/dist/questions/index.js.map +1 -1
- package/dist/realtime/index.d.ts +1 -1
- package/dist/reportsClient.d.ts +7 -9
- package/dist/reportsClient.js +53 -299
- package/dist/reportsClient.js.map +1 -1
- package/dist/schemaClient.d.ts +3 -5
- package/dist/schemaClient.js +29 -253
- package/dist/schemaClient.js.map +1 -1
- package/dist/sdkSurface.d.ts +3 -8
- package/dist/sdkSurface.js +6 -10
- package/dist/sdkSurface.js.map +1 -1
- package/dist/sourcesClient.d.ts +0 -2
- package/dist/sourcesClient.js +14 -240
- package/dist/sourcesClient.js.map +1 -1
- package/dist/topics/index.d.ts +9 -37
- package/dist/topics/index.js +1177 -3844
- package/dist/topics/index.js.map +1 -1
- package/dist/topicsClient.d.ts +0 -4
- package/dist/topicsClient.js +24 -255
- package/dist/topicsClient.js.map +1 -1
- package/dist/types.d.ts +0 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workflowClient.d.ts +40 -60
- package/dist/workflowClient.js +58 -261
- package/dist/workflowClient.js.map +1 -1
- package/dist/worktrees/index.d.ts +33 -71
- package/dist/worktrees/index.js +1177 -3842
- package/dist/worktrees/index.js.map +1 -1
- package/package.json +3 -17
- package/dist/accessControl.d.ts +0 -79
- package/dist/accessControl.js +0 -1270
- package/dist/accessControl.js.map +0 -1
- package/dist/authContext.d.ts +0 -56
- package/dist/authContext.js +0 -170
- package/dist/authContext.js.map +0 -1
- package/dist/authDeviceClient.d.ts +0 -49
- package/dist/authDeviceClient.js +0 -121
- package/dist/authDeviceClient.js.map +0 -1
- package/dist/boundaryClientSurface.d.ts +0 -20
- package/dist/boundaryClientSurface.js +0 -73
- package/dist/boundaryClientSurface.js.map +0 -1
- package/dist/clientHelpers.d.ts +0 -48
- package/dist/clientHelpers.js +0 -137
- package/dist/clientHelpers.js.map +0 -1
- package/dist/control-plane.d.ts +0 -69
- package/dist/control-plane.js +0 -674
- package/dist/control-plane.js.map +0 -1
- package/dist/embeddingsClient.d.ts +0 -106
- package/dist/embeddingsClient.js +0 -749
- package/dist/embeddingsClient.js.map +0 -1
- package/dist/eventingClient.d.ts +0 -96
- package/dist/eventingClient.js +0 -746
- package/dist/eventingClient.js.map +0 -1
- package/dist/functionSurface.d.ts +0 -144
- package/dist/functionSurface.js +0 -1227
- package/dist/functionSurface.js.map +0 -1
- package/dist/functionSurfaceClient.d.ts +0 -8
- package/dist/functionSurfaceClient.js +0 -1227
- package/dist/functionSurfaceClient.js.map +0 -1
- package/dist/graphAnalysisClient.d.ts +0 -192
- package/dist/graphAnalysisClient.js +0 -817
- package/dist/graphAnalysisClient.js.map +0 -1
- package/dist/graphIntel.d.ts +0 -4
- package/dist/graphIntel.js +0 -3
- package/dist/graphIntel.js.map +0 -1
- package/dist/graphIntelligence.d.ts +0 -2
- package/dist/graphIntelligence.js +0 -47
- package/dist/graphIntelligence.js.map +0 -1
- package/dist/graphRecommendationsClient.d.ts +0 -56
- package/dist/graphRecommendationsClient.js +0 -682
- package/dist/graphRecommendationsClient.js.map +0 -1
- package/dist/graphStateClassifierClient.d.ts +0 -73
- package/dist/graphStateClassifierClient.js +0 -734
- package/dist/graphStateClassifierClient.js.map +0 -1
- package/dist/infisicalRuntime.d.ts +0 -43
- package/dist/infisicalRuntime.js +0 -346
- package/dist/infisicalRuntime.js.map +0 -1
- package/dist/jobsClient.d.ts +0 -98
- package/dist/jobsClient.js +0 -744
- package/dist/jobsClient.js.map +0 -1
- package/dist/mcpClient.d.ts +0 -28
- package/dist/mcpClient.js +0 -687
- package/dist/mcpClient.js.map +0 -1
- package/dist/modelRuntimeClient.d.ts +0 -72
- package/dist/modelRuntimeClient.js +0 -722
- package/dist/modelRuntimeClient.js.map +0 -1
- package/dist/ontologyLinksClient.d.ts +0 -71
- package/dist/ontologyLinksClient.js +0 -715
- package/dist/ontologyLinksClient.js.map +0 -1
- package/dist/orgGraphSearchClient.d.ts +0 -85
- package/dist/orgGraphSearchClient.js +0 -690
- package/dist/orgGraphSearchClient.js.map +0 -1
- package/dist/secrets.d.ts +0 -1
- package/dist/secrets.js +0 -3
- package/dist/secrets.js.map +0 -1
- package/dist/telemetryClient.d.ts +0 -94
- package/dist/telemetryClient.js +0 -759
- package/dist/telemetryClient.js.map +0 -1
- package/dist/toolRegistryClient.d.ts +0 -115
- package/dist/toolRegistryClient.js +0 -785
- package/dist/toolRegistryClient.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,14 +5,6 @@ All notable changes to `@lucern/sdk` will be documented in this file.
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
- No unreleased changes yet.
|
|
7
7
|
|
|
8
|
-
## [0.3.0-alpha.16] - 2026-05-14
|
|
9
|
-
- Adds the exact-row reasoning-kernel migration surface required for tenant identity/scope repairs.
|
|
10
|
-
- Keeps the coherent Lucern package line aligned for StackOS and reasoning-environment adoption.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## [0.3.0-alpha.7] - 2026-05-03
|
|
14
|
-
- Rebuild the coherent Lucern package line after Campaign 1 SDK hardening fixes.
|
|
15
|
-
|
|
16
8
|
## [0.2.0-alpha.5] - 2026-04-18
|
|
17
9
|
- Refresh publish from current stackos source under EK-16 T4.
|
|
18
10
|
- Version-numbering note: 0.2.0-alpha.2 through 0.2.0-alpha.5 were published from earlier stackos source on 2026-04-12 by pete_c. This release (alpha.5) is the first to ship the current April 18 source — 56 commits of accumulated changes from the code-separation track.
|
package/README.md
CHANGED
|
@@ -10,31 +10,6 @@ Lucern gives your agents a reasoning graph that accumulates understanding across
|
|
|
10
10
|
npm install @lucern/sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## Install Model
|
|
14
|
-
|
|
15
|
-
`@lucern/sdk` is the primary TypeScript app dependency. Installing it also
|
|
16
|
-
installs its internal runtime dependencies, including Lucern contracts and
|
|
17
|
-
reasoning-kernel helpers, but a tenant should still list any `@lucern/*`
|
|
18
|
-
package that its own code or scripts import or execute.
|
|
19
|
-
|
|
20
|
-
Common direct installs:
|
|
21
|
-
|
|
22
|
-
| Need | Install |
|
|
23
|
-
| --- | --- |
|
|
24
|
-
| Programmatic Lucern API calls | `@lucern/sdk` |
|
|
25
|
-
| Tool access checks | `@lucern/access-control` |
|
|
26
|
-
| React hooks/components | `@lucern/react @lucern/sdk` |
|
|
27
|
-
| Convex component binding | `@lucern/control-plane @lucern/reasoning-kernel` |
|
|
28
|
-
| Bootstrap, auth, doctor, and operator commands | `@lucern/cli` |
|
|
29
|
-
| Agent-facing MCP server/runtime | `@lucern/mcp` |
|
|
30
|
-
| Full design-partner/package-suite pin | all packages from `TENANT_CLIENT_INSTALLABLE_PACKAGES` in `@lucern/contracts` |
|
|
31
|
-
|
|
32
|
-
The difference matters: `@lucern/cli` is a direct install because it provides
|
|
33
|
-
the `lucern` binary, but tenant app source should not import it. The Convex
|
|
34
|
-
component packages are direct installs for `convex.config.ts`, while application
|
|
35
|
-
code should stay on `@lucern/sdk`, `@lucern/react`, `@lucern/mcp`,
|
|
36
|
-
`@lucern/access-control`, `@lucern/contracts`, and `@lucern/types`.
|
|
37
|
-
|
|
38
13
|
## Canonical Interface
|
|
39
14
|
|
|
40
15
|
`@lucern/sdk` is the canonical public interface for Lucern.
|
|
@@ -42,9 +17,6 @@ code should stay on `@lucern/sdk`, `@lucern/react`, `@lucern/mcp`,
|
|
|
42
17
|
- Build applications, automations, and backend integrations against the SDK first.
|
|
43
18
|
- Treat `/api/platform/v1/*` as the transport mirror of the SDK surface.
|
|
44
19
|
- Treat MCP as an agent-facing client of the same surface, not as a privileged bypass around SDK or HTTP semantics.
|
|
45
|
-
- Treat REST, SDK, CLI, and MCP as projections of the same manifest. New
|
|
46
|
-
control-plane operations must be added to the manifest first, then exposed
|
|
47
|
-
through the generated surfaces.
|
|
48
20
|
|
|
49
21
|
IA-7 closes the remaining SDK surface gaps needed for SDK-first clients:
|
|
50
22
|
|
|
@@ -70,62 +42,6 @@ const identity = await lucern.identity.whoami();
|
|
|
70
42
|
const principal: SdkPrincipalContext = identity.data;
|
|
71
43
|
```
|
|
72
44
|
|
|
73
|
-
### Control-Plane Tenant Bootstrap
|
|
74
|
-
|
|
75
|
-
Interactive tenant applications should resolve Clerk users through the Lucern
|
|
76
|
-
control-plane identity surface before making workspace-scoped graph calls. Clerk
|
|
77
|
-
proves the browser user's identity; Lucern authorization comes from the
|
|
78
|
-
Permit-backed control-plane projection.
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
import { createLucernClient } from "@lucern/sdk";
|
|
82
|
-
|
|
83
|
-
async function createLucernForClerkUser(args: {
|
|
84
|
-
clerkUserId: string;
|
|
85
|
-
getClerkToken: () => Promise<string | null>;
|
|
86
|
-
tenantId: string;
|
|
87
|
-
workspaceId: string;
|
|
88
|
-
clerkProjectId?: string;
|
|
89
|
-
}) {
|
|
90
|
-
const token = await args.getClerkToken();
|
|
91
|
-
if (!token) {
|
|
92
|
-
throw new Error("Clerk session token is required.");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const getAuthHeaders = () => ({ Authorization: `Bearer ${token}` });
|
|
96
|
-
const lucern = createLucernClient({
|
|
97
|
-
baseUrl: "https://api.lucern.ai",
|
|
98
|
-
getAuthHeaders,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const principal =
|
|
102
|
-
await lucern.controlPlane.identity.resolveInteractivePrincipal({
|
|
103
|
-
clerkId: args.clerkUserId,
|
|
104
|
-
tenantId: args.tenantId,
|
|
105
|
-
workspaceId: args.workspaceId,
|
|
106
|
-
providerProjectId: args.clerkProjectId,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return createLucernClient({
|
|
110
|
-
baseUrl: "https://api.lucern.ai",
|
|
111
|
-
getAuthHeaders,
|
|
112
|
-
authContext: principal.data,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Use `authContext.principalId`, roles, scopes, groups, permitted tools, and
|
|
118
|
-
Permit subject data as the runtime Lucern principal context. Tenant apps must
|
|
119
|
-
not read legacy `users.mcRole` / `defaultTenantId` fields as authorization, and
|
|
120
|
-
they must not call `components.controlPlane.migration` from application code.
|
|
121
|
-
Provisioning and backfills can use migration APIs; runtime bootstrapping uses
|
|
122
|
-
`controlPlane.identity.resolveInteractivePrincipal(...)`.
|
|
123
|
-
|
|
124
|
-
StackOS, Lucern Graph, and Stack Engineering should use this bootstrap path
|
|
125
|
-
before calling morning brief, graph session, MCP, or CLI-backed runtime flows.
|
|
126
|
-
`/api/platform/v1/users/:clerkId` may be a profile facade, but it is not an
|
|
127
|
-
authorization source.
|
|
128
|
-
|
|
129
45
|
## The Full Developer Journey
|
|
130
46
|
|
|
131
47
|
This walkthrough mirrors what a developer building an AI-powered code review system would experience in a real coding session. Every API call is something you would actually use.
|
|
@@ -385,7 +301,7 @@ await lucern.graph.createEdge({
|
|
|
385
301
|
Before your agent starts its next session, it reads the graph:
|
|
386
302
|
|
|
387
303
|
```typescript
|
|
388
|
-
const context = await lucern.context.compile({
|
|
304
|
+
const context = await lucern.context.compile(topicId, {
|
|
389
305
|
query: "code review strategy and static analysis coverage",
|
|
390
306
|
ranking: "weighted_v1",
|
|
391
307
|
tokenBudget: 2000,
|
|
@@ -447,28 +363,6 @@ lucern.identity // API keys and sessions
|
|
|
447
363
|
|
|
448
364
|
The graph doesn't just store knowledge — it analyzes itself.
|
|
449
365
|
|
|
450
|
-
### Query Suite
|
|
451
|
-
|
|
452
|
-
```typescript
|
|
453
|
-
// Discover the prompt-backed Graph Intelligence recipes tenants can expose in
|
|
454
|
-
// their own UI or model workflows.
|
|
455
|
-
const catalog = await lucern.graphAnalysis.listGraphIntelligenceQueries();
|
|
456
|
-
|
|
457
|
-
// Run a named recipe. Lucern returns the resolved prompt, deterministic graph
|
|
458
|
-
// analysis bundle, sampled graph context, and public tool plan for LLM synthesis.
|
|
459
|
-
const preMortem = await lucern.graphAnalysis.runGraphIntelligenceQuery({
|
|
460
|
-
topicId,
|
|
461
|
-
queryId: "pre-mortem",
|
|
462
|
-
limit: 25,
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
await modelMachine.run({
|
|
466
|
-
prompt: preMortem.data.prompt,
|
|
467
|
-
context: preMortem.data.analysis,
|
|
468
|
-
tools: preMortem.data.toolPlan,
|
|
469
|
-
});
|
|
470
|
-
```
|
|
471
|
-
|
|
472
366
|
### Structural Analysis
|
|
473
367
|
|
|
474
368
|
```typescript
|
|
@@ -551,7 +445,7 @@ traversal.data.nodes.forEach(node => {
|
|
|
551
445
|
### Inject Reasoning Context Into Any LLM Call
|
|
552
446
|
|
|
553
447
|
```typescript
|
|
554
|
-
const context = await lucern.context.compile({
|
|
448
|
+
const context = await lucern.context.compile(topicId, {
|
|
555
449
|
query: "security review priorities",
|
|
556
450
|
ranking: "weighted_v1",
|
|
557
451
|
tokenBudget: 3000,
|
|
@@ -662,7 +556,7 @@ architectural decisions, check the reasoning graph:
|
|
|
662
556
|
|
|
663
557
|
- Read current beliefs: `lucern.beliefs.list({ topicId: "..." })`
|
|
664
558
|
- Check for contradictions: `lucern.contradictions.list({ topicId: "..." })`
|
|
665
|
-
- Compile context before analysis: `lucern.context.compile({ query: "..." })`
|
|
559
|
+
- Compile context before analysis: `lucern.context.compile(topicId, { query: "..." })`
|
|
666
560
|
|
|
667
561
|
After making decisions, write them back:
|
|
668
562
|
- Create beliefs for architectural decisions
|
|
@@ -693,7 +587,7 @@ contradictions, or knowledge state.
|
|
|
693
587
|
Compile the current context to understand what the graph knows:
|
|
694
588
|
|
|
695
589
|
\`\`\`typescript
|
|
696
|
-
const context = await lucern.context.compile({
|
|
590
|
+
const context = await lucern.context.compile(topicId, {
|
|
697
591
|
query: "<what you're working on>",
|
|
698
592
|
tokenBudget: 2000,
|
|
699
593
|
});
|
package/dist/adminClient.d.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { GatewayClientConfig, PlatformGatewaySuccess, GatewayScope } from './cor
|
|
|
2
2
|
export { LucernApiError } from './coreClient.js';
|
|
3
3
|
import { ListResult, JsonObject } from './types.js';
|
|
4
4
|
import { ControlObjectOwnershipContract } from './controlObjectOwnership.js';
|
|
5
|
-
import './authContext.js';
|
|
6
|
-
import './contracts/auth-session.contract.js';
|
|
7
5
|
import './contracts/workflow-runtime.contract.js';
|
|
8
6
|
import './contracts/lens-workflow.contract.js';
|
|
9
7
|
import './contracts/lens-filter.contract.js';
|
|
@@ -153,11 +151,11 @@ declare function createAdminClient(config?: AdminClientConfig): {
|
|
|
153
151
|
/**
|
|
154
152
|
* Get the control-object ownership contract.
|
|
155
153
|
*/
|
|
156
|
-
getControlObjectOwnership
|
|
154
|
+
getControlObjectOwnership(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
|
|
157
155
|
/**
|
|
158
156
|
* @deprecated Use getControlObjectOwnership.
|
|
159
157
|
*/
|
|
160
|
-
getControlObjectOwnershipContract
|
|
158
|
+
getControlObjectOwnershipContract(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
|
|
161
159
|
/**
|
|
162
160
|
* List workspaces for the current admin scope.
|
|
163
161
|
*/
|
|
@@ -190,33 +188,33 @@ declare function createAdminClient(config?: AdminClientConfig): {
|
|
|
190
188
|
/**
|
|
191
189
|
* Create a membership.
|
|
192
190
|
*/
|
|
193
|
-
createMembership
|
|
191
|
+
createMembership(input: GatewayScope & {
|
|
194
192
|
membershipId?: string;
|
|
195
193
|
principalId: string;
|
|
196
194
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
197
195
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
198
196
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
199
|
-
}, idempotencyKey?: string)
|
|
197
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
200
198
|
/**
|
|
201
199
|
* Update a membership.
|
|
202
200
|
*/
|
|
203
|
-
updateMembership
|
|
201
|
+
updateMembership(input: GatewayScope & {
|
|
204
202
|
membershipId?: string;
|
|
205
203
|
principalId: string;
|
|
206
204
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
207
205
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
208
206
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
209
|
-
}, idempotencyKey?: string)
|
|
207
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
210
208
|
/**
|
|
211
209
|
* @deprecated Use createMembership or updateMembership.
|
|
212
210
|
*/
|
|
213
|
-
upsertMembership
|
|
211
|
+
upsertMembership(input: GatewayScope & {
|
|
214
212
|
membershipId?: string;
|
|
215
213
|
principalId: string;
|
|
216
214
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
217
215
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
218
216
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
219
|
-
}, idempotencyKey?: string)
|
|
217
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
220
218
|
/**
|
|
221
219
|
* List tenant API keys in the current admin scope.
|
|
222
220
|
*/
|
package/dist/adminClient.js
CHANGED
|
@@ -1,170 +1,3 @@
|
|
|
1
|
-
// src/authContext.ts
|
|
2
|
-
var LucernSdkAuthContextError = class extends Error {
|
|
3
|
-
reason;
|
|
4
|
-
constructor(reason, message) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.name = "LucernSdkAuthContextError";
|
|
7
|
-
this.reason = reason;
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
function cleanString(value) {
|
|
11
|
-
const normalized = value?.trim();
|
|
12
|
-
return normalized ? normalized : void 0;
|
|
13
|
-
}
|
|
14
|
-
function cleanStringList(values) {
|
|
15
|
-
if (!values) {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
return values.map((value) => value.trim()).filter(
|
|
19
|
-
(value, index, list) => value.length > 0 && list.indexOf(value) === index
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
function requireString(value, reason, label) {
|
|
23
|
-
const normalized = cleanString(value);
|
|
24
|
-
if (!normalized) {
|
|
25
|
-
throw new LucernSdkAuthContextError(
|
|
26
|
-
reason,
|
|
27
|
-
`Canonical Lucern SDK auth context is missing ${label}.`
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
return normalized;
|
|
31
|
-
}
|
|
32
|
-
function requirePrincipalType(principalType) {
|
|
33
|
-
if (!principalType) {
|
|
34
|
-
throw new LucernSdkAuthContextError(
|
|
35
|
-
"principal_missing",
|
|
36
|
-
"Canonical Lucern SDK auth context is missing principalType."
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return principalType;
|
|
40
|
-
}
|
|
41
|
-
function requireAuthMode(authMode) {
|
|
42
|
-
if (!authMode) {
|
|
43
|
-
throw new LucernSdkAuthContextError(
|
|
44
|
-
"principal_missing",
|
|
45
|
-
"Canonical Lucern SDK auth context is missing authMode."
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
return authMode;
|
|
49
|
-
}
|
|
50
|
-
function ensurePermitMatch(args) {
|
|
51
|
-
const actual = cleanString(args.actual);
|
|
52
|
-
if (actual && actual !== args.expected) {
|
|
53
|
-
throw new LucernSdkAuthContextError(
|
|
54
|
-
"policy_denied",
|
|
55
|
-
`Canonical Lucern SDK auth context has conflicting Permit ${args.field}.`
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function normalizeCanonicalLucernAuthContext(input) {
|
|
60
|
-
if (!input) {
|
|
61
|
-
throw new LucernSdkAuthContextError(
|
|
62
|
-
"principal_missing",
|
|
63
|
-
"Canonical Lucern SDK auth context is required."
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
if (input.policyDecision === "deny") {
|
|
67
|
-
throw new LucernSdkAuthContextError(
|
|
68
|
-
"policy_denied",
|
|
69
|
-
"Canonical Lucern SDK auth context carries a denied policy decision."
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
const principalId = requireString(
|
|
73
|
-
input.principalId,
|
|
74
|
-
"principal_missing",
|
|
75
|
-
"principalId"
|
|
76
|
-
);
|
|
77
|
-
const tenantId = requireString(input.tenantId, "tenant_missing", "tenantId");
|
|
78
|
-
const workspaceId = requireString(
|
|
79
|
-
input.workspaceId,
|
|
80
|
-
"workspace_missing",
|
|
81
|
-
"workspaceId"
|
|
82
|
-
);
|
|
83
|
-
const roles = cleanStringList(input.roles);
|
|
84
|
-
const scopes = cleanStringList(input.scopes);
|
|
85
|
-
const principalType = requirePrincipalType(input.principalType);
|
|
86
|
-
const authMode = requireAuthMode(input.authMode);
|
|
87
|
-
const roleBasedInteractiveAuth = authMode === "interactive_user" && roles.length > 0;
|
|
88
|
-
if (roles.length === 0 || scopes.length === 0 && !roleBasedInteractiveAuth) {
|
|
89
|
-
throw new LucernSdkAuthContextError(
|
|
90
|
-
"membership_missing",
|
|
91
|
-
"Canonical Lucern SDK auth context requires non-empty roles and scopes."
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
const subject = cleanString(input.permit?.subject) ?? principalId;
|
|
95
|
-
const tenant = cleanString(input.permit?.tenant) ?? tenantId;
|
|
96
|
-
const workspace = cleanString(input.permit?.workspace) ?? workspaceId;
|
|
97
|
-
ensurePermitMatch({
|
|
98
|
-
field: "subject",
|
|
99
|
-
expected: principalId,
|
|
100
|
-
actual: subject
|
|
101
|
-
});
|
|
102
|
-
ensurePermitMatch({ field: "tenant", expected: tenantId, actual: tenant });
|
|
103
|
-
ensurePermitMatch({
|
|
104
|
-
field: "workspace",
|
|
105
|
-
expected: workspaceId,
|
|
106
|
-
actual: workspace
|
|
107
|
-
});
|
|
108
|
-
const context = input.permit?.context ? { ...input.permit.context } : void 0;
|
|
109
|
-
return {
|
|
110
|
-
clerkId: cleanString(input.clerkId),
|
|
111
|
-
principalId,
|
|
112
|
-
tenantId,
|
|
113
|
-
workspaceId,
|
|
114
|
-
principalType,
|
|
115
|
-
authMode,
|
|
116
|
-
roles,
|
|
117
|
-
scopes,
|
|
118
|
-
delegationChain: input.delegationChain ? [...input.delegationChain] : [],
|
|
119
|
-
policyTraceId: cleanString(input.policyTraceId),
|
|
120
|
-
correlationId: cleanString(input.correlationId),
|
|
121
|
-
membershipId: cleanString(input.membershipId),
|
|
122
|
-
permit: {
|
|
123
|
-
subject,
|
|
124
|
-
tenant,
|
|
125
|
-
workspace,
|
|
126
|
-
resource: cleanString(input.permit?.resource),
|
|
127
|
-
action: cleanString(input.permit?.action),
|
|
128
|
-
relation: cleanString(input.permit?.relation),
|
|
129
|
-
context
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
function createCanonicalAuthHeaders(authContext) {
|
|
134
|
-
const headers = {
|
|
135
|
-
"x-lucern-principal-id": authContext.principalId,
|
|
136
|
-
"x-lucern-principal-type": authContext.principalType,
|
|
137
|
-
"x-lucern-tenant": authContext.tenantId,
|
|
138
|
-
"x-lucern-tenant-id": authContext.tenantId,
|
|
139
|
-
"x-lucern-workspace": authContext.workspaceId,
|
|
140
|
-
"x-lucern-workspace-id": authContext.workspaceId,
|
|
141
|
-
"x-lucern-auth-mode": authContext.authMode,
|
|
142
|
-
"x-lucern-roles": authContext.roles.join(","),
|
|
143
|
-
"x-lucern-scopes": authContext.scopes.join(","),
|
|
144
|
-
"x-lucern-permit-context": JSON.stringify(authContext.permit)
|
|
145
|
-
};
|
|
146
|
-
if (authContext.clerkId) {
|
|
147
|
-
headers["x-lucern-clerk-id"] = authContext.clerkId;
|
|
148
|
-
headers["x-lucern-user-id"] = authContext.clerkId;
|
|
149
|
-
}
|
|
150
|
-
if (authContext.delegationChain.length > 0) {
|
|
151
|
-
headers["x-lucern-delegation-chain"] = JSON.stringify(
|
|
152
|
-
authContext.delegationChain
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
if (authContext.policyTraceId) {
|
|
156
|
-
headers["x-lucern-policy-trace-id"] = authContext.policyTraceId;
|
|
157
|
-
}
|
|
158
|
-
if (authContext.correlationId) {
|
|
159
|
-
headers["x-correlation-id"] = authContext.correlationId;
|
|
160
|
-
headers["x-lucern-correlation-id"] = authContext.correlationId;
|
|
161
|
-
}
|
|
162
|
-
if (authContext.membershipId) {
|
|
163
|
-
headers["x-lucern-membership-id"] = authContext.membershipId;
|
|
164
|
-
}
|
|
165
|
-
return headers;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
1
|
// src/coreClient.ts
|
|
169
2
|
var LucernApiError = class extends Error {
|
|
170
3
|
code;
|
|
@@ -232,7 +65,9 @@ function generatePortableRequestId() {
|
|
|
232
65
|
8
|
|
233
66
|
).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
234
67
|
}
|
|
235
|
-
|
|
68
|
+
function randomIdempotencyKey() {
|
|
69
|
+
return generatePortableRequestId();
|
|
70
|
+
}
|
|
236
71
|
function isRetryableStatus(status) {
|
|
237
72
|
return status >= 500 || status === 408 || status === 429;
|
|
238
73
|
}
|
|
@@ -297,11 +132,8 @@ function timeoutError(timeoutMs) {
|
|
|
297
132
|
error.name = "AbortError";
|
|
298
133
|
return error;
|
|
299
134
|
}
|
|
300
|
-
function isRecord(value) {
|
|
301
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
302
|
-
}
|
|
303
135
|
function readPolicySummaryFromDetails(details) {
|
|
304
|
-
if (!
|
|
136
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
|
305
137
|
return null;
|
|
306
138
|
}
|
|
307
139
|
const directSummary = details.summary;
|
|
@@ -309,11 +141,11 @@ function readPolicySummaryFromDetails(details) {
|
|
|
309
141
|
return directSummary.trim();
|
|
310
142
|
}
|
|
311
143
|
const policy = details.policy;
|
|
312
|
-
if (!
|
|
144
|
+
if (!policy || typeof policy !== "object" || Array.isArray(policy)) {
|
|
313
145
|
return null;
|
|
314
146
|
}
|
|
315
147
|
const explanation = policy.explanation;
|
|
316
|
-
if (!
|
|
148
|
+
if (!explanation || typeof explanation !== "object" || Array.isArray(explanation)) {
|
|
317
149
|
return null;
|
|
318
150
|
}
|
|
319
151
|
const nestedSummary = explanation.summary;
|
|
@@ -322,59 +154,16 @@ function readPolicySummaryFromDetails(details) {
|
|
|
322
154
|
}
|
|
323
155
|
return null;
|
|
324
156
|
}
|
|
325
|
-
async function resolveConfiguredAuthContext(authContext) {
|
|
326
|
-
if (typeof authContext === "function") {
|
|
327
|
-
return await authContext();
|
|
328
|
-
}
|
|
329
|
-
return authContext;
|
|
330
|
-
}
|
|
331
|
-
function mergeHeaderRecord(base, addition) {
|
|
332
|
-
const headers = new Headers(base);
|
|
333
|
-
for (const [key, value] of Object.entries(addition)) {
|
|
334
|
-
const existing = headers.get(key);
|
|
335
|
-
if (existing !== null && existing !== value) {
|
|
336
|
-
throw new LucernSdkAuthContextError(
|
|
337
|
-
"policy_denied",
|
|
338
|
-
`Canonical Lucern SDK auth context conflicts with existing ${key} header.`
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
headers.set(key, value);
|
|
342
|
-
}
|
|
343
|
-
return Object.fromEntries(headers.entries());
|
|
344
|
-
}
|
|
345
|
-
function cleanHeaderValue(value) {
|
|
346
|
-
const normalized = value?.trim();
|
|
347
|
-
return normalized ? normalized : void 0;
|
|
348
|
-
}
|
|
349
157
|
function createGatewayRequestClient(config = {}) {
|
|
350
158
|
const fetchImpl = config.fetchImpl ?? fetch;
|
|
351
159
|
const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
|
|
352
160
|
const maxRetries = config.maxRetries ?? 2;
|
|
353
161
|
const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
|
|
354
162
|
async function resolveAuthHeaders() {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const setIfAbsent = (name, value) => {
|
|
358
|
-
const normalized = cleanHeaderValue(value);
|
|
359
|
-
if (normalized && !headers.has(name)) {
|
|
360
|
-
headers.set(name, normalized);
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
setIfAbsent("x-lucern-key", config.apiKey);
|
|
364
|
-
setIfAbsent("x-lucern-session-token", config.userToken);
|
|
365
|
-
setIfAbsent("x-lucern-environment", config.environment);
|
|
366
|
-
setIfAbsent("x-lucern-clerk-id", config.clerkId);
|
|
367
|
-
setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
|
|
368
|
-
setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
|
|
369
|
-
const base = Object.fromEntries(headers.entries());
|
|
370
|
-
const authContextInput = await resolveConfiguredAuthContext(
|
|
371
|
-
config.authContext
|
|
372
|
-
);
|
|
373
|
-
if (!authContextInput && !config.requireCanonicalAuthContext) {
|
|
374
|
-
return base;
|
|
163
|
+
if (!config.getAuthHeaders) {
|
|
164
|
+
return {};
|
|
375
165
|
}
|
|
376
|
-
|
|
377
|
-
return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
|
|
166
|
+
return await config.getAuthHeaders();
|
|
378
167
|
}
|
|
379
168
|
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
380
169
|
const controller = new AbortController();
|
|
@@ -395,11 +184,11 @@ function createGatewayRequestClient(config = {}) {
|
|
|
395
184
|
if (!text) {
|
|
396
185
|
return null;
|
|
397
186
|
}
|
|
398
|
-
|
|
399
|
-
|
|
187
|
+
try {
|
|
188
|
+
return JSON.parse(text);
|
|
189
|
+
} catch {
|
|
400
190
|
return null;
|
|
401
191
|
}
|
|
402
|
-
return isRecord(parsed.value) ? parsed.value : null;
|
|
403
192
|
}
|
|
404
193
|
function resolveTimeoutMs(method, requestTimeoutMs) {
|
|
405
194
|
if (typeof requestTimeoutMs === "number") {
|
|
@@ -411,31 +200,16 @@ function createGatewayRequestClient(config = {}) {
|
|
|
411
200
|
}
|
|
412
201
|
return config.timeoutMs ?? 15e3;
|
|
413
202
|
}
|
|
414
|
-
function tryParseGatewayEnvelopeJson(text) {
|
|
415
|
-
const trimmed = text.trim();
|
|
416
|
-
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
417
|
-
return { ok: false, reason: "non-json" };
|
|
418
|
-
}
|
|
419
|
-
try {
|
|
420
|
-
return { ok: true, value: JSON.parse(trimmed) };
|
|
421
|
-
} catch (error) {
|
|
422
|
-
if (error instanceof SyntaxError) {
|
|
423
|
-
return { ok: false, reason: "invalid-json", error };
|
|
424
|
-
}
|
|
425
|
-
throw error;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
203
|
function buildApiError(args) {
|
|
429
204
|
const failure = args.failure;
|
|
430
|
-
const legacyError = failure &&
|
|
205
|
+
const legacyError = failure && typeof failure.error === "object" && failure.error !== null ? failure.error : failure?.legacyError;
|
|
431
206
|
const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
|
|
432
207
|
const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
|
|
433
208
|
const details = failure?.details ?? legacyError?.details;
|
|
434
209
|
const policySummary = readPolicySummaryFromDetails(details);
|
|
435
|
-
const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
|
|
436
210
|
return new LucernApiError({
|
|
437
211
|
code: failure?.code ?? legacyError?.code ?? fallbackErrorCode(args.response.status),
|
|
438
|
-
message: policySummary ??
|
|
212
|
+
message: policySummary ?? (typeof failure?.error === "string" ? failure.error : legacyError?.message ?? (args.response.ok ? "Platform API returned an invalid success payload." : "Platform API request failed.")),
|
|
439
213
|
status: args.response.status,
|
|
440
214
|
invariant: failure?.invariant,
|
|
441
215
|
suggestion: failure?.suggestion,
|
|
@@ -567,10 +341,7 @@ function createListResult(items, legacyKey) {
|
|
|
567
341
|
total: items.length
|
|
568
342
|
};
|
|
569
343
|
if (legacyKey) {
|
|
570
|
-
|
|
571
|
-
...result,
|
|
572
|
-
[legacyKey]: items
|
|
573
|
-
};
|
|
344
|
+
result[legacyKey] = items;
|
|
574
345
|
}
|
|
575
346
|
return result;
|
|
576
347
|
}
|
|
@@ -608,17 +379,6 @@ function asTenantVaultSecretArray(data) {
|
|
|
608
379
|
}
|
|
609
380
|
function createAdminClient(config = {}) {
|
|
610
381
|
const gateway = createGatewayRequestClient(config);
|
|
611
|
-
const getControlObjectOwnership = async () => gateway.request({
|
|
612
|
-
path: "/api/platform/v1/admin/control-ownership"
|
|
613
|
-
});
|
|
614
|
-
const createMembership = async (input, idempotencyKey) => gateway.request({
|
|
615
|
-
path: "/api/platform/v1/memberships",
|
|
616
|
-
method: "POST",
|
|
617
|
-
body: input,
|
|
618
|
-
idempotencyKey: idempotencyKey ?? randomIdempotencyKey()
|
|
619
|
-
});
|
|
620
|
-
const updateMembership = createMembership;
|
|
621
|
-
const upsertMembership = createMembership;
|
|
622
382
|
return {
|
|
623
383
|
/**
|
|
624
384
|
* List tenants visible to the current principal.
|
|
@@ -650,11 +410,19 @@ function createAdminClient(config = {}) {
|
|
|
650
410
|
/**
|
|
651
411
|
* Get the control-object ownership contract.
|
|
652
412
|
*/
|
|
653
|
-
getControlObjectOwnership
|
|
413
|
+
async getControlObjectOwnership() {
|
|
414
|
+
return gateway.request({
|
|
415
|
+
path: "/api/platform/v1/admin/control-ownership"
|
|
416
|
+
});
|
|
417
|
+
},
|
|
654
418
|
/**
|
|
655
419
|
* @deprecated Use getControlObjectOwnership.
|
|
656
420
|
*/
|
|
657
|
-
getControlObjectOwnershipContract
|
|
421
|
+
async getControlObjectOwnershipContract() {
|
|
422
|
+
return gateway.request({
|
|
423
|
+
path: "/api/platform/v1/admin/control-ownership"
|
|
424
|
+
});
|
|
425
|
+
},
|
|
658
426
|
/**
|
|
659
427
|
* List workspaces for the current admin scope.
|
|
660
428
|
*/
|
|
@@ -701,15 +469,26 @@ function createAdminClient(config = {}) {
|
|
|
701
469
|
/**
|
|
702
470
|
* Create a membership.
|
|
703
471
|
*/
|
|
704
|
-
createMembership,
|
|
472
|
+
async createMembership(input, idempotencyKey) {
|
|
473
|
+
return gateway.request({
|
|
474
|
+
path: "/api/platform/v1/memberships",
|
|
475
|
+
method: "POST",
|
|
476
|
+
body: input,
|
|
477
|
+
idempotencyKey: idempotencyKey ?? randomIdempotencyKey()
|
|
478
|
+
});
|
|
479
|
+
},
|
|
705
480
|
/**
|
|
706
481
|
* Update a membership.
|
|
707
482
|
*/
|
|
708
|
-
updateMembership,
|
|
483
|
+
async updateMembership(input, idempotencyKey) {
|
|
484
|
+
return this.createMembership(input, idempotencyKey);
|
|
485
|
+
},
|
|
709
486
|
/**
|
|
710
487
|
* @deprecated Use createMembership or updateMembership.
|
|
711
488
|
*/
|
|
712
|
-
upsertMembership,
|
|
489
|
+
async upsertMembership(input, idempotencyKey) {
|
|
490
|
+
return this.createMembership(input, idempotencyKey);
|
|
491
|
+
},
|
|
713
492
|
/**
|
|
714
493
|
* List tenant API keys in the current admin scope.
|
|
715
494
|
*/
|