@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.
Files changed (249) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +38 -26
  3. package/lib/api/DatalayerApi.js +52 -13
  4. package/lib/api/iam/authentication.d.ts +9 -8
  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 +18 -0
  15. package/lib/api/iam/usage.js +39 -0
  16. package/lib/api/index.d.ts +6 -6
  17. package/lib/api/index.js +6 -7
  18. package/lib/api/runtimes/environments.d.ts +2 -2
  19. package/lib/api/runtimes/environments.js +3 -2
  20. package/lib/api/runtimes/healthz.d.ts +3 -13
  21. package/lib/api/runtimes/healthz.js +4 -3
  22. package/lib/api/runtimes/index.d.ts +3 -2
  23. package/lib/api/runtimes/index.js +3 -2
  24. package/lib/api/runtimes/runtimes.d.ts +4 -4
  25. package/lib/api/runtimes/runtimes.js +17 -6
  26. package/lib/api/runtimes/snapshots.d.ts +4 -4
  27. package/lib/api/runtimes/snapshots.js +3 -2
  28. package/lib/api/spacer/documents.d.ts +12 -0
  29. package/lib/api/spacer/documents.js +43 -0
  30. package/lib/api/spacer/healthz.d.ts +3 -13
  31. package/lib/api/spacer/healthz.js +4 -3
  32. package/lib/api/spacer/index.d.ts +4 -2
  33. package/lib/api/spacer/index.js +4 -2
  34. package/lib/api/spacer/items.d.ts +9 -1
  35. package/lib/api/spacer/items.js +17 -2
  36. package/lib/api/spacer/lexicals.d.ts +1 -1
  37. package/lib/api/spacer/lexicals.js +3 -2
  38. package/lib/api/spacer/notebooks.d.ts +1 -1
  39. package/lib/api/spacer/notebooks.js +3 -2
  40. package/lib/api/spacer/spaces.d.ts +1 -1
  41. package/lib/api/spacer/spaces.js +3 -2
  42. package/lib/api/spacer/users.d.ts +1 -1
  43. package/lib/api/spacer/users.js +3 -2
  44. package/lib/api/utils/validation.d.ts +24 -1
  45. package/lib/api/utils/validation.js +62 -1
  46. package/lib/client/base.d.ts +75 -0
  47. package/lib/client/base.js +199 -0
  48. package/lib/client/constants.d.ts +22 -0
  49. package/lib/client/constants.js +22 -0
  50. package/lib/client/index.d.ts +108 -0
  51. package/lib/client/index.js +79 -0
  52. package/lib/client/mixins/IAMMixin.d.ts +54 -0
  53. package/lib/client/mixins/IAMMixin.js +181 -0
  54. package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
  55. package/lib/client/mixins/RuntimesMixin.js +229 -0
  56. package/lib/client/mixins/SpacerMixin.d.ts +111 -0
  57. package/lib/client/mixins/SpacerMixin.js +340 -0
  58. package/lib/client/utils/mixins.d.ts +12 -0
  59. package/lib/{sdk/client → client}/utils/mixins.js +0 -28
  60. package/lib/client/utils/spacerUtils.d.ts +18 -0
  61. package/lib/client/utils/spacerUtils.js +32 -0
  62. package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
  63. package/lib/collaboration/DatalayerCollaboration.js +2 -2
  64. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
  65. package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
  66. package/lib/components/progress/CreditsIndicator.d.ts +1 -1
  67. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
  68. package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
  69. package/lib/components/runtimes/RuntimeLauncherDialog.js +2 -2
  70. package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
  71. package/lib/components/runtimes/RuntimePickerBase.js +1 -1
  72. package/lib/components/runtimes/RuntimePickerCell.js +3 -3
  73. package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
  74. package/lib/components/runtimes/RuntimePickerNotebook.js +2 -2
  75. package/lib/components/runtimes/RuntimeTransfer.d.ts +2 -2
  76. package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
  77. package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
  78. package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
  79. package/lib/config/Configuration.d.ts +8 -0
  80. package/lib/hooks/useDatalayer.js +1 -1
  81. package/lib/hooks/useRuntimes.js +1 -1
  82. package/lib/hooks/useToast.js +1 -1
  83. package/lib/index.d.ts +2 -3
  84. package/lib/index.js +4 -3
  85. package/lib/models/Common.d.ts +64 -0
  86. package/lib/models/CreditsDTO.d.ts +124 -0
  87. package/lib/models/CreditsDTO.js +135 -0
  88. package/lib/models/Environment.d.ts +1 -1
  89. package/lib/models/EnvironmentDTO.d.ts +125 -0
  90. package/lib/models/EnvironmentDTO.js +88 -0
  91. package/lib/models/HealthCheck.d.ts +72 -0
  92. package/lib/models/HealthCheck.js +107 -0
  93. package/lib/{api/types/iam.d.ts → models/IAM.d.ts} +15 -78
  94. package/lib/models/ItemDTO.d.ts +74 -0
  95. package/lib/models/ItemDTO.js +186 -0
  96. package/lib/models/LexicalDTO.d.ts +155 -0
  97. package/lib/models/LexicalDTO.js +157 -0
  98. package/lib/models/NotebookDTO.d.ts +96 -0
  99. package/lib/models/NotebookDTO.js +153 -0
  100. package/lib/models/Profile.d.ts +65 -0
  101. package/lib/models/RuntimeDTO.d.ts +191 -0
  102. package/lib/models/RuntimeDTO.js +204 -0
  103. package/lib/models/RuntimeSnapshotDTO.d.ts +173 -0
  104. package/lib/models/RuntimeSnapshotDTO.js +139 -0
  105. package/lib/models/SpaceDTO.d.ts +280 -0
  106. package/lib/models/SpaceDTO.js +239 -0
  107. package/lib/models/UserDTO.d.ts +86 -0
  108. package/lib/models/UserDTO.js +84 -0
  109. package/lib/models/index.d.ts +45 -4
  110. package/lib/models/index.js +45 -4
  111. package/lib/sdk/index.d.ts +5 -4
  112. package/lib/sdk/index.js +6 -5
  113. package/lib/services/DatalayerServiceManager.js +1 -1
  114. package/lib/state/substates/CoreState.js +2 -0
  115. package/lib/state/substates/RuntimesState.d.ts +1 -1
  116. package/lib/state/substates/RuntimesState.js +1 -1
  117. package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
  118. package/lib/{sdk/stateful → stateful}/index.js +1 -1
  119. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
  120. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
  121. package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
  122. package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
  123. package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
  124. package/package.json +13 -10
  125. package/lib/__tests__/hooks.test.d.ts +0 -1
  126. package/lib/__tests__/hooks.test.js +0 -19
  127. package/lib/__tests__/index.test.d.ts +0 -1
  128. package/lib/__tests__/index.test.js +0 -27
  129. package/lib/__tests__/integration.test.d.ts +0 -1
  130. package/lib/__tests__/integration.test.js +0 -57
  131. package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
  132. package/lib/__tests__/shared/cleanup-shared.js +0 -228
  133. package/lib/__tests__/shared/test-config.d.ts +0 -51
  134. package/lib/__tests__/shared/test-config.js +0 -110
  135. package/lib/__tests__/shared/test-constants.d.ts +0 -66
  136. package/lib/__tests__/shared/test-constants.js +0 -79
  137. package/lib/__tests__/utils.test.d.ts +0 -1
  138. package/lib/__tests__/utils.test.js +0 -59
  139. package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
  140. package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
  141. package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
  142. package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
  143. package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
  144. package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
  145. package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
  146. package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
  147. package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
  148. package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
  149. package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
  150. package/lib/api/__tests__/runtimes.integration.test.js +0 -369
  151. package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
  152. package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
  153. package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
  154. package/lib/api/__tests__/spacer.integration.test.js +0 -519
  155. package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
  156. package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
  157. package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
  158. package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
  159. package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
  160. package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
  161. package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
  162. package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
  163. package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
  164. package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
  165. package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
  166. package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
  167. package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
  168. package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
  169. package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
  170. package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
  171. package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
  172. package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
  173. package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
  174. package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
  175. package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
  176. package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
  177. package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
  178. package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
  179. package/lib/api/types/index.d.ts +0 -32
  180. package/lib/api/types/index.js +0 -36
  181. package/lib/api/types/runtimes.d.ts +0 -235
  182. package/lib/api/types/spacer.d.ts +0 -271
  183. package/lib/api/types/spacer.js +0 -5
  184. package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
  185. package/lib/api/utils/__tests__/validation.test.js +0 -109
  186. package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
  187. package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
  188. package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
  189. package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
  190. package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
  191. package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
  192. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
  193. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
  194. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
  195. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
  196. package/lib/sdk/client/base.d.ts +0 -88
  197. package/lib/sdk/client/base.js +0 -112
  198. package/lib/sdk/client/index.d.ts +0 -192
  199. package/lib/sdk/client/index.js +0 -128
  200. package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
  201. package/lib/sdk/client/mixins/HealthMixin.js +0 -133
  202. package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
  203. package/lib/sdk/client/mixins/IAMMixin.js +0 -83
  204. package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
  205. package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
  206. package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
  207. package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
  208. package/lib/sdk/client/models/Lexical.d.ts +0 -156
  209. package/lib/sdk/client/models/Lexical.js +0 -275
  210. package/lib/sdk/client/models/Notebook.d.ts +0 -174
  211. package/lib/sdk/client/models/Notebook.js +0 -311
  212. package/lib/sdk/client/models/Runtime.d.ts +0 -221
  213. package/lib/sdk/client/models/Runtime.js +0 -341
  214. package/lib/sdk/client/models/Snapshot.d.ts +0 -156
  215. package/lib/sdk/client/models/Snapshot.js +0 -244
  216. package/lib/sdk/client/models/Space.d.ts +0 -182
  217. package/lib/sdk/client/models/Space.js +0 -276
  218. package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
  219. package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
  220. package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
  221. package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
  222. package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
  223. package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
  224. package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
  225. package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
  226. package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
  227. package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
  228. package/lib/sdk/client/models/index.d.ts +0 -30
  229. package/lib/sdk/client/models/index.js +0 -30
  230. package/lib/sdk/client/utils/mixins.d.ts +0 -42
  231. /package/lib/{api/types/iam.js → models/Common.js} +0 -0
  232. /package/lib/{api/types/runtimes.js → models/IAM.js} +0 -0
  233. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
  234. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
  235. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
  236. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
  237. /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
  238. /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
  239. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
  240. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
  241. /package/lib/{sdk/stateful → stateful}/runtimes/apis.js +0 -0
  242. /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
  243. /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
  244. /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
  245. /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
  246. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
  247. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
  248. /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
  249. /package/lib/{sdk/stateful → stateful}/runtimes/utils.js +0 -0
