@parmana/sdk 1.1.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.
Files changed (190) hide show
  1. package/README.md +284 -0
  2. package/dist/client/AuditApi.d.ts +18 -0
  3. package/dist/client/AuditApi.d.ts.map +1 -0
  4. package/dist/client/AuditApi.js +25 -0
  5. package/dist/client/AuditApi.js.map +1 -0
  6. package/dist/client/ExecutionApi.d.ts +39 -0
  7. package/dist/client/ExecutionApi.d.ts.map +1 -0
  8. package/dist/client/ExecutionApi.js +58 -0
  9. package/dist/client/ExecutionApi.js.map +1 -0
  10. package/dist/client/HealthApi.d.ts +22 -0
  11. package/dist/client/HealthApi.d.ts.map +1 -0
  12. package/dist/client/HealthApi.js +24 -0
  13. package/dist/client/HealthApi.js.map +1 -0
  14. package/dist/client/ParmanaClient.d.ts +154 -0
  15. package/dist/client/ParmanaClient.d.ts.map +1 -0
  16. package/dist/client/ParmanaClient.js +223 -0
  17. package/dist/client/ParmanaClient.js.map +1 -0
  18. package/dist/client/PolicyApi.d.ts +53 -0
  19. package/dist/client/PolicyApi.d.ts.map +1 -0
  20. package/dist/client/PolicyApi.js +48 -0
  21. package/dist/client/PolicyApi.js.map +1 -0
  22. package/dist/client/ReceiptApi.d.ts +29 -0
  23. package/dist/client/ReceiptApi.d.ts.map +1 -0
  24. package/dist/client/ReceiptApi.js +38 -0
  25. package/dist/client/ReceiptApi.js.map +1 -0
  26. package/dist/client/RefusalApi.d.ts +25 -0
  27. package/dist/client/RefusalApi.d.ts.map +1 -0
  28. package/dist/client/RefusalApi.js +38 -0
  29. package/dist/client/RefusalApi.js.map +1 -0
  30. package/dist/client/ReplayApi.d.ts +21 -0
  31. package/dist/client/ReplayApi.d.ts.map +1 -0
  32. package/dist/client/ReplayApi.js +30 -0
  33. package/dist/client/ReplayApi.js.map +1 -0
  34. package/dist/client/TransactionApi.d.ts +43 -0
  35. package/dist/client/TransactionApi.d.ts.map +1 -0
  36. package/dist/client/TransactionApi.js +62 -0
  37. package/dist/client/TransactionApi.js.map +1 -0
  38. package/dist/client/TrustRecordApi.d.ts +19 -0
  39. package/dist/client/TrustRecordApi.d.ts.map +1 -0
  40. package/dist/client/TrustRecordApi.js +25 -0
  41. package/dist/client/TrustRecordApi.js.map +1 -0
  42. package/dist/client/VerificationApi.d.ts +27 -0
  43. package/dist/client/VerificationApi.d.ts.map +1 -0
  44. package/dist/client/VerificationApi.js +42 -0
  45. package/dist/client/VerificationApi.js.map +1 -0
  46. package/dist/config/Configuration.d.ts +66 -0
  47. package/dist/config/Configuration.d.ts.map +1 -0
  48. package/dist/config/Configuration.js +17 -0
  49. package/dist/config/Configuration.js.map +1 -0
  50. package/dist/config/RetryPolicy.d.ts +66 -0
  51. package/dist/config/RetryPolicy.d.ts.map +1 -0
  52. package/dist/config/RetryPolicy.js +27 -0
  53. package/dist/config/RetryPolicy.js.map +1 -0
  54. package/dist/config/Transport.d.ts +80 -0
  55. package/dist/config/Transport.d.ts.map +1 -0
  56. package/dist/config/Transport.js +17 -0
  57. package/dist/config/Transport.js.map +1 -0
  58. package/dist/errors/AuthenticationError.d.ts +12 -0
  59. package/dist/errors/AuthenticationError.d.ts.map +1 -0
  60. package/dist/errors/AuthenticationError.js +21 -0
  61. package/dist/errors/AuthenticationError.js.map +1 -0
  62. package/dist/errors/AuthorizationError.d.ts +31 -0
  63. package/dist/errors/AuthorizationError.d.ts.map +1 -0
  64. package/dist/errors/AuthorizationError.js +42 -0
  65. package/dist/errors/AuthorizationError.js.map +1 -0
  66. package/dist/errors/ConfigurationError.d.ts +11 -0
  67. package/dist/errors/ConfigurationError.d.ts.map +1 -0
  68. package/dist/errors/ConfigurationError.js +20 -0
  69. package/dist/errors/ConfigurationError.js.map +1 -0
  70. package/dist/errors/ConflictError.d.ts +14 -0
  71. package/dist/errors/ConflictError.d.ts.map +1 -0
  72. package/dist/errors/ConflictError.js +23 -0
  73. package/dist/errors/ConflictError.js.map +1 -0
  74. package/dist/errors/ExecutionRejectedError.d.ts +11 -0
  75. package/dist/errors/ExecutionRejectedError.d.ts.map +1 -0
  76. package/dist/errors/ExecutionRejectedError.js +20 -0
  77. package/dist/errors/ExecutionRejectedError.js.map +1 -0
  78. package/dist/errors/InternalServerError.d.ts +11 -0
  79. package/dist/errors/InternalServerError.d.ts.map +1 -0
  80. package/dist/errors/InternalServerError.js +20 -0
  81. package/dist/errors/InternalServerError.js.map +1 -0
  82. package/dist/errors/NetworkError.d.ts +11 -0
  83. package/dist/errors/NetworkError.d.ts.map +1 -0
  84. package/dist/errors/NetworkError.js +20 -0
  85. package/dist/errors/NetworkError.js.map +1 -0
  86. package/dist/errors/NotFoundError.d.ts +13 -0
  87. package/dist/errors/NotFoundError.d.ts.map +1 -0
  88. package/dist/errors/NotFoundError.js +22 -0
  89. package/dist/errors/NotFoundError.js.map +1 -0
  90. package/dist/errors/ParmanaError.d.ts +57 -0
  91. package/dist/errors/ParmanaError.d.ts.map +1 -0
  92. package/dist/errors/ParmanaError.js +60 -0
  93. package/dist/errors/ParmanaError.js.map +1 -0
  94. package/dist/errors/RateLimitError.d.ts +24 -0
  95. package/dist/errors/RateLimitError.d.ts.map +1 -0
  96. package/dist/errors/RateLimitError.js +35 -0
  97. package/dist/errors/RateLimitError.js.map +1 -0
  98. package/dist/errors/ReplayError.d.ts +11 -0
  99. package/dist/errors/ReplayError.d.ts.map +1 -0
  100. package/dist/errors/ReplayError.js +20 -0
  101. package/dist/errors/ReplayError.js.map +1 -0
  102. package/dist/errors/TimeoutError.d.ts +11 -0
  103. package/dist/errors/TimeoutError.d.ts.map +1 -0
  104. package/dist/errors/TimeoutError.js +20 -0
  105. package/dist/errors/TimeoutError.js.map +1 -0
  106. package/dist/errors/ValidationError.d.ts +11 -0
  107. package/dist/errors/ValidationError.d.ts.map +1 -0
  108. package/dist/errors/ValidationError.js +20 -0
  109. package/dist/errors/ValidationError.js.map +1 -0
  110. package/dist/errors/VerificationError.d.ts +11 -0
  111. package/dist/errors/VerificationError.d.ts.map +1 -0
  112. package/dist/errors/VerificationError.js +20 -0
  113. package/dist/errors/VerificationError.js.map +1 -0
  114. package/dist/index.d.ts +41 -0
  115. package/dist/index.d.ts.map +1 -0
  116. package/dist/index.js +56 -0
  117. package/dist/index.js.map +1 -0
  118. package/dist/models/audit-event.d.ts +15 -0
  119. package/dist/models/audit-event.d.ts.map +1 -0
  120. package/dist/models/audit-event.js +2 -0
  121. package/dist/models/audit-event.js.map +1 -0
  122. package/dist/models/authority.d.ts +14 -0
  123. package/dist/models/authority.d.ts.map +1 -0
  124. package/dist/models/authority.js +8 -0
  125. package/dist/models/authority.js.map +1 -0
  126. package/dist/models/authorization.d.ts +13 -0
  127. package/dist/models/authorization.d.ts.map +1 -0
  128. package/dist/models/authorization.js +7 -0
  129. package/dist/models/authorization.js.map +1 -0
  130. package/dist/models/business-transaction.d.ts +25 -0
  131. package/dist/models/business-transaction.d.ts.map +1 -0
  132. package/dist/models/business-transaction.js +2 -0
  133. package/dist/models/business-transaction.js.map +1 -0
  134. package/dist/models/execution.d.ts +36 -0
  135. package/dist/models/execution.d.ts.map +1 -0
  136. package/dist/models/execution.js +2 -0
  137. package/dist/models/execution.js.map +1 -0
  138. package/dist/models/index.d.ts +15 -0
  139. package/dist/models/index.d.ts.map +1 -0
  140. package/dist/models/index.js +15 -0
  141. package/dist/models/index.js.map +1 -0
  142. package/dist/models/intent.d.ts +14 -0
  143. package/dist/models/intent.d.ts.map +1 -0
  144. package/dist/models/intent.js +7 -0
  145. package/dist/models/intent.js.map +1 -0
  146. package/dist/models/override.d.ts +9 -0
  147. package/dist/models/override.d.ts.map +1 -0
  148. package/dist/models/override.js +2 -0
  149. package/dist/models/override.js.map +1 -0
  150. package/dist/models/policy.d.ts +11 -0
  151. package/dist/models/policy.d.ts.map +1 -0
  152. package/dist/models/policy.js +7 -0
  153. package/dist/models/policy.js.map +1 -0
  154. package/dist/models/receipt.d.ts +10 -0
  155. package/dist/models/receipt.d.ts.map +1 -0
  156. package/dist/models/receipt.js +2 -0
  157. package/dist/models/receipt.js.map +1 -0
  158. package/dist/models/refusal-record.d.ts +51 -0
  159. package/dist/models/refusal-record.d.ts.map +1 -0
  160. package/dist/models/refusal-record.js +2 -0
  161. package/dist/models/refusal-record.js.map +1 -0
  162. package/dist/models/replay-result.d.ts +6 -0
  163. package/dist/models/replay-result.d.ts.map +1 -0
  164. package/dist/models/replay-result.js +2 -0
  165. package/dist/models/replay-result.js.map +1 -0
  166. package/dist/models/signature.d.ts +16 -0
  167. package/dist/models/signature.d.ts.map +1 -0
  168. package/dist/models/signature.js +10 -0
  169. package/dist/models/signature.js.map +1 -0
  170. package/dist/models/trust-record.d.ts +20 -0
  171. package/dist/models/trust-record.d.ts.map +1 -0
  172. package/dist/models/trust-record.js +2 -0
  173. package/dist/models/trust-record.js.map +1 -0
  174. package/dist/models/verification.d.ts +10 -0
  175. package/dist/models/verification.d.ts.map +1 -0
  176. package/dist/models/verification.js +2 -0
  177. package/dist/models/verification.js.map +1 -0
  178. package/dist/transport/HttpTransport.d.ts +25 -0
  179. package/dist/transport/HttpTransport.d.ts.map +1 -0
  180. package/dist/transport/HttpTransport.js +193 -0
  181. package/dist/transport/HttpTransport.js.map +1 -0
  182. package/dist/transport/mapHttpErrorResponse.d.ts +52 -0
  183. package/dist/transport/mapHttpErrorResponse.d.ts.map +1 -0
  184. package/dist/transport/mapHttpErrorResponse.js +134 -0
  185. package/dist/transport/mapHttpErrorResponse.js.map +1 -0
  186. package/dist/version.d.ts +7 -0
  187. package/dist/version.d.ts.map +1 -0
  188. package/dist/version.js +7 -0
  189. package/dist/version.js.map +1 -0
  190. package/package.json +57 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Parmana SDK
