@admiral-io/sdk 0.0.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.
Files changed (43) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +169 -0
  3. package/dist/client/client.d.ts +58 -0
  4. package/dist/client/client.d.ts.map +1 -0
  5. package/dist/client/client.js +63 -0
  6. package/dist/client/client.js.map +1 -0
  7. package/dist/client/index.d.ts +5 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +9 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/client/lib/auth.d.ts +58 -0
  12. package/dist/client/lib/auth.d.ts.map +1 -0
  13. package/dist/client/lib/auth.js +111 -0
  14. package/dist/client/lib/auth.js.map +1 -0
  15. package/dist/client/lib/config.d.ts +42 -0
  16. package/dist/client/lib/config.d.ts.map +1 -0
  17. package/dist/client/lib/config.js +29 -0
  18. package/dist/client/lib/config.js.map +1 -0
  19. package/dist/client/lib/transport.d.ts +7 -0
  20. package/dist/client/lib/transport.d.ts.map +1 -0
  21. package/dist/client/lib/transport.js +65 -0
  22. package/dist/client/lib/transport.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/proto/google/api/annotations_pb.d.ts +14 -0
  28. package/dist/proto/google/api/annotations_pb.d.ts.map +1 -0
  29. package/dist/proto/google/api/annotations_pb.js +27 -0
  30. package/dist/proto/google/api/annotations_pb.js.map +1 -0
  31. package/dist/proto/google/api/http_pb.d.ts +441 -0
  32. package/dist/proto/google/api/http_pb.d.ts.map +1 -0
  33. package/dist/proto/google/api/http_pb.js +34 -0
  34. package/dist/proto/google/api/http_pb.js.map +1 -0
  35. package/dist/proto/healthcheck/v1/healthcheck_pb.d.ts +50 -0
  36. package/dist/proto/healthcheck/v1/healthcheck_pb.d.ts.map +1 -0
  37. package/dist/proto/healthcheck/v1/healthcheck_pb.js +26 -0
  38. package/dist/proto/healthcheck/v1/healthcheck_pb.js.map +1 -0
  39. package/dist/proto/user/v1/user_pb.d.ts +91 -0
  40. package/dist/proto/user/v1/user_pb.d.ts.map +1 -0
  41. package/dist/proto/user/v1/user_pb.js +26 -0
  42. package/dist/proto/user/v1/user_pb.js.map +1 -0
  43. package/package.json +54 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Datalift, LLC.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # admiral-ts
