@datalayer/core 0.0.12 → 0.0.14
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/README.md +2 -2
- package/lib/api/DatalayerApi.d.ts +38 -26
- package/lib/api/DatalayerApi.js +52 -13
- package/lib/api/iam/authentication.d.ts +9 -8
- package/lib/api/iam/authentication.js +14 -15
- package/lib/api/iam/healthz.d.ts +3 -2
- package/lib/api/iam/healthz.js +5 -3
- package/lib/api/iam/index.d.ts +9 -4
- package/lib/api/iam/index.js +9 -4
- package/lib/api/iam/oauth2.d.ts +115 -0
- package/lib/api/iam/oauth2.js +309 -0
- package/lib/api/iam/profile.d.ts +8 -1
- package/lib/api/iam/profile.js +17 -2
- package/lib/api/iam/usage.d.ts +18 -0
- package/lib/api/iam/usage.js +39 -0
- package/lib/api/index.d.ts +6 -6
- package/lib/api/index.js +6 -7
- package/lib/api/runtimes/environments.d.ts +2 -2
- package/lib/api/runtimes/environments.js +3 -2
- package/lib/api/runtimes/healthz.d.ts +3 -13
- package/lib/api/runtimes/healthz.js +4 -3
- package/lib/api/runtimes/index.d.ts +3 -2
- package/lib/api/runtimes/index.js +3 -2
- package/lib/api/runtimes/runtimes.d.ts +4 -4
- package/lib/api/runtimes/runtimes.js +17 -6
- package/lib/api/runtimes/snapshots.d.ts +4 -4
- package/lib/api/runtimes/snapshots.js +3 -2
- package/lib/api/spacer/documents.d.ts +12 -0
- package/lib/api/spacer/documents.js +43 -0
- package/lib/api/spacer/healthz.d.ts +3 -13
- package/lib/api/spacer/healthz.js +4 -3
- package/lib/api/spacer/index.d.ts +4 -2
- package/lib/api/spacer/index.js +4 -2
- package/lib/api/spacer/items.d.ts +9 -1
- package/lib/api/spacer/items.js +17 -2
- package/lib/api/spacer/lexicals.d.ts +1 -1
- package/lib/api/spacer/lexicals.js +3 -2
- package/lib/api/spacer/notebooks.d.ts +1 -1
- package/lib/api/spacer/notebooks.js +3 -2
- package/lib/api/spacer/spaces.d.ts +1 -1
- package/lib/api/spacer/spaces.js +3 -2
- package/lib/api/spacer/users.d.ts +1 -1
- package/lib/api/spacer/users.js +3 -2
- package/lib/api/utils/validation.d.ts +24 -1
- package/lib/api/utils/validation.js +62 -1
- package/lib/client/base.d.ts +75 -0
- package/lib/client/base.js +199 -0
- package/lib/client/constants.d.ts +22 -0
- package/lib/client/constants.js +22 -0
- package/lib/client/index.d.ts +108 -0
- package/lib/client/index.js +79 -0
- package/lib/client/mixins/IAMMixin.d.ts +54 -0
- package/lib/client/mixins/IAMMixin.js +181 -0
- package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
- package/lib/client/mixins/RuntimesMixin.js +229 -0
- package/lib/client/mixins/SpacerMixin.d.ts +111 -0
- package/lib/client/mixins/SpacerMixin.js +340 -0
- package/lib/client/utils/mixins.d.ts +12 -0
- package/lib/{sdk/client → client}/utils/mixins.js +0 -28
- package/lib/client/utils/spacerUtils.d.ts +18 -0
- package/lib/client/utils/spacerUtils.js +32 -0
- package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
- package/lib/collaboration/DatalayerCollaboration.js +2 -2
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
- package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
- package/lib/components/progress/CreditsIndicator.d.ts +1 -1
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
- package/lib/components/runtimes/RuntimeLauncherDialog.js +2 -2
- package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.js +1 -1
- package/lib/components/runtimes/RuntimePickerCell.js +3 -3
- package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerNotebook.js +2 -2
- package/lib/components/runtimes/RuntimeTransfer.d.ts +2 -2
- package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
- package/lib/config/Configuration.d.ts +8 -0
- package/lib/hooks/useDatalayer.js +1 -1
- package/lib/hooks/useRuntimes.js +1 -1
- package/lib/hooks/useToast.js +1 -1
- package/lib/index.d.ts +2 -3
- package/lib/index.js +4 -3
- package/lib/models/Common.d.ts +64 -0
- package/lib/models/CreditsDTO.d.ts +124 -0
- package/lib/models/CreditsDTO.js +135 -0
- package/lib/models/Environment.d.ts +1 -1
- package/lib/models/EnvironmentDTO.d.ts +125 -0
- package/lib/models/EnvironmentDTO.js +88 -0
- package/lib/models/HealthCheck.d.ts +72 -0
- package/lib/models/HealthCheck.js +107 -0
- package/lib/{api/types/iam.d.ts → models/IAM.d.ts} +15 -78
- package/lib/models/ItemDTO.d.ts +74 -0
- package/lib/models/ItemDTO.js +186 -0
- package/lib/models/LexicalDTO.d.ts +155 -0
- package/lib/models/LexicalDTO.js +157 -0
- package/lib/models/NotebookDTO.d.ts +96 -0
- package/lib/models/NotebookDTO.js +153 -0
- package/lib/models/Profile.d.ts +65 -0
- package/lib/models/RuntimeDTO.d.ts +191 -0
- package/lib/models/RuntimeDTO.js +204 -0
- package/lib/models/RuntimeSnapshotDTO.d.ts +173 -0
- package/lib/models/RuntimeSnapshotDTO.js +139 -0
- package/lib/models/SpaceDTO.d.ts +280 -0
- package/lib/models/SpaceDTO.js +239 -0
- package/lib/models/UserDTO.d.ts +86 -0
- package/lib/models/UserDTO.js +84 -0
- package/lib/models/index.d.ts +45 -4
- package/lib/models/index.js +45 -4
- package/lib/sdk/index.d.ts +5 -4
- package/lib/sdk/index.js +6 -5
- package/lib/services/DatalayerServiceManager.js +1 -1
- package/lib/state/substates/CoreState.js +2 -0
- package/lib/state/substates/RuntimesState.d.ts +1 -1
- package/lib/state/substates/RuntimesState.js +1 -1
- package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
- package/lib/{sdk/stateful → stateful}/index.js +1 -1
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
- package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
- package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
- package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
- package/package.json +13 -10
- package/lib/__tests__/hooks.test.d.ts +0 -1
- package/lib/__tests__/hooks.test.js +0 -19
- package/lib/__tests__/index.test.d.ts +0 -1
- package/lib/__tests__/index.test.js +0 -27
- package/lib/__tests__/integration.test.d.ts +0 -1
- package/lib/__tests__/integration.test.js +0 -57
- package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
- package/lib/__tests__/shared/cleanup-shared.js +0 -228
- package/lib/__tests__/shared/test-config.d.ts +0 -51
- package/lib/__tests__/shared/test-config.js +0 -110
- package/lib/__tests__/shared/test-constants.d.ts +0 -66
- package/lib/__tests__/shared/test-constants.js +0 -79
- package/lib/__tests__/utils.test.d.ts +0 -1
- package/lib/__tests__/utils.test.js +0 -59
- package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
- package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
- package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
- package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
- package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.integration.test.js +0 -369
- package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.integration.test.js +0 -519
- package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
- package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
- package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
- package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
- package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
- package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
- package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
- package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
- package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
- package/lib/api/types/index.d.ts +0 -32
- package/lib/api/types/index.js +0 -36
- package/lib/api/types/runtimes.d.ts +0 -235
- package/lib/api/types/spacer.d.ts +0 -271
- package/lib/api/types/spacer.js +0 -5
- package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
- package/lib/api/utils/__tests__/validation.test.js +0 -109
- package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
- package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
- package/lib/sdk/client/base.d.ts +0 -88
- package/lib/sdk/client/base.js +0 -112
- package/lib/sdk/client/index.d.ts +0 -192
- package/lib/sdk/client/index.js +0 -128
- package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
- package/lib/sdk/client/mixins/HealthMixin.js +0 -133
- package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
- package/lib/sdk/client/mixins/IAMMixin.js +0 -83
- package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
- package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
- package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
- package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
- package/lib/sdk/client/models/Lexical.d.ts +0 -156
- package/lib/sdk/client/models/Lexical.js +0 -275
- package/lib/sdk/client/models/Notebook.d.ts +0 -174
- package/lib/sdk/client/models/Notebook.js +0 -311
- package/lib/sdk/client/models/Runtime.d.ts +0 -221
- package/lib/sdk/client/models/Runtime.js +0 -341
- package/lib/sdk/client/models/Snapshot.d.ts +0 -156
- package/lib/sdk/client/models/Snapshot.js +0 -244
- package/lib/sdk/client/models/Space.d.ts +0 -182
- package/lib/sdk/client/models/Space.js +0 -276
- package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
- package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
- package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
- package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
- package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
- package/lib/sdk/client/models/index.d.ts +0 -30
- package/lib/sdk/client/models/index.js +0 -30
- package/lib/sdk/client/utils/mixins.d.ts +0 -42
- /package/lib/{api/types/iam.js → models/Common.js} +0 -0
- /package/lib/{api/types/runtimes.js → models/IAM.js} +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/apis.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.js +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Base SDK class providing core configuration and token management.
|
|
7
|
+
* @module client/base
|
|
8
|
+
*/
|
|
9
|
+
import { DEFAULT_SERVICE_URLS } from '../api/constants';
|
|
10
|
+
/** Base Client class providing core configuration and token management. */
|
|
11
|
+
export class DatalayerClientBase {
|
|
12
|
+
/** URL for IAM service */
|
|
13
|
+
iamRunUrl;
|
|
14
|
+
/** URL for Runtimes service */
|
|
15
|
+
runtimesRunUrl;
|
|
16
|
+
/** URL for Spacer service */
|
|
17
|
+
spacerRunUrl;
|
|
18
|
+
/** Authentication token */
|
|
19
|
+
token;
|
|
20
|
+
/** Environments */
|
|
21
|
+
environments = [];
|
|
22
|
+
/** Method lifecycle handlers */
|
|
23
|
+
handlers;
|
|
24
|
+
/**
|
|
25
|
+
* Create a DatalayerClient base instance.
|
|
26
|
+
* @param config - Client configuration options
|
|
27
|
+
*/
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.iamRunUrl = config.iamRunUrl || DEFAULT_SERVICE_URLS.IAM;
|
|
30
|
+
this.runtimesRunUrl =
|
|
31
|
+
config.runtimesRunUrl || DEFAULT_SERVICE_URLS.RUNTIMES;
|
|
32
|
+
this.spacerRunUrl = config.spacerRunUrl || DEFAULT_SERVICE_URLS.SPACER;
|
|
33
|
+
this.token = config.token;
|
|
34
|
+
this.handlers = config.handlers;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the current configuration including service URLs and token.
|
|
38
|
+
* @returns Current configuration
|
|
39
|
+
*/
|
|
40
|
+
getConfig() {
|
|
41
|
+
return {
|
|
42
|
+
iamRunUrl: this.iamRunUrl,
|
|
43
|
+
runtimesRunUrl: this.runtimesRunUrl,
|
|
44
|
+
spacerRunUrl: this.spacerRunUrl,
|
|
45
|
+
token: this.token,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Get the IAM service URL. */
|
|
49
|
+
getIamRunUrl() {
|
|
50
|
+
return this.iamRunUrl;
|
|
51
|
+
}
|
|
52
|
+
/** Get the Runtimes service URL. */
|
|
53
|
+
getRuntimesRunUrl() {
|
|
54
|
+
return this.runtimesRunUrl;
|
|
55
|
+
}
|
|
56
|
+
/** Get the Spacer service URL. */
|
|
57
|
+
getSpacerRunUrl() {
|
|
58
|
+
return this.spacerRunUrl;
|
|
59
|
+
}
|
|
60
|
+
/** Get the current authentication token. */
|
|
61
|
+
getToken() {
|
|
62
|
+
return this.token;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* set the authentication token for all API requests.
|
|
66
|
+
* @param token - New authentication token
|
|
67
|
+
*/
|
|
68
|
+
async setToken(token) {
|
|
69
|
+
this.token = token;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Wrap all SDK methods with handlers for cross-cutting concerns.
|
|
73
|
+
* Called automatically by the DatalayerClient constructor.
|
|
74
|
+
*
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
wrapAllMethods() {
|
|
78
|
+
if (!this.handlers) {
|
|
79
|
+
return; // No handlers configured, nothing to wrap
|
|
80
|
+
}
|
|
81
|
+
// Get all method names from the prototype chain
|
|
82
|
+
const methodNames = this.getAllMethodNames();
|
|
83
|
+
// Wrap each method with handlers
|
|
84
|
+
methodNames.forEach(methodName => {
|
|
85
|
+
const original = this[methodName];
|
|
86
|
+
if (typeof original !== 'function') {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// Detect if the original method is async by checking if it's an AsyncFunction
|
|
90
|
+
const isAsync = original.constructor.name === 'AsyncFunction';
|
|
91
|
+
if (isAsync) {
|
|
92
|
+
// Create async wrapped version for originally async methods
|
|
93
|
+
this[methodName] = async (...args) => {
|
|
94
|
+
// Call beforeCall handler if defined
|
|
95
|
+
if (this.handlers?.beforeCall) {
|
|
96
|
+
await Promise.resolve(this.handlers.beforeCall(methodName, args));
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
// Call the original async method
|
|
100
|
+
const result = await original.apply(this, args);
|
|
101
|
+
// Call afterCall handler if defined
|
|
102
|
+
if (this.handlers?.afterCall) {
|
|
103
|
+
await Promise.resolve(this.handlers.afterCall(methodName, result));
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// Call onError handler if defined
|
|
109
|
+
if (this.handlers?.onError) {
|
|
110
|
+
await Promise.resolve(this.handlers.onError(methodName, error));
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// Create sync wrapped version for originally sync methods
|
|
118
|
+
this[methodName] = (...args) => {
|
|
119
|
+
// Call beforeCall handler if defined (sync version)
|
|
120
|
+
if (this.handlers?.beforeCall) {
|
|
121
|
+
const beforeResult = this.handlers.beforeCall(methodName, args);
|
|
122
|
+
// If beforeCall returns a Promise, we can't await it in sync context
|
|
123
|
+
if (beforeResult instanceof Promise) {
|
|
124
|
+
// Promise ignored in sync context
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
// Call the original sync method
|
|
129
|
+
const result = original.apply(this, args);
|
|
130
|
+
// Call afterCall handler if defined (sync version)
|
|
131
|
+
if (this.handlers?.afterCall) {
|
|
132
|
+
const afterResult = this.handlers.afterCall(methodName, result);
|
|
133
|
+
if (afterResult instanceof Promise) {
|
|
134
|
+
// Promise ignored in sync context
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
// Call onError handler if defined (sync version)
|
|
141
|
+
if (this.handlers?.onError) {
|
|
142
|
+
const errorResult = this.handlers.onError(methodName, error);
|
|
143
|
+
if (errorResult instanceof Promise) {
|
|
144
|
+
// Promise ignored in sync context
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get all method names from mixins only.
|
|
155
|
+
* @returns Array of mixin method names to wrap
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
getAllMethodNames() {
|
|
159
|
+
const methodNames = new Set();
|
|
160
|
+
// First, collect all base class methods to exclude
|
|
161
|
+
const baseClassMethods = new Set();
|
|
162
|
+
const basePrototype = DatalayerClientBase.prototype;
|
|
163
|
+
Object.getOwnPropertyNames(basePrototype).forEach(name => {
|
|
164
|
+
baseClassMethods.add(name);
|
|
165
|
+
});
|
|
166
|
+
// Also exclude methods from the concrete SDK class itself
|
|
167
|
+
const sdkPrototype = Object.getPrototypeOf(this).constructor.prototype;
|
|
168
|
+
Object.getOwnPropertyNames(sdkPrototype).forEach(name => {
|
|
169
|
+
baseClassMethods.add(name);
|
|
170
|
+
});
|
|
171
|
+
// Now walk the prototype chain and only include mixin methods
|
|
172
|
+
let obj = Object.getPrototypeOf(this);
|
|
173
|
+
while (obj && obj !== Object.prototype) {
|
|
174
|
+
const names = Object.getOwnPropertyNames(obj);
|
|
175
|
+
names.forEach(name => {
|
|
176
|
+
// Only include if:
|
|
177
|
+
// 1. Not a constructor
|
|
178
|
+
// 2. Not a private method (starts with _)
|
|
179
|
+
// 3. Not a base class method
|
|
180
|
+
// 4. Is actually a function
|
|
181
|
+
if (name !== 'constructor' &&
|
|
182
|
+
!name.startsWith('_') &&
|
|
183
|
+
!baseClassMethods.has(name)) {
|
|
184
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, name);
|
|
185
|
+
if (descriptor && typeof descriptor.value === 'function') {
|
|
186
|
+
methodNames.add(name);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
obj = Object.getPrototypeOf(obj);
|
|
191
|
+
}
|
|
192
|
+
return Array.from(methodNames);
|
|
193
|
+
}
|
|
194
|
+
// Utility Methods
|
|
195
|
+
calculateCreditsFromMinutes(minutes, burningRate) {
|
|
196
|
+
const burningRatePerMinute = burningRate * 60;
|
|
197
|
+
return Math.ceil(minutes * burningRatePerMinute);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for the Datalayer SDK.
|
|
3
|
+
*
|
|
4
|
+
* @module client/constants
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Item types used throughout the SDK and consuming applications.
|
|
8
|
+
* These constants define the type identifiers for different Datalayer items.
|
|
9
|
+
* Values match what the Datalayer API returns.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ItemTypes: {
|
|
12
|
+
readonly NOTEBOOK: "notebook";
|
|
13
|
+
readonly LEXICAL: "document";
|
|
14
|
+
readonly EXERCISE: "exercise";
|
|
15
|
+
readonly CELL: "cell";
|
|
16
|
+
readonly SPACE: "space";
|
|
17
|
+
readonly UNKNOWN: "unknown";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Type representing valid item types.
|
|
21
|
+
*/
|
|
22
|
+
export type ItemType = (typeof ItemTypes)[keyof typeof ItemTypes];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Constants for the Datalayer SDK.
|
|
7
|
+
*
|
|
8
|
+
* @module client/constants
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Item types used throughout the SDK and consuming applications.
|
|
12
|
+
* These constants define the type identifiers for different Datalayer items.
|
|
13
|
+
* Values match what the Datalayer API returns.
|
|
14
|
+
*/
|
|
15
|
+
export const ItemTypes = {
|
|
16
|
+
NOTEBOOK: 'notebook',
|
|
17
|
+
LEXICAL: 'document',
|
|
18
|
+
EXERCISE: 'exercise',
|
|
19
|
+
CELL: 'cell',
|
|
20
|
+
SPACE: 'space',
|
|
21
|
+
UNKNOWN: 'unknown',
|
|
22
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Datalayer Client with intuitive mixin-based API.
|
|
3
|
+
* Provides unified, flat API for all Datalayer platform services through TypeScript mixins.
|
|
4
|
+
*
|
|
5
|
+
* @module client
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const client = new DatalayerClient({
|
|
10
|
+
* token: 'your-api-token'
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* const user = await client.whoami();
|
|
14
|
+
* const runtime = await client.createRuntime(config);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { DatalayerClientBase, type DatalayerClientConfig, type SDKHandlers } from './base';
|
|
18
|
+
import type { UserDTO } from './../models/UserDTO';
|
|
19
|
+
import type { CreditsDTO } from '../models/CreditsDTO';
|
|
20
|
+
import type { EnvironmentDTO } from '../models/EnvironmentDTO';
|
|
21
|
+
import type { RuntimeDTO } from '../models/RuntimeDTO';
|
|
22
|
+
import type { RuntimeSnapshotDTO } from '../models/RuntimeSnapshotDTO';
|
|
23
|
+
import type { SpaceDTO } from '../models/SpaceDTO';
|
|
24
|
+
import type { NotebookDTO } from '../models/NotebookDTO';
|
|
25
|
+
import type { LexicalDTO } from '../models/LexicalDTO';
|
|
26
|
+
import type { HealthCheck } from '../models/HealthCheck';
|
|
27
|
+
declare const DatalayerClientWithMixins: typeof DatalayerClientBase;
|
|
28
|
+
/**
|
|
29
|
+
* Main Datalayer Client providing unified access to all platform services.
|
|
30
|
+
* Uses TypeScript mixins to provide a flat, discoverable API.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const client = new DatalayerClient({
|
|
35
|
+
* token: 'your-token'
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const user = await client.whoami();
|
|
39
|
+
* const runtime = await client.createRuntime({
|
|
40
|
+
* environment_name: 'python-cpu-env',
|
|
41
|
+
* credits_limit: 100
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class DatalayerClient extends DatalayerClientWithMixins {
|
|
46
|
+
/**
|
|
47
|
+
* Create a DatalayerClient instance.
|
|
48
|
+
*
|
|
49
|
+
* @param config - Client configuration options
|
|
50
|
+
*/
|
|
51
|
+
constructor(config: DatalayerClientConfig);
|
|
52
|
+
}
|
|
53
|
+
export type { DatalayerClientConfig, SDKHandlers };
|
|
54
|
+
export { DatalayerClientBase };
|
|
55
|
+
export { UserDTO as User } from './../models/UserDTO';
|
|
56
|
+
export type { UserJSON } from './../models/UserDTO';
|
|
57
|
+
export { RuntimeDTO as Runtime } from '../models/RuntimeDTO';
|
|
58
|
+
export type { RuntimeJSON } from '../models/RuntimeDTO';
|
|
59
|
+
export { EnvironmentDTO as Environment } from '../models/EnvironmentDTO';
|
|
60
|
+
export type { EnvironmentJSON } from '../models/EnvironmentDTO';
|
|
61
|
+
export { RuntimeSnapshotDTO as Snapshot } from '../models/RuntimeSnapshotDTO';
|
|
62
|
+
export { SpaceDTO as Space } from '../models/SpaceDTO';
|
|
63
|
+
export { NotebookDTO as Notebook } from '../models/NotebookDTO';
|
|
64
|
+
export { LexicalDTO } from '../models/LexicalDTO';
|
|
65
|
+
export { CreditsDTO as Credits } from '../models/CreditsDTO';
|
|
66
|
+
export { ItemDTO as Item } from '../models/ItemDTO';
|
|
67
|
+
export { HealthCheck } from '../models/HealthCheck';
|
|
68
|
+
export type { HealthCheckJSON } from '../models/HealthCheck';
|
|
69
|
+
export { ItemTypes } from './constants';
|
|
70
|
+
export type { ItemType } from './constants';
|
|
71
|
+
export interface DatalayerClient {
|
|
72
|
+
getToken(): string | undefined;
|
|
73
|
+
setToken(token: string): Promise<void>;
|
|
74
|
+
whoami(): Promise<UserDTO>;
|
|
75
|
+
login(token: string): Promise<UserDTO>;
|
|
76
|
+
logout(): Promise<void>;
|
|
77
|
+
getCredits(): Promise<CreditsDTO>;
|
|
78
|
+
calculateMaxRuntimeMinutes(availableCredits: number, burningRate: number): number;
|
|
79
|
+
calculateCreditsRequired(minutes: number, burningRate: number): number;
|
|
80
|
+
checkIAMHealth(): Promise<HealthCheck>;
|
|
81
|
+
listEnvironments(): Promise<EnvironmentDTO[]>;
|
|
82
|
+
ensureRuntime(environmentName?: string, creditsLimit?: number, waitForReady?: boolean, maxWaitTime?: number, reuseExisting?: boolean, snapshotId?: string): Promise<RuntimeDTO>;
|
|
83
|
+
createRuntime(environmentName: string, type: 'notebook' | 'terminal' | 'job', givenName: string, minutesLimit: number, fromSnapshotId?: string): Promise<RuntimeDTO>;
|
|
84
|
+
listRuntimes(): Promise<RuntimeDTO[]>;
|
|
85
|
+
getRuntime(podName: string): Promise<RuntimeDTO>;
|
|
86
|
+
deleteRuntime(podName: string): Promise<void>;
|
|
87
|
+
terminateAllRuntimes(): Promise<PromiseSettledResult<void>[]>;
|
|
88
|
+
createSnapshot(podName: string, name: string, description: string, stop?: boolean): Promise<RuntimeSnapshotDTO>;
|
|
89
|
+
listSnapshots(): Promise<RuntimeSnapshotDTO[]>;
|
|
90
|
+
getSnapshot(id: string): Promise<RuntimeSnapshotDTO>;
|
|
91
|
+
deleteSnapshot(id: string): Promise<void>;
|
|
92
|
+
checkRuntimesHealth(): Promise<HealthCheck>;
|
|
93
|
+
getMySpaces(): Promise<SpaceDTO[]>;
|
|
94
|
+
createSpace(name: string, description: string, variant: string, spaceHandle: string, organizationId: string, seedSpaceId: string, isPublic: boolean): Promise<SpaceDTO>;
|
|
95
|
+
createNotebook(spaceId: string, name: string, description: string, file?: File | Blob): Promise<NotebookDTO>;
|
|
96
|
+
getNotebook(id: string): Promise<NotebookDTO>;
|
|
97
|
+
updateNotebook(id: string, name?: string, description?: string): Promise<NotebookDTO>;
|
|
98
|
+
createLexical(spaceId: string, name: string, description: string, file?: File | Blob): Promise<LexicalDTO>;
|
|
99
|
+
getLexical(id: string): Promise<LexicalDTO>;
|
|
100
|
+
updateLexical(id: string, name?: string, description?: string): Promise<LexicalDTO>;
|
|
101
|
+
getSpaceItems(spaceId: string): Promise<(NotebookDTO | LexicalDTO)[]>;
|
|
102
|
+
getSpaceItem(itemId: string): Promise<NotebookDTO | LexicalDTO>;
|
|
103
|
+
deleteSpaceItem(itemId: string): Promise<void>;
|
|
104
|
+
getCollaborationSessionId(documentId: string): Promise<string>;
|
|
105
|
+
getContent(itemId: string): Promise<any>;
|
|
106
|
+
checkSpacerHealth(): Promise<HealthCheck>;
|
|
107
|
+
calculateCreditsFromMinutes(minutes: number, burningRate: number): number;
|
|
108
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Main Datalayer Client with intuitive mixin-based API.
|
|
7
|
+
* Provides unified, flat API for all Datalayer platform services through TypeScript mixins.
|
|
8
|
+
*
|
|
9
|
+
* @module client
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const client = new DatalayerClient({
|
|
14
|
+
* token: 'your-api-token'
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* const user = await client.whoami();
|
|
18
|
+
* const runtime = await client.createRuntime(config);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import { DatalayerClientBase, } from './base';
|
|
22
|
+
import { IAMMixin } from './mixins/IAMMixin';
|
|
23
|
+
import { RuntimesMixin } from './mixins/RuntimesMixin';
|
|
24
|
+
import { SpacerMixin } from './mixins/SpacerMixin';
|
|
25
|
+
/**
|
|
26
|
+
* Helper function to compose mixins in a more readable way.
|
|
27
|
+
* Applies mixins in the order provided.
|
|
28
|
+
*
|
|
29
|
+
* @param mixins - Array of mixin functions to apply
|
|
30
|
+
* @returns The composed class with all mixins applied
|
|
31
|
+
*/
|
|
32
|
+
function composeMixins(...mixins) {
|
|
33
|
+
return mixins.reduce((base, mixin) => mixin(base), DatalayerClientBase);
|
|
34
|
+
}
|
|
35
|
+
// Apply mixins to the base class using the helper
|
|
36
|
+
const DatalayerClientWithMixins = composeMixins(IAMMixin, RuntimesMixin, SpacerMixin);
|
|
37
|
+
/**
|
|
38
|
+
* Main Datalayer Client providing unified access to all platform services.
|
|
39
|
+
* Uses TypeScript mixins to provide a flat, discoverable API.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const client = new DatalayerClient({
|
|
44
|
+
* token: 'your-token'
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* const user = await client.whoami();
|
|
48
|
+
* const runtime = await client.createRuntime({
|
|
49
|
+
* environment_name: 'python-cpu-env',
|
|
50
|
+
* credits_limit: 100
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export class DatalayerClient extends DatalayerClientWithMixins {
|
|
55
|
+
/**
|
|
56
|
+
* Create a DatalayerClient instance.
|
|
57
|
+
*
|
|
58
|
+
* @param config - Client configuration options
|
|
59
|
+
*/
|
|
60
|
+
constructor(config) {
|
|
61
|
+
super(config);
|
|
62
|
+
// Wrap all methods with handlers if configured
|
|
63
|
+
this.wrapAllMethods();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export { DatalayerClientBase };
|
|
67
|
+
// Export models for use by consumers
|
|
68
|
+
export { UserDTO as User } from './../models/UserDTO';
|
|
69
|
+
export { RuntimeDTO as Runtime } from '../models/RuntimeDTO';
|
|
70
|
+
export { EnvironmentDTO as Environment } from '../models/EnvironmentDTO';
|
|
71
|
+
export { RuntimeSnapshotDTO as Snapshot } from '../models/RuntimeSnapshotDTO';
|
|
72
|
+
export { SpaceDTO as Space } from '../models/SpaceDTO';
|
|
73
|
+
export { NotebookDTO as Notebook } from '../models/NotebookDTO';
|
|
74
|
+
export { LexicalDTO } from '../models/LexicalDTO';
|
|
75
|
+
export { CreditsDTO as Credits } from '../models/CreditsDTO';
|
|
76
|
+
export { ItemDTO as Item } from '../models/ItemDTO';
|
|
77
|
+
export { HealthCheck } from '../models/HealthCheck';
|
|
78
|
+
// Export constants
|
|
79
|
+
export { ItemTypes } from './constants';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Constructor } from '../utils/mixins';
|
|
2
|
+
import { UserDTO } from '../../models/UserDTO';
|
|
3
|
+
import { CreditsDTO } from '../../models/CreditsDTO';
|
|
4
|
+
import { HealthCheck } from '../../models/HealthCheck';
|
|
5
|
+
/** IAM mixin providing authentication and user management. */
|
|
6
|
+
export declare function IAMMixin<TBase extends Constructor>(Base: TBase): {
|
|
7
|
+
new (...args: any[]): {
|
|
8
|
+
currentUserCache?: UserDTO;
|
|
9
|
+
/**
|
|
10
|
+
* Get the current user's profile information.
|
|
11
|
+
* @returns User model instance
|
|
12
|
+
*/
|
|
13
|
+
whoami(): Promise<UserDTO>;
|
|
14
|
+
/**
|
|
15
|
+
* Authenticate the user with a token.
|
|
16
|
+
* @param token - Authentication token
|
|
17
|
+
* @returns User object on successful login
|
|
18
|
+
* @throws Error if token is invalid
|
|
19
|
+
*/
|
|
20
|
+
login(token: string): Promise<UserDTO>;
|
|
21
|
+
/** Log out the current user. */
|
|
22
|
+
logout(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the current user's available credits and usage information.
|
|
25
|
+
* @returns Credits model instance
|
|
26
|
+
*/
|
|
27
|
+
getCredits(): Promise<CreditsDTO>;
|
|
28
|
+
/**
|
|
29
|
+
* Calculate the maximum runtime duration in minutes based on available credits and burning rate.
|
|
30
|
+
* @param availableCredits - The amount of credits available
|
|
31
|
+
* @param burningRate - The burning rate per second for the environment
|
|
32
|
+
* @returns Maximum runtime duration in minutes
|
|
33
|
+
*/
|
|
34
|
+
calculateMaxRuntimeMinutes(availableCredits: number, burningRate: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Calculate the credits required for a given runtime duration.
|
|
37
|
+
* @param minutes - Runtime duration in minutes
|
|
38
|
+
* @param burningRate - The burning rate per second for the environment
|
|
39
|
+
* @returns Credits required (rounded up to nearest integer)
|
|
40
|
+
*/
|
|
41
|
+
calculateCreditsRequired(minutes: number, burningRate: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* Calculate the burning rate per minute from the per-second rate.
|
|
44
|
+
* @param burningRatePerSecond - The burning rate per second
|
|
45
|
+
* @returns Burning rate per minute
|
|
46
|
+
*/
|
|
47
|
+
calculateBurningRatePerMinute(burningRatePerSecond: number): number;
|
|
48
|
+
/**
|
|
49
|
+
* Check the health status of the IAM service.
|
|
50
|
+
* @returns Health check model instance
|
|
51
|
+
*/
|
|
52
|
+
checkIAMHealth(): Promise<HealthCheck>;
|
|
53
|
+
};
|
|
54
|
+
} & TBase;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* IAM mixin providing authentication and user management functionality.
|
|
7
|
+
* @module client/mixins/IAMMixin
|
|
8
|
+
*/
|
|
9
|
+
import * as authentication from '../../api/iam/authentication';
|
|
10
|
+
import * as profile from '../../api/iam/profile';
|
|
11
|
+
import * as usage from '../../api/iam/usage';
|
|
12
|
+
import { UserDTO } from '../../models/UserDTO';
|
|
13
|
+
import { CreditsDTO } from '../../models/CreditsDTO';
|
|
14
|
+
import { HealthCheck } from '../../models/HealthCheck';
|
|
15
|
+
/** IAM mixin providing authentication and user management. */
|
|
16
|
+
export function IAMMixin(Base) {
|
|
17
|
+
return class extends Base {
|
|
18
|
+
// Cache for current user
|
|
19
|
+
currentUserCache;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current user's profile information.
|
|
22
|
+
* @returns User model instance
|
|
23
|
+
*/
|
|
24
|
+
async whoami() {
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
const token = this.getToken();
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
const iamRunUrl = this.getIamRunUrl();
|
|
29
|
+
const response = await profile.whoami(token, iamRunUrl);
|
|
30
|
+
// Handle the whoami response format
|
|
31
|
+
let userData;
|
|
32
|
+
if (!response) {
|
|
33
|
+
throw new Error(`No response from profile.whoami API`);
|
|
34
|
+
}
|
|
35
|
+
// Check if response has the expected wrapper structure with profile
|
|
36
|
+
if (response.profile) {
|
|
37
|
+
// Transform the API response to match the User model's expected data structure
|
|
38
|
+
// Note: whoami returns fields with suffixes like _s, _t
|
|
39
|
+
userData = {
|
|
40
|
+
id: response.profile.id,
|
|
41
|
+
uid: response.profile.uid,
|
|
42
|
+
// User model expects fields with suffixes from API types
|
|
43
|
+
handle_s: response.profile.handle_s || response.profile.handle,
|
|
44
|
+
email_s: response.profile.email_s || response.profile.email,
|
|
45
|
+
first_name_t: response.profile.first_name_t || response.profile.first_name || '',
|
|
46
|
+
last_name_t: response.profile.last_name_t || response.profile.last_name || '',
|
|
47
|
+
// Use avatar_url_s if available, otherwise leave undefined for fallback
|
|
48
|
+
avatar_url_s: response.profile.avatar_url_s || response.profile.avatar_url,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Fallback for unexpected format
|
|
52
|
+
else {
|
|
53
|
+
throw new Error(`Unexpected response format from profile.whoami API: ${JSON.stringify(response)}`);
|
|
54
|
+
}
|
|
55
|
+
// Create new User instance (User model is immutable, no update method)
|
|
56
|
+
this.currentUserCache = new UserDTO(userData, this);
|
|
57
|
+
return this.currentUserCache;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Authenticate the user with a token.
|
|
61
|
+
* @param token - Authentication token
|
|
62
|
+
* @returns User object on successful login
|
|
63
|
+
* @throws Error if token is invalid
|
|
64
|
+
*/
|
|
65
|
+
async login(token) {
|
|
66
|
+
// For token-based login, we simply set the token and verify it works
|
|
67
|
+
await this.setToken(token);
|
|
68
|
+
// Verify the token by calling whoami
|
|
69
|
+
try {
|
|
70
|
+
const user = await this.whoami();
|
|
71
|
+
return user;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
// Clear the invalid token
|
|
75
|
+
await this.setToken('');
|
|
76
|
+
throw new Error(`Invalid token: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Log out the current user. */
|
|
80
|
+
async logout() {
|
|
81
|
+
const token = this.getToken();
|
|
82
|
+
const iamRunUrl = this.getIamRunUrl();
|
|
83
|
+
await authentication.logout(token, iamRunUrl);
|
|
84
|
+
// Clear the token from the SDK and cached user
|
|
85
|
+
this.setToken('');
|
|
86
|
+
this.currentUserCache = undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the current user's available credits and usage information.
|
|
90
|
+
* @returns Credits model instance
|
|
91
|
+
*/
|
|
92
|
+
async getCredits() {
|
|
93
|
+
const token = this.getToken();
|
|
94
|
+
const iamRunUrl = this.getIamRunUrl();
|
|
95
|
+
const response = await usage.getCredits(token, iamRunUrl);
|
|
96
|
+
if (!response || !response.credits) {
|
|
97
|
+
throw new Error('Invalid response from credits API');
|
|
98
|
+
}
|
|
99
|
+
return new CreditsDTO(response.credits, response.reservations || []);
|
|
100
|
+
}
|
|
101
|
+
// ========================================================================
|
|
102
|
+
// Credits Calculation Utilities
|
|
103
|
+
// ========================================================================
|
|
104
|
+
/**
|
|
105
|
+
* Calculate the maximum runtime duration in minutes based on available credits and burning rate.
|
|
106
|
+
* @param availableCredits - The amount of credits available
|
|
107
|
+
* @param burningRate - The burning rate per second for the environment
|
|
108
|
+
* @returns Maximum runtime duration in minutes
|
|
109
|
+
*/
|
|
110
|
+
calculateMaxRuntimeMinutes(availableCredits, burningRate) {
|
|
111
|
+
if (!burningRate || burningRate <= 0)
|
|
112
|
+
return 0;
|
|
113
|
+
const burningRatePerMinute = burningRate * 60;
|
|
114
|
+
return Math.floor(availableCredits / burningRatePerMinute);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Calculate the credits required for a given runtime duration.
|
|
118
|
+
* @param minutes - Runtime duration in minutes
|
|
119
|
+
* @param burningRate - The burning rate per second for the environment
|
|
120
|
+
* @returns Credits required (rounded up to nearest integer)
|
|
121
|
+
*/
|
|
122
|
+
calculateCreditsRequired(minutes, burningRate) {
|
|
123
|
+
if (!burningRate || burningRate <= 0 || !minutes || minutes <= 0)
|
|
124
|
+
return 0;
|
|
125
|
+
return Math.ceil(minutes * this.calculateBurningRatePerMinute(burningRate));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Calculate the burning rate per minute from the per-second rate.
|
|
129
|
+
* @param burningRatePerSecond - The burning rate per second
|
|
130
|
+
* @returns Burning rate per minute
|
|
131
|
+
*/
|
|
132
|
+
calculateBurningRatePerMinute(burningRatePerSecond) {
|
|
133
|
+
return burningRatePerSecond * 60;
|
|
134
|
+
}
|
|
135
|
+
// ========================================================================
|
|
136
|
+
// Service Health Checks
|
|
137
|
+
// ========================================================================
|
|
138
|
+
/**
|
|
139
|
+
* Check the health status of the IAM service.
|
|
140
|
+
* @returns Health check model instance
|
|
141
|
+
*/
|
|
142
|
+
async checkIAMHealth() {
|
|
143
|
+
const startTime = Date.now();
|
|
144
|
+
const errors = [];
|
|
145
|
+
let status = 'unknown';
|
|
146
|
+
let healthy = false;
|
|
147
|
+
try {
|
|
148
|
+
// Test basic connectivity and authentication by getting user profile
|
|
149
|
+
const user = await this.whoami();
|
|
150
|
+
const responseTime = Date.now() - startTime;
|
|
151
|
+
if (user && user.uid) {
|
|
152
|
+
healthy = true;
|
|
153
|
+
status = 'operational';
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
status = 'degraded';
|
|
157
|
+
errors.push('Unexpected response format from profile endpoint');
|
|
158
|
+
}
|
|
159
|
+
return new HealthCheck({
|
|
160
|
+
healthy,
|
|
161
|
+
status,
|
|
162
|
+
responseTime,
|
|
163
|
+
errors,
|
|
164
|
+
timestamp: new Date(),
|
|
165
|
+
}, this);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
const responseTime = Date.now() - startTime;
|
|
169
|
+
status = 'down';
|
|
170
|
+
errors.push(`Service unreachable: ${error}`);
|
|
171
|
+
return new HealthCheck({
|
|
172
|
+
healthy: false,
|
|
173
|
+
status,
|
|
174
|
+
responseTime,
|
|
175
|
+
errors,
|
|
176
|
+
timestamp: new Date(),
|
|
177
|
+
}, this);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|