@to11ai/sdk 0.0.2 → 0.1.1

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/dist/errors.cjs CHANGED
@@ -44,7 +44,12 @@ __export(exports_errors, {
44
44
  To11aiNetworkError: () => To11aiNetworkError,
45
45
  To11aiError: () => To11aiError,
46
46
  To11aiAuthError: () => To11aiAuthError,
47
- To11aiApiError: () => To11aiApiError
47
+ To11aiApiError: () => To11aiApiError,
48
+ RuleVersionInvalidSnapshotError: () => RuleVersionInvalidSnapshotError,
49
+ RuleNotFoundError: () => RuleNotFoundError,
50
+ PromptLabelNotRegisteredError: () => PromptLabelNotRegisteredError,
51
+ NoApplicableRouteError: () => NoApplicableRouteError,
52
+ EnvNotEnabledForProviderError: () => EnvNotEnabledForProviderError
48
53
  });
49
54
  module.exports = __toCommonJS(exports_errors);
50
55
 
@@ -103,3 +108,86 @@ class To11aiNetworkError extends To11aiError {
103
108
  Object.setPrototypeOf(this, new.target.prototype);
104
109
  }
105
110
  }
111
+
112
+ class PromptLabelNotRegisteredError extends To11aiApiError {
113
+ projectId;
114
+ label;
115
+ constructor(message, projectId, label, details) {
116
+ super(message, 422, "PROMPT_LABEL_NOT_REGISTERED", details !== undefined ? details : { projectId, label });
117
+ this.name = "PromptLabelNotRegisteredError";
118
+ this.projectId = projectId;
119
+ this.label = label;
120
+ Object.setPrototypeOf(this, new.target.prototype);
121
+ }
122
+ static is(err) {
123
+ return err instanceof PromptLabelNotRegisteredError;
124
+ }
125
+ }
126
+
127
+ class RuleNotFoundError extends To11aiApiError {
128
+ ruleId;
129
+ model;
130
+ env;
131
+ constructor(message, errorCode, fields, details) {
132
+ super(message, 404, errorCode, details);
133
+ this.name = "RuleNotFoundError";
134
+ this.ruleId = fields.ruleId;
135
+ this.model = fields.model;
136
+ this.env = fields.env;
137
+ Object.setPrototypeOf(this, new.target.prototype);
138
+ }
139
+ static is(err) {
140
+ return err instanceof RuleNotFoundError;
141
+ }
142
+ }
143
+
144
+ class NoApplicableRouteError extends To11aiApiError {
145
+ ruleId;
146
+ versionId;
147
+ reason;
148
+ constructor(message, fields, details) {
149
+ super(message, 422, "NO_APPLICABLE_ROUTE", details);
150
+ this.name = "NoApplicableRouteError";
151
+ this.ruleId = fields.ruleId;
152
+ this.versionId = fields.versionId;
153
+ this.reason = fields.reason;
154
+ Object.setPrototypeOf(this, new.target.prototype);
155
+ }
156
+ static is(err) {
157
+ return err instanceof NoApplicableRouteError;
158
+ }
159
+ }
160
+
161
+ class EnvNotEnabledForProviderError extends To11aiApiError {
162
+ ruleId;
163
+ envSlug;
164
+ providerId;
165
+ constructor(message, fields, details) {
166
+ super(message, 422, "ENV_NOT_ENABLED_FOR_PROVIDER", details);
167
+ this.name = "EnvNotEnabledForProviderError";
168
+ this.ruleId = fields.ruleId;
169
+ this.envSlug = fields.envSlug;
170
+ this.providerId = fields.providerId;
171
+ Object.setPrototypeOf(this, new.target.prototype);
172
+ }
173
+ static is(err) {
174
+ return err instanceof EnvNotEnabledForProviderError;
175
+ }
176
+ }
177
+
178
+ class RuleVersionInvalidSnapshotError extends To11aiApiError {
179
+ field;
180
+ reason;
181
+ variantName;
182
+ constructor(message, errorCode, fields, details, statusCode = 400) {
183
+ super(message, statusCode, errorCode, details);
184
+ this.name = "RuleVersionInvalidSnapshotError";
185
+ this.field = fields.field;
186
+ this.reason = fields.reason;
187
+ this.variantName = fields.variantName;
188
+ Object.setPrototypeOf(this, new.target.prototype);
189
+ }
190
+ static is(err) {
191
+ return err instanceof RuleVersionInvalidSnapshotError;
192
+ }
193
+ }
package/dist/errors.d.ts CHANGED
@@ -38,3 +38,99 @@ export declare class To11aiRateLimitError extends To11aiApiError {
38
38
  export declare class To11aiNetworkError extends To11aiError {
39
39
  constructor(message: string, cause?: unknown);
40
40
  }
41
+ /**
42
+ * Thrown when strict-mode rejects a label move for an unregistered label.
43
+ *
44
+ * The API returns 422 with `error.code === "PROMPT_LABEL_NOT_REGISTERED"`
45
+ * when `project.enforce_label_registry = true` and the caller tries to
46
+ * move a label that has no active entry in the project label registry.
47
+ * The transport surfaces these as this typed subclass; existing
48
+ * `instanceof To11aiApiError` blocks still match.
49
+ *
50
+ * Note: this extends `To11aiApiError` directly (not `To11aiValidationError`,
51
+ * which hardcodes status 400). The API returns 422 for this case.
52
+ */
53
+ export declare class PromptLabelNotRegisteredError extends To11aiApiError {
54
+ readonly projectId: string;
55
+ readonly label: string;
56
+ constructor(message: string, projectId: string, label: string, details?: unknown);
57
+ /** Type guard helper — checks `instanceof` (not parent + errorCode string). */
58
+ static is(err: unknown): err is PromptLabelNotRegisteredError;
59
+ }
60
+ /**
61
+ * Thrown when a rule cannot be located. Covers two variants of the same
62
+ * named class (single class so existing `catch (err: RuleNotFoundError)`
63
+ * blocks match both):
64
+ *
65
+ * * Control-plane variant (404 `RULE_NOT_FOUND`) — `ruleId` is the id
66
+ * the caller supplied and that did not exist in the project.
67
+ * * Gateway variant (404 `RULE_NOT_FOUND_IN_ENV`) — `model` is the
68
+ * `function::<alias>` (or raw model id) the gateway tried to resolve
69
+ * and `env` is the request env. `ruleId` is undefined because the
70
+ * alias may not resolve to any rule in the env.
71
+ */
72
+ export declare class RuleNotFoundError extends To11aiApiError {
73
+ readonly ruleId: string | undefined;
74
+ readonly model: string | undefined;
75
+ readonly env: string | undefined;
76
+ constructor(message: string, errorCode: string, fields: {
77
+ ruleId?: string;
78
+ model?: string;
79
+ env?: string;
80
+ }, details?: unknown);
81
+ static is(err: unknown): err is RuleNotFoundError;
82
+ }
83
+ export type NoApplicableRouteReason = "all_conditions_false" | "all_variants_unreachable" | "all_steps_non_routable";
84
+ /**
85
+ * Thrown when the gateway resolved a rule + version but no variant /
86
+ * step / chain element was applicable to the request — every condition
87
+ * was false, every variant unreachable, or every fallback step
88
+ * non-routable. Surfaces as 422 `NO_APPLICABLE_ROUTE`.
89
+ */
90
+ export declare class NoApplicableRouteError extends To11aiApiError {
91
+ readonly ruleId: string;
92
+ readonly versionId: string;
93
+ readonly reason: NoApplicableRouteReason | string;
94
+ constructor(message: string, fields: {
95
+ ruleId: string;
96
+ versionId: string;
97
+ reason: string;
98
+ }, details?: unknown);
99
+ static is(err: unknown): err is NoApplicableRouteError;
100
+ }
101
+ /**
102
+ * Thrown when a rule references a provider that has no activation in the
103
+ * requested env. Surfaces as 422 `ENV_NOT_ENABLED_FOR_PROVIDER`.
104
+ */
105
+ export declare class EnvNotEnabledForProviderError extends To11aiApiError {
106
+ readonly ruleId: string;
107
+ readonly envSlug: string;
108
+ readonly providerId: string;
109
+ constructor(message: string, fields: {
110
+ ruleId: string;
111
+ envSlug: string;
112
+ providerId: string;
113
+ }, details?: unknown);
114
+ static is(err: unknown): err is EnvNotEnabledForProviderError;
115
+ }
116
+ /**
117
+ * Thrown when version create rejects the snapshot for a structural
118
+ * reason — invalid variant params, malformed `when` clause, illegal
119
+ * weight set, malformed retry policy, … Surfaces with one of the
120
+ * `INVALID_VARIANT_PARAMS` / `INVALID_VARIANT_WEIGHTS` /
121
+ * `INVALID_RULE_STRATEGY` / `INVALID_STEP_COUNT` /
122
+ * `RULE_ENDPOINT_MISMATCH` / `INVALID_WHEN_CLAUSE` /
123
+ * `INVALID_STRATEGY_VARIANTS` / `INVALID_RETRY_POLICY` error codes
124
+ * at HTTP status 400 or 422.
125
+ */
126
+ export declare class RuleVersionInvalidSnapshotError extends To11aiApiError {
127
+ readonly field: string | undefined;
128
+ readonly reason: string | undefined;
129
+ readonly variantName: string | undefined;
130
+ constructor(message: string, errorCode: string, fields: {
131
+ field?: string;
132
+ reason?: string;
133
+ variantName?: string;
134
+ }, details?: unknown, statusCode?: number);
135
+ static is(err: unknown): err is RuleVersionInvalidSnapshotError;
136
+ }
package/dist/errors.js CHANGED
@@ -54,11 +54,99 @@ class To11aiNetworkError extends To11aiError {
54
54
  Object.setPrototypeOf(this, new.target.prototype);
55
55
  }
56
56
  }
