@granular-software/sdk 0.4.52 → 0.4.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -14431,6 +14431,7 @@ var Environment = class _Environment {
14431
14431
  import: async (records, options) => this.enqueueRecordImport(records, options),
14432
14432
  listImports: async (status) => this.listRecordImports(status),
14433
14433
  getImport: async (importId) => this.getRecordImport(importId),
14434
+ listImportItems: async (importId, status) => this.listRecordImportItems(importId, status),
14434
14435
  getImportSummary: async () => this.getRecordImportSummary(),
14435
14436
  cancelImport: async (importId) => this.cancelRecordImport(importId),
14436
14437
  getAwaitingCount: async () => this.getAwaitingRecordCount()
@@ -15609,6 +15610,15 @@ var Environment = class _Environment {
15609
15610
  `/control/record-imports/${importId}`
15610
15611
  );
15611
15612
  }
15613
+ /**
15614
+ * List the individual records persisted for one asynchronous import. This
15615
+ * makes terminal import failures diagnosable without database access.
15616
+ */
15617
+ async listRecordImportItems(importId, status) {
15618
+ const suffix = status ? `?status=${encodeURIComponent(status)}` : "";
15619
+ const response = await this.controlPlaneRequest(`/control/record-imports/${importId}/items${suffix}`);
15620
+ return Array.isArray(response.items) ? response.items : [];
15621
+ }
15612
15622
  /**
15613
15623
  * Cancel a queued/background record import.
15614
15624
  */
@@ -16425,6 +16435,55 @@ var Granular = class _Granular {
16425
16435
  throw error;
16426
16436
  }
16427
16437
  }
16438
+ /**
16439
+ * Resolve one exact environment only when Granular confirms that it belongs
16440
+ * to the given external user in the requested sandbox (and, optionally,
16441
+ * tag). This is deliberately read-only: callers use it to keep an already
16442
+ * opened delegated workspace stable while a newer active environment is
16443
+ * being prepared in the background.
16444
+ */
16445
+ async getEnvironmentForUser(options) {
16446
+ const sandboxId = options.sandboxId.trim();
16447
+ const userId = options.userId.trim();
16448
+ const environmentId = options.environmentId.trim();
16449
+ const tagName = options.tag?.trim();
16450
+ if (!sandboxId || !userId || !environmentId) {
16451
+ throw new Error(
16452
+ "getEnvironmentForUser() requires sandboxId, userId, and environmentId."
16453
+ );
16454
+ }
16455
+ const subjects = await this.request(
16456
+ `/control/subjects?identityId=${encodeURIComponent(userId)}`
16457
+ );
16458
+ const subject = (subjects.items || []).find(
16459
+ (item) => item.identityId === userId || item.userId === userId
16460
+ );
16461
+ const subjectId = subject?.subjectId || subject?.granularId;
16462
+ if (!subjectId) return null;
16463
+ let environment;
16464
+ try {
16465
+ environment = await this.environments.get(environmentId);
16466
+ } catch (error) {
16467
+ const message = error instanceof Error ? error.message : String(error);
16468
+ if (message.includes("404") || message.includes("not found")) {
16469
+ return null;
16470
+ }
16471
+ throw error;
16472
+ }
16473
+ if (environment.sandboxId !== sandboxId || environment.subjectId !== subjectId) {
16474
+ return null;
16475
+ }
16476
+ if (tagName) {
16477
+ const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
16478
+ const tag = (tags.items || []).find(
16479
+ (candidate) => candidate?.name === tagName
16480
+ );
16481
+ if (!tag || environment.tagId !== tag.tagId) {
16482
+ return null;
16483
+ }
16484
+ }
16485
+ return this.bindEnvironmentHandle(environment);
16486
+ }
16428
16487
  /**
16429
16488
  * Register one reviewed, pre-existing environment as the active workspace
16430
16489
  * for an external user. This is for a controlled migration only: it does