@datalayer/core 0.0.12 → 0.0.13

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 (237) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +38 -26
  3. package/lib/api/DatalayerApi.js +35 -8
  4. package/lib/api/iam/authentication.d.ts +8 -7
  5. package/lib/api/iam/authentication.js +14 -15
  6. package/lib/api/iam/healthz.d.ts +3 -2
  7. package/lib/api/iam/healthz.js +5 -3
  8. package/lib/api/iam/index.d.ts +9 -4
  9. package/lib/api/iam/index.js +9 -4
  10. package/lib/api/iam/oauth2.d.ts +115 -0
  11. package/lib/api/iam/oauth2.js +309 -0
  12. package/lib/api/iam/profile.d.ts +8 -1
  13. package/lib/api/iam/profile.js +17 -2
  14. package/lib/api/iam/usage.d.ts +56 -0
  15. package/lib/api/iam/usage.js +39 -0
  16. package/lib/api/index.d.ts +6 -5
  17. package/lib/api/index.js +6 -5
  18. package/lib/api/runtimes/environments.js +3 -2
  19. package/lib/api/runtimes/healthz.d.ts +3 -13
  20. package/lib/api/runtimes/healthz.js +4 -3
  21. package/lib/api/runtimes/index.d.ts +3 -2
  22. package/lib/api/runtimes/index.js +3 -2
  23. package/lib/api/runtimes/runtimes.js +17 -6
  24. package/lib/api/runtimes/snapshots.js +3 -2
  25. package/lib/api/spacer/documents.d.ts +12 -0
  26. package/lib/api/spacer/documents.js +43 -0
  27. package/lib/api/spacer/healthz.d.ts +3 -13
  28. package/lib/api/spacer/healthz.js +4 -3
  29. package/lib/api/spacer/index.d.ts +4 -2
  30. package/lib/api/spacer/index.js +4 -2
  31. package/lib/api/spacer/items.d.ts +9 -1
  32. package/lib/api/spacer/items.js +17 -2
  33. package/lib/api/spacer/lexicals.js +3 -2
  34. package/lib/api/spacer/notebooks.js +3 -2
  35. package/lib/api/spacer/spaces.js +3 -2
  36. package/lib/api/spacer/users.js +3 -2
  37. package/lib/api/types/common.d.ts +64 -0
  38. package/lib/api/types/iam.d.ts +88 -65
  39. package/lib/api/types/index.d.ts +4 -2
  40. package/lib/api/types/index.js +4 -2
  41. package/lib/api/types/runtimes.d.ts +9 -39
  42. package/lib/api/types/spacer.d.ts +37 -65
  43. package/lib/api/utils/validation.d.ts +24 -1
  44. package/lib/api/utils/validation.js +62 -1
  45. package/lib/client/base.d.ts +75 -0
  46. package/lib/client/base.js +199 -0
  47. package/lib/client/constants.d.ts +22 -0
  48. package/lib/client/constants.js +22 -0
  49. package/lib/client/index.d.ts +108 -0
  50. package/lib/client/index.js +79 -0
  51. package/lib/client/mixins/IAMMixin.d.ts +54 -0
  52. package/lib/client/mixins/IAMMixin.js +181 -0
  53. package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
  54. package/lib/client/mixins/RuntimesMixin.js +229 -0
  55. package/lib/client/mixins/SpacerMixin.d.ts +111 -0
  56. package/lib/client/mixins/SpacerMixin.js +340 -0
  57. package/lib/client/models/Credits.d.ts +91 -0
  58. package/lib/client/models/Credits.js +130 -0
  59. package/lib/client/models/Environment.d.ts +73 -0
  60. package/lib/client/models/Environment.js +88 -0
  61. package/lib/client/models/HealthCheck.d.ts +72 -0
  62. package/lib/client/models/HealthCheck.js +107 -0
  63. package/lib/client/models/Item.d.ts +69 -0
  64. package/lib/client/models/Item.js +191 -0
  65. package/lib/client/models/Lexical.d.ts +83 -0
  66. package/lib/client/models/Lexical.js +152 -0
  67. package/lib/client/models/Notebook.d.ts +87 -0
  68. package/lib/client/models/Notebook.js +153 -0
  69. package/lib/client/models/Runtime.d.ts +122 -0
  70. package/lib/client/models/Runtime.js +204 -0
  71. package/lib/client/models/Snapshot.d.ts +92 -0
  72. package/lib/client/models/Snapshot.js +139 -0
  73. package/lib/client/models/Space.d.ts +135 -0
  74. package/lib/client/models/Space.js +234 -0
  75. package/lib/client/models/User.d.ts +64 -0
  76. package/lib/client/models/User.js +83 -0
  77. package/lib/client/models/index.d.ts +26 -0
  78. package/lib/client/models/index.js +25 -0
  79. package/lib/client/utils/mixins.d.ts +12 -0
  80. package/lib/{sdk/client → client}/utils/mixins.js +0 -28
  81. package/lib/client/utils/spacerUtils.d.ts +18 -0
  82. package/lib/client/utils/spacerUtils.js +32 -0
  83. package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
  84. package/lib/collaboration/DatalayerCollaboration.js +2 -2
  85. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
  86. package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
  87. package/lib/components/progress/CreditsIndicator.d.ts +1 -1
  88. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
  89. package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
  90. package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
  91. package/lib/components/runtimes/RuntimePickerBase.js +1 -1
  92. package/lib/components/runtimes/RuntimePickerCell.js +2 -2
  93. package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
  94. package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
  95. package/lib/components/runtimes/RuntimeTransfer.d.ts +1 -1
  96. package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
  97. package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
  98. package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
  99. package/lib/config/Configuration.d.ts +8 -0
  100. package/lib/hooks/useDatalayer.js +1 -1
  101. package/lib/hooks/useRuntimes.js +1 -1
  102. package/lib/hooks/useToast.js +1 -1
  103. package/lib/index.d.ts +2 -2
  104. package/lib/index.js +4 -2
  105. package/lib/sdk/index.d.ts +5 -4
  106. package/lib/sdk/index.js +6 -5
  107. package/lib/services/DatalayerServiceManager.js +1 -1
  108. package/lib/state/substates/CoreState.js +2 -0
  109. package/lib/state/substates/RuntimesState.d.ts +1 -1
  110. package/lib/state/substates/RuntimesState.js +1 -1
  111. package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
  112. package/lib/{sdk/stateful → stateful}/index.js +1 -1
  113. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
  114. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
  115. package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
  116. package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
  117. package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
  118. package/lib/stateful/runtimes/apis.js +5 -0
  119. package/package.json +12 -10
  120. package/lib/__tests__/hooks.test.d.ts +0 -1
  121. package/lib/__tests__/hooks.test.js +0 -19
  122. package/lib/__tests__/index.test.d.ts +0 -1
  123. package/lib/__tests__/index.test.js +0 -27
  124. package/lib/__tests__/integration.test.d.ts +0 -1
  125. package/lib/__tests__/integration.test.js +0 -57
  126. package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
  127. package/lib/__tests__/shared/cleanup-shared.js +0 -228
  128. package/lib/__tests__/shared/test-config.d.ts +0 -51
  129. package/lib/__tests__/shared/test-config.js +0 -110
  130. package/lib/__tests__/shared/test-constants.d.ts +0 -66
  131. package/lib/__tests__/shared/test-constants.js +0 -79
  132. package/lib/__tests__/utils.test.d.ts +0 -1
  133. package/lib/__tests__/utils.test.js +0 -59
  134. package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
  135. package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
  136. package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
  137. package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
  138. package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
  139. package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
  140. package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
  141. package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
  142. package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
  143. package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
  144. package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
  145. package/lib/api/__tests__/runtimes.integration.test.js +0 -369
  146. package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
  147. package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
  148. package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
  149. package/lib/api/__tests__/spacer.integration.test.js +0 -519
  150. package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
  151. package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
  152. package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
  153. package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
  154. package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
  155. package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
  156. package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
  157. package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
  158. package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
  159. package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
  160. package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
  161. package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
  162. package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
  163. package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
  164. package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
  165. package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
  166. package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
  167. package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
  168. package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
  169. package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
  170. package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
  171. package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
  172. package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
  173. package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
  174. package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
  175. package/lib/api/utils/__tests__/validation.test.js +0 -109
  176. package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
  177. package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
  178. package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
  179. package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
  180. package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
  181. package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
  182. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
  183. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
  184. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
  185. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
  186. package/lib/sdk/client/base.d.ts +0 -88
  187. package/lib/sdk/client/base.js +0 -112
  188. package/lib/sdk/client/index.d.ts +0 -192
  189. package/lib/sdk/client/index.js +0 -128
  190. package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
  191. package/lib/sdk/client/mixins/HealthMixin.js +0 -133
  192. package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
  193. package/lib/sdk/client/mixins/IAMMixin.js +0 -83
  194. package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
  195. package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
  196. package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
  197. package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
  198. package/lib/sdk/client/models/Lexical.d.ts +0 -156
  199. package/lib/sdk/client/models/Lexical.js +0 -275
  200. package/lib/sdk/client/models/Notebook.d.ts +0 -174
  201. package/lib/sdk/client/models/Notebook.js +0 -311
  202. package/lib/sdk/client/models/Runtime.d.ts +0 -221
  203. package/lib/sdk/client/models/Runtime.js +0 -341
  204. package/lib/sdk/client/models/Snapshot.d.ts +0 -156
  205. package/lib/sdk/client/models/Snapshot.js +0 -244
  206. package/lib/sdk/client/models/Space.d.ts +0 -182
  207. package/lib/sdk/client/models/Space.js +0 -276
  208. package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
  209. package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
  210. package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
  211. package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
  212. package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
  213. package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
  214. package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
  215. package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
  216. package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
  217. package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
  218. package/lib/sdk/client/models/index.d.ts +0 -30
  219. package/lib/sdk/client/models/index.js +0 -30
  220. package/lib/sdk/client/utils/mixins.d.ts +0 -42
  221. /package/lib/{sdk/stateful/runtimes/apis.js → api/types/common.js} +0 -0
  222. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
  223. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
  224. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
  225. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
  226. /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
  227. /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
  228. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
  229. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
  230. /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
  231. /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
  232. /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
  233. /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
  234. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
  235. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
  236. /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
  237. /package/lib/{sdk/stateful → stateful}/runtimes/utils.js +0 -0
