@relyio/sdk 0.4.0 → 0.5.0

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.
@@ -768,6 +768,7 @@ var DECLARED_PATHS = {
768
768
  "/v1/meta/schema": true,
769
769
  "/v1/meta/schema/{contentType}": true,
770
770
  "/v1/meta/schema/{contentType}/fields": true,
771
+ "/v1/project": true,
771
772
  "/v1/query": true,
772
773
  "/v1/search": true,
773
774
  "/v1/search/autocomplete": true,
@@ -4176,6 +4177,10 @@ function aborted(signal) {
4176
4177
  __name(aborted, "aborted");
4177
4178
 
4178
4179
  // src/config/dev-detection.ts
4180
+ function sandboxStateOf(resolution) {
4181
+ return resolution.state === "active" ? resolution.sandbox : resolution;
4182
+ }
4183
+ __name(sandboxStateOf, "sandboxStateOf");
4179
4184
  function getProcess() {
4180
4185
  return typeof process !== "undefined" ? process : void 0;
4181
4186
  }
@@ -4199,11 +4204,14 @@ function resolveFromEnv(proc, now) {
4199
4204
  case "active":
4200
4205
  return {
4201
4206
  state: "active",
4202
- override: {
4203
- dataset: verdict.credentials.dataset,
4204
- apiKey: verdict.credentials.apiKey,
4207
+ sandbox: {
4208
+ state: "active",
4209
+ datasetId: verdict.credentials.dataset,
4210
+ branchId: null,
4211
+ expiresAt: verdict.expiresAt,
4205
4212
  source: "env"
4206
- }
4213
+ },
4214
+ apiKey: verdict.credentials.apiKey
4207
4215
  };
4208
4216
  case "expired":
4209
4217
  return { state: "expired", expiredAt: verdict.expiredAt };
@@ -4234,11 +4242,14 @@ function resolveFromFile(proc, now) {
4234
4242
  case "active":
4235
4243
  return {
4236
4244
  state: "active",
4237
- override: {
4238
- dataset: verdict.context.datasetId,
4239
- apiKey: verdict.context.previewApiKey,
4245
+ sandbox: {
4246
+ state: "active",
4247
+ datasetId: verdict.context.datasetId,
4248
+ branchId: verdict.context.branchId,
4249
+ expiresAt: verdict.context.expiresAt,
4240
4250
  source: "file"
4241
- }
4251
+ },
4252
+ apiKey: verdict.context.previewApiKey
4242
4253
  };
4243
4254
  case "expired":
4244
4255
  return { state: "expired", expiredAt: verdict.expiredAt };
@@ -4319,7 +4330,7 @@ function validateConfig(config) {
4319
4330
  }
4320
4331
  __name(validateConfig, "validateConfig");
4321
4332
  var devOverrideNotified = false;
4322
- function mergeConfig(userConfig) {
4333
+ function resolveConfig(userConfig) {
4323
4334
  validateConfig(userConfig);
4324
4335
  const merged = {
4325
4336
  ...DEFAULT_CONFIG,
@@ -4347,12 +4358,12 @@ function mergeConfig(userConfig) {
4347
4358
  };
4348
4359
  const dev = resolveDevOverride(userConfig.dev);
4349
4360
  if (dev.state === "active") {
4350
- merged.apiKey = dev.override.apiKey;
4351
- merged.dataset = dev.override.dataset;
4361
+ merged.apiKey = dev.apiKey;
4362
+ merged.dataset = dev.sandbox.datasetId;
4352
4363
  if (!devOverrideNotified) {
4353
4364
  devOverrideNotified = true;
4354
4365
  console.info(
4355
- `[RelyIO] Sandbox dev mode active (${dev.override.source}) \u2014 targeting dataset "${dev.override.dataset}" with a scoped preview key.`
4366
+ `[RelyIO] Sandbox dev mode active (${dev.sandbox.source}) \u2014 targeting dataset "${dev.sandbox.datasetId}" with a scoped preview key.`
4356
4367
  );
4357
4368
  }
4358
4369
  } else if (dev.state === "expired" && !devOverrideNotified) {
@@ -4366,9 +4377,9 @@ function mergeConfig(userConfig) {
4366
4377
  `[RelyIO] Your .relyio/dev.json could not be read (${dev.reason}) \u2014 ignoring it and using the configured dataset "${merged.dataset}". Run \`relyio dev\` to rewrite it.`
4367
4378
  );
4368
4379
  }
4369
- return merged;
4380
+ return { config: merged, sandbox: sandboxStateOf(dev) };
4370
4381
  }
4371
- __name(mergeConfig, "mergeConfig");
4382
+ __name(resolveConfig, "resolveConfig");
4372
4383
 
4373
4384
  // src/client/create-client.ts
4374
4385
  var API_VERSION_SEGMENT = "v1";
@@ -4376,13 +4387,16 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4376
4387
  constructor(config) {
4377
4388
  __publicField(this, "httpClient");
4378
4389
  __publicField(this, "config");
4390
+ __publicField(this, "_sandbox");
4379
4391
  __publicField(this, "_search");
4380
4392
  __publicField(this, "_batch");
4381
4393
  __publicField(this, "_adhocQuery");
4382
4394
  __publicField(this, "_schema");
4383
4395
  const { schema, ...clientConfig } = config;
4384
4396
  this._schema = schema;
4385
- this.config = mergeConfig(clientConfig);
4397
+ const resolved = resolveConfig(clientConfig);
4398
+ this.config = resolved.config;
4399
+ this._sandbox = resolved.sandbox;
4386
4400
  this.httpClient = new HttpClient(this.config);
4387
4401
  this._search = new SearchClient(this.httpClient);
4388
4402
  this._batch = new BatchClient(this.httpClient);
@@ -4397,6 +4411,23 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4397
4411
  get schema() {
4398
4412
  return this._schema;
4399
4413
  }
4414
+ /**
4415
+ * The `relyio dev` sandbox this client resolved at construction, as the preview toolbar displays
4416
+ * it (`sdk-surfaces-spec.md` decision 22).
4417
+ *
4418
+ * Plain, JSON-serializable data and no key, so a server component can hand it to a client
4419
+ * component as a prop — the browser cannot read the handshake itself, so a client created there
4420
+ * reports `absent`. See {@link SandboxState} for what each state means.
4421
+ *
4422
+ * @example
4423
+ * ```tsx
4424
+ * // app/layout.tsx — a server component handing the state to a client component
4425
+ * <SandboxBadge sandbox={relyio.sandbox} />
4426
+ * ```
4427
+ */
4428
+ get sandbox() {
4429
+ return this._sandbox;
4430
+ }
4400
4431
  /**
4401
4432
  * Get the ad-hoc query client
4402
4433
  */
@@ -4620,6 +4651,23 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4620
4651
  const payload = readPayload(response.body);
4621
4652
  return Array.isArray(payload) ? payload : [payload];
4622
4653
  }
4654
+ /**
4655
+ * Describe the project this key resolves to — `GET /v1/project`.
4656
+ *
4657
+ * `dataset` is the one this client's requests select (`dataset`, a sandbox from the `relyio dev`
4658
+ * handshake, or the key's default), which is not always the project's default, so a Studio link
4659
+ * built from `studioUrl` should carry it as `?dataset=`. `studioUrl` is `null` — a value, not an
4660
+ * error — when the service has no Dashboard address configured.
4661
+ *
4662
+ * @example
4663
+ * ```typescript
4664
+ * const { studioUrl, dataset } = await relyio.project()
4665
+ * if (studioUrl !== null) window.open(`${studioUrl}?dataset=${dataset.id}`)
4666
+ * ```
4667
+ */
4668
+ async project() {
4669
+ return this.httpClient.fetchPayload("/v1/project", "get", {});
4670
+ }
4623
4671
  /**
4624
4672
  * Get schema information from the API
4625
4673
  */
@@ -4666,7 +4714,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4666
4714
  * Update the configuration and reinitialize all clients
4667
4715
  */
4668
4716
  updateConfig(newConfig) {
4669
- this.config = mergeConfig({ ...this.config, ...newConfig });
4717
+ const resolved = resolveConfig({ ...this.config, ...newConfig });
4718
+ this.config = resolved.config;
4719
+ this._sandbox = resolved.sandbox;
4670
4720
  this.httpClient = new HttpClient(this.config);
4671
4721
  this._search = new SearchClient(this.httpClient);
4672
4722
  this._batch = new BatchClient(this.httpClient);
@@ -4764,5 +4814,5 @@ function createClient(config) {
4764
4814
  __name(createClient, "createClient");
4765
4815
 
4766
4816
  export { AdhocQueryBuilder, AdhocQueryClient, AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthenticationError, AuthorizationError, AutocompleteBuilder, BaseValidationError, BatchBuilder, BatchClient, ChangesExpiredError, ConnectionError, ContentByIdBuilder, ContentClient, ContentQueryBuilder, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidFieldTypeError, InvalidPayloadError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, RequiredFieldError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, SchemaValidationError, SearchBuilder, SearchClient, ServerError, ServiceIndeterminateError, SettingsClient, SimilarBuilder, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, entityTagOf, isAssetEntry, isResourceNotFound, matchRoute, validateFile };
4767
- //# sourceMappingURL=chunk-43VPZT2G.js.map
4768
- //# sourceMappingURL=chunk-43VPZT2G.js.map
4817
+ //# sourceMappingURL=chunk-5AZUUV5B.js.map
4818
+ //# sourceMappingURL=chunk-5AZUUV5B.js.map
@@ -770,6 +770,7 @@ var DECLARED_PATHS = {
770
770
  "/v1/meta/schema": true,
771
771
  "/v1/meta/schema/{contentType}": true,
772
772
  "/v1/meta/schema/{contentType}/fields": true,
773
+ "/v1/project": true,
773
774
  "/v1/query": true,
774
775
  "/v1/search": true,
775
776
  "/v1/search/autocomplete": true,
@@ -4178,6 +4179,10 @@ function aborted(signal) {
4178
4179
  chunkMWMSFIWN_cjs.__name(aborted, "aborted");
4179
4180
 
4180
4181
  // src/config/dev-detection.ts
4182
+ function sandboxStateOf(resolution) {
4183
+ return resolution.state === "active" ? resolution.sandbox : resolution;
4184
+ }
4185
+ chunkMWMSFIWN_cjs.__name(sandboxStateOf, "sandboxStateOf");
4181
4186
  function getProcess() {
4182
4187
  return typeof process !== "undefined" ? process : void 0;
4183
4188
  }
@@ -4201,11 +4206,14 @@ function resolveFromEnv(proc, now) {
4201
4206
  case "active":
4202
4207
  return {
4203
4208
  state: "active",
4204
- override: {
4205
- dataset: verdict.credentials.dataset,
4206
- apiKey: verdict.credentials.apiKey,
4209
+ sandbox: {
4210
+ state: "active",
4211
+ datasetId: verdict.credentials.dataset,
4212
+ branchId: null,
4213
+ expiresAt: verdict.expiresAt,
4207
4214
  source: "env"
4208
- }
4215
+ },
4216
+ apiKey: verdict.credentials.apiKey
4209
4217
  };
4210
4218
  case "expired":
4211
4219
  return { state: "expired", expiredAt: verdict.expiredAt };
@@ -4236,11 +4244,14 @@ function resolveFromFile(proc, now) {
4236
4244
  case "active":
4237
4245
  return {
4238
4246
  state: "active",
4239
- override: {
4240
- dataset: verdict.context.datasetId,
4241
- apiKey: verdict.context.previewApiKey,
4247
+ sandbox: {
4248
+ state: "active",
4249
+ datasetId: verdict.context.datasetId,
4250
+ branchId: verdict.context.branchId,
4251
+ expiresAt: verdict.context.expiresAt,
4242
4252
  source: "file"
4243
- }
4253
+ },
4254
+ apiKey: verdict.context.previewApiKey
4244
4255
  };
4245
4256
  case "expired":
4246
4257
  return { state: "expired", expiredAt: verdict.expiredAt };
@@ -4321,7 +4332,7 @@ function validateConfig(config) {
4321
4332
  }
4322
4333
  chunkMWMSFIWN_cjs.__name(validateConfig, "validateConfig");
4323
4334
  var devOverrideNotified = false;
4324
- function mergeConfig(userConfig) {
4335
+ function resolveConfig(userConfig) {
4325
4336
  validateConfig(userConfig);
4326
4337
  const merged = {
4327
4338
  ...DEFAULT_CONFIG,
@@ -4349,12 +4360,12 @@ function mergeConfig(userConfig) {
4349
4360
  };
4350
4361
  const dev = resolveDevOverride(userConfig.dev);
4351
4362
  if (dev.state === "active") {
4352
- merged.apiKey = dev.override.apiKey;
4353
- merged.dataset = dev.override.dataset;
4363
+ merged.apiKey = dev.apiKey;
4364
+ merged.dataset = dev.sandbox.datasetId;
4354
4365
  if (!devOverrideNotified) {
4355
4366
  devOverrideNotified = true;
4356
4367
  console.info(
4357
- `[RelyIO] Sandbox dev mode active (${dev.override.source}) \u2014 targeting dataset "${dev.override.dataset}" with a scoped preview key.`
4368
+ `[RelyIO] Sandbox dev mode active (${dev.sandbox.source}) \u2014 targeting dataset "${dev.sandbox.datasetId}" with a scoped preview key.`
4358
4369
  );
4359
4370
  }
4360
4371
  } else if (dev.state === "expired" && !devOverrideNotified) {
@@ -4368,9 +4379,9 @@ function mergeConfig(userConfig) {
4368
4379
  `[RelyIO] Your .relyio/dev.json could not be read (${dev.reason}) \u2014 ignoring it and using the configured dataset "${merged.dataset}". Run \`relyio dev\` to rewrite it.`
4369
4380
  );
4370
4381
  }
4371
- return merged;
4382
+ return { config: merged, sandbox: sandboxStateOf(dev) };
4372
4383
  }
4373
- chunkMWMSFIWN_cjs.__name(mergeConfig, "mergeConfig");
4384
+ chunkMWMSFIWN_cjs.__name(resolveConfig, "resolveConfig");
4374
4385
 
4375
4386
  // src/client/create-client.ts
4376
4387
  var API_VERSION_SEGMENT = "v1";
@@ -4378,13 +4389,16 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4378
4389
  constructor(config) {
4379
4390
  chunkMWMSFIWN_cjs.__publicField(this, "httpClient");
4380
4391
  chunkMWMSFIWN_cjs.__publicField(this, "config");
4392
+ chunkMWMSFIWN_cjs.__publicField(this, "_sandbox");
4381
4393
  chunkMWMSFIWN_cjs.__publicField(this, "_search");
4382
4394
  chunkMWMSFIWN_cjs.__publicField(this, "_batch");
4383
4395
  chunkMWMSFIWN_cjs.__publicField(this, "_adhocQuery");
4384
4396
  chunkMWMSFIWN_cjs.__publicField(this, "_schema");
4385
4397
  const { schema, ...clientConfig } = config;
4386
4398
  this._schema = schema;
4387
- this.config = mergeConfig(clientConfig);
4399
+ const resolved = resolveConfig(clientConfig);
4400
+ this.config = resolved.config;
4401
+ this._sandbox = resolved.sandbox;
4388
4402
  this.httpClient = new HttpClient(this.config);
4389
4403
  this._search = new SearchClient(this.httpClient);
4390
4404
  this._batch = new BatchClient(this.httpClient);
@@ -4399,6 +4413,23 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4399
4413
  get schema() {
4400
4414
  return this._schema;
4401
4415
  }
4416
+ /**
4417
+ * The `relyio dev` sandbox this client resolved at construction, as the preview toolbar displays
4418
+ * it (`sdk-surfaces-spec.md` decision 22).
4419
+ *
4420
+ * Plain, JSON-serializable data and no key, so a server component can hand it to a client
4421
+ * component as a prop — the browser cannot read the handshake itself, so a client created there
4422
+ * reports `absent`. See {@link SandboxState} for what each state means.
4423
+ *
4424
+ * @example
4425
+ * ```tsx
4426
+ * // app/layout.tsx — a server component handing the state to a client component
4427
+ * <SandboxBadge sandbox={relyio.sandbox} />
4428
+ * ```
4429
+ */
4430
+ get sandbox() {
4431
+ return this._sandbox;
4432
+ }
4402
4433
  /**
4403
4434
  * Get the ad-hoc query client
4404
4435
  */
@@ -4622,6 +4653,23 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4622
4653
  const payload = readPayload(response.body);
4623
4654
  return Array.isArray(payload) ? payload : [payload];
4624
4655
  }
4656
+ /**
4657
+ * Describe the project this key resolves to — `GET /v1/project`.
4658
+ *
4659
+ * `dataset` is the one this client's requests select (`dataset`, a sandbox from the `relyio dev`
4660
+ * handshake, or the key's default), which is not always the project's default, so a Studio link
4661
+ * built from `studioUrl` should carry it as `?dataset=`. `studioUrl` is `null` — a value, not an
4662
+ * error — when the service has no Dashboard address configured.
4663
+ *
4664
+ * @example
4665
+ * ```typescript
4666
+ * const { studioUrl, dataset } = await relyio.project()
4667
+ * if (studioUrl !== null) window.open(`${studioUrl}?dataset=${dataset.id}`)
4668
+ * ```
4669
+ */
4670
+ async project() {
4671
+ return this.httpClient.fetchPayload("/v1/project", "get", {});
4672
+ }
4625
4673
  /**
4626
4674
  * Get schema information from the API
4627
4675
  */
@@ -4668,7 +4716,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
4668
4716
  * Update the configuration and reinitialize all clients
4669
4717
  */
4670
4718
  updateConfig(newConfig) {
4671
- this.config = mergeConfig({ ...this.config, ...newConfig });
4719
+ const resolved = resolveConfig({ ...this.config, ...newConfig });
4720
+ this.config = resolved.config;
4721
+ this._sandbox = resolved.sandbox;
4672
4722
  this.httpClient = new HttpClient(this.config);
4673
4723
  this._search = new SearchClient(this.httpClient);
4674
4724
  this._batch = new BatchClient(this.httpClient);
@@ -4820,5 +4870,5 @@ exports.isAssetEntry = isAssetEntry;
4820
4870
  exports.isResourceNotFound = isResourceNotFound;
4821
4871
  exports.matchRoute = matchRoute;
4822
4872
  exports.validateFile = validateFile;
4823
- //# sourceMappingURL=chunk-XS32U2UP.cjs.map
4824
- //# sourceMappingURL=chunk-XS32U2UP.cjs.map
4873
+ //# sourceMappingURL=chunk-CIRT6TVT.cjs.map
4874
+ //# sourceMappingURL=chunk-CIRT6TVT.cjs.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkXS32U2UP_cjs = require('../chunk-XS32U2UP.cjs');
3
+ var chunkCIRT6TVT_cjs = require('../chunk-CIRT6TVT.cjs');
4
4
  require('../chunk-LSRPMNPT.cjs');
5
5
  require('../chunk-MWMSFIWN.cjs');
6
6
 
@@ -8,11 +8,11 @@ require('../chunk-MWMSFIWN.cjs');
8
8
 
9
9
  Object.defineProperty(exports, "TypedRelyIOClient", {
10
10
  enumerable: true,
11
- get: function () { return chunkXS32U2UP_cjs.TypedRelyIOClient; }
11
+ get: function () { return chunkCIRT6TVT_cjs.TypedRelyIOClient; }
12
12
  });
13
13
  Object.defineProperty(exports, "createClient", {
14
14
  enumerable: true,
15
- get: function () { return chunkXS32U2UP_cjs.createClient; }
15
+ get: function () { return chunkCIRT6TVT_cjs.createClient; }
16
16
  });
17
17
  //# sourceMappingURL=index.cjs.map
18
18
  //# sourceMappingURL=index.cjs.map
@@ -1,4 +1,5 @@
1
- export { C as ClientSchema, R as Register, b as RegisteredSchema, a as TypedClientConfig, T as TypedRelyIOClient, c as createClient } from '../index-BvO6HDtY.cjs';
2
- import '../index-DFehx5sI.cjs';
1
+ export { b as ClientSchema, R as Register, d as RegisteredSchema, a as TypedClientConfig, T as TypedRelyIOClient, c as createClient } from '../index-BozPz4n1.cjs';
2
+ import '../index-C5mRBb6t.cjs';
3
3
  import '../define-content-type-CBfnTWSS.cjs';
4
4
  import '../define-schema-2xbHgtK-.cjs';
5
+ import '../dev-handshake/index.cjs';
@@ -1,4 +1,5 @@
1
- export { C as ClientSchema, R as Register, b as RegisteredSchema, a as TypedClientConfig, T as TypedRelyIOClient, c as createClient } from '../index-BzOFJJKS.js';
2
- import '../index-FDak5ofk.js';
1
+ export { b as ClientSchema, R as Register, d as RegisteredSchema, a as TypedClientConfig, T as TypedRelyIOClient, c as createClient } from '../index-Dzo-upNS.js';
2
+ import '../index-mXUx2H99.js';
3
3
  import '../define-content-type-CBfnTWSS.js';
4
4
  import '../define-schema-DzYXk4HL.js';
5
+ import '../dev-handshake/index.js';
@@ -1,4 +1,4 @@
1
- export { TypedRelyIOClient, createClient } from '../chunk-43VPZT2G.js';
1
+ export { TypedRelyIOClient, createClient } from '../chunk-5AZUUV5B.js';
2
2
  import '../chunk-BBUB7C2Z.js';
3
3
  import '../chunk-XQ4QHWZE.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,69 @@
1
- import { J as MergedRelyIOConfig, A as ApiPath, a as ApiMethod, K as PathParamsOf, t as ApiResponse, W as Wire, s as RequestConfig, B as BaseContent, d as WhereClause, f as SortOptions, g as ContentQueryResult, Q as QueryOptions, C as CreateInput, U as UpdateInput, S as SDKError, x as BaseValidationError, w as ValidationViolation, N as components, O as paths, R as RelyIOConfig } from './index-DFehx5sI.cjs';
1
+ import { J as MergedRelyIOConfig, A as ApiPath, a as ApiMethod, K as PathParamsOf, t as ApiResponse, W as Wire, s as RequestConfig, B as BaseContent, d as WhereClause, f as SortOptions, g as ContentQueryResult, Q as QueryOptions, C as CreateInput, U as UpdateInput, S as SDKError, x as BaseValidationError, w as ValidationViolation, N as components, O as paths, R as RelyIOConfig } from './index-C5mRBb6t.cjs';
2
2
  import { a as SchemaDefinition, b as SchemaContentTypeNames, h as SchemaAssetTypeNames, M as InferAssetType, c as SchemaSingletonNames, t as InferSingleton, g as SchemaSettingsGroupNames, E as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-2xbHgtK-.cjs';
3
3
  import { J as InferContentType } from './define-content-type-CBfnTWSS.cjs';
4
+ import { DevUnreadableReason } from './dev-handshake/index.cjs';
5
+
6
+ /**
7
+ * Dev-mode detection for `relyio dev` sandboxes — the SDK's I/O shell over `../dev-handshake`.
8
+ *
9
+ * Every rule about the handshake — the path, the env names, the required fields, the deadline —
10
+ * lives in `@relyio/sdk/dev-handshake`, which `relyio dev` imports too. What is left here is the
11
+ * part that is genuinely the SDK's: reading env and walking the filesystem from the cwd, both of
12
+ * which have to happen without a static `node:*` import so the module stays browser-safe.
13
+ *
14
+ * Node access goes through `process.getBuiltinModule` (Node ≥ 20.16 / 22, and the platform targets
15
+ * Node 24), which is absent in browsers and edge runtimes — so the resolver is inert everywhere it
16
+ * should be, and a bundler never has to shim `fs`.
17
+ *
18
+ * **Order: env, then file.** The wrapped-child env is the primary carrier and wins. Before REL-647
19
+ * it won *unconditionally*, because it had no deadline to lose on; it now goes through the same
20
+ * rule the file does.
21
+ */
22
+
23
+ /**
24
+ * What the handshake says about the sandbox, as the preview toolbar displays it
25
+ * (`sdk-surfaces-spec.md` decision 22). `TypedRelyIOClient.sandbox` returns it.
26
+ *
27
+ * **Plain data, on purpose.** In Next the toolbar is rendered from a server layout, and a client
28
+ * cannot cross the RSC boundary — while the browser cannot read the handshake at all, because this
29
+ * module is inert without `process.getBuiltinModule`. So the server-created client's `sandbox` is the
30
+ * prop the toolbar is handed, and it has to survive `JSON` unchanged: strings and `null`, dates as
31
+ * the ISO strings the handshake carried, no class instances.
32
+ *
33
+ * **No key.** The handshake also carries the sandbox's preview key; that is the client's credential,
34
+ * held beside this value in {@link DevResolution} and never inside it, so handing the state around
35
+ * does not hand the key with it.
36
+ *
37
+ * - `active` — the client targets the sandbox. `branchId` is `null` from the env carrier, which names
38
+ * no branch; only `.relyio/dev.json` does. `expiresAt` is `null` for an unbounded sandbox.
39
+ * - `expired` / `unreadable` — a handshake was found and refused; the client targets the configured
40
+ * dataset and key, and `mergeConfig` has said so on the console.
41
+ * - `absent` — no handshake on either carrier. This is also what a browser or edge runtime reads,
42
+ * since neither can see the env or the file.
43
+ * - `disabled` — detection did not run: `dev: false` was passed, or `NODE_ENV === 'production'`
44
+ * and `dev: true` was not.
45
+ */
46
+ type SandboxState = {
47
+ state: 'active';
48
+ datasetId: string;
49
+ branchId: string | null;
50
+ expiresAt: string | null;
51
+ source: 'env' | 'file';
52
+ } | {
53
+ state: 'expired';
54
+ expiredAt: string;
55
+ } | {
56
+ state: 'unreadable';
57
+ reason: DevUnreadableReason;
58
+ } | {
59
+ state: 'absent';
60
+ } | {
61
+ state: 'disabled';
62
+ };
63
+ /** The sandbox the client targets, once a carrier has been accepted. */
64
+ type ActiveSandbox = Extract<SandboxState, {
65
+ state: 'active';
66
+ }>;
4
67
 
5
68
  /**
6
69
  * What a call site supplies beside the route it named.
@@ -2557,6 +2620,15 @@ type RegisteredSchema = Register extends {
2557
2620
  schema: infer S extends AnySchemaDefinition;
2558
2621
  } ? S : undefined;
2559
2622
 
2623
+ /**
2624
+ * The key's project, as `GET /v1/project` describes it: organization, project, dataset and branch,
2625
+ * each by id and name, and `studioUrl` — the Studio root the preview toolbar deep-links from
2626
+ * (`sdk-surfaces-spec.md` decision 24), or `null` when the service has no Dashboard address.
2627
+ *
2628
+ * Read from the committed document's `application/json` content by name, never written here
2629
+ * (`INV-API-CLIENT-IS-DERIVED`); `derived-transport.types.ts` holds the two equal.
2630
+ */
2631
+ type Project = paths['/v1/project']['get']['responses'][200]['content']['application/json']['data'];
2560
2632
  /**
2561
2633
  * Client configuration with optional schema
2562
2634
  */
@@ -2592,6 +2664,7 @@ interface TypedClientConfig<TSchema extends AnySchemaDefinition | undefined = un
2592
2664
  declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined = undefined> {
2593
2665
  private httpClient;
2594
2666
  private config;
2667
+ private _sandbox;
2595
2668
  private _search;
2596
2669
  private _batch;
2597
2670
  private _adhocQuery;
@@ -2601,6 +2674,21 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
2601
2674
  * Get the schema definition
2602
2675
  */
2603
2676
  get schema(): TSchema;
2677
+ /**
2678
+ * The `relyio dev` sandbox this client resolved at construction, as the preview toolbar displays
2679
+ * it (`sdk-surfaces-spec.md` decision 22).
2680
+ *
2681
+ * Plain, JSON-serializable data and no key, so a server component can hand it to a client
2682
+ * component as a prop — the browser cannot read the handshake itself, so a client created there
2683
+ * reports `absent`. See {@link SandboxState} for what each state means.
2684
+ *
2685
+ * @example
2686
+ * ```tsx
2687
+ * // app/layout.tsx — a server component handing the state to a client component
2688
+ * <SandboxBadge sandbox={relyio.sandbox} />
2689
+ * ```
2690
+ */
2691
+ get sandbox(): SandboxState;
2604
2692
  /**
2605
2693
  * Get the ad-hoc query client
2606
2694
  */
@@ -2779,6 +2867,21 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
2779
2867
  * ```
2780
2868
  */
2781
2869
  executeQuery<K extends TSchema extends AnySchemaDefinition ? SchemaQueryNames<TSchema> : string>(queryName: K, params?: Record<string, unknown>): Promise<unknown[]>;
2870
+ /**
2871
+ * Describe the project this key resolves to — `GET /v1/project`.
2872
+ *
2873
+ * `dataset` is the one this client's requests select (`dataset`, a sandbox from the `relyio dev`
2874
+ * handshake, or the key's default), which is not always the project's default, so a Studio link
2875
+ * built from `studioUrl` should carry it as `?dataset=`. `studioUrl` is `null` — a value, not an
2876
+ * error — when the service has no Dashboard address configured.
2877
+ *
2878
+ * @example
2879
+ * ```typescript
2880
+ * const { studioUrl, dataset } = await relyio.project()
2881
+ * if (studioUrl !== null) window.open(`${studioUrl}?dataset=${dataset.id}`)
2882
+ * ```
2883
+ */
2884
+ project(): Promise<Project>;
2782
2885
  /**
2783
2886
  * Get schema information from the API
2784
2887
  */
@@ -2930,4 +3033,4 @@ declare function createClient<TSchema extends AnySchemaDefinition>(config: Typed
2930
3033
  */
2931
3034
  type ClientSchema<T extends TypedRelyIOClient<AnySchemaDefinition>> = T extends TypedRelyIOClient<infer TSchema> ? TSchema : never;
2932
3035
 
2933
- export { type FullTextConfig as $, AutocompleteBuilder as A, type SimilarResult as B, type ClientSchema as C, type SimilarResponse as D, type ExtendedQueryResult as E, type SearchFilter as F, type SearchFields as G, HttpClient as H, BatchClient as I, BatchBuilder as J, type BatchMethod as K, type BatchOperation as L, type BatchOptions as M, type BatchOperationResult as N, type BatchSummary as O, type BatchResponse as P, AdhocQueryClient as Q, type Register as R, type SendOptions as S, TypedRelyIOClient as T, AdhocQueryBuilder as U, type FetchBlock as V, type AggregateBlock as W, type AggregateMetric as X, type SearchBlock as Y, type SimilarBlock as Z, type FilterValue as _, type TypedClientConfig as a, type AdhocQueryDefinition as a0, type AdhocQueryOptions as a1, type QueryMetadata as a2, type AdhocQueryResult as a3, AssetClient as a4, AssetFileBuilder as a5, AssetUploadBuilder as a6, isAssetEntry as a7, type AssetVisibility as a8, type FileStatus as a9, validateFile as aA, type FileBackend as aa, type AssetFileBlock as ab, type AssetFileExtracted as ac, type AssetUrls as ad, type AssetEntryResponse as ae, type PopulatedAssetReference as af, type PresignInput as ag, type PresignResult as ah, type ConfirmInput as ai, type ConfirmResult as aj, type ResolveUrlInput as ak, type ResolveUrlResult as al, type CreateAssetOptions as am, type WaitUntilReadyOptions as an, type MultipartCreateResult as ao, type MultipartPart as ap, type MultipartTarget as aq, type UploadProgress as ar, ResourceNotFoundError as as, ResourceConflictError as at, ResourceExpiredError as au, isResourceNotFound as av, type FileErrorCode as aw, FileUploadError as ax, FileValidationError as ay, type FileValidationConstraints as az, type RegisteredSchema as b, createClient as c, type ConditionalWriteOptions as d, entityTagOf as e, type RetryableWriteOptions as f, ChangesExpiredError as g, type Change as h, type ChangesOptions as i, type ChangesExpiredReason as j, ContentClient as k, SingletonClient as l, SettingsClient as m, ContentQueryBuilder as n, ContentByIdBuilder as o, type ChildrenOptions as p, type SingletonFetchOptions as q, type SettingsFetchOptions as r, SearchClient as s, SearchBuilder as t, SimilarBuilder as u, type SearchMode as v, type SearchResultItem as w, type SearchResponse as x, type AutocompleteSuggestion as y, type AutocompleteResponse as z };
3036
+ export { type SearchBlock as $, type ActiveSandbox as A, type AutocompleteSuggestion as B, type Change as C, type AutocompleteResponse as D, type ExtendedQueryResult as E, type SimilarResult as F, type SimilarResponse as G, HttpClient as H, type SearchFilter as I, type SearchFields as J, BatchClient as K, BatchBuilder as L, type BatchMethod as M, type BatchOperation as N, type BatchOptions as O, type Project as P, type BatchOperationResult as Q, type Register as R, type SandboxState as S, TypedRelyIOClient as T, type BatchSummary as U, type BatchResponse as V, AdhocQueryClient as W, AdhocQueryBuilder as X, type FetchBlock as Y, type AggregateBlock as Z, type AggregateMetric as _, type TypedClientConfig as a, type SimilarBlock as a0, type FilterValue as a1, type FullTextConfig as a2, type AdhocQueryDefinition as a3, type AdhocQueryOptions as a4, type QueryMetadata as a5, type AdhocQueryResult as a6, AssetClient as a7, AssetFileBuilder as a8, AssetUploadBuilder as a9, FileUploadError as aA, FileValidationError as aB, type FileValidationConstraints as aC, validateFile as aD, isAssetEntry as aa, type AssetVisibility as ab, type FileStatus as ac, type FileBackend as ad, type AssetFileBlock as ae, type AssetFileExtracted as af, type AssetUrls as ag, type AssetEntryResponse as ah, type PopulatedAssetReference as ai, type PresignInput as aj, type PresignResult as ak, type ConfirmInput as al, type ConfirmResult as am, type ResolveUrlInput as an, type ResolveUrlResult as ao, type CreateAssetOptions as ap, type WaitUntilReadyOptions as aq, type MultipartCreateResult as ar, type MultipartPart as as, type MultipartTarget as at, type UploadProgress as au, ResourceNotFoundError as av, ResourceConflictError as aw, ResourceExpiredError as ax, isResourceNotFound as ay, type FileErrorCode as az, type ClientSchema as b, createClient as c, type RegisteredSchema as d, type SendOptions as e, entityTagOf as f, type ConditionalWriteOptions as g, type RetryableWriteOptions as h, ChangesExpiredError as i, type ChangesOptions as j, type ChangesExpiredReason as k, ContentClient as l, SingletonClient as m, SettingsClient as n, ContentQueryBuilder as o, ContentByIdBuilder as p, type ChildrenOptions as q, type SingletonFetchOptions as r, type SettingsFetchOptions as s, SearchClient as t, SearchBuilder as u, AutocompleteBuilder as v, SimilarBuilder as w, type SearchMode as x, type SearchResultItem as y, type SearchResponse as z };