@datalayer/core 1.0.13 → 1.0.15

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 (275) hide show
  1. package/lib/App.js +2 -2
  2. package/lib/api/DatalayerApi.js +6 -1
  3. package/lib/api/constants.d.ts +1 -1
  4. package/lib/api/constants.js +1 -1
  5. package/lib/api/iam/authentication.js +3 -3
  6. package/lib/api/iam/datasources.js +3 -3
  7. package/lib/api/iam/healthz.js +2 -2
  8. package/lib/api/iam/index.js +12 -12
  9. package/lib/api/iam/oauth2.js +2 -2
  10. package/lib/api/iam/profile.js +3 -3
  11. package/lib/api/iam/secrets.js +3 -3
  12. package/lib/api/iam/usage.js +2 -2
  13. package/lib/api/index.js +8 -8
  14. package/lib/api/otel/index.js +5 -5
  15. package/lib/api/otel/logs.js +3 -3
  16. package/lib/api/otel/metrics.js +3 -3
  17. package/lib/api/otel/query.js +3 -3
  18. package/lib/api/otel/services.js +3 -3
  19. package/lib/api/otel/traces.js +3 -3
  20. package/lib/api/runtimes/checkpoints.js +3 -3
  21. package/lib/api/runtimes/environments.js +3 -3
  22. package/lib/api/runtimes/healthz.js +2 -2
  23. package/lib/api/runtimes/index.js +5 -5
  24. package/lib/api/runtimes/runtimes.js +3 -3
  25. package/lib/api/runtimes/snapshots.js +3 -3
  26. package/lib/api/spacer/documents.js +2 -2
  27. package/lib/api/spacer/healthz.js +2 -2
  28. package/lib/api/spacer/index.js +7 -7
  29. package/lib/api/spacer/items.js +2 -2
  30. package/lib/api/spacer/lexicals.d.ts +8 -0
  31. package/lib/api/spacer/lexicals.js +16 -2
  32. package/lib/api/spacer/notebooks.d.ts +8 -0
  33. package/lib/api/spacer/notebooks.js +16 -2
  34. package/lib/api/spacer/spaces.d.ts +76 -1
  35. package/lib/api/spacer/spaces.js +143 -3
  36. package/lib/api/spacer/users.js +3 -3
  37. package/lib/client/auth/AuthenticationManager.js +3 -3
  38. package/lib/client/auth/index.js +4 -4
  39. package/lib/client/auth/storage.d.ts +3 -1
  40. package/lib/client/auth/storage.js +35 -14
  41. package/lib/client/auth/strategies.js +3 -3
  42. package/lib/client/base.js +2 -2
  43. package/lib/client/index.d.ts +22 -2
  44. package/lib/client/index.js +21 -20
  45. package/lib/client/mixins/IAMMixin.js +10 -10
  46. package/lib/client/mixins/RuntimesMixin.js +7 -7
  47. package/lib/client/mixins/SpacerMixin.d.ts +99 -0
  48. package/lib/client/mixins/SpacerMixin.js +265 -11
  49. package/lib/client/utils/slugify.d.ts +8 -0
  50. package/lib/client/utils/slugify.js +18 -0
  51. package/lib/client/utils/spacerUtils.js +3 -3
  52. package/lib/collaboration/DatalayerCollaborationProvider.js +1 -1
  53. package/lib/collaboration/index.js +2 -2
  54. package/lib/components/auth/Login.js +6 -6
  55. package/lib/components/auth/Login.stories.js +2 -2
  56. package/lib/components/auth/LoginToken.js +2 -2
  57. package/lib/components/auth/index.js +3 -3
  58. package/lib/components/avatars/BoringAvatar.stories.js +1 -1
  59. package/lib/components/avatars/UserProfileAvatar.js +2 -2
  60. package/lib/components/avatars/index.js +2 -2
  61. package/lib/components/banners/NoAutomationBanner.js +1 -1
  62. package/lib/components/banners/index.js +1 -1
  63. package/lib/components/buttons/DownloadCSVButton.js +1 -1
  64. package/lib/components/buttons/DownloadJsonButton.js +1 -1
  65. package/lib/components/buttons/index.js +5 -5
  66. package/lib/components/checkout/StripeCheckout.js +1 -1
  67. package/lib/components/checkout/index.js +1 -1
  68. package/lib/components/confetti/index.js +1 -1
  69. package/lib/components/context/OrganizationSelect.js +2 -2
  70. package/lib/components/context/SpaceSelect.js +2 -2
  71. package/lib/components/context/index.js +2 -2
  72. package/lib/components/display/DatalayerBox.js +1 -1
  73. package/lib/components/display/LiveRelativeTime.js +1 -1
  74. package/lib/components/display/NavLink.js +1 -1
  75. package/lib/components/display/index.js +14 -14
  76. package/lib/components/echarts/index.js +1 -1
  77. package/lib/components/flashes/FlashDisclaimer.js +2 -2
  78. package/lib/components/flashes/FlashGuest.js +4 -4
  79. package/lib/components/flashes/FlashSurveys.js +4 -4
  80. package/lib/components/flashes/FlashUnauthorized.js +1 -1
  81. package/lib/components/flashes/index.js +6 -6
  82. package/lib/components/flashes/surveys/index.js +2 -2
  83. package/lib/components/iam/ExternalTokenSilentLogin.js +3 -3
  84. package/lib/components/iam/index.js +1 -1
  85. package/lib/components/icons/index.js +1 -1
  86. package/lib/components/index.js +2 -2
  87. package/lib/components/labels/index.js +1 -1
  88. package/lib/components/landings/index.js +1 -1
  89. package/lib/components/navbar/NavigationVisbilityObserver.js +4 -4
  90. package/lib/components/navbar/SubdomainNavBar.js +5 -5
  91. package/lib/components/navbar/index.js +2 -2
  92. package/lib/components/nbgrader/index.js +1 -1
  93. package/lib/components/notebooks/index.js +2 -2
  94. package/lib/components/progress/ConsumptionBar.js +1 -1
  95. package/lib/components/progress/CreditsIndicator.js +2 -2
  96. package/lib/components/progress/index.js +6 -6
  97. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +2 -2
  98. package/lib/components/runtimes/RuntimeLauncherDialog.js +9 -9
  99. package/lib/components/runtimes/RuntimePickerBase.js +3 -3
  100. package/lib/components/runtimes/RuntimePickerCell.js +8 -8
  101. package/lib/components/runtimes/RuntimePickerNotebook.js +6 -6
  102. package/lib/components/runtimes/RuntimeSimplePicker.js +3 -3
  103. package/lib/components/runtimes/index.js +11 -11
  104. package/lib/components/screencapture/ScreencaptureButton.js +3 -3
  105. package/lib/components/screencapture/index.js +2 -2
  106. package/lib/components/snapshots/RuntimeSnapshotMenu.js +4 -4
  107. package/lib/components/snapshots/index.js +1 -1
  108. package/lib/components/snippets/SnippetDialog.js +1 -1
  109. package/lib/components/snippets/index.js +1 -1
  110. package/lib/components/sparklines/Sparklines.js +5 -1
  111. package/lib/components/sparklines/dataProcessing.d.ts +2 -4
  112. package/lib/components/sparklines/dataProcessing.js +1 -1
  113. package/lib/components/sparklines/index.d.ts +1 -0
  114. package/lib/components/sparklines/index.js +7 -3
  115. package/lib/components/sparklines/types.js +1 -1
  116. package/lib/components/storage/ContentsBrowser.js +3 -3
  117. package/lib/components/storage/index.js +2 -2
  118. package/lib/components/students/index.js +1 -1
  119. package/lib/components/subnav/SubNav.js +2 -2
  120. package/lib/components/subnav/index.js +1 -1
  121. package/lib/components/tables/index.js +1 -1
  122. package/lib/components/text-reveal/TextRevealAnimation.js +1 -1
  123. package/lib/components/text-reveal/index.js +1 -1
  124. package/lib/components/tokens/index.js +1 -1
  125. package/lib/components/toolbars/AssignmentEditorToolbar.js +1 -1
  126. package/lib/components/toolbars/DocumentEditorToolbar.js +1 -1
  127. package/lib/components/toolbars/index.js +3 -3
  128. package/lib/components/users/PeerIndicator.js +1 -1
  129. package/lib/components/users/index.js +1 -1
  130. package/lib/config/Configuration.d.ts +1 -1
  131. package/lib/config/Configuration.js +2 -2
  132. package/lib/config/index.js +2 -2
  133. package/lib/config/integrations/index.js +1 -1
  134. package/lib/hooks/assets/index.js +1 -1
  135. package/lib/hooks/index.js +33 -33
  136. package/lib/hooks/layouts/LayoutBackdrop.js +2 -2
  137. package/lib/hooks/layouts/LayoutScreencapture.js +3 -3
  138. package/lib/hooks/layouts/index.js +2 -2
  139. package/lib/hooks/useAuthorization.js +3 -3
  140. package/lib/hooks/useBackdrop.js +2 -2
  141. package/lib/hooks/useCache.js +9 -9
  142. package/lib/hooks/useCellOutputshot.js +2 -2
  143. package/lib/hooks/useDatalayer.js +6 -6
  144. package/lib/hooks/useIAM.js +4 -4
  145. package/lib/hooks/useLocation.js +2 -2
  146. package/lib/hooks/useLocationHandles.js +3 -3
  147. package/lib/hooks/useNavigate.js +4 -4
  148. package/lib/hooks/useParams.js +2 -2
  149. package/lib/hooks/useProjects.d.ts +2 -8
  150. package/lib/hooks/useProjects.js +2 -2
  151. package/lib/hooks/useRuntimes.js +1 -1
  152. package/lib/hooks/useScreencapture.js +1 -1
  153. package/lib/hooks/useToast.js +41 -5
  154. package/lib/hooks/useUpload.js +2 -2
  155. package/lib/hooks/useUser.js +1 -1
  156. package/lib/i18n/index.js +1 -1
  157. package/lib/index.d.ts +1 -1
  158. package/lib/index.js +17 -17
  159. package/lib/main.js +1 -1
  160. package/lib/mocks/components/FlashMock.js +1 -1
  161. package/lib/mocks/components/index.js +1 -1
  162. package/lib/mocks/hooks/index.js +1 -1
  163. package/lib/mocks/hooks/rests/index.js +1 -1
  164. package/lib/mocks/hooks/useDatalayerMock.js +5 -5
  165. package/lib/mocks/index.js +5 -5
  166. package/lib/mocks/models/CourseMock.js +3 -3
  167. package/lib/mocks/models/InviteMock.js +2 -2
  168. package/lib/mocks/models/OrganisationMock.js +1 -1
  169. package/lib/mocks/models/SchoolMock.js +1 -1
  170. package/lib/mocks/models/SpaceMock.js +2 -2
  171. package/lib/mocks/models/TeamMock.js +1 -1
  172. package/lib/mocks/models/UserMock.js +1 -1
  173. package/lib/mocks/models/index.js +9 -9
  174. package/lib/mocks/views/ChartMock.js +3 -3
  175. package/lib/mocks/views/DashboardMock.js +2 -2
  176. package/lib/mocks/views/TableMock.js +1 -1
  177. package/lib/mocks/views/index.js +7 -7
  178. package/lib/models/Contact.js +3 -3
  179. package/lib/models/CreditsDTO.js +1 -1
  180. package/lib/models/Datasource.js +1 -1
  181. package/lib/models/EnvironmentDTO.d.ts +1 -1
  182. package/lib/models/EnvironmentDTO.js +2 -2
  183. package/lib/models/HealthCheck.js +1 -1
  184. package/lib/models/IAMProviderUsers.js +1 -1
  185. package/lib/models/Invite.js +1 -1
  186. package/lib/models/ItemDTO.js +1 -1
  187. package/lib/models/LexicalDTO.js +4 -4
  188. package/lib/models/NotebookDTO.js +4 -4
  189. package/lib/models/Organization.js +2 -2
  190. package/lib/models/Page.js +2 -2
  191. package/lib/models/ProjectDTO.d.ts +89 -0
  192. package/lib/models/ProjectDTO.js +131 -0
  193. package/lib/models/RuntimeDTO.js +2 -2
  194. package/lib/models/RuntimeSnapshotDTO.js +2 -2
  195. package/lib/models/Secret.js +1 -1
  196. package/lib/models/Space.d.ts +1 -1
  197. package/lib/models/Space.js +3 -3
  198. package/lib/models/SpaceDTO.d.ts +61 -0
  199. package/lib/models/SpaceDTO.js +9 -9
  200. package/lib/models/Team.js +2 -2
  201. package/lib/models/User.js +5 -5
  202. package/lib/models/UserDTO.js +1 -1
  203. package/lib/models/index.js +75 -75
  204. package/lib/navigation/components.js +1 -1
  205. package/lib/navigation/index.js +4 -4
  206. package/lib/otel/client/OtelClient.js +1 -1
  207. package/lib/otel/client/index.js +1 -1
  208. package/lib/otel/hooks/index.js +1 -1
  209. package/lib/otel/index.js +15 -15
  210. package/lib/otel/types.d.ts +1 -1
  211. package/lib/otel/views/OtelLive.js +11 -11
  212. package/lib/otel/views/OtelLogsList.js +1 -1
  213. package/lib/otel/views/OtelMetricsList.d.ts +2 -5
  214. package/lib/otel/views/OtelMetricsList.js +2 -2
  215. package/lib/otel/views/OtelSpanDetail.js +2 -2
  216. package/lib/otel/views/OtelSpanTree.js +1 -1
  217. package/lib/otel/views/OtelSqlView.js +1 -1
  218. package/lib/otel/views/OtelSystemView.js +1 -1
  219. package/lib/otel/views/OtelTimeline.js +1 -1
  220. package/lib/otel/views/OtelTracesList.js +1 -1
  221. package/lib/otel/views/index.d.ts +1 -0
  222. package/lib/otel/views/index.js +12 -12
  223. package/lib/routes/index.js +1 -1
  224. package/lib/services/DatalayerServiceManager.d.ts +1 -1
  225. package/lib/services/DatalayerServiceManager.js +4 -4
  226. package/lib/services/index.js +3 -3
  227. package/lib/state/State.js +13 -13
  228. package/lib/state/index.js +3 -3
  229. package/lib/state/storage/IAMStorage.js +31 -6
  230. package/lib/state/storage/index.js +1 -1
  231. package/lib/state/substates/CoreState.js +2 -2
  232. package/lib/state/substates/IAMState.js +5 -5
  233. package/lib/state/substates/RuntimesState.js +3 -3
  234. package/lib/state/substates/SurveysState.js +4 -4
  235. package/lib/state/substates/TeamState.js +1 -1
  236. package/lib/state/substates/index.js +14 -14
  237. package/lib/stateful/index.js +2 -2
  238. package/lib/stateful/jupyter/exec/Snippets.js +1 -1
  239. package/lib/stateful/jupyter/exec/index.js +2 -2
  240. package/lib/stateful/jupyter/index.js +2 -2
  241. package/lib/stateful/runtimes/actions.js +4 -4
  242. package/lib/stateful/runtimes/index.js +5 -5
  243. package/lib/stateful/runtimes/snapshots.js +1 -1
  244. package/lib/utils/Date.d.ts +11 -0
  245. package/lib/utils/Date.js +30 -0
  246. package/lib/utils/cli/index.js +1 -1
  247. package/lib/utils/index.js +29 -29
  248. package/lib/views/datasources/DatasourceDetail.js +3 -3
  249. package/lib/views/datasources/DatasourceNew.js +2 -2
  250. package/lib/views/datasources/Datasources.js +1 -1
  251. package/lib/views/datasources/index.js +3 -3
  252. package/lib/views/iam/SignInSimple.js +1 -1
  253. package/lib/views/iam/index.js +1 -1
  254. package/lib/views/iam-tokens/IAMTokenEdit.js +3 -3
  255. package/lib/views/iam-tokens/IAMTokenNew.js +2 -2
  256. package/lib/views/iam-tokens/IAMTokens.js +1 -1
  257. package/lib/views/iam-tokens/Tokens.js +1 -1
  258. package/lib/views/iam-tokens/index.js +3 -3
  259. package/lib/views/index.js +3 -3
  260. package/lib/views/otel/DashboardView.js +1 -1
  261. package/lib/views/otel/LogsView.js +1 -1
  262. package/lib/views/otel/MetricsView.js +1 -1
  263. package/lib/views/otel/OtelHeader.js +1 -1
  264. package/lib/views/otel/SqlView.js +1 -1
  265. package/lib/views/otel/SystemView.js +1 -1
  266. package/lib/views/otel/TracesView.js +1 -1
  267. package/lib/views/otel/index.js +8 -8
  268. package/lib/views/otel/simpleAuthStore.js +1 -1
  269. package/lib/views/profile/UserBadge.js +1 -1
  270. package/lib/views/profile/index.js +1 -1
  271. package/lib/views/secrets/SecretEdit.js +3 -3
  272. package/lib/views/secrets/SecretNew.js +2 -2
  273. package/lib/views/secrets/Secrets.js +1 -1
  274. package/lib/views/secrets/index.js +3 -3
  275. package/package.json +1 -1