@@ -1,179 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2025 Datalayer, Inc.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- import { describe, it, expect, beforeAll } from 'vitest';
6
- import { DatalayerSDK } from '..';
7
- import { testConfig } from '../../../__tests__/shared/test-config';
8
- import { DEFAULT_SERVICE_URLS } from '../../../api/constants';
9
- /**
10
- * SDK IAM Integration Tests
11
- *
12
- * Tests authentication and identity management functionality
13
- * using the SDK client.
14
- */
15
- describe('SDK IAM Integration Tests', () => {
16
- let sdk;
17
- beforeAll(() => {
18
- if (!testConfig.hasToken()) {
19
- return;
20
- }
21
- sdk = new DatalayerSDK({
22
- token: testConfig.getToken(),
23
- iamRunUrl: DEFAULT_SERVICE_URLS.IAM,
24
- runtimesRunUrl: DEFAULT_SERVICE_URLS.RUNTIMES,
25
- spacerRunUrl: DEFAULT_SERVICE_URLS.SPACER,
26
- });
27
- });
28
- describe.skipIf(!testConfig.hasToken())('IAM authentication methods', () => {
29
- describe('whoami', () => {
30
- it('should get current user profile', async () => {
31
- console.log('Testing whoami...');
32
- const user = await sdk.whoami();
33
- expect(user).toBeDefined();
34
- expect(user.id).toBeDefined();
35
- expect(user.uid).toBeDefined();
36
- expect(user.handle).toBeDefined();
37
- expect(user.roles).toBeDefined();
38
- expect(Array.isArray(user.roles)).toBe(true);
39
- console.log('Current user:');
40
- console.log(` ID: ${user.id}`);
41
- console.log(` UID: ${user.uid}`);
42
- console.log(` Handle: ${user.handle}`);
43
- console.log(` Email: ${user.email || 'Not provided'}`);
44
- console.log(` Name: ${user.first_name} ${user.last_name}`);
45
- console.log(` Roles: ${user.roles.join(', ')}`);
46
- });
47
- it('should include organization info if available', async () => {
48
- console.log('Checking organization info...');
49
- const user = await sdk.whoami();
50
- if (user.organizationIds &&
51
- user.organizationIds.length > 0) {
52
- console.log(`User belongs to ${user.organizationIds.length} organization(s)`);
53
- expect(Array.isArray(user.organizationIds)).toBe(true);
54
- }
55
- else {
56
- console.log('User does not belong to any organizations');
57
- }
58
- });
59
- it('should cache user profile for performance', async () => {
60
- console.log('Testing user profile caching...');
61
- const start1 = Date.now();
62
- const user1 = await sdk.whoami();
63
- const time1 = Date.now() - start1;
64
- const start2 = Date.now();
65
- const user2 = await sdk.whoami();
66
- const time2 = Date.now() - start2;
67
- // Second call should be same or faster (cached)
68
- expect(user2.id).toBe(user1.id);
69
- console.log(`First call: ${time1}ms, Second call: ${time2}ms`);
70
- });
71
- });
72
- describe('login', () => {
73
- it('should handle invalid credentials properly', async () => {
74
- console.log('Testing login with invalid credentials...');
75
- try {
76
- await sdk.login({
77
- handle: 'invalid@example.com',
78
- password: 'wrong-password',
79
- });
80
- // Should not reach here
81
- expect(true).toBe(false);
82
- }
83
- catch (error) {
84
- expect(error).toBeDefined();
85
- console.log('Invalid login rejected correctly');
86
- }
87
- });
88
- it('should validate login request structure', async () => {
89
- console.log('Testing login validation...');
90
- try {
91
- // Missing required fields
92
- await sdk.login({});
93
- expect(true).toBe(false);
94
- }
95
- catch (error) {
96
- expect(error).toBeDefined();
97
- console.log('Invalid login request rejected');
98
- }
99
- });
100
- });
101
- describe('token management', () => {
102
- it('should include token in all API requests', async () => {
103
- console.log('Verifying token is included in requests...');
104
- // Make a request and verify it succeeds (which means token was included)
105
- const user = await sdk.whoami();
106
- expect(user).toBeDefined();
107
- // Verify token is stored in SDK
108
- const token = sdk.getToken();
109
- expect(token).toBe(testConfig.getToken());
110
- console.log('Token management verified');
111
- });
112
- it('should handle expired tokens gracefully', async () => {
113
- console.log('Testing expired token handling...');
114
- const expiredSdk = new DatalayerSDK({
115
- token: 'expired.invalid.token',
116
- iamRunUrl: DEFAULT_SERVICE_URLS.IAM,
117
- runtimesRunUrl: DEFAULT_SERVICE_URLS.RUNTIMES,
118
- spacerRunUrl: DEFAULT_SERVICE_URLS.SPACER,
119
- });
120
- try {
121
- await expiredSdk.whoami();
122
- expect(true).toBe(false);
123
- }
124
- catch (error) {
125
- expect(error).toBeDefined();
126
- console.log('Expired token rejected correctly');
127
- }
128
- });
129
- });
130
- describe('logout', () => {
131
- it('should handle logout operation', async () => {
132
- console.log('Testing logout...');
133
- // Create a separate SDK instance for logout test
134
- const logoutSdk = new DatalayerSDK({
135
- token: testConfig.getToken(),
136
- iamRunUrl: DEFAULT_SERVICE_URLS.IAM,
137
- runtimesRunUrl: DEFAULT_SERVICE_URLS.RUNTIMES,
138
- spacerRunUrl: DEFAULT_SERVICE_URLS.SPACER,
139
- });
140
- // Verify we can make authenticated requests
141
- const userBefore = await logoutSdk.whoami();
142
- expect(userBefore).toBeDefined();
143
- // Note: Actual logout may not invalidate the token server-side
144
- // This tests the logout method exists and can be called
145
- await logoutSdk.logout();
146
- console.log('Logout completed');
147
- // In a real scenario, subsequent requests might fail
148
- // But with API tokens, they typically remain valid until expiry
149
- });
150
- });
151
- describe('error handling', () => {
152
- it('should provide clear error messages for auth failures', async () => {
153
- console.log('Testing auth error messages...');
154
- const invalidSdk = new DatalayerSDK({
155
- token: 'invalid-token',
156
- iamRunUrl: DEFAULT_SERVICE_URLS.IAM,
157
- runtimesRunUrl: DEFAULT_SERVICE_URLS.RUNTIMES,
158
- spacerRunUrl: DEFAULT_SERVICE_URLS.SPACER,
159
- });
160
- try {
161
- await invalidSdk.whoami();
162
- expect(true).toBe(false);
163
- }
164
- catch (error) {
165
- expect(error.message).toBeDefined();
166
- // Error should mention authentication, token, or invalid
167
- const errorLower = error.message.toLowerCase();
168
- expect(errorLower.includes('auth') ||
169
- errorLower.includes('unauth') ||
170
- errorLower.includes('401') ||
171
- errorLower.includes('403') ||
172
- errorLower.includes('invalid') ||
173
- errorLower.includes('token')).toBe(true);
174
- console.log('Auth error message is clear and helpful');
175
- }
176
- });
177
- });
178
- });
179
- });
@@ -1,376 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2025 Datalayer, Inc.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
6
- import { DatalayerSDK } from '..';
7
- import { Runtime } from '../models/Runtime';
8
- import { Snapshot } from '../models/Snapshot';
9
- import { Notebook } from '../models/Notebook';
10
- import { Lexical } from '../models/Lexical';
11
- import { testConfig } from '../../../__tests__/shared/test-config';
12
- import { DEFAULT_SERVICE_URLS } from '../../../api/constants';
13
- import { performCleanup } from '../../../__tests__/shared/cleanup-shared';
14
- /**
15
- * SDK Models Integration Tests
16
- *
17
- * Tests model state management, lazy loading, and relationships
18
- * using the SDK client and model classes.
19
- */
20
- describe('SDK Models Integration Tests', () => {
21
- let sdk;
22
- let testSpace = null;
23
- let testNotebook = null;
24
- let testLexical = null;
25
- let testRuntime = null;
26
- let testSnapshot = null;
27
- beforeAll(async () => {
28
- if (!testConfig.hasToken()) {
29
- return;
30
- }
31
- await performCleanup('setup');
32
- sdk = new DatalayerSDK({
33
- token: testConfig.getToken(),
34
- iamRunUrl: DEFAULT_SERVICE_URLS.IAM,
35
- runtimesRunUrl: DEFAULT_SERVICE_URLS.RUNTIMES,
36
- spacerRunUrl: DEFAULT_SERVICE_URLS.SPACER,
37
- });
38
- });
39
- afterAll(async () => {
40
- if (!testConfig.hasToken()) {
41
- return;
42
- }
43
- await performCleanup('teardown');
44
- }, 30000);
45
- describe.skipIf(!testConfig.hasToken())('Model state management', () => {
46
- it('should mark models as deleted after deletion', async () => {
47
- console.log('Testing model deletion state...');
48
- // Get a space to work with
49
- const spaces = await sdk.getMySpaces();
50
- expect(spaces.length).toBeGreaterThan(0);
51
- testSpace = spaces[0];
52
- // Create a notebook
53
- const notebook = await sdk.createNotebook({
54
- spaceId: testSpace.uid,
55
- notebookType: 'jupyter',
56
- name: 'model-test-notebook-' + Date.now(),
57
- description: 'Test notebook for model tests',
58
- });
59
- expect(notebook).toBeInstanceOf(Notebook);
60
- // Delete it
61
- await notebook.delete();
62
- // Verify it's marked as deleted
63
- expect(notebook.isDeleted).toBe(true);
64
- // Verify methods throw errors
65
- try {
66
- await notebook.getName();
67
- expect(true).toBe(false); // Should not reach here
68
- }
69
- catch (error) {
70
- expect(error.message).toContain('deleted');
71
- console.log('Deleted model correctly throws error');
72
- }
73
- });
74
- it('should handle lazy loading of model properties', async () => {
75
- if (!testSpace) {
76
- throw new Error('Test dependency failed: testSpace should be available from previous test');
77
- }
78
- console.log('Testing lazy loading...');
79
- // Create a notebook with minimal data
80
- testNotebook = await sdk.createNotebook({
81
- spaceId: testSpace.uid,
82
- notebookType: 'jupyter',
83
- name: 'lazy-load-test-' + Date.now(),
84
- description: 'Test description',
85
- });
86
- // First call should fetch from API
87
- const name1 = await testNotebook.getName();
88
- expect(name1).toBeDefined();
89
- // Second call should use cached value (faster)
90
- const start = Date.now();
91
- const name2 = await testNotebook.getName();
92
- const elapsed = Date.now() - start;
93
- expect(name2).toBe(name1);
94
- expect(elapsed).toBeLessThan(10); // Should be instant
95
- console.log(`Lazy loading working - cached access in ${elapsed}ms`);
96
- });
97
- it('should refresh data when explicitly requested', async () => {
98
- // Ensure we have a space to work with
99
- if (!testSpace) {
100
- const spaces = await sdk.getMySpaces();
101
- expect(spaces.length).toBeGreaterThan(0);
102
- testSpace = spaces[0];
103
- }
104
- // Create a notebook if we don't have one
105
- if (!testNotebook) {
106
- testNotebook = await sdk.createNotebook({
107
- spaceId: testSpace.uid,
108
- notebookType: 'jupyter',
109
- name: 'refresh-test-' + Date.now(),
110
- description: 'Test description',
111
- });
112
- }
113
- console.log('Testing data refresh...');
114
- // Get initial name
115
- const originalName = await testNotebook.getName();
116
- expect(originalName).toBeDefined();
117
- // Test that we can fetch fresh data
118
- const content = await testNotebook.getContent();
119
- expect(content).toBeDefined();
120
- // Verify the model is working properly
121
- const uid = testNotebook.uid;
122
- expect(uid).toBeDefined();
123
- console.log(`Model data access verified - name: ${originalName}, uid: ${uid}`);
124
- });
125
- });
126
- describe.skipIf(!testConfig.hasToken())('Model relationships', () => {
127
- it('should handle Space → Notebook relationship', async () => {
128
- // Ensure we have a space
129
- if (!testSpace) {
130
- const spaces = await sdk.getMySpaces();
131
- expect(spaces.length).toBeGreaterThan(0);
132
- testSpace = spaces[0];
133
- }
134
- // Ensure we have a notebook
135
- if (!testNotebook) {
136
- testNotebook = await sdk.createNotebook({
137
- spaceId: testSpace.uid,
138
- notebookType: 'jupyter',
139
- name: 'relationship-test-' + Date.now(),
140
- description: 'Test notebook for relationships',
141
- });
142
- }
143
- console.log('Testing Space → Notebook relationship...');
144
- // Get items from space
145
- const items = await testSpace.getItems();
146
- expect(Array.isArray(items)).toBe(true);
147
- console.log(`Space has ${items.length} items`);
148
- console.log('Looking for notebook with id:', testNotebook.id);
149
- console.log('Items in space:', items.map(item => ({
150
- id: item.id,
151
- uid: item.uid,
152
- type: item.type || item.type,
153
- name: item.name,
154
- })));
155
- // Our test notebook should be in the items
156
- // Note: Space items may not have a 'type' property
157
- const foundNotebook = items.find(item => item.id === testNotebook.id ||
158
- item.uid === testNotebook.uid);
159
- expect(foundNotebook).toBeDefined();
160
- console.log(`Found notebook ${testNotebook.id} in space items`);
161
- console.log(`Space contains ${items.length} items`);
162
- });
163
- it('should handle Space → Lexical relationship', async () => {
164
- // Ensure we have a space
165
- if (!testSpace) {
166
- const spaces = await sdk.getMySpaces();
167
- expect(spaces.length).toBeGreaterThan(0);
168
- testSpace = spaces[0];
169
- }
170
- console.log('Testing Space → Lexical relationship...');
171
- // Create a lexical document
172
- testLexical = await sdk.createLexical({
173
- spaceId: testSpace.uid,
174
- name: 'relationship-test-lexical-' + Date.now(),
175
- documentType: 'document',
176
- description: 'Test lexical document for relationships',
177
- });
178
- expect(testLexical).toBeInstanceOf(Lexical);
179
- // Verify it appears in space items
180
- const items = await testSpace.getItems();
181
- const foundLexical = items.find(item => item.id === testLexical.id || item.uid === testLexical.uid);
182
- expect(foundLexical).toBeDefined();
183
- console.log(`Created lexical ${testLexical.id} in space`);
184
- });
185
- });
186
- describe.skipIf(!testConfig.hasToken() || testConfig.shouldSkipExpensive())('Runtime → Snapshot relationship', () => {
187
- it('should handle Runtime → Snapshot creation', async () => {
188
- console.log('Testing Runtime → Snapshot relationship...');
189
- // Create a runtime
190
- testRuntime = await sdk.createRuntime({
191
- environment_name: 'python-cpu-env',
192
- type: 'notebook',
193
- given_name: 'model-test-runtime',
194
- credits_limit: 10,
195
- });
196
- expect(testRuntime).toBeInstanceOf(Runtime);
197
- console.log(`Created runtime: ${testRuntime.podName}`);
198
- // Create a snapshot from the runtime
199
- testSnapshot = await testRuntime.createSnapshot('model-test-snapshot', 'Test snapshot from model test');
200
- expect(testSnapshot).toBeInstanceOf(Snapshot);
201
- // Snapshots don't have a podName property
202
- // Instead, check that the snapshot was created successfully
203
- expect(testSnapshot.uid).toBeDefined();
204
- expect(testSnapshot.name).toBe('model-test-snapshot');
205
- console.log(`Created snapshot ${testSnapshot.uid} from runtime`);
206
- });
207
- it('should list runtime snapshots', async () => {
208
- if (!testRuntime || !testSnapshot) {
209
- throw new Error('Test dependency failed: testRuntime and testSnapshot should be available from previous test');
210
- }
211
- console.log('Testing runtime snapshot listing...');
212
- // List all snapshots
213
- const snapshots = await sdk.listSnapshots();
214
- // Find our test snapshot
215
- const found = snapshots.find(s => s.uid === testSnapshot.uid);
216
- expect(found).toBeDefined();
217
- console.log(`Found ${snapshots.length} snapshots total`);
218
- });
219
- });
220
- describe.skipIf(!testConfig.hasToken())('Model serialization', () => {
221
- it('should serialize Space model to JSON', async () => {
222
- if (!testSpace) {
223
- throw new Error('Test dependency failed: testSpace should be available from previous test');
224
- }
225
- console.log('Testing Space serialization...');
226
- const json = await testSpace.toJSON();
227
- expect(json).toBeDefined();
228
- expect(json.id || json.uid).toBeDefined();
229
- // JSON should include fetched properties
230
- if (testSpace.name) {
231
- expect(json.name).toBe(testSpace.name);
232
- }
233
- console.log('Space serialized successfully');
234
- });
235
- it('should serialize Notebook model to JSON', async () => {
236
- // Always create a fresh notebook for this test to avoid state issues
237
- // Ensure we have a space first
238
- if (!testSpace) {
239
- const spaces = await sdk.getMySpaces();
240
- expect(spaces.length).toBeGreaterThan(0);
241
- testSpace = spaces[0];
242
- }
243
- const freshNotebook = await sdk.createNotebook({
244
- spaceId: testSpace.uid,
245
- notebookType: 'jupyter',
246
- name: 'serialization-test-' + Date.now(),
247
- description: 'Test notebook for serialization',
248
- });
249
- console.log('Testing Notebook serialization...');
250
- console.log('Notebook created with id:', freshNotebook.id);
251
- const json = await freshNotebook.toJSON();
252
- expect(json).toBeDefined();
253
- expect(json.id).toBe(freshNotebook.id);
254
- // Log the JSON to see what fields are present
255
- console.log('Notebook JSON:', JSON.stringify(json, null, 2));
256
- // The notebook should have its basic properties
257
- // The name might be in name, name_t, or notebook_name_s
258
- const name = json.name || json.name_t || json.notebook_name_s;
259
- expect(name).toBeDefined();
260
- expect(json.id).toBeDefined();
261
- expect(json.uid).toBeDefined();
262
- console.log('Notebook serialized successfully');
263
- });
264
- it.skipIf(testConfig.shouldSkipExpensive())('should serialize Runtime model to JSON', async () => {
265
- if (!testRuntime) {
266
- throw new Error('Test dependency failed: testRuntime should be available from previous test');
267
- }
268
- console.log('Testing Runtime serialization...');
269
- const json = await testRuntime.toJSON();
270
- expect(json).toBeDefined();
271
- expect(json.pod_name).toBe(testRuntime.podName);
272
- expect(json.environment_name).toBe(testRuntime.environmentName);
273
- console.log('Runtime serialized successfully');
274
- });
275
- it.skipIf(testConfig.shouldSkipExpensive())('should serialize Snapshot model to JSON', async () => {
276
- if (!testSnapshot) {
277
- throw new Error('Test dependency failed: testSnapshot should be available from previous test');
278
- }
279
- console.log('Testing Snapshot serialization...');
280
- const json = await testSnapshot.toJSON();
281
- expect(json).toBeDefined();
282
- expect(json.uid).toBe(testSnapshot.uid);
283
- console.log('Snapshot serialized successfully');
284
- });
285
- });
286
- describe.skipIf(!testConfig.hasToken())('Model error handling', () => {
287
- it('should handle API errors gracefully in models', async () => {
288
- console.log('Testing model error handling...');
289
- // Create a fake notebook with invalid ID
290
- const fakeNotebook = new Notebook({ id: 'invalid-id', space_id: 'invalid-space' }, sdk);
291
- try {
292
- await fakeNotebook.getName();
293
- expect(true).toBe(false); // Should not reach here
294
- }
295
- catch (error) {
296
- expect(error).toBeDefined();
297
- console.log('Model correctly propagates API errors');
298
- }
299
- });
300
- it('should validate model operations', async () => {
301
- if (!testNotebook) {
302
- throw new Error('Test dependency failed: testNotebook should be available from previous test');
303
- }
304
- console.log('Testing model validation...');
305
- try {
306
- // Try to update with invalid data
307
- await testNotebook.update({});
308
- // This might succeed with empty update, which is okay
309
- console.log('Empty update handled');
310
- }
311
- catch (error) {
312
- console.log('Invalid update rejected');
313
- }
314
- });
315
- it('should handle concurrent model operations', async () => {
316
- if (!testNotebook) {
317
- throw new Error('Test dependency failed: testNotebook should be available from previous test');
318
- }
319
- console.log('Testing concurrent model operations...');
320
- // Make multiple concurrent requests
321
- const promises = [
322
- testNotebook.getName(),
323
- testNotebook.getContent(),
324
- testNotebook.getUpdatedAt(),
325
- ];
326
- const results = await Promise.all(promises);
327
- expect(results[0]).toBeDefined(); // name
328
- expect(results[1]).toBeDefined(); // content
329
- expect(results[2]).toBeInstanceOf(Date); // updatedAt
330
- console.log('Concurrent operations completed successfully');
331
- });
332
- });
333
- describe.skipIf(!testConfig.hasToken())('Model lifecycle', () => {
334
- it('should support full model lifecycle', async () => {
335
- // Ensure we have a space
336
- if (!testSpace) {
337
- const spaces = await sdk.getMySpaces();
338
- expect(spaces.length).toBeGreaterThan(0);
339
- testSpace = spaces[0];
340
- }
341
- console.log('Testing full model lifecycle...');
342
- // 1. Create
343
- const notebook = await sdk.createNotebook({
344
- spaceId: testSpace.uid,
345
- notebookType: 'jupyter',
346
- name: 'lifecycle-test-' + Date.now(),
347
- description: 'Lifecycle test notebook',
348
- });
349
- expect(notebook).toBeInstanceOf(Notebook);
350
- console.log('1. Created notebook');
351
- // 2. Read
352
- const retrieved = await sdk.getNotebook(notebook.uid);
353
- expect(retrieved.id).toBe(notebook.id);
354
- console.log('2. Retrieved notebook');
355
- // 3. Use methods to access properties
356
- const name = await notebook.getName();
357
- expect(name).toBeDefined();
358
- const content = await notebook.getContent();
359
- expect(content).toBeDefined();
360
- console.log('3. Used notebook methods');
361
- // 4. Delete
362
- await notebook.delete();
363
- expect(notebook.isDeleted).toBe(true);
364
- console.log('4. Deleted notebook');
365
- // 5. Verify deletion
366
- try {
367
- await notebook.getName();
368
- expect(true).toBe(false);
369
- }
370
- catch (error) {
371
- expect(error.message).toContain('deleted');
372
- console.log('5. Verified deletion state');
373
- }
374
- });
375
- });
376
- });