2
+
3
+ TypeScript client library for the Admiral API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @admiral-io/sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { createClient } from "@admiral-io/sdk";
15
+
16
+ const client = createClient({
17
+ baseUrl: "https://api.admiral.io",
18
+ authToken: "your-token-here",
19
+ });
20
+
21
+ // Access services via properties
22
+ // await client.healthcheck.methodName({ ... });
23
+ // await client.user.methodName({ ... });
24
+ ```
25
+
26
+ ## Available Services
27
+
28
+ | Service | Property | Description |
29
+ |---------|----------|-------------|
30
+ | HealthcheckAPI | `client.healthcheck` | Healthcheck service |
31
+ | UserAPI | `client.user` | User service |
32
+
33
+ ## Example
34
+
35
+ ```typescript
36
+ import { createClient } from "@admiral-io/sdk";
37
+
38
+ async function main() {
39
+ const client = createClient({
40
+ baseUrl: "https://api.admiral.io",
41
+ authToken: process.env.ADMIRAL_TOKEN,
42
+ });
43
+
44
+ // Validate token before making requests
45
+ const validation = client.validateToken();
46
+ if (!validation.valid) {
47
+ throw new Error(`Invalid token: ${validation.error}`);
48
+ }
49
+
50
+ // Call a service method
51
+ try {
52
+ const response = await client.healthcheck.listMethod({});
53
+ console.log(response);
54
+ } catch (err) {
55
+ console.error("Request failed:", err);
56
+ }
57
+ }
58
+
59
+ main();
60
+ ```
61
+
62
+ ## Configuration
63
+
64
+ ```typescript
65
+ import { createClient, type ClientConfig } from "@admiral-io/sdk";
66
+
67
+ const config: ClientConfig = {
68
+ // Base URL for the API server
69
+ baseUrl: "https://api.admiral.io",
70
+
71
+ // Authentication token (JWT)
72
+ authToken: "your-jwt-token",
73
+
74
+ // Request timeout in milliseconds (default: 30000)
75
+ timeout: 30000,
76
+
77
+ // HTTP version: "1.1" or "2" (default: "2")
78
+ httpVersion: "2",
79
+
80
+ // Custom headers to include in all requests
81
+ headers: {
82
+ "X-Custom-Header": "value",
83
+ },
84
+ };
85
+
86
+ const client = createClient(config);
87
+ ```
88
+
89
+ ## Token Validation
90
+
91
+ ```typescript
92
+ // Validate token format and expiration
93
+ const validation = client.validateToken();
94
+ if (!validation.valid) {
95
+ console.error("Invalid token:", validation.error);
96
+ }
97
+
98
+ // Get detailed token information
99
+ const info = client.getTokenInfo();
100
+ if (info) {
101
+ console.log("Subject:", info.claims.sub);
102
+ console.log("Expired:", info.isExpired);
103
+ console.log("Expires in:", info.expiresIn, "ms");
104
+ }
105
+ ```
106
+
107
+ ## Token Utilities
108
+
109
+ Standalone functions for working with JWT tokens:
110
+
111
+ ```typescript
112
+ import {
113
+ parseJWTToken,
114
+ validateAuthToken,
115
+ isTokenExpired,
116
+ isTokenNotYetValid,
117
+ tokenExpiresIn,
118
+ getTokenInfo,
119
+ } from "@admiral-io/sdk";
120
+
121
+ // Parse JWT claims without validation
122
+ const claims = parseJWTToken(token);
123
+ console.log("Subject:", claims.sub);
124
+ console.log("Issuer:", claims.iss);
125
+
126
+ // Validate token format and timing
127
+ const result = validateAuthToken(token);
128
+ if (!result.valid) {
129
+ console.error(result.error);
130
+ }
131
+
132
+ // Check expiration status
133
+ if (isTokenExpired(claims)) {
134
+ console.log("Token has expired");
135
+ }
136
+
137
+ // Check if token is not yet valid (nbf claim)
138
+ if (isTokenNotYetValid(claims)) {
139
+ console.log("Token not yet valid");
140
+ }
141
+
142
+ // Get milliseconds until expiration
143
+ const expiresIn = tokenExpiresIn(claims);
144
+ console.log("Expires in:", expiresIn, "ms");
145
+ ```
146
+
147
+ ## Advanced: Direct Transport Access
148
+
149
+ For advanced use cases, you can access the underlying Connect transport:
150
+
151
+ ```typescript
152
+ import { createClient } from "@admiral-io/sdk";
153
+ import { createClient as createConnectClient } from "@connectrpc/connect";
154
+ import { SomeOtherService } from "./custom-service_pb";
155
+
156
+ const client = createClient({ ... });
157
+
158
+ // Use the transport directly with other services
159
+ const customClient = createConnectClient(SomeOtherService, client.transport);
160
+ ```
161
+
162
+ ## Requirements
163
+
164
+ - Node.js >= 22
165
+ - ESM only (no CommonJS support)
166
+
167
+ ## License
168
+
169
+ MIT License - see [LICENSE](LICENSE.txt) for details.
@@ -0,0 +1,58 @@
1
+ import type { Transport, Client as ConnectClient } from "@connectrpc/connect";
2
+ import type { ClientConfig } from "./lib/config.js";
3
+ import { type JWTClaims } from "./lib/auth.js";
4
+ import { HealthcheckAPI } from "../proto/healthcheck/v1/healthcheck_pb.js";
5
+ import { UserAPI } from "../proto/user/v1/user_pb.js";
6
+ type HealthcheckClient = ConnectClient<typeof HealthcheckAPI>;
7
+ type UserClient = ConnectClient<typeof UserAPI>;
8
+ /**
9
+ * Admiral client interface.
10
+ */
11
+ export interface Client {
12
+ /** The underlying Connect transport */
13
+ readonly transport: Transport;
14
+ /** Healthcheck service client */
15
+ readonly healthcheck: HealthcheckClient;
16
+ /** User service client */
17
+ readonly user: UserClient;
18
+ /**
19
+ * Validates the current auth token.
20
+ * @returns Token validation result
21
+ */
22
+ validateToken(): {
23
+ valid: boolean;
24
+ error?: string;
25
+ claims?: JWTClaims;
26
+ };
27
+ /**
28
+ * Gets information about the current auth token.
29
+ * @returns Token claims and expiration info
30
+ */
31
+ getTokenInfo(): {
32
+ claims: JWTClaims;
33
+ isExpired: boolean;
34
+ expiresIn: number;
35
+ } | null;
36
+ }
37
+ /**
38
+ * Creates a new Admiral API client.
39
+ *
40
+ * @param config - Client configuration
41
+ * @returns Client instance with service accessors
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import { createClient } from "@admiral-io/sdk";
46
+ *
47
+ * const client = createClient({
48
+ * baseUrl: "https://api.admiral.io",
49
+ * authToken: "your-token-here",
50
+ * });
51
+ *
52
+ * // Access services via properties
53
+ * const resp = await client.healthcheck.healthcheckMethod({});
54
+ * ```
55
+ */
56
+ export declare function createClient(config: ClientConfig): Client;
57
+ export {};
58
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../client/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGtD,KAAK,iBAAiB,GAAG,aAAa,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,KAAK,UAAU,GAAG,aAAa,CAAC,OAAO,OAAO,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,iCAAiC;IACjC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAExC,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAE1B;;;OAGG;IACH,aAAa,IAAI;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IAExE;;;OAGG;IACH,YAAY,IAAI;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACrF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0CzD"}
@@ -0,0 +1,63 @@
1
+ import { createClient as createConnectClient } from "@connectrpc/connect";
2
+ import { createTransport } from "./lib/transport.js";
3
+ import { validateAuthToken, getTokenInfo } from "./lib/auth.js";
4
+ import { HealthcheckAPI } from "../proto/healthcheck/v1/healthcheck_pb.js";
5
+ import { UserAPI } from "../proto/user/v1/user_pb.js";
6
+ /**
7
+ * Creates a new Admiral API client.
8
+ *
9
+ * @param config - Client configuration
10
+ * @returns Client instance with service accessors
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { createClient } from "@admiral-io/sdk";
15
+ *
16
+ * const client = createClient({
17
+ * baseUrl: "https://api.admiral.io",
18
+ * authToken: "your-token-here",
19
+ * });
20
+ *
21
+ * // Access services via properties
22
+ * const resp = await client.healthcheck.healthcheckMethod({});
23
+ * ```
24
+ */
25
+ export function createClient(config) {
26
+ const transport = createTransport(config);
27
+ // Lazily initialized service clients
28
+ let _healthcheck;
29
+ let _user;
30
+ return {
31
+ transport,
32
+ get healthcheck() {
33
+ if (!_healthcheck) {
34
+ _healthcheck = createConnectClient(HealthcheckAPI, transport);
35
+ }
36
+ return _healthcheck;
37
+ },
38
+ get user() {
39
+ if (!_user) {
40
+ _user = createConnectClient(UserAPI, transport);
41
+ }
42
+ return _user;
43
+ },
44
+ validateToken() {
45
+ if (!config.authToken) {
46
+ return { valid: false, error: "No auth token configured" };
47
+ }
48
+ return validateAuthToken(config.authToken);
49
+ },
50
+ getTokenInfo() {
51
+ if (!config.authToken) {
52
+ return null;
53
+ }
54
+ try {
55
+ return getTokenInfo(config.authToken);
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ },
61
+ };
62
+ }
63
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../client/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAkB,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAgCtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAE1C,qCAAqC;IACrC,IAAI,YAA2C,CAAC;IAChD,IAAI,KAA6B,CAAC;IAElC,OAAO;QACL,SAAS;QAET,IAAI,WAAW;YACb,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,GAAG,mBAAmB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YAChE,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,IAAI,IAAI;YACN,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,aAAa;YACX,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC;YAC7D,CAAC;YACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC;QAED,YAAY;YACV,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { createClient, type Client } from "./client.js";
2
+ export { type ClientConfig, DEFAULT_CONFIG, resolveConfig } from "./lib/config.js";
3
+ export { type JWTClaims, type TokenValidation, parseJWTToken, validateAuthToken, isTokenExpired, isTokenNotYetValid, tokenExpiresIn, getTokenInfo, } from "./lib/auth.js";
4
+ export { createTransport } from "./lib/transport.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,KAAK,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGnF,OAAO,EACL,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Client
2
+ export { createClient } from "./client.js";
3
+ // Configuration
4
+ export { DEFAULT_CONFIG, resolveConfig } from "./lib/config.js";
5
+ // Token utilities
6
+ export { parseJWTToken, validateAuthToken, isTokenExpired, isTokenNotYetValid, tokenExpiresIn, getTokenInfo, } from "./lib/auth.js";
7
+ // Transport (for advanced use cases)
8
+ export { createTransport } from "./lib/transport.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAExD,gBAAgB;AAChB,OAAO,EAAqB,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEnF,kBAAkB;AAClB,OAAO,EAGL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,qCAAqC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Standard JWT claims.
3
+ */
4
+ export interface JWTClaims {
5
+ /** Issuer */
6
+ iss?: string;
7
+ /** Subject */
8
+ sub?: string;
9
+ /** Audience */
10
+ aud?: string | string[];
11
+ /** Expiration time (Unix timestamp) */
12
+ exp?: number;
13
+ /** Not before (Unix timestamp) */
14
+ nbf?: number;
15
+ /** Issued at (Unix timestamp) */
16
+ iat?: number;
17
+ /** JWT ID */
18
+ jti?: string;
19
+ }
20
+ /**
21
+ * Token validation result.
22
+ */
23
+ export interface TokenValidation {
24
+ valid: boolean;
25
+ error?: string;
26
+ claims?: JWTClaims;
27
+ }
28
+ /**
29
+ * Parses a JWT token and extracts claims without validating the signature.
30
+ * This is sufficient for basic format validation and expiration checking.
31
+ */
32
+ export declare function parseJWTToken(token: string): JWTClaims;
33
+ /**
34
+ * Checks if the token is expired based on the exp claim.
35
+ */
36
+ export declare function isTokenExpired(claims: JWTClaims): boolean;
37
+ /**
38
+ * Checks if the token is not yet valid based on the nbf claim.
39
+ */
40
+ export declare function isTokenNotYetValid(claims: JWTClaims): boolean;
41
+ /**
42
+ * Returns the duration in milliseconds until the token expires.
43
+ */
44
+ export declare function tokenExpiresIn(claims: JWTClaims): number;
45
+ /**
46
+ * Validates the format and expiration of an auth token.
47
+ * Assumes the token is a JWT but gracefully handles non-JWT tokens.
48
+ */
49
+ export declare function validateAuthToken(token: string): TokenValidation;
50
+ /**
51
+ * Gets token info including claims and expiration status.
52
+ */
53
+ export declare function getTokenInfo(token: string): {
54
+ claims: JWTClaims;
55
+ isExpired: boolean;
56
+ expiresIn: number;
57
+ };
58
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../client/lib/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe;IACf,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAkBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAiBtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAKzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAK7D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAKxD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAqChE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG;IAC3C,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CASA"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Decodes a base64url string.
3
+ */
4
+ function base64UrlDecode(input) {
5
+ // Replace base64url characters with base64 characters
6
+ let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
7
+ // Add padding if necessary
8
+ const padding = base64.length % 4;
9
+ if (padding) {
10
+ base64 += "=".repeat(4 - padding);
11
+ }
12
+ return Buffer.from(base64, "base64").toString("utf-8");
13
+ }
14
+ /**
15
+ * Parses a JWT token and extracts claims without validating the signature.
16
+ * This is sufficient for basic format validation and expiration checking.
17
+ */
18
+ export function parseJWTToken(token) {
19
+ const parts = token.split(".");
20
+ if (parts.length !== 3) {
21
+ throw new Error(`Invalid token format: expected 3 parts, got ${parts.length}`);
22
+ }
23
+ const payload = parts[1];
24
+ if (!payload) {
25
+ throw new Error("Invalid token format: missing payload");
26
+ }
27
+ try {
28
+ const decoded = base64UrlDecode(payload);
29
+ return JSON.parse(decoded);
30
+ }
31
+ catch (err) {
32
+ throw new Error(`Failed to parse token payload: ${err instanceof Error ? err.message : String(err)}`);
33
+ }
34
+ }
35
+ /**
36
+ * Checks if the token is expired based on the exp claim.
37
+ */
38
+ export function isTokenExpired(claims) {
39
+ if (!claims.exp) {
40
+ return false; // No expiration set
41
+ }
42
+ return Date.now() >= claims.exp * 1000;
43
+ }
44
+ /**
45
+ * Checks if the token is not yet valid based on the nbf claim.
46
+ */
47
+ export function isTokenNotYetValid(claims) {
48
+ if (!claims.nbf) {
49
+ return false; // No nbf claim set
50
+ }
51
+ return Date.now() < claims.nbf * 1000;
52
+ }
53
+ /**
54
+ * Returns the duration in milliseconds until the token expires.
55
+ */
56
+ export function tokenExpiresIn(claims) {
57
+ if (!claims.exp) {
58
+ return 0; // No expiration
59
+ }
60
+ return claims.exp * 1000 - Date.now();
61
+ }
62
+ /**
63
+ * Validates the format and expiration of an auth token.
64
+ * Assumes the token is a JWT but gracefully handles non-JWT tokens.
65
+ */
66
+ export function validateAuthToken(token) {
67
+ if (!token) {
68
+ return { valid: false, error: "Auth token is empty" };
69
+ }
70
+ // Remove Bearer prefix if present
71
+ const actualToken = token.replace(/^Bearer\s+/i, "");
72
+ // If it doesn't look like a JWT (no dots), treat it as an opaque token
73
+ if (!actualToken.includes(".")) {
74
+ if (actualToken.length < 10) {
75
+ return { valid: false, error: `Token appears too short (length: ${actualToken.length})` };
76
+ }
77
+ return { valid: true }; // Assume opaque token is valid
78
+ }
79
+ // Parse as JWT
80
+ let claims;
81
+ try {
82
+ claims = parseJWTToken(actualToken);
83
+ }
84
+ catch (err) {
85
+ return { valid: false, error: err instanceof Error ? err.message : String(err) };
86
+ }
87
+ // Check if token is expired
88
+ if (isTokenExpired(claims)) {
89
+ const expDate = claims.exp ? new Date(claims.exp * 1000).toISOString() : "unknown";
90
+ return { valid: false, error: `Token expired at ${expDate}`, claims };
91
+ }
92
+ // Check if token is not yet valid
93
+ if (isTokenNotYetValid(claims)) {
94
+ const nbfDate = claims.nbf ? new Date(claims.nbf * 1000).toISOString() : "unknown";
95
+ return { valid: false, error: `Token not yet valid until ${nbfDate}`, claims };
96
+ }
97
+ return { valid: true, claims };
98
+ }
99
+ /**
100
+ * Gets token info including claims and expiration status.
101
+ */
102
+ export function getTokenInfo(token) {
103
+ const actualToken = token.replace(/^Bearer\s+/i, "");
104
+ const claims = parseJWTToken(actualToken);
105
+ return {
106
+ claims,
107
+ isExpired: isTokenExpired(claims),
108
+ expiresIn: tokenExpiresIn(claims),
109
+ };
110
+ }
111
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../client/lib/auth.ts"],"names":[],"mappings":"AA6BA;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,sDAAsD;IACtD,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAEzD,2BAA2B;IAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+CAA+C,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC,CAAC,oBAAoB;IACpC,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC,CAAC,mBAAmB;IACnC,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,CAAC,CAAC,gBAAgB;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;IACxD,CAAC;IAED,kCAAkC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAErD,uEAAuE;IACvE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,IAAI,WAAW,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC;QAC5F,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,+BAA+B;IACzD,CAAC;IAED,eAAe;IACf,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACnF,CAAC;IAED,4BAA4B;IAC5B,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACnF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC;IACxE,CAAC;IAED,kCAAkC;IAClC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACnF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC;IACjF,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IAKxC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAE1C,OAAO;QACL,MAAM;QACN,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC;QACjC,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Client configuration options.
3
+ */
4
+ export interface ClientConfig {
5
+ /**
6
+ * Base URL for the API server.
7
+ * @default "https://api.admiral.io"
8
+ * @example "https://api.admiral.io"
9
+ */
10
+ baseUrl?: string;
11
+ /**
12
+ * Authentication token (JWT or opaque token).
13
+ */
14
+ authToken?: string;
15
+ /**
16
+ * Request timeout in milliseconds.
17
+ * @default 30000
18
+ */
19
+ timeout?: number;
20
+ /**
21
+ * HTTP version to use.
22
+ * @default "2"
23
+ */
24
+ httpVersion?: "1.1" | "2";
25
+ /**
26
+ * Custom headers to include in all requests.
27
+ */
28
+ headers?: Record<string, string>;
29
+ }
30
+ /**
31
+ * Default configuration values.
32
+ */
33
+ export declare const DEFAULT_CONFIG: {
34
+ readonly baseUrl: "https://api.admiral.io";
35
+ readonly timeout: 30000;
36
+ readonly httpVersion: "2";
37
+ };
38
+ /**
39
+ * Validates and applies defaults to the configuration.
40
+ */
41
+ export declare function resolveConfig(config: ClientConfig): Required<Omit<ClientConfig, "authToken" | "headers">> & Pick<ClientConfig, "authToken" | "headers">;
42
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../client/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC;IAE1B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC,CAiBvJ"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Default configuration values.
3
+ */
4
+ export const DEFAULT_CONFIG = {
5
+ baseUrl: "https://api.admiral.io",
6
+ timeout: 30000,
7
+ httpVersion: "2",
8
+ };
9
+ /**
10
+ * Validates and applies defaults to the configuration.
11
+ */
12
+ export function resolveConfig(config) {
13
+ const baseUrl = config.baseUrl ?? DEFAULT_CONFIG.baseUrl;
14
+ // Validate URL format
15
+ try {
16
+ new URL(baseUrl);
17
+ }
18
+ catch {
19
+ throw new Error(`Invalid baseUrl: ${baseUrl}`);
20
+ }
21
+ return {
22
+ baseUrl: baseUrl.replace(/\/$/, ""), // Remove trailing slash
23
+ authToken: config.authToken,
24
+ timeout: config.timeout ?? DEFAULT_CONFIG.timeout,
25
+ httpVersion: config.httpVersion ?? DEFAULT_CONFIG.httpVersion,
26
+ headers: config.headers,
27
+ };
28
+ }
29
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../client/lib/config.ts"],"names":[],"mappings":"AAkCA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,GAAY;CACjB,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoB;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC;IAEzD,sBAAsB;IACtB,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,wBAAwB;QAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;QACjD,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,cAAc,CAAC,WAAW;QAC7D,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Transport } from "@connectrpc/connect";
2
+ import type { ClientConfig } from "./config.js";
3
+ /**
4
+ * Creates a Connect transport with the provided configuration.
5
+ */
6
+ export declare function createTransport(config: ClientConfig): Transport;
7
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../client/lib/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA8ChD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAuB/D"}