@@ -6,17 +6,19 @@
6
6
  * Spacer mixin for managing workspaces, notebooks, and content.
7
7
  * @module client/mixins/SpacerMixin
8
8
  */
9
- import * as spaces from '../../api/spacer/spaces';
10
- import * as notebooks from '../../api/spacer/notebooks';
11
- import * as users from '../../api/spacer/users';
12
- import * as lexicals from '../../api/spacer/lexicals';
13
- import * as documents from '../../api/spacer/documents';
14
- import * as items from '../../api/spacer/items';
15
- import { NotebookDTO } from '../../models/NotebookDTO';
16
- import { LexicalDTO } from '../../models/LexicalDTO';
17
- import { SpaceDTO } from '../../models/SpaceDTO';
18
- import { HealthCheck } from '../../models/HealthCheck';
19
- import { convertSpaceItemsToModels } from '../utils/spacerUtils';
9
+ import * as spaces from '../../api/spacer/spaces.js';
10
+ import * as notebooks from '../../api/spacer/notebooks.js';
11
+ import * as users from '../../api/spacer/users.js';
12
+ import * as lexicals from '../../api/spacer/lexicals.js';
13
+ import * as documents from '../../api/spacer/documents.js';
14
+ import * as items from '../../api/spacer/items.js';
15
+ import { NotebookDTO } from '../../models/NotebookDTO.js';
16
+ import { LexicalDTO } from '../../models/LexicalDTO.js';
17
+ import { SpaceDTO } from '../../models/SpaceDTO.js';
18
+ import { ProjectDTO } from '../../models/ProjectDTO.js';
19
+ import { HealthCheck } from '../../models/HealthCheck.js';
20
+ import { convertSpaceItemsToModels } from '../utils/spacerUtils.js';
21
+ import { generateHandle } from '../utils/slugify.js';
20
22
  /** Spacer mixin providing workspace and content management. */
