@quantum-hub/qhub-service 1.2.2 → 1.3.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.
package/dist/client.d.ts CHANGED
@@ -1,6 +1,24 @@
1
- import { HubServiceClient as BaseHubServiceClient, type HubService } from '@quantum-hub/qhub-api/service';
1
+ import { type HubService, HubServiceClient as BaseHubServiceClient } from '@quantum-hub/qhub-api/service';
2
+ import { HubPlatformClient as BaseHubPlatformClient } from '@quantum-hub/qhub-api/platform';
3
+ import { type DataPoolGrant } from './datapool.js';
2
4
  type ServiceApiClient = InstanceType<typeof BaseHubServiceClient>['serviceApi'];
5
+ type DataPoolGrantsClient = InstanceType<typeof BaseHubPlatformClient>['dataPoolGrants'];
3
6
  export declare const DEFAULT_TOKEN_ENDPOINT = "https://gateway.hub.kipu-quantum.com/token";
7
+ export interface HubPlatformClientOptions {
8
+ apiKey: string;
9
+ platformEndpoint?: string;
10
+ organizationId?: string;
11
+ }
12
+ export declare class HubPlatformClient {
13
+ private _client;
14
+ private readonly _organizationId;
15
+ constructor(options: HubPlatformClientOptions);
16
+ get organizationId(): string | undefined;
17
+ get dataPoolGrants(): DataPoolGrantsClient;
18
+ }
19
+ export interface RunOptions {
20
+ grants?: DataPoolGrant[];
21
+ }
4
22
  export declare class HubServiceAuth {
5
23
  private accessToken;
6
24
  private readonly accessKeyId;
@@ -12,9 +30,12 @@ export declare class HubServiceAuth {
12
30
  }
13
31
  export declare class HubServiceClient {
14
32
  private _api;
15
- constructor(serviceEndpoint: string, accessKeyId?: string, secretAccessKey?: string, tokenEndpoint?: string);
33
+ private readonly _platform;
34
+ private _grantCache;
35
+ constructor(serviceEndpoint: string, accessKeyId?: string, secretAccessKey?: string, tokenEndpoint?: string, platformClient?: HubPlatformClient);
16
36
  api(): ServiceApiClient;
17
- run(request: Record<string, unknown>, secrets?: Record<string, unknown>, tags?: string[]): Promise<HubService.ServiceExecution>;
37
+ run(request: Record<string, unknown>, secrets?: Record<string, unknown>, tags?: string[], options?: RunOptions): Promise<HubService.ServiceExecution>;
38
+ private _acquireGrant;
18
39
  }
19
40
  export {};
20
41
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,IAAI,oBAAoB,EAAE,KAAK,UAAU,EAAC,MAAM,+BAA+B,CAAA;AAEvG,KAAK,gBAAgB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAA;AAE/E,eAAO,MAAM,sBAAsB,+CAA+C,CAAA;AAElF,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;gBAE1B,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,GAAE,MAA+B;IAMlG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAYvC,OAAO,CAAC,gBAAgB;CAiBzB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAsB;gBAEtB,eAAe,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,EAAE,aAAa,GAAE,MAA+B;IAe5H,GAAG,IAAI,gBAAgB;IAIjB,GAAG,CACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC;CASxC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,UAAU,EAAE,gBAAgB,IAAI,oBAAoB,EAAC,MAAM,+BAA+B,CAAA;AACvG,OAAO,EAAC,iBAAiB,IAAI,qBAAqB,EAAC,MAAM,gCAAgC,CAAA;AACzF,OAAO,EAAC,KAAK,aAAa,EAAgB,MAAM,eAAe,CAAA;AAE/D,KAAK,gBAAgB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAA;AAC/E,KAAK,oBAAoB,GAAG,YAAY,CAAC,OAAO,qBAAqB,CAAC,CAAC,gBAAgB,CAAC,CAAA;AAExF,eAAO,MAAM,sBAAsB,+CAA+C,CAAA;AAIlF,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoB;gBAExC,OAAO,EAAE,wBAAwB;IAQ7C,IAAI,cAAc,IAAI,MAAM,GAAG,SAAS,CAEvC;IAED,IAAI,cAAc,IAAI,oBAAoB,CAEzC;CACF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,aAAa,EAAE,CAAA;CACzB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;gBAE1B,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,GAAE,MAA+B;IAMlG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAYvC,OAAO,CAAC,gBAAgB;CAiBzB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IACzD,OAAO,CAAC,WAAW,CAAuD;gBAGtE,eAAe,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,GAAE,MAA+B,EAC9C,cAAc,CAAC,EAAE,iBAAiB;IAkB/B,GAAG,IAAI,gBAAgB;IAIjB,GAAG,CACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAwBzB,aAAa;CAkB5B"}
package/dist/client.js CHANGED
@@ -1,6 +1,26 @@
1
1
  import { ClientCredentials } from 'simple-oauth2';
2
2
  import { HubServiceClient as BaseHubServiceClient } from '@quantum-hub/qhub-api/service';
3
+ import { HubPlatformClient as BaseHubPlatformClient } from '@quantum-hub/qhub-api/platform';
4
+ import { ReferenceType } from './datapool.js';
3
5
  export const DEFAULT_TOKEN_ENDPOINT = 'https://gateway.hub.kipu-quantum.com/token';
6
+ const GRANT_CACHE_BUFFER_SECONDS = 30;
7
+ export class HubPlatformClient {
8
+ _client;
9
+ _organizationId;
10
+ constructor(options) {
11
+ this._client = new BaseHubPlatformClient({
12
+ apiKey: options.apiKey,
13
+ ...(options.platformEndpoint ? { environment: () => options.platformEndpoint } : {}),
14
+ });
15
+ this._organizationId = options.organizationId;
16
+ }
17
+ get organizationId() {
18
+ return this._organizationId;
19
+ }
20
+ get dataPoolGrants() {
21
+ return this._client.dataPoolGrants;
22
+ }
23
+ }
4
24
  export class HubServiceAuth {
5
25
  accessToken;
6
26
  accessKeyId;
@@ -40,7 +60,9 @@ export class HubServiceAuth {
40
60
  }
41
61
  export class HubServiceClient {
42
62
  _api;
43
- constructor(serviceEndpoint, accessKeyId, secretAccessKey, tokenEndpoint = DEFAULT_TOKEN_ENDPOINT) {
63
+ _platform;
64
+ _grantCache = new Map();
65
+ constructor(serviceEndpoint, accessKeyId, secretAccessKey, tokenEndpoint = DEFAULT_TOKEN_ENDPOINT, platformClient) {
44
66
  if (accessKeyId && secretAccessKey) {
45
67
  const auth = new HubServiceAuth(accessKeyId, secretAccessKey, tokenEndpoint);
46
68
  this._api = new BaseHubServiceClient({
@@ -54,17 +76,48 @@ export class HubServiceClient {
54
76
  token: async () => Math.random().toString(36).slice(2),
55
77
  });
56
78
  }
79
+ this._platform = platformClient;
57
80
  }
58
81
  api() {
59
82
  return this._api.serviceApi;
60
83
  }
61
- async run(request, secrets, tags) {
84
+ async run(request, secrets, tags, options) {
62
85
  if (tags !== undefined && !('$tags' in request)) {
63
86
  request['$tags'] = tags;
64
87
  }
65
88
  if (secrets !== undefined && !('$secrets' in request)) {
66
89
  request['$secrets'] = secrets;
67
90
  }
91
+ if (options?.grants) {
92
+ if (!this._platform) {
93
+ throw new Error('apiKey is required for data pool grant acquisition');
94
+ }
95
+ await Promise.all(options.grants.map(async (g) => {
96
+ const token = await this._acquireGrant(g.datapoolId, g.applicationId, g.permission ?? 'MODIFY');
97
+ request[g.name] = { id: g.datapoolId, ref: ReferenceType.DATAPOOL, grant: token };
98
+ }));
99
+ }
68
100
  return this.api().startExecution(request);
69
101
  }
102
+ async _acquireGrant(datapoolId, applicationId, permission) {
103
+ const cacheKey = `${datapoolId}:${applicationId}:${permission}`;
104
+ const cached = this._grantCache.get(cacheKey);
105
+ if (cached && Date.now() / 1000 < cached.expiry - GRANT_CACHE_BUFFER_SECONDS) {
106
+ return cached.token;
107
+ }
108
+ const grant = await this._platform.dataPoolGrants.createGrant(datapoolId, {
109
+ applicationId,
110
+ permission,
111
+ 'X-OrganizationId': this._platform.organizationId,
112
+ });
113
+ const token = grant.token;
114
+ const expiry = parseJwtExpiry(token);
115
+ this._grantCache.set(cacheKey, { token, expiry });
116
+ return token;
117
+ }
118
+ }
119
+ function parseJwtExpiry(token) {
120
+ const payload = token.split('.')[1];
121
+ const decoded = JSON.parse(atob(payload));
122
+ return decoded.exp ?? 0;
70
123
  }
@@ -1,9 +1,20 @@
1
1
  export declare enum ReferenceType {
2
2
  DATAPOOL = "DATAPOOL"
3
3
  }
4
+ export declare enum DataPoolPermission {
5
+ VIEW = "VIEW",
6
+ MODIFY = "MODIFY"
7
+ }
4
8
  export interface DataPoolReference {
5
9
  id: string;
6
10
  ref: ReferenceType;
11
+ grant?: string;
12
+ }
13
+ export interface DataPoolGrant {
14
+ name: string;
15
+ datapoolId: string;
16
+ applicationId: string;
17
+ permission?: DataPoolPermission;
7
18
  }
8
19
  /**
9
20
  * Factory function to create DataPoolReference objects with ref always set to DATAPOOL.
@@ -1 +1 @@
1
- {"version":3,"file":"datapool.d.ts","sourceRoot":"","sources":["../src/datapool.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa;IACvB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,aAAa,CAAA;CACnB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAKnE"}
1
+ {"version":3,"file":"datapool.d.ts","sourceRoot":"","sources":["../src/datapool.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa;IACvB,QAAQ,aAAa;CACtB;AAED,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,aAAa,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAKnE"}
package/dist/datapool.js CHANGED
@@ -2,6 +2,11 @@ export var ReferenceType;
2
2
  (function (ReferenceType) {
3
3
  ReferenceType["DATAPOOL"] = "DATAPOOL";
4
4
  })(ReferenceType || (ReferenceType = {}));
5
+ export var DataPoolPermission;
6
+ (function (DataPoolPermission) {
7
+ DataPoolPermission["VIEW"] = "VIEW";
8
+ DataPoolPermission["MODIFY"] = "MODIFY";
9
+ })(DataPoolPermission || (DataPoolPermission = {}));
5
10
  /**
6
11
  * Factory function to create DataPoolReference objects with ref always set to DATAPOOL.
7
12
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantum-hub/qhub-service",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "SDK to interact with managed services on the Kipu Quantum Hub.",
5
5
  "author": "Kipu Quantum GmbH",
6
6
  "contributors": [