57
+
58
+ class PromptLabelNotRegisteredError extends To11aiApiError {
59
+ projectId;
60
+ label;
61
+ constructor(message, projectId, label, details) {
62
+ super(message, 422, "PROMPT_LABEL_NOT_REGISTERED", details !== undefined ? details : { projectId, label });
63
+ this.name = "PromptLabelNotRegisteredError";
64
+ this.projectId = projectId;
65
+ this.label = label;
66
+ Object.setPrototypeOf(this, new.target.prototype);
67
+ }
68
+ static is(err) {
69
+ return err instanceof PromptLabelNotRegisteredError;
70
+ }
71
+ }
72
+
73
+ class RuleNotFoundError extends To11aiApiError {
74
+ ruleId;
75
+ model;
76
+ env;
77
+ constructor(message, errorCode, fields, details) {
78
+ super(message, 404, errorCode, details);
79
+ this.name = "RuleNotFoundError";
80
+ this.ruleId = fields.ruleId;
81
+ this.model = fields.model;
82
+ this.env = fields.env;
83
+ Object.setPrototypeOf(this, new.target.prototype);
84
+ }
85
+ static is(err) {
86
+ return err instanceof RuleNotFoundError;
87
+ }
88
+ }
89
+
90
+ class NoApplicableRouteError extends To11aiApiError {
91
+ ruleId;
92
+ versionId;
93
+ reason;
94
+ constructor(message, fields, details) {
95
+ super(message, 422, "NO_APPLICABLE_ROUTE", details);
96
+ this.name = "NoApplicableRouteError";
97
+ this.ruleId = fields.ruleId;
98
+ this.versionId = fields.versionId;
99
+ this.reason = fields.reason;
100
+ Object.setPrototypeOf(this, new.target.prototype);
101
+ }
102
+ static is(err) {
103
+ return err instanceof NoApplicableRouteError;
104
+ }
105
+ }
106
+
107
+ class EnvNotEnabledForProviderError extends To11aiApiError {
108
+ ruleId;
109
+ envSlug;
110
+ providerId;
111
+ constructor(message, fields, details) {
112
+ super(message, 422, "ENV_NOT_ENABLED_FOR_PROVIDER", details);
113
+ this.name = "EnvNotEnabledForProviderError";
114
+ this.ruleId = fields.ruleId;
115
+ this.envSlug = fields.envSlug;
116
+ this.providerId = fields.providerId;
117
+ Object.setPrototypeOf(this, new.target.prototype);
118
+ }
119
+ static is(err) {
120
+ return err instanceof EnvNotEnabledForProviderError;
121
+ }
122
+ }
123
+
124
+ class RuleVersionInvalidSnapshotError extends To11aiApiError {
125
+ field;
126
+ reason;
127
+ variantName;
128
+ constructor(message, errorCode, fields, details, statusCode = 400) {
129
+ super(message, statusCode, errorCode, details);
130
+ this.name = "RuleVersionInvalidSnapshotError";
131
+ this.field = fields.field;
132
+ this.reason = fields.reason;
133
+ this.variantName = fields.variantName;
134
+ Object.setPrototypeOf(this, new.target.prototype);
135
+ }
136
+ static is(err) {
137
+ return err instanceof RuleVersionInvalidSnapshotError;
138
+ }
139
+ }
57
140
  export {
58
141
  To11aiValidationError,
59
142
  To11aiRateLimitError,
60
143
  To11aiNetworkError,
61
144
  To11aiError,
62
145
  To11aiAuthError,
63
- To11aiApiError
146
+ To11aiApiError,
147
+ RuleVersionInvalidSnapshotError,
148
+ RuleNotFoundError,
149
+ PromptLabelNotRegisteredError,
150
+ NoApplicableRouteError,
151
+ EnvNotEnabledForProviderError
64
152
  };