21
23
  export function SpacerMixin(Base) {
22
24
  return class extends Base {
@@ -336,5 +338,257 @@ export function SpacerMixin(Base) {
336
338
  }
337
339
  return response.sessionId;
338
340
  }
341
+ // ========================================================================
342
+ // Additional Space Operations
343
+ // ========================================================================
344
+ /**
345
+ * Get a space by UID.
346
+ * @param uid - Space UID
347
+ * @returns Space instance
348
+ */
349
+ async getSpace(uid) {
350
+ const token = this.getToken();
351
+ const spacerRunUrl = this.getSpacerRunUrl();
352
+ const response = await spaces.getSpace(token, uid, spacerRunUrl);
353
+ if (!response.space) {
354
+ throw new Error(`Space with UID '${uid}' not found`);
355
+ }
356
+ return new SpaceDTO(response.space, this);
357
+ }
358
+ /**
359
+ * Update a space (owner updating their own space).
360
+ * @param uid - Space UID
361
+ * @param data - Update data (supports arbitrary Solr fields)
362
+ * @returns Updated Space instance
363
+ */
364
+ async updateSpace(uid, data) {
365
+ const token = this.getToken();
366
+ const spacerRunUrl = this.getSpacerRunUrl();
367
+ const response = await spaces.updateSpace(token, uid, data, spacerRunUrl);
368
+ if (!response.space) {
369
+ throw new Error(`Failed to update space '${uid}'`);
370
+ }
371
+ return new SpaceDTO(response.space, this);
372
+ }
373
+ /**
374
+ * Update a user-specific space (e.g., org admin context).
375
+ * @param uid - Space UID
376
+ * @param userId - User ID
377
+ * @param data - Update data (supports arbitrary Solr fields)
378
+ * @returns Updated Space instance
379
+ */
380
+ async updateUserSpace(uid, userId, data) {
381
+ const token = this.getToken();
382
+ const spacerRunUrl = this.getSpacerRunUrl();
383
+ const response = await spaces.updateUserSpace(token, uid, userId, data, spacerRunUrl);
384
+ if (!response.space) {
385
+ throw new Error(`Failed to update space '${uid}' for user '${userId}'`);
386
+ }
387
+ return new SpaceDTO(response.space, this);
388
+ }
389
+ /**
390
+ * Delete a space and all its contents.
391
+ * @param uid - Space UID
392
+ */
393
+ async deleteSpace(uid) {
394
+ const token = this.getToken();
395
+ const spacerRunUrl = this.getSpacerRunUrl();
396
+ await spaces.deleteSpace(token, uid, spacerRunUrl);
397
+ }
398
+ /**
399
+ * Make a space public.
400
+ * @param uid - Space UID
401
+ * @returns Updated Space instance
402
+ */
403
+ async makeSpacePublic(uid) {
404
+ const token = this.getToken();
405
+ const spacerRunUrl = this.getSpacerRunUrl();
406
+ const response = await spaces.makeSpacePublic(token, uid, spacerRunUrl);
407
+ if (!response.space) {
408
+ throw new Error(`Failed to make space '${uid}' public`);
409
+ }
410
+ return new SpaceDTO(response.space, this);
411
+ }
412
+ /**
413
+ * Make a space private.
414
+ * @param uid - Space UID
415
+ * @returns Updated Space instance
416
+ */
417
+ async makeSpacePrivate(uid) {
418
+ const token = this.getToken();
419
+ const spacerRunUrl = this.getSpacerRunUrl();
420
+ const response = await spaces.makeSpacePrivate(token, uid, spacerRunUrl);
421
+ if (!response.space) {
422
+ throw new Error(`Failed to make space '${uid}' private`);
423
+ }
424
+ return new SpaceDTO(response.space, this);
425
+ }
426
+ /**
427
+ * Export a space and its contents.
428
+ * @param uid - Space UID
429
+ * @returns Export data
430
+ */
431
+ async exportSpace(uid) {
432
+ const token = this.getToken();
433
+ const spacerRunUrl = this.getSpacerRunUrl();
434
+ return spaces.exportSpace(token, uid, spacerRunUrl);
435
+ }
436
+ /**
437
+ * Clone a notebook.
438
+ * @param id - Notebook ID to clone
439
+ * @returns Cloned Notebook instance
440
+ */
441
+ async cloneNotebook(id) {
442
+ const token = this.getToken();
443
+ const spacerRunUrl = this.getSpacerRunUrl();
444
+ const response = await notebooks.cloneNotebook(token, id, spacerRunUrl);
445
+ if (!response.notebook) {
446
+ throw new Error(`Failed to clone notebook '${id}'`);
447
+ }
448
+ return new NotebookDTO(response.notebook, this);
449
+ }
450
+ /**
451
+ * Clone a lexical document.
452
+ * @param id - Document ID to clone
453
+ * @returns Cloned Lexical instance
454
+ */
455
+ async cloneLexical(id) {
456
+ const token = this.getToken();
457
+ const spacerRunUrl = this.getSpacerRunUrl();
458
+ const response = await lexicals.cloneLexical(token, id, spacerRunUrl);
459
+ if (!response.document) {
460
+ throw new Error(`Failed to clone lexical document '${id}'`);
461
+ }
462
+ return new LexicalDTO(response.document, this);
463
+ }
464
+ // ========================================================================
465
+ // Projects
466
+ // ========================================================================
467
+ /**
468
+ * Get all projects for the authenticated user.
469
+ * Projects are spaces with variant='project'.
470
+ * @returns Array of Project instances
471
+ */
472
+ async getProjects() {
473
+ // Use getMySpaces and filter by variant, because the
474
+ // /spaces/types/project endpoint returns empty results.
475
+ const allSpaces = await this.getMySpaces();
476
+ return allSpaces
477
+ .filter(s => s.variant === 'project')
478
+ .map(s => new ProjectDTO(s.rawData()));
479
+ }
480
+ /**
481
+ * Get a project by UID.
482
+ * @param uid - Project UID
483
+ * @returns Project instance
484
+ */
485
+ async getProject(uid) {
486
+ const token = this.getToken();
487
+ const spacerRunUrl = this.getSpacerRunUrl();
488
+ const response = await spaces.getSpace(token, uid, spacerRunUrl);
489
+ if (!response.space) {
490
+ throw new Error(`Project with UID '${uid}' not found`);
491
+ }
492
+ return new ProjectDTO(response.space);
493
+ }
494
+ /**
495
+ * Create a new project.
496
+ * @param name - Project name
497
+ * @param description - Project description
498
+ * @returns Created Project instance
499
+ */
500
+ async createProject(name, description) {
501
+ const token = this.getToken();
502
+ const spacerRunUrl = this.getSpacerRunUrl();
503
+ const spaceHandle = generateHandle(name);
504
+ const data = {
505
+ name,
506
+ description: description || '',
507
+ variant: 'project',
508
+ spaceHandle,
509
+ organizationId: '',
510
+ seedSpaceId: '',
511
+ public: false,
512
+ };
513
+ const response = await spaces.createSpace(token, data, spacerRunUrl);
514
+ if (!response.space) {
515
+ throw new Error('Failed to create project: no project returned');
516
+ }
517
+ return new ProjectDTO(response.space);
518
+ }
519
+ /**
520
+ * Update a project.
521
+ * @param uid - Project UID
522
+ * @param data - Update data (supports arbitrary Solr fields)
523
+ * @returns Updated Project instance
524
+ */
525
+ async updateProject(uid, data) {
526
+ const token = this.getToken();
527
+ const spacerRunUrl = this.getSpacerRunUrl();
528
+ // Resolve userId from: IAM mixin cache > AuthenticationManager cache > whoami()
529
+ let resolvedUserId;
530
+ const iamUser = this.currentUserCache;
531
+ if (iamUser) {
532
+ resolvedUserId = iamUser.uid ?? iamUser.id;
533
+ }
534
+ if (!resolvedUserId) {
535
+ const authUser = this.auth?.getCurrentUser?.();
536
+ if (authUser) {
537
+ resolvedUserId = authUser.uid ?? authUser.id;
538
+ }
539
+ }
540
+ if (!resolvedUserId) {
541
+ try {
542
+ const user = await this.whoami();
543
+ resolvedUserId = user?.uid ?? user?.id;
544
+ }
545
+ catch (_e) {
546
+ // whoami() not available — no user context
547
+ }
548
+ }
549
+ if (!resolvedUserId) {
550
+ throw new Error('Cannot update project: no authenticated user');
551
+ }
552
+ const response = await spaces.updateUserSpace(token, uid, resolvedUserId, data, spacerRunUrl);
553
+ if (response.space) {
554
+ return new ProjectDTO(response.space);
555
+ }
556
+ // Backend returns space: null on success for user-scoped updates.
557
+ // Re-fetch the project to return fresh data.
558
+ const freshResponse = await spaces.getSpace(token, uid, spacerRunUrl);
559
+ if (!freshResponse.space) {
560
+ throw new Error(`Failed to update project '${uid}'`);
561
+ }
562
+ return new ProjectDTO(freshResponse.space);
563
+ }
564
+ /**
565
+ * Rename a project.
566
+ * @param uid - Project UID
567
+ * @param newName - New project name
568
+ * @param description - Project description to preserve.
569
+ * @param userId - Authenticated user ID for user-scoped update.
570
+ * @returns Updated Project instance
571
+ */
572
+ async renameProject(uid, newName, description) {
573
+ const data = { name: newName };
574
+ if (description !== undefined) {
575
+ data.description = description;
576
+ }
577
+ return this.updateProject(uid, data);
578
+ }
579
+ /**
580
+ * Get default items (notebook UID and document UID) for a project.
581
+ * @param uid - Project UID
582
+ * @returns Default notebook and document UIDs
583
+ */
584
+ async getProjectDefaultItems(uid) {
585
+ const token = this.getToken();
586
+ const spacerRunUrl = this.getSpacerRunUrl();
587
+ const response = await spaces.getSpaceDefaultItems(token, uid, spacerRunUrl);
588
+ return {
589
+ defaultNotebookUid: response.default_notebook_uid,
590
+ defaultDocumentUid: response.default_document_uid,
591
+ };
592
+ }
339
593
  };