3
+ *
4
+ * Canonical HTTP transport.
5
+ *
6
+ * Responsibilities:
7
+ * - Send HTTP requests.
8
+ * - Serialize request bodies.
9
+ * - Deserialize responses.
10
+ * - Return canonical TransportResponse objects.
11
+ *
12
+ * This transport does NOT:
13
+ * - evaluate policy
14
+ * - authorize execution
15
+ * - implement business logic
16
+ */
17
+ import { RetryStrategy, } from "../config/RetryPolicy.js";
18
+ import { ParmanaError, } from "../errors/ParmanaError.js";
19
+ import { NetworkError, } from "../errors/NetworkError.js";
20
+ import { TimeoutError, } from "../errors/TimeoutError.js";
21
+ import { InternalServerError, } from "../errors/InternalServerError.js";
22
+ import { RateLimitError, } from "../errors/RateLimitError.js";
23
+ import { mapHttpErrorResponse, } from "./mapHttpErrorResponse.js";
24
+ /**
25
+ * Retries are restricted to idempotent methods only. A retried POST
26
+ * (e.g. /execute) risks a second real side effect on the underlying
27
+ * system if the first attempt actually succeeded but the response was
28
+ * lost -- the server's own businessTransactionId uniqueness check turns
29
+ * that into a 409, not a duplicate execution, but blindly retrying
30
+ * non-idempotent requests is still not a safe default without deliberate
31
+ * per-route design this SDK doesn't have. Mirrors the Python SDK's own
32
+ * documented choice (urllib3 Retry scoped to GET only).
33
+ */
34
+ const RETRYABLE_METHODS = ["GET"];
35
+ /**
36
+ * Every 5xx this API can return for a GET request maps to
37
+ * InternalServerError (mapHttpErrorResponse.ts only special-cases 4xx
38
+ * statuses individually) -- so "retryable HTTP failure" is exactly
39
+ * "InternalServerError on a GET", no separate status-code bookkeeping
40
+ * needed. Network failures and timeouts are retryable regardless of
41
+ * which HTTP status (if any) was ever reached. RateLimitError (429) is
42
+ * retryable too -- GET /health,/ready are IP-rate-limited (see
43
+ * packages/api's rate-limiting middleware) and a caller polling them on
44
+ * a fixed interval should be able to just wait out the window rather
45
+ * than handling 429 specially. POST /execute is also rate-limited, but
46
+ * RETRYABLE_METHODS already excludes POST for the unrelated
47
+ * non-idempotency reason above, so this doesn't risk a double-submit.
48
+ * Note: retry timing here still follows the configured backoff
49
+ * (delayForAttempt below), not RateLimitError.retryAfterSeconds -- the
50
+ * Runtime's hint is exposed on the error for a caller that wants to
51
+ * honor it directly, but isn't yet wired into this loop's own delay.
52
+ */
53
+ function isRetryableFailure(error) {
54
+ return (error instanceof NetworkError ||
55
+ error instanceof TimeoutError ||
56
+ error instanceof InternalServerError ||
57
+ error instanceof RateLimitError);
58
+ }
59
+ function delayForAttempt(attempt, policy) {
60
+ const raw = policy.strategy === RetryStrategy.FIXED
61
+ ? policy.initialDelayMs
62
+ : policy.initialDelayMs * 2 ** attempt;
63
+ return Math.min(raw, policy.maxDelayMs);
64
+ }
65
+ function sleep(ms) {
66
+ return new Promise((resolve) => setTimeout(resolve, ms));
67
+ }
68
+ /**
69
+ * Resolves the effective retry policy for a request, or undefined when
70
+ * retries do not apply at all -- disabled, no configuration.retryPolicy,
71
+ * maxAttempts <= 0 (the documented default), or a non-idempotent method.
72
+ * Every field below mirrors RetryPolicy.ts's own documented defaults.
73
+ */
74
+ function resolveRetryPolicy(configuration, method) {
75
+ const policy = configuration.retryPolicy;
76
+ if (policy?.enabled !== true) {
77
+ return undefined;
78
+ }
79
+ const maxAttempts = policy.maxAttempts ?? 0;
80
+ if (maxAttempts <= 0) {
81
+ return undefined;
82
+ }
83
+ if (!RETRYABLE_METHODS.includes(method)) {
84
+ return undefined;
85
+ }
86
+ return {
87
+ maxAttempts,
88
+ initialDelayMs: policy.initialDelayMs ?? 1000,
89
+ maxDelayMs: policy.maxDelayMs ?? 30_000,
90
+ strategy: policy.strategy ?? RetryStrategy.EXPONENTIAL,
91
+ };
92
+ }
93
+ export class HttpTransport {
94
+ configuration;
95
+ constructor(configuration) {
96
+ this.configuration = configuration;
97
+ }
98
+ async send(request) {
99
+ const retryPolicy = resolveRetryPolicy(this.configuration, request.method);
100
+ if (retryPolicy === undefined) {
101
+ return this.attempt(request);
102
+ }
103
+ // maxAttempts counts retries, not the initial try -- maxAttempts: 3
104
+ // means up to 4 total requests (1 initial + 3 retries), matching
105
+ // RetryPolicy.ts's own doc comment ("Maximum retry attempts").
106
+ for (let attempt = 0;; attempt++) {
107
+ try {
108
+ return await this.attempt(request);
109
+ }
110
+ catch (error) {
111
+ const canRetry = isRetryableFailure(error) && attempt < retryPolicy.maxAttempts;
112
+ if (!canRetry) {
113
+ throw error;
114
+ }
115
+ await sleep(delayForAttempt(attempt, retryPolicy));
116
+ }
117
+ }
118
+ }
119
+ async attempt(request) {
120
+ const controller = new AbortController();
121
+ const timeout = this.configuration.timeout ??
122
+ 30_000;
123
+ const timer = setTimeout(() => controller.abort(), timeout);
124
+ try {
125
+ const init = {
126
+ method: request.method,
127
+ headers: {
128
+ "Content-Type": "application/json",
129
+ ...(this.configuration.apiKey !== undefined && {
130
+ Authorization: `Bearer ${this.configuration.apiKey}`,
131
+ }),
132
+ ...(request.headers ?? {}),
133
+ },
134
+ signal: controller.signal,
135
+ };
136
+ if (request.body !== undefined) {
137
+ init.body =
138
+ JSON.stringify(request.body);
139
+ }
140
+ const response = await fetch(this.configuration.endpoint +
141
+ request.path, init);
142
+ clearTimeout(timer);
143
+ const headers = {};
144
+ response.headers.forEach((value, key) => {
145
+ headers[key] = value;
146
+ });
147
+ let body;
148
+ if (response.status === 204) {
149
+ body = undefined;
150
+ }
151
+ else {
152
+ try {
153
+ body =
154
+ (await response.json());
155
+ }
156
+ catch {
157
+ // A non-JSON or empty body. Real, error-envelope
158
+ // responses from this API are always JSON; this only
159
+ // guards mapHttpErrorResponse below against an
160
+ // unparseable body rather than throwing an opaque
161
+ // SyntaxError for it.
162
+ body = undefined;
163
+ }
164
+ }
165
+ if (response.status >= 400 &&
166
+ !(request.nonThrowingStatuses ?? []).includes(response.status)) {
167
+ throw mapHttpErrorResponse(response.status, body, headers);
168
+ }
169
+ return {
170
+ status: response.status,
171
+ headers,
172
+ body,
173
+ };
174
+ }
175
+ catch (error) {
176
+ clearTimeout(timer);
177
+ if (error instanceof ParmanaError) {
178
+ // Already the correct typed error (mapHttpErrorResponse,
179
+ // above) — rethrow as-is, do not fold it into NetworkError.
180
+ throw error;
181
+ }
182
+ if (error instanceof DOMException &&
183
+ error.name ===
184
+ "AbortError") {
185
+ throw new TimeoutError("Request timed out.");
186
+ }
187
+ throw new NetworkError("Unable to communicate with the Parmana Runtime.", {
188
+ cause: error,
189
+ });
190
+ }
191
+ }
192
+ }
193
+ //# sourceMappingURL=HttpTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpTransport.js","sourceRoot":"","sources":["../../src/transport/HttpTransport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Parmana SDK
3
+ *
4
+ * Maps a non-2xx HTTP response from the Parmana Runtime to the
5
+ * corresponding typed SDK error.
6
+ *
7
+ * The real Runtime envelope (packages/api/src/middleware/error-handler.ts)
8
+ * is `{ "error": string }`, sometimes with a second `code` field. `code`
9
+ * is present only when the failure reached the shared error handler as a
10
+ * typed error carrying its own status/code (RuntimeError, or a
11
+ * ParmanaError subclass such as NonceAlreadyConsumedError); most 4xx
12
+ * responses carry no `code` at all. Classification below is therefore
13
+ * driven primarily by HTTP status, with `code` used to distinguish the
14
+ * cases that need it. This API returns THREE distinct 403 shapes, not
15
+ * two — a fact this docstring previously got wrong:
16
+ * - `code: "POLICY_DENIED"` — a policy REJECTED decision, mapped to
17
+ * ExecutionRejectedError, checked first since it needs a wholly
18
+ * different SDK error class.
19
+ * - `code: "CAPABILITY_NOT_ALLOWED"` — a caller invoking a capability
20
+ * it isn't permitted to invoke (isCapabilityAllowed.ts). Checked
21
+ * explicitly (not left to fall through the generic status branch
22
+ * below) so its `code` is preserved on AuthorizationError.serverCode
23
+ * instead of being silently dropped.
24
+ * - no `code` at all — a caller asserting an authority.principalId it
25
+ * isn't permitted to assert (isPrincipalAllowed.ts,
26
+ * packages/api/src/routes/execute.ts and transactions.ts). Also maps
27
+ * to AuthorizationError, via the generic `status === 403` branch.
28
+ * See /api-reference/error-catalog for the exhaustive, real, verified
29
+ * list this mapping is built from.
30
+ *
31
+ * Previously, a policy rejection had no dedicated status of its own and
32
+ * fell through to a generic `500` with `code: "RUNTIME_ERROR"` — this
33
+ * function used to special-case exactly that shape to still produce an
34
+ * ExecutionRejectedError. That gap is now fixed at the source
35
+ * (packages/runtime/src/ExecutionGate.ts, packages/api/src/middleware/
36
+ * error-handler.ts); this mapping was updated to match, not to work
37
+ * around the old ambiguity.
38
+ *
39
+ * One route, POST /policies/validate, does not use this envelope at all
40
+ * (every status it returns is `{valid, errors}`); PolicyApi.validate
41
+ * opts out of this mapping entirely via TransportRequest.throwOnHttpError,
42
+ * so this function is never called for that route's responses.
43
+ */
44
+ import type { ParmanaError } from "../errors/ParmanaError.js";
45
+ /**
46
+ * Maps a non-2xx HTTP response to the typed SDK error it should be
47
+ * thrown as. `headers` is optional only so existing direct callers
48
+ * (tests, primarily) that don't have a header set need not supply one —
49
+ * every real HttpTransport response has one.
50
+ */
51
+ export declare function mapHttpErrorResponse(status: number, body: unknown, headers?: Record<string, string>): ParmanaError;
52
+ //# sourceMappingURL=mapHttpErrorResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapHttpErrorResponse.d.ts","sourceRoot":"","sources":["../../src/transport/mapHttpErrorResponse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAUH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAyD9D;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,YAAY,CAmDd"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Parmana SDK
3
+ *
4
+ * Maps a non-2xx HTTP response from the Parmana Runtime to the
5
+ * corresponding typed SDK error.
6
+ *
7
+ * The real Runtime envelope (packages/api/src/middleware/error-handler.ts)
8
+ * is `{ "error": string }`, sometimes with a second `code` field. `code`
9
+ * is present only when the failure reached the shared error handler as a
10
+ * typed error carrying its own status/code (RuntimeError, or a
11
+ * ParmanaError subclass such as NonceAlreadyConsumedError); most 4xx
12
+ * responses carry no `code` at all. Classification below is therefore
13
+ * driven primarily by HTTP status, with `code` used to distinguish the
14
+ * cases that need it. This API returns THREE distinct 403 shapes, not
15
+ * two — a fact this docstring previously got wrong:
16
+ * - `code: "POLICY_DENIED"` — a policy REJECTED decision, mapped to
17
+ * ExecutionRejectedError, checked first since it needs a wholly
18
+ * different SDK error class.
19
+ * - `code: "CAPABILITY_NOT_ALLOWED"` — a caller invoking a capability
20
+ * it isn't permitted to invoke (isCapabilityAllowed.ts). Checked
21
+ * explicitly (not left to fall through the generic status branch
22
+ * below) so its `code` is preserved on AuthorizationError.serverCode
23
+ * instead of being silently dropped.
24
+ * - no `code` at all — a caller asserting an authority.principalId it
25
+ * isn't permitted to assert (isPrincipalAllowed.ts,
26
+ * packages/api/src/routes/execute.ts and transactions.ts). Also maps
27
+ * to AuthorizationError, via the generic `status === 403` branch.
28
+ * See /api-reference/error-catalog for the exhaustive, real, verified
29
+ * list this mapping is built from.
30
+ *
31
+ * Previously, a policy rejection had no dedicated status of its own and
32
+ * fell through to a generic `500` with `code: "RUNTIME_ERROR"` — this
33
+ * function used to special-case exactly that shape to still produce an
34
+ * ExecutionRejectedError. That gap is now fixed at the source
35
+ * (packages/runtime/src/ExecutionGate.ts, packages/api/src/middleware/
36
+ * error-handler.ts); this mapping was updated to match, not to work
37
+ * around the old ambiguity.
38
+ *
39
+ * One route, POST /policies/validate, does not use this envelope at all
40
+ * (every status it returns is `{valid, errors}`); PolicyApi.validate
41
+ * opts out of this mapping entirely via TransportRequest.throwOnHttpError,
42
+ * so this function is never called for that route's responses.
43
+ */
44
+ import { ValidationError } from "../errors/ValidationError.js";
45
+ import { AuthenticationError } from "../errors/AuthenticationError.js";
46
+ import { AuthorizationError } from "../errors/AuthorizationError.js";
47
+ import { NotFoundError } from "../errors/NotFoundError.js";
48
+ import { ConflictError } from "../errors/ConflictError.js";
49
+ import { ExecutionRejectedError } from "../errors/ExecutionRejectedError.js";
50
+ import { RateLimitError } from "../errors/RateLimitError.js";
51
+ import { InternalServerError } from "../errors/InternalServerError.js";
52
+ function extractMessage(status, body) {
53
+ if (body !== null &&
54
+ typeof body === "object" &&
55
+ "error" in body) {
56
+ const message = body.error;
57
+ if (typeof message === "string" && message.length > 0) {
58
+ return message;
59
+ }
60
+ }
61
+ return `Request failed with status ${status}.`;
62
+ }
63
+ function extractCode(body) {
64
+ if (body !== null &&
65
+ typeof body === "object" &&
66
+ "code" in body) {
67
+ const code = body.code;
68
+ return typeof code === "string" ? code : undefined;
69
+ }
70
+ return undefined;
71
+ }
72
+ /**
73
+ * Parses a `Retry-After` header value into seconds. Per RFC 9110 this is
74
+ * either an integer number of seconds or an HTTP-date; this API only
75
+ * ever sends the integer-seconds form (express-rate-limit's default),
76
+ * so an HTTP-date is treated as absent rather than guessed at.
77
+ */
78
+ function extractRetryAfterSeconds(headers) {
79
+ const raw = headers?.["retry-after"];
80
+ if (raw === undefined) {
81
+ return undefined;
82
+ }
83
+ const seconds = Number(raw);
84
+ return Number.isFinite(seconds) && seconds >= 0 ? seconds : undefined;
85
+ }
86
+ /**
87
+ * Maps a non-2xx HTTP response to the typed SDK error it should be
88
+ * thrown as. `headers` is optional only so existing direct callers
89
+ * (tests, primarily) that don't have a header set need not supply one —
90
+ * every real HttpTransport response has one.
91
+ */
92
+ export function mapHttpErrorResponse(status, body, headers) {
93
+ const message = extractMessage(status, body);
94
+ const code = extractCode(body);
95
+ // Checked ahead of the generic status branches: a policy REJECTED
96
+ // decision carries this exact code alongside its 403 status, and must
97
+ // not be classified as the *other* 403 this API returns (a
98
+ // caller-identity/principal mismatch, which carries no code at all).
99
+ if (code === "POLICY_DENIED") {
100
+ return new ExecutionRejectedError(message);
101
+ }
102
+ // Also checked ahead of the generic status branches, for the same
103
+ // reason as POLICY_DENIED above: a capability-denied 403 carries this
104
+ // code, and letting it fall through to the generic `status === 403`
105
+ // branch below would still produce the right error class
106
+ // (AuthorizationError) but silently drop the code — checking it here
107
+ // preserves it on `serverCode` instead.
108
+ if (code === "CAPABILITY_NOT_ALLOWED") {
109
+ return new AuthorizationError(message, { serverCode: code });
110
+ }
111
+ if (status === 400) {
112
+ return new ValidationError(message);
113
+ }
114
+ if (status === 401) {
115
+ return new AuthenticationError(message);
116
+ }
117
+ if (status === 403) {
118
+ return new AuthorizationError(message);
119
+ }
120
+ if (status === 404) {
121
+ return new NotFoundError(message);
122
+ }
123
+ if (status === 409) {
124
+ return new ConflictError(message);
125
+ }
126
+ if (status === 429) {
127
+ const retryAfterSeconds = extractRetryAfterSeconds(headers);
128
+ return new RateLimitError(message, {
129
+ ...(retryAfterSeconds !== undefined && { retryAfterSeconds }),
130
+ });
131
+ }
132
+ return new InternalServerError(message);
133
+ }
134
+ //# sourceMappingURL=mapHttpErrorResponse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapHttpErrorResponse.js","sourceRoot":"","sources":["../../src/transport/mapHttpErrorResponse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Parmana TypeScript SDK
3
+ *
4
+ * SDK version.
5
+ */
6
+ export declare const VERSION = "1.0.0";
7
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Parmana TypeScript SDK
3
+ *
4
+ * SDK version.
5
+ */
6
+ export const VERSION = "1.0.0";
7
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@parmana/sdk",
3
+ "version": "1.1.0",
4
+ "private": false,
5
+ "description": "Official Parmana TypeScript SDK",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
25
+ "clean": "rimraf dist"
26
+ },
27
+ "keywords": [
28
+ "parmana",
29
+ "ai",
30
+ "governance",
31
+ "authorization",
32
+ "verification",
33
+ "execution",
34
+ "trust",
35
+ "agentic-ai",
36
+ "sdk"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/pavancharak/parmana-exp.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/pavancharak/parmana-exp/issues"
44
+ },
45
+ "homepage": "https://github.com/pavancharak/parmana-exp",
46
+ "dependencies": {
47
+ "dotenv": "^17.4.2"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^24.0.0",
51
+ "typescript": "^5.8.0",
52
+ "vitest": "^4.1.9"
53
+ },
54
+ "engines": {
55
+ "node": ">=20"
56
+ }
57
+ }