package/dist/gateway.cjs CHANGED
@@ -50,10 +50,17 @@ function gatewayAuthHeaders(options) {
50
50
  if (options.projectId.trim().length === 0) {
51
51
  throw new Error("[to11ai/sdk] `projectId` must not be empty.");
52
52
  }
53
- return {
53
+ const headers = {
54
54
  "x-to11-authorization": `Bearer ${options.apiKey}`,
55
55
  "x-to11-project-id": options.projectId
56
56
  };
57
+ if (options.env !== undefined) {
58
+ if (options.env.trim().length === 0) {
59
+ throw new Error("[to11ai/sdk] `env` must not be empty — omit the field to use the project's gateway-fallback environment.");
60
+ }
61
+ headers["x-to11-env"] = options.env;
62
+ }
63
+ return headers;
57
64
  }
58
65
  function gatewayPromptHeaders(prompt) {
59
66
  const headers = {
package/dist/gateway.d.ts CHANGED
@@ -2,12 +2,31 @@ import type { ResolvedPrompt } from "./prompts/types";
2
2
  export interface GatewayAuthOptions {
3
3
  apiKey: string;
4
4
  projectId: string;
5
+ /**
6
+ * Optional environment slug routed via the gateway's `x-to11-env`
7
+ * header. When omitted, the gateway falls back to the project's
8
+ * `is_gateway_fallback=true` environment; if no fallback exists, the
9
+ * request fails with `400 missing_env_no_project_default`.
10
+ *
11
+ * Slug validation matches the project-environments registry:
12
+ * lowercase-kebab (`a-z`, `0-9`, `-`, 1..63 chars). The SDK rejects
13
+ * empty / whitespace-only values eagerly so misconfiguration surfaces
14
+ * before the request hits the wire.
15
+ */
16
+ env?: string;
5
17
  }
6
18
  /**
7
19
  * Build the auth headers required for every request through the to11 gateway.
8
20
  *
21
+ * Includes `x-to11-env: <slug>` when `options.env` is set — see the
22
+ * environments-registry spec for gateway routing semantics. Empty /
23
+ * whitespace-only env values throw immediately so caller misconfiguration
24
+ * is loud.
25
+ *
9
26
  * @example
10
27
  * const headers = gatewayAuthHeaders({ apiKey, projectId });
28
+ * @example
29
+ * const headers = gatewayAuthHeaders({ apiKey, projectId, env: "staging" });
11
30
  */
12
31
  export declare function gatewayAuthHeaders(options: GatewayAuthOptions): Record<string, string>;
13
32
  /**
package/dist/gateway.js CHANGED
@@ -6,10 +6,17 @@ function gatewayAuthHeaders(options) {
6
6
  if (options.projectId.trim().length === 0) {
7
7
  throw new Error("[to11ai/sdk] `projectId` must not be empty.");
8
8
  }
9
- return {
9
+ const headers = {
10
10
  "x-to11-authorization": `Bearer ${options.apiKey}`,
11
11
  "x-to11-project-id": options.projectId
12
12
  };
13
+ if (options.env !== undefined) {
14
+ if (options.env.trim().length === 0) {
15
+ throw new Error("[to11ai/sdk] `env` must not be empty — omit the field to use the project's gateway-fallback environment.");
16
+ }
17
+ headers["x-to11-env"] = options.env;
18
+ }
19
+ return headers;
13
20
  }
14
21
  function gatewayPromptHeaders(prompt) {
15
22
  const headers = {
@@ -0,0 +1,110 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
8
+ var __toCommonJS = (from) => {
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
+ if (entry)
11
+ return entry;
12
+ entry = __defProp({}, "__esModule", { value: true });
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ __moduleCache.set(from, entry);
22
+ return entry;
23
+ };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
29
+ var __export = (target, all) => {
30
+ for (var name in all)
31
+ __defProp(target, name, {
32
+ get: all[name],
33
+ enumerable: true,
34
+ configurable: true,
35
+ set: __exportSetter.bind(all, name)
36
+ });
37
+ };
38
+
39
+ // src/projectEnvironments/resource.ts
40
+ var exports_resource = {};
41
+ __export(exports_resource, {
42
+ ProjectEnvironmentResource: () => ProjectEnvironmentResource
43
+ });
44
+ module.exports = __toCommonJS(exports_resource);
45
+ function unwrap(envelope) {
46
+ if (envelope.data === null || envelope.data === undefined) {
47
+ throw new Error("API returned success but data is null");
48
+ }
49
+ return envelope.data;
50
+ }
51
+ function projectEnvironmentsPath(projectId) {
52
+ return `/v1/projects/${encodeURIComponent(projectId)}/environments`;
53
+ }
54
+ function projectEnvironmentPath(projectId, slug) {
55
+ return `${projectEnvironmentsPath(projectId)}/${encodeURIComponent(slug)}`;
56
+ }
57
+
58
+ class ProjectEnvironmentResource {
59
+ transport;
60
+ constructor(transport) {
61
+ this.transport = transport;
62
+ }
63
+ async list(input) {
64
+ const envelope = await this.transport.request("GET", projectEnvironmentsPath(input.projectId), {
65
+ query: input.includeArchived ? { includeArchived: "true" } : undefined
66
+ });
67
+ return unwrap(envelope);
68
+ }
69
+ async get(input) {
70
+ const envelope = await this.transport.request("GET", projectEnvironmentPath(input.projectId, input.slug));
71
+ return unwrap(envelope);
72
+ }
73
+ async create(input) {
74
+ const { projectId, ...body } = input;
75
+ const envelope = await this.transport.request("POST", projectEnvironmentsPath(projectId), { body });
76
+ return unwrap(envelope);
77
+ }
78
+ async update(input) {
79
+ const { projectId, slug, newSlug, ...rest } = input;
80
+ const body = {};
81
+ if (newSlug !== undefined)
82
+ body.slug = newSlug;
83
+ if (rest.name !== undefined)
84
+ body.name = rest.name;
85
+ if (rest.color !== undefined)
86
+ body.color = rest.color;
87
+ if (rest.description !== undefined)
88
+ body.description = rest.description;
89
+ if (rest.isPointer !== undefined)
90
+ body.isPointer = rest.isPointer;
91
+ if (rest.requiresApproval !== undefined)
92
+ body.requiresApproval = rest.requiresApproval;
93
+ if (rest.isDefault !== undefined)
94
+ body.isDefault = rest.isDefault;
95
+ if (rest.isGatewayFallback !== undefined)
96
+ body.isGatewayFallback = rest.isGatewayFallback;
97
+ if (rest.sortOrder !== undefined)
98
+ body.sortOrder = rest.sortOrder;
99
+ const envelope = await this.transport.request("PATCH", projectEnvironmentPath(projectId, slug), { body });
100
+ return unwrap(envelope);
101
+ }
102
+ async archive(input) {
103
+ const envelope = await this.transport.request("POST", `${projectEnvironmentPath(input.projectId, input.slug)}/archive`);
104
+ return unwrap(envelope);
105
+ }
106
+ async restore(input) {
107
+ const envelope = await this.transport.request("POST", `${projectEnvironmentPath(input.projectId, input.slug)}/restore`);
108
+ return unwrap(envelope);
109
+ }
110
+ }
@@ -0,0 +1,67 @@
1
+ import type { Transport } from "../transport";
2
+ import type { ArchiveProjectEnvironmentInput, ArchiveProjectEnvironmentResult, CreateProjectEnvironmentInput, CreateProjectEnvironmentResult, GetProjectEnvironmentInput, GetProjectEnvironmentResult, ListProjectEnvironmentsInput, ListProjectEnvironmentsResult, RestoreProjectEnvironmentInput, RestoreProjectEnvironmentResult, UpdateProjectEnvironmentInput, UpdateProjectEnvironmentResult } from "./types";
3
+ export type { ArchiveProjectEnvironmentInput, ArchiveProjectEnvironmentResult, CreateProjectEnvironmentInput, CreateProjectEnvironmentResult, GetProjectEnvironmentInput, GetProjectEnvironmentResult, ListProjectEnvironmentsInput, ListProjectEnvironmentsResult, LivePointerCounts, ProjectEnvironment, RestoreProjectEnvironmentInput, RestoreProjectEnvironmentResult, UpdateProjectEnvironmentInput, UpdateProjectEnvironmentResult, } from "./types";
4
+ /**
5
+ * SDK resource for `/v1/projects/:projectId/environments`. Constructed by
6
+ * `createClient` and exposed as `client.projectEnvironments`.
7
+ */
8
+ export declare class ProjectEnvironmentResource {
9
+ private readonly transport;
10
+ constructor(transport: Transport);
11
+ /**
12
+ * List the project's environments. Excludes archived rows by default —
13
+ * pass `includeArchived: true` to include rows with a non-null
14
+ * `archivedAt` (used by the admin / restore UI).
15
+ */
16
+ list(input: ListProjectEnvironmentsInput): Promise<ListProjectEnvironmentsResult>;
17
+ get(input: GetProjectEnvironmentInput): Promise<GetProjectEnvironmentResult>;
18
+ /**
19
+ * Create a new environment.
20
+ *
21
+ * `slug` must match lowercase-kebab (`a-z`, `0-9`, `-`, 1..63 chars).
22
+ * Reserved system slugs (`prod`, `staging`) and any already-used slug
23
+ * return 409 `ENVIRONMENT_SLUG_TAKEN`.
24
+ *
25
+ * Setting `isGatewayFallback: true` additionally requires the
26
+ * `project:manage_default_environment` capability; the create use
27
+ * case clears the flag on any other env in the same project.
28
+ */
29
+ create(input: CreateProjectEnvironmentInput): Promise<CreateProjectEnvironmentResult>;
30
+ /**
31
+ * PATCH an environment.
32
+ *
33
+ * - System envs (`isSystem: true`) reject `slug`/`isSystem`/immutable-
34
+ * field mutations with 409 `SYSTEM_ENV_IMMUTABLE`.
35
+ * - Renaming via `newSlug` triggers a 7-day alias row server-side so
36
+ * in-flight gateway requests carrying the old slug keep resolving.
37
+ * - Mutating `isGatewayFallback` requires the
38
+ * `project:manage_default_environment` capability AND the target
39
+ * env must have at least one live snapshot (else 409
40
+ * `FALLBACK_ENV_NOT_READY`).
41
+ *
42
+ * The SDK marshals `newSlug` onto the wire as `slug` (the API accepts
43
+ * `slug` on the PATCH body for a rename — the URL slug stays the
44
+ * pre-rename identifier).
45
+ */
46
+ update(input: UpdateProjectEnvironmentInput): Promise<UpdateProjectEnvironmentResult>;
47
+ /**
48
+ * Soft-archive an environment. The response carries the archived row
49
+ * plus a `livePointerCounts` summary (informational — pointers are
50
+ * cascade-cleared by the use case).
51
+ *
52
+ * System envs (`isSystem: true`) and the current gateway-fallback env
53
+ * cannot be archived; the API returns 409 `SYSTEM_ENV_IMMUTABLE` or
54
+ * `CANNOT_ARCHIVE_GATEWAY_FALLBACK` respectively.
55
+ *
56
+ * Uses `POST /:slug/archive` rather than `DELETE` so the server can
57
+ * return a structured 200 with the archived row + counts.
58
+ */
59
+ archive(input: ArchiveProjectEnvironmentInput): Promise<ArchiveProjectEnvironmentResult>;
60
+ /**
61
+ * Restore a previously-archived environment. The server resets
62
+ * `archivedAt` to `null` and returns the live row. No-op if the env
63
+ * is already live; returns 404 `ENVIRONMENT_NOT_FOUND` if the slug
64
+ * has never existed.
65
+ */
66
+ restore(input: RestoreProjectEnvironmentInput): Promise<RestoreProjectEnvironmentResult>;
67
+ }
@@ -0,0 +1,70 @@
1
+ // src/projectEnvironments/resource.ts
2
+ function unwrap(envelope) {
3
+ if (envelope.data === null || envelope.data === undefined) {
4
+ throw new Error("API returned success but data is null");
5
+ }
6
+ return envelope.data;
7
+ }
8
+ function projectEnvironmentsPath(projectId) {
9
+ return `/v1/projects/${encodeURIComponent(projectId)}/environments`;
10
+ }
11
+ function projectEnvironmentPath(projectId, slug) {
12
+ return `${projectEnvironmentsPath(projectId)}/${encodeURIComponent(slug)}`;
13
+ }
14
+
15
+ class ProjectEnvironmentResource {
16
+ transport;
17
+ constructor(transport) {
18
+ this.transport = transport;
19
+ }
20
+ async list(input) {
21
+ const envelope = await this.transport.request("GET", projectEnvironmentsPath(input.projectId), {
22
+ query: input.includeArchived ? { includeArchived: "true" } : undefined
23
+ });
24
+ return unwrap(envelope);
25
+ }
26
+ async get(input) {
27
+ const envelope = await this.transport.request("GET", projectEnvironmentPath(input.projectId, input.slug));
28
+ return unwrap(envelope);
29
+ }
30
+ async create(input) {
31
+ const { projectId, ...body } = input;
32
+ const envelope = await this.transport.request("POST", projectEnvironmentsPath(projectId), { body });
33
+ return unwrap(envelope);
34
+ }
35
+ async update(input) {
36
+ const { projectId, slug, newSlug, ...rest } = input;
37
+ const body = {};
38
+ if (newSlug !== undefined)
39
+ body.slug = newSlug;
40
+ if (rest.name !== undefined)
41
+ body.name = rest.name;
42
+ if (rest.color !== undefined)
43
+ body.color = rest.color;
44
+ if (rest.description !== undefined)
45
+ body.description = rest.description;
46
+ if (rest.isPointer !== undefined)
47
+ body.isPointer = rest.isPointer;
48
+ if (rest.requiresApproval !== undefined)
49
+ body.requiresApproval = rest.requiresApproval;
50
+ if (rest.isDefault !== undefined)
51
+ body.isDefault = rest.isDefault;
52
+ if (rest.isGatewayFallback !== undefined)
53
+ body.isGatewayFallback = rest.isGatewayFallback;
54
+ if (rest.sortOrder !== undefined)
55
+ body.sortOrder = rest.sortOrder;
56
+ const envelope = await this.transport.request("PATCH", projectEnvironmentPath(projectId, slug), { body });
57
+ return unwrap(envelope);
58
+ }
59
+ async archive(input) {
60
+ const envelope = await this.transport.request("POST", `${projectEnvironmentPath(input.projectId, input.slug)}/archive`);
61
+ return unwrap(envelope);
62
+ }
63
+ async restore(input) {
64
+ const envelope = await this.transport.request("POST", `${projectEnvironmentPath(input.projectId, input.slug)}/restore`);
65
+ return unwrap(envelope);
66
+ }
67
+ }
68
+ export {
69
+ ProjectEnvironmentResource
70
+ };