340
594
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generate a URL-friendly handle from a name.
3
+ *
4
+ * @param name - The name to convert to a handle
5
+ * @param fallbackPrefix - Prefix for the fallback handle if name produces empty result
6
+ * @returns URL-friendly handle string
7
+ */
8
+ export declare function generateHandle(name: string, fallbackPrefix?: string): string;
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Generate a URL-friendly handle from a name.
7
+ *
8
+ * @param name - The name to convert to a handle
9
+ * @param fallbackPrefix - Prefix for the fallback handle if name produces empty result
10
+ * @returns URL-friendly handle string
11
+ */
12
+ export function generateHandle(name, fallbackPrefix = 'project') {
13
+ const handle = name
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9]+/g, '-')
16
+ .replace(/^-|-$/g, '');
17
+ return handle || `${fallbackPrefix}-${Date.now()}`;
18
+ }
@@ -2,9 +2,9 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import { NotebookDTO } from '../../models/NotebookDTO';
6
- import { LexicalDTO } from '../../models/LexicalDTO';
7
- import { ItemTypes } from '../constants';
5
+ import { NotebookDTO } from '../../models/NotebookDTO.js';
6
+ import { LexicalDTO } from '../../models/LexicalDTO.js';
7
+ import { ItemTypes } from '../constants.js';
8
8
  /**
9
9
  * Convert raw space items from API response to model instances.
10
10
  * This utility function is shared between Space.getItems() and SpacerMixin.getSpaceItems()
@@ -13,7 +13,7 @@ export var CollaborationStatus;
13
13
  CollaborationStatus["Connected"] = "connected";
14
14
  CollaborationStatus["Error"] = "error";
15
15
  })(CollaborationStatus || (CollaborationStatus = {}));
16
- import { requestDatalayerCollaborationSessionId } from './DatalayerCollaboration';
16
+ import { requestDatalayerCollaborationSessionId } from './DatalayerCollaboration.js';
17
17
  /**
18
18
  * Datalayer collaboration provider
19
19
  *
@@ -2,5 +2,5 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './DatalayerCollaboration';
6
- export * from './DatalayerCollaborationProvider';
5
+ export * from './DatalayerCollaboration.js';
6
+ export * from './DatalayerCollaborationProvider.js';
@@ -8,12 +8,12 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
8
8
  import { EyeIcon, EyeClosedIcon, MarkGithubIcon } from '@primer/octicons-react';
9
9
  import { Button, FormControl, Heading, Link, PageLayout, TextInput, } from '@primer/react';
10
10
  import { Box } from '@datalayer/primer-addons';
11
- import { asUser, IAMProvidersSpecs } from '../../models';
12
- import { useIAMStore } from '../../state';
13
- import { CenteredSpinner } from '../display';
14
- import { isInsideJupyterLab, validateLength } from '../../utils';
15
- import { useNavigate, useCache, useToast, useIAM } from '../../hooks';
16
- import { LoginToken } from './LoginToken';
11
+ import { asUser, IAMProvidersSpecs } from '../../models/index.js';
12
+ import { useIAMStore } from '../../state/index.js';
13
+ import { CenteredSpinner } from '../display/index.js';
14
+ import { isInsideJupyterLab, validateLength } from '../../utils/index.js';
15
+ import { useNavigate, useCache, useToast, useIAM } from '../../hooks/index.js';
16
+ import { LoginToken } from './LoginToken.js';
17
17
  /** Inline Google "G" icon for the login button. */