@@ -1,519 +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, test } from 'vitest';
6
- import { users, notebooks, lexicals, items } from '../spacer';
7
- import { testConfig, debugLog, skipIfNoToken, } from '../../__tests__/shared/test-config';
8
- import { performCleanup } from '../../__tests__/shared/cleanup-shared';
9
- let DATALAYER_TOKEN;
10
- let BASE_URL;
11
- // Skip all tests if no token is available
12
- const skipTests = skipIfNoToken();
13
- beforeAll(async () => {
14
- if (skipTests) {
15
- console.log('WARNING: Skipping Spacer Lifecycle integration tests: No Datalayer API token configured');
16
- console.log(' Set DATALAYER_API_TOKEN env var or DATALAYER_TEST_TOKEN in .env.test');
17
- return;
18
- }
19
- // Get token and base URL from test config
20
- DATALAYER_TOKEN = testConfig.getToken();
21
- BASE_URL = testConfig.getBaseUrl('SPACER');
22
- debugLog('Test configuration loaded');
23
- debugLog('Base URL:', BASE_URL);
24
- debugLog('Token available:', !!DATALAYER_TOKEN);
25
- // Pre-test cleanup
26
- await performCleanup('setup');
27
- });
28
- afterAll(async () => {
29
- if (skipTests) {
30
- return;
31
- }
32
- // Post-test cleanup
33
- await performCleanup('teardown');
34
- });
35
- describe.skipIf(skipTests)('Spacer Complete Lifecycle Integration Tests', () => {
36
- // Complete lifecycle test for spacer resources
37
- describe.sequential('complete spacer resource lifecycle', () => {
38
- let testSpaceId;
39
- let createdNotebookId;
40
- let createdLexicalId;
41
- let createdItemIds = [];
42
- const testNamePrefix = `test-${Date.now()}`;
43
- // No cleanup needed - handled by global setup/teardown
44
- test('1. should get user spaces to find a valid space ID', async () => {
45
- console.log('Getting user spaces...');
46
- const response = await users.getMySpaces(DATALAYER_TOKEN, BASE_URL);
47
- expect(response).toBeDefined();
48
- expect(response).toHaveProperty('success');
49
- expect(response.success).toBe(true);
50
- expect(response).toHaveProperty('spaces');
51
- expect(Array.isArray(response.spaces)).toBe(true);
52
- console.log(`Found ${response.spaces.length} space(s) for user`);
53
- if (response.spaces.length > 0) {
54
- const firstSpace = response.spaces[0];
55
- testSpaceId = firstSpace.uid || firstSpace.id;
56
- const spaceName = firstSpace.name || firstSpace.name_t;
57
- console.log(`Using space ID: ${testSpaceId} (${spaceName})`);
58
- // Verify space structure - check for either old or new field names
59
- expect(firstSpace).toHaveProperty('uid');
60
- expect(firstSpace).toSatisfy((space) => space.name !== undefined || space.name_t !== undefined);
61
- }
62
- else {
63
- console.log('WARNING: No spaces found - some tests may fail');
64
- // Use a placeholder space ID
65
- testSpaceId = 'test-space-id';
66
- }
67
- });
68
- test('2. should create a notebook', async () => {
69
- if (!testSpaceId) {
70
- console.log('No space ID available, skipping notebook creation');
71
- return;
72
- }
73
- // Add initial delay to spread out load when running with other tests
74
- await new Promise(resolve => setTimeout(resolve, 1000));
75
- console.log('Creating notebook...');
76
- const notebookContent = {
77
- cells: [
78
- {
79
- cell_type: 'markdown',
80
- metadata: {},
81
- source: [
82
- '# Test Notebook\n',
83
- 'This is a test notebook created by integration tests',
84
- ],
85
- },
86
- {
87
- cell_type: 'code',
88
- metadata: {},
89
- source: ['print("Hello from integration test")'],
90
- outputs: [],
91
- },
92
- ],
93
- metadata: {
94
- kernelspec: {
95
- display_name: 'Python 3',
96
- language: 'python',
97
- name: 'python3',
98
- },
99
- },
100
- nbformat: 4,
101
- nbformat_minor: 4,
102
- };
103
- const file = new Blob([JSON.stringify(notebookContent)], {
104
- type: 'application/json',
105
- });
106
- try {
107
- const response = await notebooks.createNotebook(DATALAYER_TOKEN, {
108
- spaceId: testSpaceId,
109
- notebookType: 'jupyter',
110
- name: `${testNamePrefix}-notebook`,
111
- description: 'Integration test notebook',
112
- file: file,
113
- }, BASE_URL);
114
- console.log('Notebook response:', JSON.stringify(response, null, 2));
115
- if (response.success) {
116
- expect(response).toHaveProperty('notebook');
117
- expect(response.notebook).toHaveProperty('id');
118
- createdNotebookId = response.notebook.uid;
119
- console.log(`Created notebook with UID: ${createdNotebookId}`);
120
- createdItemIds.push(createdNotebookId);
121
- }
122
- else {
123
- console.log('Notebook creation failed:', response.message);
124
- }
125
- }
126
- catch (error) {
127
- console.error('Error creating notebook:', error.message);
128
- }
129
- });
130
- test('3. should create a lexical document', async () => {
131
- if (!testSpaceId) {
132
- console.log('No space ID available, skipping lexical creation');
133
- return;
134
- }
135
- // Add delay to spread out load when running with other tests
136
- await new Promise(resolve => setTimeout(resolve, 2000)); // Stagger more than notebook creation
137
- console.log('Creating lexical document...');
138
- const lexicalContent = {
139
- root: {
140
- type: 'root',
141
- format: '',
142
- indent: 0,
143
- version: 1,
144
- children: [
145
- {
146
- type: 'paragraph',
147
- format: '',
148
- indent: 0,
149
- version: 1,
150
- children: [
151
- {
152
- type: 'text',
153
- format: 0,
154
- style: '',
155
- mode: 'normal',
156
- text: 'Test lexical document from integration test',
157
- version: 1,
158
- detail: 0,
159
- },
160
- ],
161
- },
162
- ],
163
- },
164
- };
165
- const file = new Blob([JSON.stringify(lexicalContent)], {
166
- type: 'application/json',
167
- });
168
- try {
169
- const response = await lexicals.createLexical(DATALAYER_TOKEN, {
170
- spaceId: testSpaceId,
171
- documentType: 'lexical',
172
- name: `${testNamePrefix}-lexical`,
173
- description: 'Integration test lexical document',
174
- file: file,
175
- }, BASE_URL);
176
- console.log('Lexical response:', JSON.stringify(response, null, 2));
177
- if (response.success) {
178
- expect(response).toHaveProperty('document');
179
- expect(response.document).toHaveProperty('id');
180
- createdLexicalId = response.document.uid;
181
- console.log(`Created lexical with UID: ${createdLexicalId}`);
182
- createdItemIds.push(createdLexicalId);
183
- }
184
- else {
185
- console.log('Lexical creation failed:', response.message);
186
- }
187
- }
188
- catch (error) {
189
- console.error('Error creating lexical:', error.message);
190
- }
191
- });
192
- test('4. should list all items in the space', async () => {
193
- if (!testSpaceId) {
194
- console.log('No space ID available, skipping list items');
195
- return;
196
- }
197
- console.log('Listing items in space...');
198
- const response = await items.getSpaceItems(DATALAYER_TOKEN, testSpaceId, BASE_URL);
199
- console.log('Items response:', JSON.stringify(response, null, 2));
200
- expect(response).toBeDefined();
201
- expect(response).toHaveProperty('success');
202
- expect(response).toHaveProperty('items');
203
- if (response.success && Array.isArray(response.items)) {
204
- console.log(`Found ${response.items.length} items in space`);
205
- // Find our created items
206
- const foundNotebook = createdNotebookId
207
- ? response.items.find((item) => item.id === createdNotebookId)
208
- : null;
209
- const foundLexical = createdLexicalId
210
- ? response.items.find((item) => item.id === createdLexicalId)
211
- : null;
212
- if (foundNotebook) {
213
- console.log('✓ Found created notebook in items list');
214
- console.log('Notebook object:', JSON.stringify(foundNotebook, null, 2));
215
- // Handle both name formats that might be returned
216
- const notebookName = foundNotebook.name || foundNotebook.name_t || '';
217
- if (notebookName) {
218
- expect(notebookName).toContain(testNamePrefix);
219
- }
220
- else {
221
- console.log('Warning: Notebook found but has no name field');
222
- }
223
- }
224
- if (foundLexical) {
225
- console.log('✓ Found created lexical in items list');
226
- console.log('Lexical object:', JSON.stringify(foundLexical, null, 2));
227
- // Handle both name formats that might be returned
228
- const lexicalName = foundLexical.name || foundLexical.name_t || '';
229
- if (lexicalName) {
230
- expect(lexicalName).toContain(testNamePrefix);
231
- }
232
- else {
233
- console.log('Warning: Lexical found but has no name field');
234
- }
235
- }
236
- }
237
- });
238
- test('5. should get notebook details', async () => {
239
- if (!createdNotebookId) {
240
- console.log('No notebook was created, skipping get test');
241
- return;
242
- }
243
- console.log('Getting notebook details...');
244
- try {
245
- // Add a small delay to allow server processing
246
- await new Promise(resolve => setTimeout(resolve, 1000));
247
- const response = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
248
- console.log('Get notebook response:', JSON.stringify(response, null, 2));
249
- expect(response).toBeDefined();
250
- expect(response).toHaveProperty('success');
251
- if (response.success) {
252
- expect(response).toHaveProperty('notebook');
253
- expect(response.notebook?.uid).toBe(createdNotebookId);
254
- console.log('✓ Retrieved notebook details successfully');
255
- }
256
- }
257
- catch (error) {
258
- console.log('Expected error getting notebook:', error.message);
259
- // The notebook might not be immediately available after creation
260
- // This is acceptable for this test scenario
261
- }
262
- });
263
- test('6. should get lexical details', async () => {
264
- if (!createdLexicalId) {
265
- console.log('No lexical was created, skipping get test');
266
- return;
267
- }
268
- console.log('Getting lexical details...');
269
- try {
270
- // Add a small delay to allow server processing
271
- await new Promise(resolve => setTimeout(resolve, 1000));
272
- const response = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
273
- console.log('Get lexical response:', JSON.stringify(response, null, 2));
274
- expect(response).toBeDefined();
275
- expect(response).toHaveProperty('success');
276
- if (response.success) {
277
- expect(response).toHaveProperty('document');
278
- expect(response.document?.uid).toBe(createdLexicalId);
279
- console.log('✓ Retrieved lexical details successfully');
280
- }
281
- }
282
- catch (error) {
283
- console.log('Expected error getting lexical:', error.message);
284
- // The lexical might not be immediately available after creation
285
- // This is acceptable for this test scenario
286
- }
287
- });
288
- test('7. should update notebook', async () => {
289
- if (!createdNotebookId) {
290
- console.log('No notebook was created, skipping update test');
291
- return;
292
- }
293
- console.log('Updating notebook...');
294
- const updateData = {
295
- name: `${testNamePrefix}-notebook-updated`,
296
- description: 'Updated integration test notebook',
297
- };
298
- try {
299
- // Add delay to allow server processing and avoid resource contention
300
- await new Promise(resolve => setTimeout(resolve, 5000)); // 5 second delay for bulk test runs
301
- const response = await notebooks.updateNotebook(DATALAYER_TOKEN, createdNotebookId, updateData, BASE_URL);
302
- console.log('Update notebook response:', JSON.stringify(response, null, 2));
303
- expect(response).toBeDefined();
304
- expect(response).toHaveProperty('success');
305
- if (response.success) {
306
- expect(response).toHaveProperty('notebook');
307
- expect(response.notebook.uid).toBe(createdNotebookId);
308
- const nameObj = response.notebook.name_t || response.notebook.name || {};
309
- const notebookName = nameObj && typeof nameObj === 'object' && nameObj.set
310
- ? nameObj.set
311
- : typeof nameObj === 'string'
312
- ? nameObj
313
- : '';
314
- expect(notebookName).toContain('updated');
315
- console.log('✓ Updated notebook successfully');
316
- }
317
- }
318
- catch (error) {
319
- console.log('Error updating notebook:', error.message);
320
- throw error; // Let the test fail
321
- }
322
- });
323
- test('8. should update lexical', async () => {
324
- if (!createdLexicalId) {
325
- console.log('No lexical was created, skipping update test');
326
- return;
327
- }
328
- console.log('Updating lexical...');
329
- const updateData = {
330
- name: `${testNamePrefix}-lexical-updated`,
331
- description: 'Updated integration test lexical',
332
- };
333
- try {
334
- // Add delay to allow server processing and avoid resource contention
335
- await new Promise(resolve => setTimeout(resolve, 5000)); // 5 second delay for bulk test runs
336
- const response = await lexicals.updateLexical(DATALAYER_TOKEN, createdLexicalId, updateData, BASE_URL);
337
- console.log('Update lexical response:', JSON.stringify(response, null, 2));
338
- expect(response).toBeDefined();
339
- expect(response).toHaveProperty('success');
340
- if (response.success) {
341
- expect(response).toHaveProperty('document');
342
- expect(response.document.uid).toBe(createdLexicalId);
343
- const nameObj = response.document.name_t || response.document.name || {};
344
- const lexicalName = nameObj && typeof nameObj === 'object' && nameObj.set
345
- ? nameObj.set
346
- : typeof nameObj === 'string'
347
- ? nameObj
348
- : '';
349
- expect(lexicalName).toContain('updated');
350
- console.log('✓ Updated lexical successfully');
351
- }
352
- }
353
- catch (error) {
354
- console.log('Error updating lexical:', error.message);
355
- throw error; // Let the test fail
356
- }
357
- });
358
- test('9. should verify updates by getting items again', async () => {
359
- if (!createdNotebookId && !createdLexicalId) {
360
- console.log('No items were created, skipping verification');
361
- return;
362
- }
363
- console.log('Verifying updates...');
364
- // Get notebook to verify update
365
- if (createdNotebookId) {
366
- const notebookResponse = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
367
- if (notebookResponse.success && notebookResponse.notebook) {
368
- const notebookName = notebookResponse.notebook.name ||
369
- notebookResponse.notebook.name_t ||
370
- '';
371
- expect(notebookName).toContain('updated');
372
- console.log('✓ Notebook update verified');
373
- }
374
- }
375
- // Get lexical to verify update
376
- if (createdLexicalId) {
377
- const lexicalResponse = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
378
- if (lexicalResponse.success && lexicalResponse.document) {
379
- const lexicalName = lexicalResponse.document.name ||
380
- lexicalResponse.document.name_t ||
381
- '';
382
- expect(lexicalName).toContain('updated');
383
- console.log('✓ Lexical update verified');
384
- }
385
- }
386
- });
387
- test('10. should delete notebook', async () => {
388
- if (!createdNotebookId) {
389
- console.log('No notebook was created, skipping delete test');
390
- return;
391
- }
392
- console.log('Deleting notebook...');
393
- try {
394
- await items.deleteItem(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
395
- console.log('Notebook deletion request sent');
396
- // Verify deletion
397
- const getResponse = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
398
- if (!getResponse.success) {
399
- console.log('✓ Notebook properly deleted');
400
- }
401
- else {
402
- console.log('WARNING: Notebook still exists after deletion');
403
- }
404
- // Remove from cleanup list
405
- createdNotebookId = undefined;
406
- createdItemIds = createdItemIds.filter(id => id !== createdNotebookId);
407
- }
408
- catch (error) {
409
- console.log('Expected deletion error:', error.message);
410
- }
411
- });
412
- test('11. should delete lexical', async () => {
413
- if (!createdLexicalId) {
414
- console.log('No lexical was created, skipping delete test');
415
- return;
416
- }
417
- console.log('Deleting lexical...');
418
- try {
419
- await items.deleteItem(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
420
- console.log('Lexical deletion request sent');
421
- // Verify deletion
422
- const getResponse = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
423
- if (!getResponse.success) {
424
- console.log('✓ Lexical properly deleted');
425
- }
426
- else {
427
- console.log('WARNING: Lexical still exists after deletion');
428
- }
429
- // Remove from cleanup list
430
- createdLexicalId = undefined;
431
- createdItemIds = createdItemIds.filter(id => id !== createdLexicalId);
432
- }
433
- catch (error) {
434
- console.log('Expected deletion error:', error.message);
435
- }
436
- });
437
- test('12. should verify all items are deleted', async () => {
438
- if (!testSpaceId) {
439
- console.log('No space ID available, skipping final verification');
440
- return;
441
- }
442
- console.log('Final verification...');
443
- const response = await items.getSpaceItems(DATALAYER_TOKEN, testSpaceId, BASE_URL);
444
- if (response.success && Array.isArray(response.items)) {
445
- const remainingTestItems = response.items.filter((item) => item.name?.includes(testNamePrefix));
446
- expect(remainingTestItems.length).toBe(0);
447
- if (remainingTestItems.length === 0) {
448
- console.log('✓ All test items successfully deleted');
449
- }
450
- else {
451
- console.log(`WARNING: ${remainingTestItems.length} test items still exist`);
452
- }
453
- }
454
- console.log('Complete spacer lifecycle test finished successfully!');
455
- });
456
- });
457
- // Basic smoke tests that always run
458
- describe('smoke tests', () => {
459
- it('should successfully get user spaces', async () => {
460
- console.log('Testing get user spaces endpoint...');
461
- const response = await users.getMySpaces(DATALAYER_TOKEN, BASE_URL);
462
- console.log(`Found ${response.spaces.length} space(s)`);
463
- expect(response).toBeDefined();
464
- expect(response).toHaveProperty('success');
465
- expect(response.success).toBe(true);
466
- expect(response).toHaveProperty('spaces');
467
- expect(Array.isArray(response.spaces)).toBe(true);
468
- if (response.spaces.length > 0) {
469
- const firstSpace = response.spaces[0];
470
- const spaceName = firstSpace.name || firstSpace.name_t;
471
- console.log('First space:', spaceName);
472
- expect(firstSpace).toHaveProperty('uid');
473
- expect(firstSpace).toSatisfy((space) => space.name !== undefined || space.name_t !== undefined);
474
- }
475
- });
476
- it('should handle non-existent notebook gracefully', async () => {
477
- console.log('Testing get with non-existent notebook ID...');
478
- try {
479
- const response = await notebooks.getNotebook(DATALAYER_TOKEN, 'non-existent-notebook-id-123456789', BASE_URL);
480
- console.log('404 response:', JSON.stringify(response, null, 2));
481
- expect(response).toBeDefined();
482
- expect(response).toHaveProperty('success');
483
- expect(response).toHaveProperty('message');
484
- if (!response.success) {
485
- expect(response.notebook).toBeUndefined();
486
- console.log('Expected 404 message:', response.message);
487
- }
488
- }
489
- catch (error) {
490
- console.log('Expected error for non-existent notebook:', error.message);
491
- expect(error).toBeDefined();
492
- // API may return either "not found" or "Network Error" for non-existent resources
493
- expect(error.message.toLowerCase().includes('not found') ||
494
- error.message.includes('Network Error')).toBeTruthy();
495
- }
496
- });
497
- it('should handle non-existent lexical gracefully', async () => {
498
- console.log('Testing get with non-existent lexical ID...');
499
- try {
500
- const response = await lexicals.getLexical(DATALAYER_TOKEN, 'non-existent-lexical-id-123456789', BASE_URL);
501
- console.log('404 response:', JSON.stringify(response, null, 2));
502
- expect(response).toBeDefined();
503
- expect(response).toHaveProperty('success');
504
- expect(response).toHaveProperty('message');
505
- if (!response.success) {
506
- expect(response.document).toBeUndefined();
507
- console.log('Expected 404 message:', response.message);
508
- }
509
- }
510
- catch (error) {
511
- console.log('Expected error for non-existent lexical:', error.message);
512
- expect(error).toBeDefined();
513
- // API may return either "not found" or "Network Error" for non-existent resources
514
- expect(error.message.toLowerCase().includes('not found') ||
515
- error.message.includes('Network Error')).toBeTruthy();
516
- }
517
- });
518
- });
519
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,63 +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 } from 'vitest';
6
- import { authentication } from '..';
7
- describe('IAM Authentication Unit Tests', () => {
8
- describe('login parameter validation', () => {
9
- const mockBaseUrl = 'https://example.com';
10
- it('should fail when providing both token and credentials', async () => {
11
- console.log('Testing invalid login with both token and credentials...');
12
- await expect(authentication.login({
13
- token: 'some-token',
14
- handle: 'user@example.com',
15
- password: 'password123',
16
- }, mockBaseUrl)).rejects.toThrow('Cannot provide both credentials (handle/password) and token');
17
- console.log('Correctly rejected login with both authentication methods');
18
- });
19
- it('should fail when providing neither token nor credentials', async () => {
20
- console.log('Testing invalid login with no authentication...');
21
- await expect(authentication.login({}, mockBaseUrl)).rejects.toThrow('Must provide either credentials (handle+password) or token');
22
- console.log('Correctly rejected login with no authentication');
23
- });
24
- it('should fail when providing handle without password', async () => {
25
- console.log('Testing invalid login with handle but no password...');
26
- await expect(authentication.login({
27
- handle: 'user@example.com',
28
- }, mockBaseUrl)).rejects.toThrow('Both handle and password are required for credential-based authentication');
29
- console.log('Correctly rejected login with incomplete credentials');
30
- });
31
- it('should fail when providing password without handle', async () => {
32
- console.log('Testing invalid login with password but no handle...');
33
- await expect(authentication.login({
34
- password: 'password123',
35
- }, mockBaseUrl)).rejects.toThrow('Both handle and password are required for credential-based authentication');
36
- console.log('Correctly rejected login with incomplete credentials');
37
- });
38
- });
39
- describe('logout parameter validation', () => {
40
- it('should require a token for logout', async () => {
41
- console.log('Testing logout without token...');
42
- // TypeScript should prevent this at compile time, but let's test runtime behavior
43
- // @ts-expect-error Testing missing required parameter
44
- await expect(authentication.logout()).rejects.toThrow();
45
- console.log('Correctly rejected logout without token');
46
- });
47
- it('should accept logout with only token (using default URL)', async () => {
48
- console.log('Testing logout with token only (default URL)...');
49
- // This should not throw a validation error (though it may fail with API)
50
- // The method signature allows this since baseUrl has a default
51
- const mockToken = 'mock-token';
52
- // We can't test the actual API call in a unit test, but we can verify
53
- // the method accepts this signature
54
- expect(() => {
55
- // This should not throw a compile-time or immediate runtime error
56
- const promise = authentication.logout(mockToken);
57
- // Cancel the promise to avoid actual API call in unit test
58
- promise.catch(() => { }); // Ignore the error
59
- }).not.toThrow();
60
- console.log('Logout accepts token with default URL');
61
- });
62
- });
63
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,60 +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, vi, beforeEach } from 'vitest';
6
- import { ping } from '../healthz';
7
- import { requestDatalayerAPI } from '../../DatalayerApi';
8
- // Mock the DatalayerAPI module
9
- vi.mock('../../DatalayerApi');
10
- describe('IAM Healthz Unit Tests', () => {
11
- beforeEach(() => {
12
- vi.clearAllMocks();
13
- });
14
- describe('ping', () => {
15
- it('should return health status on successful health check', async () => {
16
- const mockResponse = {
17
- success: true,
18
- message: 'datalayer_iam is up and running.',
19
- status: { status: 'OK' },
20
- version: '1.0.7',
21
- };
22
- vi.mocked(requestDatalayerAPI).mockResolvedValueOnce(mockResponse);
23
- const result = await ping();
24
- expect(result).toEqual(mockResponse);
25
- expect(requestDatalayerAPI).toHaveBeenCalledWith({
26
- url: 'https://prod1.datalayer.run/api/iam/v1/ping',
27
- method: 'GET',
28
- });
29
- });
30
- it('should use custom base URL when provided', async () => {
31
- const mockResponse = {
32
- success: true,
33
- message: 'Service is healthy',
34
- status: { status: 'OK' },
35
- version: '2.0.0',
36
- };
37
- const customUrl = 'https://custom.example.com';
38
- vi.mocked(requestDatalayerAPI).mockResolvedValueOnce(mockResponse);
39
- const result = await ping(customUrl);
40
- expect(result).toEqual(mockResponse);
41
- expect(requestDatalayerAPI).toHaveBeenCalledWith({
42
- url: `${customUrl}/api/iam/v1/ping`,
43
- method: 'GET',
44
- });
45
- });
46
- it('should throw error with status code on failure', async () => {
47
- const mockError = {
48
- response: { status: 500 },
49
- message: 'Internal Server Error',
50
- };
51
- vi.mocked(requestDatalayerAPI).mockRejectedValueOnce(mockError);
52
- await expect(ping()).rejects.toThrow('Health check failed: Service unhealthy (status 500) - Internal Server Error');
53
- });
54
- it('should throw generic error on network failure', async () => {
55
- const mockError = new Error('Network error');
56
- vi.mocked(requestDatalayerAPI).mockRejectedValueOnce(mockError);
57
- await expect(ping()).rejects.toThrow('Health check failed: Network error');
58
- });
59
- });
60
- });
@@ -1 +0,0 @@
1
- export {};