catalyst-relay 0.6.4 → 0.6.6

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/index.d.mts CHANGED
@@ -598,6 +598,66 @@ interface SearchOptions {
598
598
  */
599
599
  type ClassIncludeType = 'definitions' | 'implementations' | 'macros' | 'testclasses';
600
600
 
601
+ /**
602
+ * API Release types — shared across the apirelease module
603
+ *
604
+ * Models the C1 release contract of a CDS DDL source (DDLS). SAP exposes a
605
+ * generic API release framework (contracts C0–C4); this module is scoped to
606
+ * the C1 (customer / SAP Cloud Platform) contract on CDS queries.
607
+ */
608
+ /**
609
+ * Release status of an API contract.
610
+ *
611
+ * These are the states SAP reports for the C1 contract on a CDS DDL source.
612
+ */
613
+ type ApiReleaseStatus = 'NOT_RELEASED' | 'RELEASED' | 'DEPRECATED' | 'NOT_TO_BE_RELEASED' | 'NOT_TO_BE_RELEASED_STABLE';
614
+ /**
615
+ * A message returned by the contract validation run (pre-flight check).
616
+ *
617
+ * Warnings (e.g. "referenced data element is not released") are informational
618
+ * and do not block the operation; errors do.
619
+ */
620
+ interface ApiReleaseValidationMessage {
621
+ severity: 'error' | 'warning' | 'info';
622
+ text: string;
623
+ /** SAP message class (e.g. ARS_DEP_CHECKS), if present. */
624
+ msgid?: string;
625
+ /** SAP message number, if present. */
626
+ msgno?: string;
627
+ }
628
+ /**
629
+ * Current C1 release state of a CDS DDL source.
630
+ */
631
+ interface ApiReleaseState {
632
+ /** Object name (e.g. ZSNAP_F04S_Q01). */
633
+ name: string;
634
+ /** Releasable object ADT URI (e.g. /sap/bc/adt/ddic/ddl/sources/zsnap_f04s_q01). */
635
+ uri: string;
636
+ /** Current C1 contract status. */
637
+ status: ApiReleaseStatus;
638
+ /** Human-readable status description (e.g. "Released"). */
639
+ statusDescription: string;
640
+ /** Convenience flag: true when status is RELEASED. */
641
+ released: boolean;
642
+ /** States the C1 contract can transition to from the current status. */
643
+ allowedTransitions: ApiReleaseStatus[];
644
+ /** User who last changed the C1 contract, if any. */
645
+ changedBy?: string;
646
+ /** Timestamp the C1 contract was last changed, if any. */
647
+ changedAt?: string;
648
+ }
649
+ /**
650
+ * Result of a release / unrelease operation.
651
+ */
652
+ interface ApiReleaseResult {
653
+ /** Object name (e.g. ZSNAP_F04S_Q01). */
654
+ name: string;
655
+ /** Resulting C1 contract status after the operation. */
656
+ status: ApiReleaseStatus;
657
+ /** Non-blocking validation messages surfaced during the operation. */
658
+ messages: ApiReleaseValidationMessage[];
659
+ }
660
+
601
661
  /**
602
662
  * Create Transport — create a new transport request.
603
663
  *
@@ -775,6 +835,9 @@ interface ADTClient {
775
835
  gitDiff(objects: ObjectContent[]): AsyncResult<DiffResult[]>;
776
836
  createServiceBinding(options: CreateServiceBindingOptions): AsyncResult<ServiceBindingResult>;
777
837
  deleteServiceBinding(bindingName: string, transport?: string): AsyncResult<void>;
838
+ getApiReleaseState(objectName: string): AsyncResult<ApiReleaseState>;
839
+ releaseApi(objectName: string, transport?: string): AsyncResult<ApiReleaseResult>;
840
+ unreleaseApi(objectName: string, transport?: string): AsyncResult<ApiReleaseResult>;
778
841
  getObjectConfig(): ObjectConfig[];
779
842
  }
780
843
 
@@ -800,4 +863,4 @@ declare function activateLogging(): void;
800
863
  */
801
864
  declare function deactivateLogging(): void;
802
865
 
803
- export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
866
+ export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiReleaseResult, type ApiReleaseState, type ApiReleaseStatus, type ApiReleaseValidationMessage, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
package/dist/index.d.ts CHANGED
@@ -598,6 +598,66 @@ interface SearchOptions {
598
598
  */
599
599
  type ClassIncludeType = 'definitions' | 'implementations' | 'macros' | 'testclasses';
600
600
 
601
+ /**
602
+ * API Release types — shared across the apirelease module
603
+ *
604
+ * Models the C1 release contract of a CDS DDL source (DDLS). SAP exposes a
605
+ * generic API release framework (contracts C0–C4); this module is scoped to
606
+ * the C1 (customer / SAP Cloud Platform) contract on CDS queries.
607
+ */
608
+ /**
609
+ * Release status of an API contract.
610
+ *
611
+ * These are the states SAP reports for the C1 contract on a CDS DDL source.
612
+ */
613
+ type ApiReleaseStatus = 'NOT_RELEASED' | 'RELEASED' | 'DEPRECATED' | 'NOT_TO_BE_RELEASED' | 'NOT_TO_BE_RELEASED_STABLE';
614
+ /**
615
+ * A message returned by the contract validation run (pre-flight check).
616
+ *
617
+ * Warnings (e.g. "referenced data element is not released") are informational
618
+ * and do not block the operation; errors do.
619
+ */
620
+ interface ApiReleaseValidationMessage {
621
+ severity: 'error' | 'warning' | 'info';
622
+ text: string;
623
+ /** SAP message class (e.g. ARS_DEP_CHECKS), if present. */
624
+ msgid?: string;
625
+ /** SAP message number, if present. */
626
+ msgno?: string;
627
+ }
628
+ /**
629
+ * Current C1 release state of a CDS DDL source.
630
+ */
631
+ interface ApiReleaseState {
632
+ /** Object name (e.g. ZSNAP_F04S_Q01). */
633
+ name: string;
634
+ /** Releasable object ADT URI (e.g. /sap/bc/adt/ddic/ddl/sources/zsnap_f04s_q01). */
635
+ uri: string;
636
+ /** Current C1 contract status. */
637
+ status: ApiReleaseStatus;
638
+ /** Human-readable status description (e.g. "Released"). */
639
+ statusDescription: string;
640
+ /** Convenience flag: true when status is RELEASED. */
641
+ released: boolean;
642
+ /** States the C1 contract can transition to from the current status. */
643
+ allowedTransitions: ApiReleaseStatus[];
644
+ /** User who last changed the C1 contract, if any. */
645
+ changedBy?: string;
646
+ /** Timestamp the C1 contract was last changed, if any. */
647
+ changedAt?: string;
648
+ }
649
+ /**
650
+ * Result of a release / unrelease operation.
651
+ */
652
+ interface ApiReleaseResult {
653
+ /** Object name (e.g. ZSNAP_F04S_Q01). */
654
+ name: string;
655
+ /** Resulting C1 contract status after the operation. */
656
+ status: ApiReleaseStatus;
657
+ /** Non-blocking validation messages surfaced during the operation. */
658
+ messages: ApiReleaseValidationMessage[];
659
+ }
660
+
601
661
  /**
602
662
  * Create Transport — create a new transport request.
603
663
  *
@@ -775,6 +835,9 @@ interface ADTClient {
775
835
  gitDiff(objects: ObjectContent[]): AsyncResult<DiffResult[]>;
776
836
  createServiceBinding(options: CreateServiceBindingOptions): AsyncResult<ServiceBindingResult>;
777
837
  deleteServiceBinding(bindingName: string, transport?: string): AsyncResult<void>;
838
+ getApiReleaseState(objectName: string): AsyncResult<ApiReleaseState>;
839
+ releaseApi(objectName: string, transport?: string): AsyncResult<ApiReleaseResult>;
840
+ unreleaseApi(objectName: string, transport?: string): AsyncResult<ApiReleaseResult>;
778
841
  getObjectConfig(): ObjectConfig[];
779
842
  }
780
843
 
@@ -800,4 +863,4 @@ declare function activateLogging(): void;
800
863
  */
801
864
  declare function deactivateLogging(): void;
802
865
 
803
- export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
866
+ export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiReleaseResult, type ApiReleaseState, type ApiReleaseStatus, type ApiReleaseValidationMessage, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
package/dist/index.js CHANGED
@@ -2088,6 +2088,192 @@ function extractActivationErrors(objects, xml) {
2088
2088
  return ok(results);
2089
2089
  }
2090
2090
 
2091
+ // src/core/adt/craud/apirelease/helpers.ts
2092
+ var DDLS_ENDPOINT = "ddic/ddl/sources";
2093
+ var CONTRACT_PATH = "c1";
2094
+ var CONTRACT_ELEMENT = "ars:c1Release";
2095
+ var APIRELEASE_MEDIA_TYPE = "application/vnd.sap.adt.apirelease.v10+xml";
2096
+ var APIRELEASE_VALIDATION_CONTENT_TYPE = "application/vnd.sap.adt.apireleasecontractvalidation+xml";
2097
+ var APIRELEASE_VALIDATION_ACCEPT = "application/vnd.sap.adt.apireleasecontractvalidation+xml, application/vnd.sap.adt.apireleasecontractvalidation.v2+xml";
2098
+ function buildReleasableUri(name) {
2099
+ return `/sap/bc/adt/${DDLS_ENDPOINT}/${name.toLowerCase()}`;
2100
+ }
2101
+ function buildApiReleasePath(name) {
2102
+ return `/sap/bc/adt/apireleases/${encodeURIComponent(buildReleasableUri(name))}`;
2103
+ }
2104
+ function buildContractPath(name) {
2105
+ return `${buildApiReleasePath(name)}/${CONTRACT_PATH}`;
2106
+ }
2107
+ function buildValidationRunPath(name) {
2108
+ return `${buildContractPath(name)}/validationrun`;
2109
+ }
2110
+ function buildC1ReleaseBody(status) {
2111
+ return `<?xml version="1.0" encoding="UTF-8"?><ars:apiRelease xmlns:ars="http://www.sap.com/adt/ars">
2112
+ <ars:c1Release ars:comment="" ars:contract="C1" ars:createAuthValues="false" ars:featureToggle="" ars:useInKeyUserApps="true" ars:useInSAPCloudPlatform="true">
2113
+ <ars:status ars:state="${status}"/>
2114
+ <ars:useConceptAsSuccessor>false</ars:useConceptAsSuccessor>
2115
+ <ars:successors/>
2116
+ <ars:successorConceptName/>
2117
+ </ars:c1Release>
2118
+ <ars:apiCatalogData ars:isAnyAssignmentPossible="false" ars:isAnyContractReleased="false">
2119
+ <ars:ApiCatalogs/>
2120
+ </ars:apiCatalogData>
2121
+ </ars:apiRelease>`;
2122
+ }
2123
+ function toStatus(state) {
2124
+ return state;
2125
+ }
2126
+ function findContractElement(doc) {
2127
+ const candidates = doc.getElementsByTagName(CONTRACT_ELEMENT);
2128
+ for (let i = 0; i < candidates.length; i++) {
2129
+ const el = candidates[i];
2130
+ if (!el) continue;
2131
+ if (el.getElementsByTagName("ars:status").length === 0) continue;
2132
+ return el;
2133
+ }
2134
+ return null;
2135
+ }
2136
+ function parseReleaseState(xml, fallbackName) {
2137
+ const [doc, parseErr] = safeParseXml(xml);
2138
+ if (parseErr) return err(parseErr);
2139
+ const contract = findContractElement(doc);
2140
+ if (!contract) return err(new Error("apiRelease response missing C1 contract element"));
2141
+ const statusEl = contract.getElementsByTagName("ars:status")[0];
2142
+ const state = statusEl?.getAttribute("ars:state");
2143
+ if (!state) return err(new Error("apiRelease response missing C1 status"));
2144
+ const statusDescription = statusEl?.getAttribute("ars:stateDescription") ?? "";
2145
+ const allowedTransitions = [];
2146
+ const transitionsEl = contract.getElementsByTagName("ars:stateTransitions")[0];
2147
+ if (transitionsEl) {
2148
+ const transitionStatuses = transitionsEl.getElementsByTagName("ars:status");
2149
+ for (let i = 0; i < transitionStatuses.length; i++) {
2150
+ const transitionState = transitionStatuses[i]?.getAttribute("ars:state");
2151
+ if (transitionState) allowedTransitions.push(toStatus(transitionState));
2152
+ }
2153
+ }
2154
+ const releasable = doc.getElementsByTagName("ars:releasableObject")[0];
2155
+ const name = releasable?.getAttribute("adtcore:name") ?? fallbackName;
2156
+ const uri = releasable?.getAttribute("adtcore:uri") ?? buildReleasableUri(fallbackName);
2157
+ const result = {
2158
+ name,
2159
+ uri,
2160
+ status: toStatus(state),
2161
+ statusDescription,
2162
+ released: state === "RELEASED",
2163
+ allowedTransitions
2164
+ };
2165
+ const changedBy = contract.getAttribute("adtcore:changedBy");
2166
+ if (changedBy) result.changedBy = changedBy;
2167
+ const changedAt = contract.getAttribute("adtcore:changedAt");
2168
+ if (changedAt) result.changedAt = changedAt;
2169
+ return ok(result);
2170
+ }
2171
+ function parseValidationMessages(xml) {
2172
+ const [doc, parseErr] = safeParseXml(xml);
2173
+ if (parseErr) return [];
2174
+ const messages = [];
2175
+ const elements = doc.getElementsByTagName("ars:validationMessage");
2176
+ for (let i = 0; i < elements.length; i++) {
2177
+ const el = elements[i];
2178
+ if (!el) continue;
2179
+ const text = el.getAttribute("text");
2180
+ if (!text) continue;
2181
+ const message = {
2182
+ severity: mapSeverity(el.getAttribute("type")),
2183
+ text
2184
+ };
2185
+ const msgid = el.getAttribute("msgid");
2186
+ if (msgid) message.msgid = msgid;
2187
+ const msgno = el.getAttribute("msgno");
2188
+ if (msgno) message.msgno = msgno;
2189
+ messages.push(message);
2190
+ }
2191
+ return messages;
2192
+ }
2193
+ function collectErrors(messages) {
2194
+ return messages.filter((m) => m.severity === "error");
2195
+ }
2196
+ function mapSeverity(type) {
2197
+ if (type === "E" || type === "A" || type === "X") return "error";
2198
+ if (type === "W") return "warning";
2199
+ return "info";
2200
+ }
2201
+
2202
+ // src/core/adt/craud/apirelease/getState.ts
2203
+ async function getApiReleaseState(client, objectName) {
2204
+ const [response, requestErr] = await client.request({
2205
+ method: "GET",
2206
+ path: buildApiReleasePath(objectName),
2207
+ headers: { "Accept": APIRELEASE_MEDIA_TYPE }
2208
+ });
2209
+ const [text, checkErr] = await checkResponse(
2210
+ response,
2211
+ requestErr,
2212
+ `Failed to read API release state for ${objectName}`
2213
+ );
2214
+ if (checkErr) return err(checkErr);
2215
+ const [state, parseErr] = parseReleaseState(text, objectName);
2216
+ if (parseErr) return err(parseErr);
2217
+ return ok(state);
2218
+ }
2219
+
2220
+ // src/core/adt/craud/apirelease/release.ts
2221
+ async function releaseApi(client, objectName, transport) {
2222
+ return setApiReleaseState(client, objectName, "RELEASED", transport);
2223
+ }
2224
+ async function unreleaseApi(client, objectName, transport) {
2225
+ return setApiReleaseState(client, objectName, "NOT_RELEASED", transport);
2226
+ }
2227
+ async function setApiReleaseState(client, objectName, status, transport) {
2228
+ const body = buildC1ReleaseBody(status);
2229
+ const [validationRes, validationReqErr] = await client.request({
2230
+ method: "POST",
2231
+ path: buildValidationRunPath(objectName),
2232
+ headers: {
2233
+ "Content-Type": APIRELEASE_VALIDATION_CONTENT_TYPE,
2234
+ "Accept": APIRELEASE_VALIDATION_ACCEPT
2235
+ },
2236
+ body
2237
+ });
2238
+ const [validationText, validationCheckErr] = await checkResponse(
2239
+ validationRes,
2240
+ validationReqErr,
2241
+ `API release validation failed for ${objectName}`
2242
+ );
2243
+ if (validationCheckErr) return err(validationCheckErr);
2244
+ const messages = parseValidationMessages(validationText);
2245
+ const errors = collectErrors(messages);
2246
+ if (errors.length > 0) {
2247
+ const detail = errors.map((e) => e.text).join("; ");
2248
+ return err(new Error(`API release validation failed for ${objectName}: ${detail}`));
2249
+ }
2250
+ const params = {};
2251
+ if (transport) params["request"] = transport;
2252
+ const [putRes, putReqErr] = await client.request({
2253
+ method: "PUT",
2254
+ path: buildContractPath(objectName),
2255
+ params,
2256
+ headers: {
2257
+ "Content-Type": APIRELEASE_MEDIA_TYPE,
2258
+ "Accept": APIRELEASE_MEDIA_TYPE
2259
+ },
2260
+ body
2261
+ });
2262
+ const [putText, putCheckErr] = await checkResponse(
2263
+ putRes,
2264
+ putReqErr,
2265
+ `Failed to set API release state for ${objectName}`
2266
+ );
2267
+ if (putCheckErr) return err(putCheckErr);
2268
+ const [state, parseErr] = parseReleaseState(putText, objectName);
2269
+ if (parseErr) return err(parseErr);
2270
+ return ok({
2271
+ name: state.name,
2272
+ status: state.status,
2273
+ messages
2274
+ });
2275
+ }
2276
+
2091
2277
  // src/core/adt/craud/syntaxCheck.ts
2092
2278
  async function checkSyntax(client, objects) {
2093
2279
  if (objects.length === 0) {
@@ -3920,6 +4106,24 @@ async function deleteServiceBinding2(state, requestor, bindingName, transport) {
3920
4106
  return deleteServiceBinding(requestor, bindingName, transport);
3921
4107
  }
3922
4108
 
4109
+ // src/client/methods/apirelease/getApiReleaseState.ts
4110
+ async function getApiReleaseState2(state, requestor, objectName) {
4111
+ if (!state.session) return err(new Error("Not logged in"));
4112
+ return getApiReleaseState(requestor, objectName);
4113
+ }
4114
+
4115
+ // src/client/methods/apirelease/releaseApi.ts
4116
+ async function releaseApi2(state, requestor, objectName, transport) {
4117
+ if (!state.session) return err(new Error("Not logged in"));
4118
+ return releaseApi(requestor, objectName, transport);
4119
+ }
4120
+
4121
+ // src/client/methods/apirelease/unreleaseApi.ts
4122
+ async function unreleaseApi2(state, requestor, objectName, transport) {
4123
+ if (!state.session) return err(new Error("Not logged in"));
4124
+ return unreleaseApi(requestor, objectName, transport);
4125
+ }
4126
+
3923
4127
  // src/client/methods/internal/cookies.ts
3924
4128
  function storeCookies(cookies, response) {
3925
4129
  const setCookieHeader = response.headers.get("set-cookie");
@@ -4112,9 +4316,12 @@ async function executeRequest(deps, options, selfRequest) {
4112
4316
  }
4113
4317
  if (response.status === 500) {
4114
4318
  const text = await response.text();
4115
- const [, resetErr] = await sessionReset(state, selfRequest);
4116
- if (resetErr) {
4117
- return err(new Error(`Session reset failed: ${resetErr.message}`));
4319
+ const isSessionError = /session/i.test(text) && /(timed out|expired|no longer exists|not found)/i.test(text);
4320
+ if (isSessionError && config.auth.type !== "saml") {
4321
+ const [, resetErr] = await sessionReset(state, selfRequest);
4322
+ if (resetErr) {
4323
+ debugError(`Session reset after 500 failed: ${resetErr.message}`);
4324
+ }
4118
4325
  }
4119
4326
  return ok(new Response(text, {
4120
4327
  status: response.status,
@@ -4310,6 +4517,16 @@ var ADTClientImpl = class {
4310
4517
  async deleteServiceBinding(bindingName, transport) {
4311
4518
  return deleteServiceBinding2(this.state, this.requestor, bindingName, transport);
4312
4519
  }
4520
+ // --- API Release ---
4521
+ async getApiReleaseState(objectName) {
4522
+ return getApiReleaseState2(this.state, this.requestor, objectName);
4523
+ }
4524
+ async releaseApi(objectName, transport) {
4525
+ return releaseApi2(this.state, this.requestor, objectName, transport);
4526
+ }
4527
+ async unreleaseApi(objectName, transport) {
4528
+ return unreleaseApi2(this.state, this.requestor, objectName, transport);
4529
+ }
4313
4530
  // --- Configuration ---
4314
4531
  getObjectConfig() {
4315
4532
  return getObjectConfig();