18
18
  const GoogleIcon = () => (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 48 48", children: [_jsx("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }), _jsx("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }), _jsx("path", { fill: "#FBBC05", d: "M10.53 28.59a14.5 14.5 0 0 1 0-9.18l-7.98-6.19a24.1 24.1 0 0 0 0 21.56l7.98-6.19z" }), _jsx("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" })] }));
19
19
  export const Login = (props) => {
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { BrowserRouter } from 'react-router-dom';
3
3
  import { QueryClientProvider } from '@tanstack/react-query';
4
- import { queryClient } from '../../utils/cli/query';
5
- import { Login } from './Login';
4
+ import { queryClient } from '../../utils/cli/query.js';
5
+ import { Login } from './Login.js';
6
6
  /**
7
7
  * Login component provides a comprehensive authentication interface with multiple methods:
8
8
  * - Email/password authentication
@@ -8,8 +8,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  import { useState } from 'react';
9
9
  import { Button, FormControl, TextInput } from '@primer/react';
10
10
  import { Box } from '@datalayer/primer-addons';
11
- import { useIAM, useNavigate, useToast } from '../../hooks';
12
- import { useIAMStore } from '../../state';
11
+ import { useIAM, useNavigate, useToast } from '../../hooks/index.js';
12
+ import { useIAMStore } from '../../state/index.js';
13
13
  /**
14
14
  * Component for token-based authentication
15
15
  * Provides a simple button that expands to show a token input form
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Authentication components for Datalayer platform
7
7
  */
8
- export * from './Login';
8
+ export * from './Login.js';
9
9
  // LoginCLI is excluded from build - it's meant for CLI apps with full routing.
10
- // export * from './LoginCLI';
11
- export * from './LoginToken';
10
+ // export * from './LoginCLI.js';
11
+ export * from './LoginToken.js';
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import { BoringAvatar } from './BoringAvatar';
5
+ import { BoringAvatar } from './BoringAvatar.js';
6
6
  const meta = {
7
7
  title: 'Datalayer/BoringAvatar',
8
8
  component: BoringAvatar,
@@ -5,8 +5,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  */
6
6
  import { Avatar, Link } from '@primer/react';
7
7
  import { Box } from '@datalayer/primer-addons';
8
- import { AvatarSkeleton } from '../../components/display';
9
- import { getAvatarURL } from '../../utils';
8
+ import { AvatarSkeleton } from '../../components/display/index.js';
9
+ import { getAvatarURL } from '../../utils/index.js';
10
10
  const Profile = ({ user, size = 100, onClick }) => {
11
11
  return (_jsx(Box, { style: { width: size }, children: _jsx(Avatar
12
12
  // square
@@ -2,5 +2,5 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './BoringAvatar';
6
- export * from './UserProfileAvatar';
5
+ export * from './BoringAvatar.js';
6
+ export * from './UserProfileAvatar.js';
@@ -5,7 +5,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
5
5
  */
6
6
  import { Link } from '@primer/react';
7
7
  import { Banner } from '@primer/react/experimental';
8
- import { useNavigate } from '../../hooks';
8
+ import { useNavigate } from '../../hooks/index.js';
9
9
  export const NoAutomationBanner = () => {
10
10
  const navigate = useNavigate();
11
11
  return (_jsx(_Fragment, { children: _jsx(Banner, { title: "Warning", description: _jsxs(_Fragment, { children: ["We don't have bandwidth to automate this feature.", ' ', _jsx(Link, { href: "", onClick: e => navigate('/contact', e), children: "Please reach out" }), ' ', "to prioritize this."] }), primaryAction: _jsx(Banner.PrimaryAction, { onClick: e => navigate('/contact', e), children: "Reach out" }), variant: "warning" }) }));
@@ -2,4 +2,4 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './NoAutomationBanner';
5
+ export * from './NoAutomationBanner.js';
@@ -5,7 +5,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  */
6
6
  import { Button } from '@primer/react';
7
7
  import { DownloadIcon } from '@primer/octicons-react';
8
- import { downloadCSV } from '../../utils';
8
+ import { downloadCSV } from '../../utils/index.js';
9
9
  export const DownloadCSVButton = ({ data, fileName, variant = 'default', }) => {
10
10
  return (_jsx(Button, { variant: variant, leadingVisual: DownloadIcon, onClick: e => downloadCSV(data, fileName), children: "Download" }));
11
11
  };
@@ -5,7 +5,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  */
6
6
  import { Button } from '@primer/react';
7
7
  import { DownloadIcon } from '@primer/octicons-react';
8
- import { downloadJson } from '../../utils';
8
+ import { downloadJson } from '../../utils/index.js';
9
9
  export const DownloadJsonButton = ({ data, fileName, variant = 'default', extension = 'json', }) => {
10
10
  return (_jsx(Button, { variant: variant, leadingVisual: DownloadIcon, onClick: e => downloadJson(data, fileName, extension), children: "Download" }));
11
11
  };
@@ -2,8 +2,8 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './DownloadCSVButton';
6
- export * from './DownloadJsonButton';
7
- export * from './LongActionButton';
8
- export * from './UploadButton';
9
- export * from './VariantType';
5
+ export * from './DownloadCSVButton.js';
6
+ export * from './DownloadJsonButton.js';
7
+ export * from './LongActionButton.js';
8
+ export * from './UploadButton.js';
9
+ export * from './VariantType.js';
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  import { createElement, useCallback, useEffect, useState } from 'react';
7
7
  import { Button, Flash, FormControl, Spinner, Text } from '@primer/react';
8
8
  import { Box } from '@datalayer/primer-addons';
9
- import { useCache } from '../../hooks';
9
+ import { useCache } from '../../hooks/index.js';
10
10
  /**
11
11
  * Stripe checkout.
12
12
  */
@@ -2,4 +2,4 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './StripeCheckout';
5
+ export * from './StripeCheckout.js';
@@ -2,4 +2,4 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './ConfettiSuccess';
5
+ export * from './ConfettiSuccess.js';
@@ -5,8 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
5
5
  */
6
6
  import { useCallback, useEffect } from 'react';
7
7
  import { Select } from '@primer/react';
8
- import { useCache, useUser } from './../../hooks';
9
- import { useLayoutStore } from '../../state';
8
+ import { useCache, useUser } from './../../hooks/index.js';
9
+ import { useLayoutStore } from '../../state/index.js';
10
10
  const NO_ORGANIZATION_SELECTED_VALUE = 'NO_ORGANIZATION_SELECTED_VALUE';
11
11
  export const OrganizationSelect = () => {
12
12
  const user = useUser();
@@ -6,8 +6,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  import { useCallback, useEffect } from 'react';
7
7
  import { FormControl, Select } from '@primer/react';
8
8
  import { Box } from '@datalayer/primer-addons';
9
- import { useCache, useUser } from './../../hooks';
10
- import { useLayoutStore } from '../../state';
9
+ import { useCache, useUser } from './../../hooks/index.js';
10
+ import { useLayoutStore } from '../../state/index.js';
11
11
  export const SpaceSelect = () => {
12
12
  const user = useUser();
13
13
  const { organization, space, updateLayoutSpace } = useLayoutStore();
@@ -2,5 +2,5 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './OrganizationSelect';
6
- export * from './SpaceSelect';
5
+ export * from './OrganizationSelect.js';
6
+ export * from './SpaceSelect.js';
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  import { Link, Text } from '@primer/react';
7
7
  import { Box } from '@datalayer/primer-addons';
8
8
  import { ArrowRightIcon } from '@primer/octicons-react';
9
- import { useNavigate } from '../../hooks';
9
+ import { useNavigate } from '../../hooks/index.js';
10
10
  export const DatalayerBox = (props) => {
11
11
  const { title, linkLabel, linkRoute, children } = props;
12
12
  const navigate = useNavigate();
@@ -4,7 +4,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import { useEffect, useMemo, useState } from 'react';
7
- import { formatRelativeTime } from '../../utils';
7
+ import { formatRelativeTime } from '../../utils/index.js';
8
8
  /**
9
9
  * Display a live-updating relative time label (e.g. "5m ago").
10
10
  */
@@ -4,7 +4,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import { forwardRef, useCallback } from 'react';
7
- import { useNavigate } from '../../hooks';
7
+ import { useNavigate } from '../../hooks/index.js';
8
8
  /**
9
9
  * Navigation link for primer NavList
10
10
  * Works with React Router, Next.js, or native browser navigation
@@ -2,17 +2,17 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './AvatarSkeleton';
6
- export * from './CenteredSpinner';
7
- export * from './CodePreview';
8
- export * from './DatalayerBox';
9
- export * from './HorizontalCenter';
10
- export * from './JupyterDialog';
11
- export * from './LiveRelativeTime';
12
- export * from './Markdown';
13
- export * from './NavLink';
14
- export * from './NotebookSkeleton';
15
- export * from './BusyDots';
16
- export * from './Placeholder';
17
- export * from './ToTopBranded';
18
- export * from './VisuallyHidden';
5
+ export * from './AvatarSkeleton.js';
6
+ export * from './CenteredSpinner.js';
7
+ export * from './CodePreview.js';
8
+ export * from './DatalayerBox.js';
9
+ export * from './HorizontalCenter.js';
10
+ export * from './JupyterDialog.js';
11
+ export * from './LiveRelativeTime.js';
12
+ export * from './Markdown.js';
13
+ export * from './NavLink.js';
14
+ export * from './NotebookSkeleton.js';
15
+ export * from './BusyDots.js';
16
+ export * from './Placeholder.js';
17
+ export * from './ToTopBranded.js';
18
+ export * from './VisuallyHidden.js';
@@ -2,4 +2,4 @@
2
2
  * Copyright (c) 2023-2025 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './EChartsReact';
5
+ export * from './EChartsReact.js';
@@ -6,8 +6,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  import { Label, Link } from '@primer/react';
7
7
  import { Box } from '@datalayer/primer-addons';
8
8
  import { Banner } from '@primer/react/experimental';
9
- import { useCoreStore, useRuntimesStore } from '../../state';
10
- import { useNavigate } from '../../hooks';
9
+ import { useCoreStore, useRuntimesStore } from '../../state/index.js';
10
+ import { useNavigate } from '../../hooks/index.js';
11
11
  export const FlashDisclaimer = () => {
12
12
  const { configuration } = useCoreStore();
13
13
  const { showDisclaimer, setShowDisclaimer } = useRuntimesStore();