@vectros-ai/mcp-server 0.11.0 → 0.13.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.
- package/CHANGELOG.md +66 -0
- package/README.md +2 -2
- package/dist/cli-http.js +211 -65
- package/dist/cli-http.js.map +1 -1
- package/dist/cli-http.mjs +211 -65
- package/dist/cli-http.mjs.map +1 -1
- package/dist/cli.js +211 -65
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +211 -65
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +211 -65
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
42
42
|
// src/server.ts
|
|
43
43
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
44
44
|
|
|
45
|
-
//
|
|
45
|
+
// node_modules/@vectros-ai/sdk/dist/index.mjs
|
|
46
46
|
var __defProp2 = Object.defineProperty;
|
|
47
47
|
var __export2 = (target, all) => {
|
|
48
48
|
for (var name in all)
|
|
@@ -2471,7 +2471,7 @@ var AuthClient = class {
|
|
|
2471
2471
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/admin/access-log");
|
|
2472
2472
|
}
|
|
2473
2473
|
/**
|
|
2474
|
-
* Lists
|
|
2474
|
+
* Lists your scoped API keys (`ssk_*`) in your credential's own environment — a live key lists live keys, a test key lists test keys. Revoked keys are excluded. Requires the `keys:r` scope.
|
|
2475
2475
|
*
|
|
2476
2476
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
2477
2477
|
*
|
|
@@ -2854,7 +2854,7 @@ var AuthClient = class {
|
|
|
2854
2854
|
);
|
|
2855
2855
|
}
|
|
2856
2856
|
/**
|
|
2857
|
-
* Creates a new access profile under the given app context. This call is idempotent by `principalId`: if a profile with the same `principalId` already exists, the existing profile is returned (with status 200) instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing profile was returned) tells the two apart. To overwrite an existing profile's `scopes`/`roleId`, `identityOverrides`, and `status` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope). You must provide exactly one of `scopes` (an inline list of scopes) or `roleId` (a reference to a role); supplying both, or neither, is rejected. `identityOverrides` is keyed by ownership namespace in `scope:<namespace>` form — `scope:org` and `scope:client` for the reserved namespaces, or any namespace you have registered — and may name at most two; any other key (including the account identifier or `userId`) is rejected. If you use a scoped credential, the profile's effective scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
|
|
2857
|
+
* Creates a new access profile under the given app context. This call is idempotent by `principalId`: if a profile with the same `principalId` already exists, the existing profile is returned (with status 200) instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing profile was returned) tells the two apart. To overwrite an existing profile's `scopes`/`roleId`, `identityOverrides`, and `status` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope, and applies the same `identityOverrides` bounds the update endpoint documents — a scoped credential may not repoint or clear an identity value it does not itself hold). You must provide exactly one of `scopes` (an inline list of scopes) or `roleId` (a reference to a role); supplying both, or neither, is rejected. `identityOverrides` is keyed by ownership namespace in `scope:<namespace>` form — `scope:org` and `scope:client` for the reserved namespaces, or any namespace you have registered — and may name at most two; any other key (including the account identifier or `userId`) is rejected. If you use a scoped credential, the profile's effective scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
|
|
2858
2858
|
*
|
|
2859
2859
|
* @param {Vectros.CreateAccessProfileRequest} request
|
|
2860
2860
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3272,7 +3272,7 @@ var AuthClient = class {
|
|
|
3272
3272
|
);
|
|
3273
3273
|
}
|
|
3274
3274
|
/**
|
|
3275
|
-
* Updates an access profile. This is a partial update: any field you omit (or send as null) keeps its existing value. A profile must reference either inline `scopes` or a `roleId`, never both — so setting `scopes` clears any `roleId`, and setting `roleId` clears any inline `scopes`. The `contextId` and `principalId` are immutable. Status changes (for example active to suspended) take effect within about five minutes. If you use a scoped credential, the profile's effective scopes may not exceed your own
|
|
3275
|
+
* Updates an access profile. This is a partial update: any field you omit (or send as null) keeps its existing value. A profile must reference either inline `scopes` or a `roleId`, never both — so setting `scopes` clears any `roleId`, and setting `roleId` clears any inline `scopes`. The `contextId` and `principalId` are immutable. Status changes (for example active to suspended) take effect within about five minutes. If you use a scoped credential, the profile's effective scopes may not exceed your own, and its `identityOverrides` are bounded twice: you may only set a value your own identity holds, and you may only change or clear a value the profile already holds if that value is yours as well. Repointing or clearing another principal's established identity therefore returns 403. A root API key (`sk_`) is exempt. Requires the `profiles:u` scope.
|
|
3276
3276
|
*
|
|
3277
3277
|
* @param {Vectros.UpdateAccessProfileRequest} request
|
|
3278
3278
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3345,7 +3345,7 @@ var AuthClient = class {
|
|
|
3345
3345
|
);
|
|
3346
3346
|
}
|
|
3347
3347
|
/**
|
|
3348
|
-
* Deletes an access profile. Within about five minutes (the access-profile cache lifetime), token minting for this principal in this context will be denied. Requires the `profiles:d` scope.
|
|
3348
|
+
* Deletes an access profile. Within about five minutes (the access-profile cache lifetime), token minting for this principal in this context will be denied. If you use a scoped credential and the profile carries `identityOverrides`, you may only delete it when you hold those values yourself — deleting a profile removes its identity, so the same bound applies as when clearing it. A profile with no `identityOverrides` is unaffected, and a root API key (`sk_`) is exempt. Requires the `profiles:d` scope.
|
|
3349
3349
|
*
|
|
3350
3350
|
* @param {Vectros.DeleteAccessProfileRequest} request
|
|
3351
3351
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4199,7 +4199,7 @@ var AuthClient = class {
|
|
|
4199
4199
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/auth/token");
|
|
4200
4200
|
}
|
|
4201
4201
|
/**
|
|
4202
|
-
* Invite a new member to one of your app contexts by email. Creates a pending user with a pre-resolved access profile (their permissions on accept) and signs an invitation token. This call is idempotent on the combination of context and email: re-inviting the same email in the same context rotates the token and resends the invitation rather than creating a duplicate. Returns HTTP 201 on a new invite or a successful resend. Returns 409 if that email already belongs to an active or suspended member of the app context, or already has an identity elsewhere in your account (an email can currently belong to only one tenant per account, i.e. your test and live environments cannot share an email). When `sendEmail` is false, the response includes the raw token and a ready-to-use accept link so you can deliver the invitation through your own email provider. Requires the `
|
|
4202
|
+
* Invite a new member to one of your app contexts by email. Creates a pending user with a pre-resolved access profile (their permissions on accept) and signs an invitation token. This call is idempotent on the combination of context and email: re-inviting the same email in the same context rotates the token and resends the invitation rather than creating a duplicate — this requires the `users:r` and `users:u` scopes in addition to `users:c`, because resending rotates a credential on an existing invitation and invalidates any link already sent. Without them the collision returns 409 instead, with no invitation details and no change to the outstanding invitation. Returns HTTP 201 on a new invite or a successful resend. Returns 409 if that email already belongs to an active or suspended member of the app context, or already has an identity elsewhere in your account (an email can currently belong to only one tenant per account, i.e. your test and live environments cannot share an email). When `sendEmail` is false, the response includes the raw token and a ready-to-use accept link so you can deliver the invitation through your own email provider. Requires the `users:c` scope.
|
|
4203
4203
|
*
|
|
4204
4204
|
* @param {Vectros.CreateInviteRequest} request
|
|
4205
4205
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4270,7 +4270,7 @@ var AuthClient = class {
|
|
|
4270
4270
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/users/invite");
|
|
4271
4271
|
}
|
|
4272
4272
|
/**
|
|
4273
|
-
* Resend an outstanding invitation, identified by its email and app context. Rotates the invitation token and extends its expiry, then (when `sendEmail` is true) re-delivers the email. Rotating the token invalidates any previously issued link for this invitation, so only the newest link works. The invitee's pending permissions are left unchanged.
|
|
4273
|
+
* Resend an outstanding invitation, identified by its email and app context. Rotates the invitation token and extends its expiry, then (when `sendEmail` is true) re-delivers the email. Rotating the token invalidates any previously issued link for this invitation, so only the newest link works. The invitee's pending permissions are left unchanged. Because this rotates a credential on an existing invitation, it requires the `users:c`, `users:r` and `users:u` scopes.
|
|
4274
4274
|
*
|
|
4275
4275
|
* @param {Vectros.CreateInviteRequest} request
|
|
4276
4276
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4604,7 +4604,7 @@ var DocumentsClient = class {
|
|
|
4604
4604
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
4605
4605
|
* scope: "group:eng-team",
|
|
4606
4606
|
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
4607
|
-
* startFrom: "
|
|
4607
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
4608
4608
|
* })
|
|
4609
4609
|
*/
|
|
4610
4610
|
listDocuments(request = {}, requestOptions) {
|
|
@@ -4652,7 +4652,7 @@ var DocumentsClient = class {
|
|
|
4652
4652
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
|
|
4653
4653
|
}
|
|
4654
4654
|
/**
|
|
4655
|
-
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Optionally supply an `externalId` to make the create idempotent — if a document with the same `externalId` already exists in your context, that existing document is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing document was returned) tells the two apart. To overwrite an existing document's content instead of returning it unchanged, set `?upsert=true` (this also requires the `documents:u` scope). Requires the `documents:c` scope.
|
|
4655
|
+
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Optionally supply an `externalId` to make the create idempotent — if a document with the same `externalId` already exists in your context, that existing document is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing document was returned) tells the two apart. To overwrite an existing document's content instead of returning it unchanged, set `?upsert=true` (this also requires the `documents:u` scope). Requires the `documents:c` scope to create. Being returned the existing document on a collision is a read of that document's data and additionally requires the `documents:r` scope — a credential holding `documents:c` alone receives a `400` ("already exists") on collision instead of the document.
|
|
4656
4656
|
*
|
|
4657
4657
|
* @param {Vectros.IngestDocumentRequest} request
|
|
4658
4658
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4914,6 +4914,7 @@ var DocumentsClient = class {
|
|
|
4914
4914
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4915
4915
|
*
|
|
4916
4916
|
* @throws {@link Vectros.BadRequestError}
|
|
4917
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
4917
4918
|
* @throws {@link Vectros.NotFoundError}
|
|
4918
4919
|
* @throws {@link Vectros.ConflictError}
|
|
4919
4920
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -4961,6 +4962,8 @@ var DocumentsClient = class {
|
|
|
4961
4962
|
switch (_response.error.statusCode) {
|
|
4962
4963
|
case 400:
|
|
4963
4964
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4965
|
+
case 403:
|
|
4966
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4964
4967
|
case 404:
|
|
4965
4968
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4966
4969
|
case 409:
|
|
@@ -4978,25 +4981,29 @@ var DocumentsClient = class {
|
|
|
4978
4981
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
|
|
4979
4982
|
}
|
|
4980
4983
|
/**
|
|
4981
|
-
* Finds documents of a given type by field value. Supported fields: `externalId` (the document's first-class external identifier — no schema declaration required) and any field declared as a lookup field on the bound schema. A lookup on a sensitive field is rejected here because the value would appear in the URL query string; use POST /v1/documents/lookup (the request-body variant) for a sensitive field instead. Results are paginated: set `limit` for the page size and feed the returned `nextCursor` back as `startFrom` to fetch the next page. The response is a `{data, nextCursor}` envelope. Requires the `documents:r` scope.
|
|
4984
|
+
* Finds documents of a given type by field value. Supported fields: `externalId` (the document's first-class external identifier — no schema declaration required) and any field declared as a lookup field on the bound schema. A lookup on a sensitive field is rejected here because the value would appear in the URL query string; use POST /v1/documents/lookup (the request-body variant) for a sensitive field instead. `type`'s schema resolves with basedOn-aware shadowing: your own `userId`- or `scope`-owned variant if you have one, otherwise the shared base — for a scoped credential the owner is always your own token identity; `userId`/`scope` here only apply as an explicit owner selector for a root API key. Results are paginated: set `limit` for the page size and feed the returned `nextCursor` back as `startFrom` to fetch the next page. The response is a `{data, nextCursor}` envelope. Requires the `documents:r` scope.
|
|
4982
4985
|
*
|
|
4983
4986
|
* @param {Vectros.LookupDocumentsRequest} request
|
|
4984
4987
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4985
4988
|
*
|
|
4989
|
+
* @throws {@link Vectros.BadRequestError}
|
|
4990
|
+
*
|
|
4986
4991
|
* @example
|
|
4987
4992
|
* await client.documents.lookupDocuments({
|
|
4988
4993
|
* type: "invoice",
|
|
4989
4994
|
* field: "po_number",
|
|
4990
4995
|
* value: "PO-1001",
|
|
4991
4996
|
* prefix: "PO-2024",
|
|
4992
|
-
* startFrom: "
|
|
4997
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl",
|
|
4998
|
+
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
4999
|
+
* scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
|
4993
5000
|
* })
|
|
4994
5001
|
*/
|
|
4995
5002
|
lookupDocuments(request, requestOptions) {
|
|
4996
5003
|
return HttpResponsePromise.fromPromise(this.__lookupDocuments(request, requestOptions));
|
|
4997
5004
|
}
|
|
4998
5005
|
async __lookupDocuments(request, requestOptions) {
|
|
4999
|
-
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order } = request;
|
|
5006
|
+
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order, userId, scope } = request;
|
|
5000
5007
|
const _queryParams = {
|
|
5001
5008
|
type: type_,
|
|
5002
5009
|
field,
|
|
@@ -5006,7 +5013,9 @@ var DocumentsClient = class {
|
|
|
5006
5013
|
prefix,
|
|
5007
5014
|
startFrom,
|
|
5008
5015
|
limit,
|
|
5009
|
-
order: order != null ? order : void 0
|
|
5016
|
+
order: order != null ? order : void 0,
|
|
5017
|
+
userId,
|
|
5018
|
+
scope
|
|
5010
5019
|
};
|
|
5011
5020
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5012
5021
|
const _headers = mergeHeaders(
|
|
@@ -5032,11 +5041,16 @@ var DocumentsClient = class {
|
|
|
5032
5041
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
5033
5042
|
}
|
|
5034
5043
|
if (_response.error.reason === "status-code") {
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5044
|
+
switch (_response.error.statusCode) {
|
|
5045
|
+
case 400:
|
|
5046
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5047
|
+
default:
|
|
5048
|
+
throw new VectrosError({
|
|
5049
|
+
statusCode: _response.error.statusCode,
|
|
5050
|
+
body: _response.error.body,
|
|
5051
|
+
rawResponse: _response.rawResponse
|
|
5052
|
+
});
|
|
5053
|
+
}
|
|
5040
5054
|
}
|
|
5041
5055
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/lookup");
|
|
5042
5056
|
}
|
|
@@ -5356,7 +5370,7 @@ var FoldersClient = class {
|
|
|
5356
5370
|
* parentFolderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
5357
5371
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
5358
5372
|
* scope: "group:eng-team",
|
|
5359
|
-
* startFrom: "
|
|
5373
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
5360
5374
|
* })
|
|
5361
5375
|
*/
|
|
5362
5376
|
listFolders(request = {}, requestOptions) {
|
|
@@ -5404,7 +5418,7 @@ var FoldersClient = class {
|
|
|
5404
5418
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
|
|
5405
5419
|
}
|
|
5406
5420
|
/**
|
|
5407
|
-
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Folder creation is idempotent by (slug + parent): if a folder with the same slug already exists under the same parent, that existing folder is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing folder was returned) tells the two apart. To overwrite an existing folder's mutable fields instead of returning it unchanged, set `?upsert=true` (this also requires the `folders:u` scope). Requires the `folders:c` scope.
|
|
5421
|
+
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Folder creation is idempotent by (slug + parent): if a folder with the same slug already exists under the same parent, that existing folder is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing folder was returned) tells the two apart. To overwrite an existing folder's mutable fields instead of returning it unchanged, set `?upsert=true` (this also requires the `folders:u` scope). Requires the `folders:c` scope to create. Being returned the existing folder on a collision is a read of that folder's data and additionally requires the `folders:r` scope — a credential holding `folders:c` alone receives a `400` ("already exists") on collision instead of the folder.
|
|
5408
5422
|
*
|
|
5409
5423
|
* @param {Vectros.CreateFolderRequest} request
|
|
5410
5424
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -5533,6 +5547,7 @@ var FoldersClient = class {
|
|
|
5533
5547
|
* @param {Vectros.UpdateFolderRequest} request
|
|
5534
5548
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5535
5549
|
*
|
|
5550
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5536
5551
|
* @throws {@link Vectros.NotFoundError}
|
|
5537
5552
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
5538
5553
|
*
|
|
@@ -5577,6 +5592,8 @@ var FoldersClient = class {
|
|
|
5577
5592
|
}
|
|
5578
5593
|
if (_response.error.reason === "status-code") {
|
|
5579
5594
|
switch (_response.error.statusCode) {
|
|
5595
|
+
case 403:
|
|
5596
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5580
5597
|
case 404:
|
|
5581
5598
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5582
5599
|
case 429:
|
|
@@ -5659,6 +5676,7 @@ var FoldersClient = class {
|
|
|
5659
5676
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5660
5677
|
*
|
|
5661
5678
|
* @throws {@link Vectros.BadRequestError}
|
|
5679
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5662
5680
|
* @throws {@link Vectros.NotFoundError}
|
|
5663
5681
|
* @throws {@link Vectros.ConflictError}
|
|
5664
5682
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -5706,6 +5724,8 @@ var FoldersClient = class {
|
|
|
5706
5724
|
switch (_response.error.statusCode) {
|
|
5707
5725
|
case 400:
|
|
5708
5726
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5727
|
+
case 403:
|
|
5728
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5709
5729
|
case 404:
|
|
5710
5730
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5711
5731
|
case 409:
|
|
@@ -5793,7 +5813,8 @@ var IdentityClient = class {
|
|
|
5793
5813
|
*
|
|
5794
5814
|
* @example
|
|
5795
5815
|
* await client.identity.listEntities({
|
|
5796
|
-
* namespace: "team"
|
|
5816
|
+
* namespace: "team",
|
|
5817
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
5797
5818
|
* })
|
|
5798
5819
|
*/
|
|
5799
5820
|
listEntities(request, requestOptions) {
|
|
@@ -5862,7 +5883,7 @@ var IdentityClient = class {
|
|
|
5862
5883
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
|
|
5863
5884
|
}
|
|
5864
5885
|
/**
|
|
5865
|
-
* Creates a new entity in the given namespace. This call is idempotent on `externalId` within the namespace: if an entity with the same `externalId` already exists, the existing record is returned instead of creating a duplicate (`created: false`, HTTP 200). To overwrite an existing entity's content instead of returning it unchanged, set `?upsert=true` (also requires the `entities:u:<namespace>` scope). The namespace must be entity-backed (`org`/`client`, or registered via `POST /v1/namespaces`). Requires the `entities:c:<namespace>` scope.
|
|
5886
|
+
* Creates a new entity in the given namespace. This call is idempotent on `externalId` within the namespace: if an entity with the same `externalId` already exists, the existing record is returned instead of creating a duplicate (`created: false`, HTTP 200). To overwrite an existing entity's content instead of returning it unchanged, set `?upsert=true` (also requires the `entities:u:<namespace>` scope). The namespace must be entity-backed (`org`/`client`, or registered via `POST /v1/namespaces`). Requires the `entities:c:<namespace>` scope to create. Being returned the existing entity on a collision is a read of that entity's data and additionally requires the `entities:r:<namespace>` scope — a credential holding `entities:c:<namespace>` alone receives a `400` ("already in use") on collision instead of the entity.
|
|
5866
5887
|
*
|
|
5867
5888
|
* @param {Vectros.CreateEntityRequest} request
|
|
5868
5889
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6306,7 +6327,7 @@ var IdentityClient = class {
|
|
|
6306
6327
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
|
|
6307
6328
|
}
|
|
6308
6329
|
/**
|
|
6309
|
-
* Updates the mutable fields (`entityBacked`, `defaultSchemaId`) of a registered namespace. The namespace name itself is immutable. Requires a root API key. The reserved built-ins cannot be updated.
|
|
6330
|
+
* Updates the mutable fields (`entityBacked`, `defaultSchemaId`, `specificityRank`) of a registered namespace. The namespace name itself is immutable. Requires a root API key. The reserved built-ins cannot be updated.
|
|
6310
6331
|
*
|
|
6311
6332
|
* @param {Vectros.UpdateNamespaceRequest} request
|
|
6312
6333
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6319,7 +6340,8 @@ var IdentityClient = class {
|
|
|
6319
6340
|
* await client.identity.updateNamespace({
|
|
6320
6341
|
* namespace: "team",
|
|
6321
6342
|
* body: {
|
|
6322
|
-
* namespace: "team"
|
|
6343
|
+
* namespace: "team",
|
|
6344
|
+
* specificityRank: 1500
|
|
6323
6345
|
* }
|
|
6324
6346
|
* })
|
|
6325
6347
|
*/
|
|
@@ -6484,7 +6506,7 @@ var IdentityClient = class {
|
|
|
6484
6506
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
|
|
6485
6507
|
}
|
|
6486
6508
|
/**
|
|
6487
|
-
* Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Requires a root API key. The reserved names `org` and `client` are built in and cannot be registered.
|
|
6509
|
+
* Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Also requires `specificityRank`, an explicit, account-unique position in the specificity order used to break recordType schema-resolution ties. Requires a root API key. The reserved names `org` and `client` are built in and cannot be registered.
|
|
6488
6510
|
*
|
|
6489
6511
|
* @param {Vectros.NamespaceRequest} request
|
|
6490
6512
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6495,7 +6517,8 @@ var IdentityClient = class {
|
|
|
6495
6517
|
*
|
|
6496
6518
|
* @example
|
|
6497
6519
|
* await client.identity.registerNamespace({
|
|
6498
|
-
* namespace: "team"
|
|
6520
|
+
* namespace: "team",
|
|
6521
|
+
* specificityRank: 1500
|
|
6499
6522
|
* })
|
|
6500
6523
|
*/
|
|
6501
6524
|
registerNamespace(request, requestOptions) {
|
|
@@ -6555,7 +6578,7 @@ var IdentityClient = class {
|
|
|
6555
6578
|
* @example
|
|
6556
6579
|
* await client.identity.listUsers({
|
|
6557
6580
|
* externalId: "usr_12345",
|
|
6558
|
-
* startFrom: "
|
|
6581
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl",
|
|
6559
6582
|
* type: "person_v1",
|
|
6560
6583
|
* field: "team",
|
|
6561
6584
|
* value: "engineering",
|
|
@@ -6612,7 +6635,7 @@ var IdentityClient = class {
|
|
|
6612
6635
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
|
|
6613
6636
|
}
|
|
6614
6637
|
/**
|
|
6615
|
-
* Creates a user identity in your account. The operation is idempotent on `externalId`: if a user with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing user was returned) tells the two apart. To overwrite an existing user's mutable fields (email, status, payload, schema binding) instead of returning it unchanged, set `?upsert=true` (this also requires the `users:u` scope). Requires the `users:c` scope.
|
|
6638
|
+
* Creates a user identity in your account. The operation is idempotent on `externalId`: if a user with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing user was returned) tells the two apart. To overwrite an existing user's mutable fields (email, status, payload, schema binding) instead of returning it unchanged, set `?upsert=true` (this also requires the `users:u` scope). Requires the `users:c` scope to create. Being returned the existing user on a collision is a read of that user's data and additionally requires the `users:r` scope — a credential holding `users:c` alone receives a `400` ("already exists") on collision instead of the user.
|
|
6616
6639
|
*
|
|
6617
6640
|
* @param {Vectros.CreateUserRequest} request
|
|
6618
6641
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6736,11 +6759,12 @@ var IdentityClient = class {
|
|
|
6736
6759
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users/{id}");
|
|
6737
6760
|
}
|
|
6738
6761
|
/**
|
|
6739
|
-
* Updates mutable fields on an existing user (such as email, status, payload, or schema binding). The `type` field is immutable after creation. This endpoint also activates an invited user: a PUT that moves a PENDING user to ACTIVE and carries `inviteToken`, `externalSubject`, and `emailVerifiedAttestation=true` completes the invitation. Requires the `users:u` scope.
|
|
6762
|
+
* Updates mutable fields on an existing user (such as email, status, payload, or schema binding). The `type` field is immutable after creation, and `email` cannot be changed while an invitation to that user is still outstanding — revoke the invitation, or invite the new address instead. This endpoint also activates an invited user: a PUT that moves a PENDING user to ACTIVE and carries `inviteToken`, `externalSubject`, and `emailVerifiedAttestation=true` completes the invitation. Requires the `users:u` scope.
|
|
6740
6763
|
*
|
|
6741
6764
|
* @param {Vectros.UpdateUserRequest} request
|
|
6742
6765
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6743
6766
|
*
|
|
6767
|
+
* @throws {@link Vectros.BadRequestError}
|
|
6744
6768
|
* @throws {@link Vectros.NotFoundError}
|
|
6745
6769
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
6746
6770
|
*
|
|
@@ -6785,6 +6809,8 @@ var IdentityClient = class {
|
|
|
6785
6809
|
}
|
|
6786
6810
|
if (_response.error.reason === "status-code") {
|
|
6787
6811
|
switch (_response.error.statusCode) {
|
|
6812
|
+
case 400:
|
|
6813
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6788
6814
|
case 404:
|
|
6789
6815
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6790
6816
|
case 429:
|
|
@@ -7432,7 +7458,7 @@ var RecordsClient = class {
|
|
|
7432
7458
|
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
7433
7459
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
7434
7460
|
* scope: "group:eng-team",
|
|
7435
|
-
* startFrom: "
|
|
7461
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
7436
7462
|
* })
|
|
7437
7463
|
*/
|
|
7438
7464
|
listRecords(request = {}, requestOptions) {
|
|
@@ -7483,7 +7509,7 @@ var RecordsClient = class {
|
|
|
7483
7509
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
|
|
7484
7510
|
}
|
|
7485
7511
|
/**
|
|
7486
|
-
* Creates a new record of a given type. The `payload` is validated against that type's schema before the record is stored. Identify the type by sending `typeName`, `schemaId`, or both (they must agree); if you send only `schemaId`, the type is taken from that schema. Optionally supply an `externalId` to make the create idempotent — if a record with the same `externalId` already exists in your context, that existing record is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing record was returned) tells the two apart. To overwrite an existing record's content instead of returning it unchanged, set `?upsert=true` (this also requires the `records:u:<type>` scope). Requires the `records:c:<type>` scope.
|
|
7512
|
+
* Creates a new record of a given type. The `payload` is validated against that type's schema before the record is stored. Identify the type by sending `typeName`, `schemaId`, or both (they must agree); if you send only `schemaId`, the type is taken from that schema. Optionally supply an `externalId` to make the create idempotent — if a record with the same `externalId` already exists in your context, that existing record is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing record was returned) tells the two apart. To overwrite an existing record's content instead of returning it unchanged, set `?upsert=true` (this also requires the `records:u:<type>` scope). Requires the `records:c:<type>` scope to create. Being returned the existing record on a collision is a read of that record's data and additionally requires the `records:r:<type>` scope — a credential holding `records:c:<type>` alone receives a `400` ("already exists") on collision instead of the record.
|
|
7487
7513
|
*
|
|
7488
7514
|
* @param {Vectros.CreateRecordRequest} request
|
|
7489
7515
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -7620,6 +7646,7 @@ var RecordsClient = class {
|
|
|
7620
7646
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7621
7647
|
*
|
|
7622
7648
|
* @throws {@link Vectros.BadRequestError}
|
|
7649
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
7623
7650
|
* @throws {@link Vectros.NotFoundError}
|
|
7624
7651
|
* @throws {@link Vectros.ConflictError}
|
|
7625
7652
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -7668,6 +7695,8 @@ var RecordsClient = class {
|
|
|
7668
7695
|
switch (_response.error.statusCode) {
|
|
7669
7696
|
case 400:
|
|
7670
7697
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7698
|
+
case 403:
|
|
7699
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7671
7700
|
case 404:
|
|
7672
7701
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7673
7702
|
case 409:
|
|
@@ -7749,6 +7778,7 @@ var RecordsClient = class {
|
|
|
7749
7778
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7750
7779
|
*
|
|
7751
7780
|
* @throws {@link Vectros.BadRequestError}
|
|
7781
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
7752
7782
|
* @throws {@link Vectros.NotFoundError}
|
|
7753
7783
|
* @throws {@link Vectros.ConflictError}
|
|
7754
7784
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -7799,6 +7829,8 @@ var RecordsClient = class {
|
|
|
7799
7829
|
switch (_response.error.statusCode) {
|
|
7800
7830
|
case 400:
|
|
7801
7831
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7832
|
+
case 403:
|
|
7833
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7802
7834
|
case 404:
|
|
7803
7835
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7804
7836
|
case 409:
|
|
@@ -7816,7 +7848,15 @@ var RecordsClient = class {
|
|
|
7816
7848
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/records/{id}");
|
|
7817
7849
|
}
|
|
7818
7850
|
/**
|
|
7819
|
-
* Finds records by the value of a lookup field declared on the type's schema. Provide exactly one lookup mode: `value` (exact match), `from`+`to` (inclusive range, ascending by value), or `prefix` (string fields only, ascending). Range and prefix lookups are not supported on a sensitive field, because its value is stored as a blind index and has no sortable order. An exact-`value` lookup on a sensitive field is also rejected on this GET endpoint — the value must not appear in the URL — so use the `POST /v1/records/lookup` body variant for sensitive fields.
|
|
7851
|
+
* Finds records by the value of a lookup field declared on the type's schema. Provide exactly one lookup mode: `value` (exact match), `from`+`to` (inclusive range, ascending by value), or `prefix` (string fields only, ascending). Range and prefix lookups are not supported on a sensitive field, because its value is stored as a blind index and has no sortable order. An exact-`value` lookup on a sensitive field is also rejected on this GET endpoint — the value must not appear in the URL — so use the `POST /v1/records/lookup` body variant for sensitive fields.
|
|
7852
|
+
*
|
|
7853
|
+
* A `value` lookup can additionally be narrowed to a window of the lookup field's **sort key** using `sortFrom` and/or `sortTo` (inclusive) — for example, one session's records created since a timestamp. The sort key is whatever the schema declares as that lookup's `sortBy` (`createdAt` by default, `lastUpdated`, or another field), and bounds are given in that field's own units — epoch milliseconds for the two timestamp options. **Records that have no value for the sorted field are never included in a bounded window** — they are ordered ahead of every record that does have one, and a `sortFrom`/`sortTo` window only ever selects from records carrying a value. The sorted field does not have to be `required`.
|
|
7854
|
+
*
|
|
7855
|
+
* Narrowing is available on any lookup field your schema declares for fast equality lookup, and on `externalId` — which is always ordered by creation time, so its bounds are epoch milliseconds whatever the schema says. It is rejected (`400`) for a field declared with `rangeEnabled`, for a field declared beyond the schema's fast-lookup budget, for a lookup whose `sortBy` names a sensitive field (a sensitive value is stored as a blind index and has no order), and for a window whose start is after its end. Ownership fields are not lookup fields on this endpoint at all — see the `field` parameter.
|
|
7856
|
+
*
|
|
7857
|
+
* While paging a narrowed lookup, keep every other parameter identical. The cursor is valid only for the exact query that returned it — changing `order`, `sortFrom`, `sortTo`, or dropping them altogether, is rejected rather than silently resumed at a position that means something different in the new query.
|
|
7858
|
+
*
|
|
7859
|
+
* Results are paginated: set `limit` for the page size and pass the returned `nextCursor` back as `startFrom` for the next page. **Keep paging until `nextCursor` is null** — a page can come back empty or shorter than `limit` while more results remain, so an empty page is not the end of the results. Requires the `records:r:<type>` scope.
|
|
7820
7860
|
*
|
|
7821
7861
|
* @param {Vectros.LookupRecordsRequest} request
|
|
7822
7862
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -7828,22 +7868,40 @@ var RecordsClient = class {
|
|
|
7828
7868
|
* type: "intake_form",
|
|
7829
7869
|
* field: "email",
|
|
7830
7870
|
* value: "jane@example.com",
|
|
7871
|
+
* values: ["open"],
|
|
7831
7872
|
* prefix: "jane",
|
|
7832
|
-
* startFrom: "
|
|
7873
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
7833
7874
|
* })
|
|
7834
7875
|
*/
|
|
7835
7876
|
lookupRecords(request, requestOptions) {
|
|
7836
7877
|
return HttpResponsePromise.fromPromise(this.__lookupRecords(request, requestOptions));
|
|
7837
7878
|
}
|
|
7838
7879
|
async __lookupRecords(request, requestOptions) {
|
|
7839
|
-
const {
|
|
7880
|
+
const {
|
|
7881
|
+
type: type_,
|
|
7882
|
+
field,
|
|
7883
|
+
value,
|
|
7884
|
+
values,
|
|
7885
|
+
from: from_,
|
|
7886
|
+
to,
|
|
7887
|
+
prefix,
|
|
7888
|
+
sortFrom,
|
|
7889
|
+
sortTo,
|
|
7890
|
+
startFrom,
|
|
7891
|
+
limit,
|
|
7892
|
+
includePayload,
|
|
7893
|
+
order
|
|
7894
|
+
} = request;
|
|
7840
7895
|
const _queryParams = {
|
|
7841
7896
|
type: type_,
|
|
7842
7897
|
field,
|
|
7843
7898
|
value,
|
|
7899
|
+
values,
|
|
7844
7900
|
from: from_,
|
|
7845
7901
|
to,
|
|
7846
7902
|
prefix,
|
|
7903
|
+
sortFrom,
|
|
7904
|
+
sortTo,
|
|
7847
7905
|
startFrom,
|
|
7848
7906
|
limit,
|
|
7849
7907
|
includePayload,
|
|
@@ -7887,7 +7945,7 @@ var RecordsClient = class {
|
|
|
7887
7945
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records/lookup");
|
|
7888
7946
|
}
|
|
7889
7947
|
/**
|
|
7890
|
-
* Body-based equivalent of `GET /v1/records/lookup`. Use this when looking up by a sensitive field: the value travels in the request body (and is blind-indexed server-side) instead of in the URL query string, so it never lands in access, CDN, or proxy logs. The GET variant rejects an exact-value lookup on a sensitive field and directs you here. Non-sensitive exact-value, range (`from`+`to`), and prefix lookups also work here. Returns the same `{data, nextCursor}` envelope and uses the same pagination as the GET variant. Requires the `records:r:<type>` scope.
|
|
7948
|
+
* Body-based equivalent of `GET /v1/records/lookup`. Use this when looking up by a sensitive field: the value travels in the request body (and is blind-indexed server-side) instead of in the URL query string, so it never lands in access, CDN, or proxy logs. The GET variant rejects an exact-value lookup on a sensitive field and directs you here. Non-sensitive exact-value, range (`from`+`to`), and prefix lookups also work here, as does narrowing a `value` lookup by the field's sort key with `sortFrom`/`sortTo` — see the GET variant for what the sort key is and when narrowing by it is available. Returns the same `{data, nextCursor}` envelope and uses the same pagination as the GET variant; keep paging until `nextCursor` is null rather than stopping on an empty page. Requires the `records:r:<type>` scope.
|
|
7891
7949
|
*
|
|
7892
7950
|
* @param {Vectros.RecordLookupRequest} request
|
|
7893
7951
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8074,13 +8132,15 @@ var SchemasClient = class {
|
|
|
8074
8132
|
* @param {Vectros.ListSchemasRequest} request
|
|
8075
8133
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8076
8134
|
*
|
|
8135
|
+
* @throws {@link Vectros.BadRequestError}
|
|
8136
|
+
*
|
|
8077
8137
|
* @example
|
|
8078
8138
|
* await client.schemas.listSchemas({
|
|
8079
8139
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
8080
8140
|
* scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
|
8081
8141
|
* surface: "document",
|
|
8082
8142
|
* recordType: "intake_form",
|
|
8083
|
-
* startFrom: "
|
|
8143
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
8084
8144
|
* })
|
|
8085
8145
|
*/
|
|
8086
8146
|
listSchemas(request = {}, requestOptions) {
|
|
@@ -8120,16 +8180,21 @@ var SchemasClient = class {
|
|
|
8120
8180
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
8121
8181
|
}
|
|
8122
8182
|
if (_response.error.reason === "status-code") {
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8183
|
+
switch (_response.error.statusCode) {
|
|
8184
|
+
case 400:
|
|
8185
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8186
|
+
default:
|
|
8187
|
+
throw new VectrosError({
|
|
8188
|
+
statusCode: _response.error.statusCode,
|
|
8189
|
+
body: _response.error.body,
|
|
8190
|
+
rawResponse: _response.rawResponse
|
|
8191
|
+
});
|
|
8192
|
+
}
|
|
8128
8193
|
}
|
|
8129
8194
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
|
|
8130
8195
|
}
|
|
8131
8196
|
/**
|
|
8132
|
-
* Defines a new record type with optional field definitions, validation rules, and lookup indexes. Idempotent by `typeName` within the same ownership scope: re-creating an existing `typeName` returns the existing schema rather than failing. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing schema was returned) tells the two apart. To reconcile an existing schema to the submitted shape instead of returning it unchanged, set `?upsert=true` (this also requires the `schemas:
|
|
8197
|
+
* Defines a new record type with optional field definitions, validation rules, and lookup indexes. Idempotent by `typeName` within the same ownership scope: re-creating an existing `typeName` returns the existing schema rather than failing. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing schema was returned) tells the two apart. To reconcile an existing schema to the submitted shape instead of returning it unchanged, set `?upsert=true` (this also requires the `schemas:u` scope; only legal schema changes are applied — migration-locked changes are rejected). Requires the `schemas:c` scope to create. Being returned the existing schema on a collision is a read of that schema's data and additionally requires the `schemas:r` scope — a credential holding `schemas:c` alone receives a `400` ("already in use") on collision instead of the schema.
|
|
8133
8198
|
*
|
|
8134
8199
|
* @param {Vectros.CreateSchemaRequest} request
|
|
8135
8200
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8273,12 +8338,13 @@ var SchemasClient = class {
|
|
|
8273
8338
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas/{id}");
|
|
8274
8339
|
}
|
|
8275
8340
|
/**
|
|
8276
|
-
* Updates a record schema. Fields you omit are preserved; `typeName` is immutable and cannot be changed. Collection fields (`fields`, `lookupFields`, `renderHints`, `capabilities`) are replaced in full when supplied. Requires the `schemas:
|
|
8341
|
+
* Updates a record schema. Fields you omit are preserved; `typeName` is immutable and cannot be changed. Collection fields (`fields`, `lookupFields`, `renderHints`, `capabilities`) are replaced in full when supplied. Requires the `schemas:u` scope.
|
|
8277
8342
|
*
|
|
8278
8343
|
* @param {Vectros.UpdateSchemaRequest} request
|
|
8279
8344
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8280
8345
|
*
|
|
8281
8346
|
* @throws {@link Vectros.BadRequestError}
|
|
8347
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
8282
8348
|
* @throws {@link Vectros.NotFoundError}
|
|
8283
8349
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
8284
8350
|
*
|
|
@@ -8327,6 +8393,8 @@ var SchemasClient = class {
|
|
|
8327
8393
|
switch (_response.error.statusCode) {
|
|
8328
8394
|
case 400:
|
|
8329
8395
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8396
|
+
case 403:
|
|
8397
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8330
8398
|
case 404:
|
|
8331
8399
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8332
8400
|
case 429:
|
|
@@ -8342,7 +8410,7 @@ var SchemasClient = class {
|
|
|
8342
8410
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
|
|
8343
8411
|
}
|
|
8344
8412
|
/**
|
|
8345
|
-
* Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. Requires the `schemas:
|
|
8413
|
+
* Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. A lineage base (a schema other schemas declare `basedOn`) also cannot be deleted while any such variant still exists — delete the variant schema(s) first. Requires the `schemas:d` scope.
|
|
8346
8414
|
*
|
|
8347
8415
|
* @param {Vectros.DeleteSchemaRequest} request
|
|
8348
8416
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8639,8 +8707,8 @@ function warnOnSuboptimalKey(key, log) {
|
|
|
8639
8707
|
|
|
8640
8708
|
// src/build-info.ts
|
|
8641
8709
|
var BUILD_INFO = {
|
|
8642
|
-
mcpServer: true ? "0.
|
|
8643
|
-
sdk: true ? "0.
|
|
8710
|
+
mcpServer: true ? "0.13.0" : "dev",
|
|
8711
|
+
sdk: true ? "0.38.0" : "dev"
|
|
8644
8712
|
};
|
|
8645
8713
|
|
|
8646
8714
|
// src/log.ts
|
|
@@ -8680,7 +8748,9 @@ async function resolveIdentity({
|
|
|
8680
8748
|
const derived = {
|
|
8681
8749
|
status: "ok",
|
|
8682
8750
|
environment: deriveEnvironment(environment),
|
|
8683
|
-
principalType: derivePrincipalType(apiKey)
|
|
8751
|
+
principalType: derivePrincipalType(apiKey),
|
|
8752
|
+
mcpServerVersion: BUILD_INFO.mcpServer,
|
|
8753
|
+
sdkVersion: BUILD_INFO.sdk
|
|
8684
8754
|
};
|
|
8685
8755
|
if (!apiKey || !environment) {
|
|
8686
8756
|
log.debug({ component: "identity", mode: "derived-only" }, "identity derived (no fetch)");
|
|
@@ -8708,7 +8778,13 @@ async function resolveIdentity({
|
|
|
8708
8778
|
);
|
|
8709
8779
|
}
|
|
8710
8780
|
}
|
|
8711
|
-
const merged = {
|
|
8781
|
+
const merged = {
|
|
8782
|
+
...derived,
|
|
8783
|
+
...extended,
|
|
8784
|
+
status: "ok",
|
|
8785
|
+
mcpServerVersion: derived.mcpServerVersion,
|
|
8786
|
+
sdkVersion: derived.sdkVersion
|
|
8787
|
+
};
|
|
8712
8788
|
log.debug(
|
|
8713
8789
|
{
|
|
8714
8790
|
component: "identity",
|
|
@@ -9030,14 +9106,23 @@ var import_zod2 = require("zod");
|
|
|
9030
9106
|
function pageItems(page) {
|
|
9031
9107
|
return page.data ?? [];
|
|
9032
9108
|
}
|
|
9109
|
+
var MAX_PAGES = 100;
|
|
9110
|
+
var MAX_ROWS = 1e6;
|
|
9033
9111
|
async function drainPages(fetchPage) {
|
|
9034
9112
|
const all = [];
|
|
9035
9113
|
let startFrom;
|
|
9114
|
+
let pages = 0;
|
|
9036
9115
|
for (; ; ) {
|
|
9037
9116
|
const page = await fetchPage(startFrom);
|
|
9038
|
-
|
|
9117
|
+
pages++;
|
|
9118
|
+
if (page.data?.length) for (const item of page.data) all.push(item);
|
|
9039
9119
|
const next = page.nextCursor;
|
|
9040
9120
|
if (!next) break;
|
|
9121
|
+
if (pages > MAX_PAGES || all.length > MAX_ROWS) {
|
|
9122
|
+
throw new Error(
|
|
9123
|
+
`drainPages: exceeded the runaway guard (${all.length} rows over ${pages} pages, limits ${MAX_ROWS}/${MAX_PAGES}) without the cursor going null. Refusing to return a partial result \u2014 the backend may be returning empty pages with a live cursor.`
|
|
9124
|
+
);
|
|
9125
|
+
}
|
|
9041
9126
|
startFrom = next;
|
|
9042
9127
|
}
|
|
9043
9128
|
return all;
|
|
@@ -9048,14 +9133,23 @@ var MCP_DEFAULT_LIMIT2 = 3;
|
|
|
9048
9133
|
var MCP_MAX_LIMIT2 = 100;
|
|
9049
9134
|
var inputSchema2 = {
|
|
9050
9135
|
type: import_zod2.z.string().min(1, "type (record type) is required").describe('Record type / schema name (e.g. "patient", "clinical_note").'),
|
|
9051
|
-
// Lookup-mode args — provide `field` plus EXACTLY ONE of: value | from+to | prefix.
|
|
9136
|
+
// Lookup-mode args — provide `field` plus EXACTLY ONE of: value | values | from+to | prefix.
|
|
9052
9137
|
field: import_zod2.z.string().optional().describe(
|
|
9053
|
-
'Lookup mode: name of the lookup-indexed field to query by. `externalId` is always queryable \u2014 e.g. `{type:"control", field:"externalId", value:"ctrl-scoped-key"}` finds the record you created under that externalId. (record_get / record_update also accept externalId directly.)'
|
|
9138
|
+
'Lookup mode: name of the lookup-indexed field to query by. `externalId` is always queryable \u2014 e.g. `{type:"control", field:"externalId", value:"ctrl-scoped-key"}` finds the record you created under that externalId. (record_get / record_update also accept externalId directly.) For a SCHEMA-declared composite lookup \u2014 check list_schemas\' lookupFields for a fieldNames entry, not any two fields you pick \u2014 give those field names comma-joined in the declared order (e.g. "status,area"). Use `values` to match on several of those fields at once, or `value` to match on just the FIRST field named (equivalent to a one-element `values`); range/prefix are not valid on a composite field.'
|
|
9139
|
+
),
|
|
9140
|
+
value: import_zod2.z.string().optional().describe(
|
|
9141
|
+
"Lookup mode (equality): exact-match value for `field`. Also valid when `field` names a SCHEMA-declared composite lookup \u2014 matches just the first named field, grouping by the rest (equivalent to `values` with one entry)."
|
|
9142
|
+
),
|
|
9143
|
+
values: import_zod2.z.array(import_zod2.z.string()).min(1).max(3).optional().describe(
|
|
9144
|
+
'Lookup mode (composite equality): only valid against a lookup the SCHEMA declares over several fields together (a fieldNames entry in list_schemas \u2014 you cannot combine two ordinary single-field lookups this way). One value per field, in the order the schema declares them (e.g. field="status,area", values=["open","billing"]). Mutually exclusive with `value`; a single-element array is exactly `value` written uniformly. Supplying FEWER values than the lookup declares is allowed \u2014 as long as they\'re a leading run of its fields \u2014 and returns records grouped by the fields left unspecified; `order` then sorts within each group, not across them. Record lookups only (not documents/users/entities).'
|
|
9054
9145
|
),
|
|
9055
|
-
value: import_zod2.z.string().optional().describe("Lookup mode (equality): exact-match value for `field`."),
|
|
9056
9146
|
from: import_zod2.z.string().optional().describe("Lookup mode (range): inclusive lower bound; requires `to`. Non-sensitive fields only."),
|
|
9057
9147
|
to: import_zod2.z.string().optional().describe("Lookup mode (range): inclusive upper bound; requires `from`."),
|
|
9058
9148
|
prefix: import_zod2.z.string().optional().describe("Lookup mode (prefix): match values starting with this. String, non-sensitive fields only."),
|
|
9149
|
+
sortFrom: import_zod2.z.string().optional().describe(
|
|
9150
|
+
"Lookup mode (equality/composite only): inclusive lower bound on the lookup field's sort key, narrowing a `value`/`values` match to a window instead of paging the whole match. Give the bound in the sort field's own units (epoch milliseconds for `createdAt`/`lastUpdated`). With `values`, requires every value be supplied (no grouping) for one continuous ordering. Not valid with `from`/`to`/`prefix`."
|
|
9151
|
+
),
|
|
9152
|
+
sortTo: import_zod2.z.string().optional().describe("Lookup mode (equality/composite only): inclusive upper bound on the sort key; pairs with `sortFrom`."),
|
|
9059
9153
|
order: import_zod2.z.enum(["asc", "desc"]).optional().describe(
|
|
9060
9154
|
"Lookup mode: sort direction by the looked-up field. `asc` (default) or `desc` \u2014 use `desc` with a range/prefix lookup to get the most-recent / highest values first (e.g. latest-N). Ignored in list mode."
|
|
9061
9155
|
),
|
|
@@ -9072,54 +9166,106 @@ var inputSchema2 = {
|
|
|
9072
9166
|
var recordQuery = ({ client, log }) => ({
|
|
9073
9167
|
name: "record_query",
|
|
9074
9168
|
title: "Record query (list or lookup)",
|
|
9075
|
-
description: "Query structured records of a given type. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields too
|
|
9169
|
+
description: "Query structured records of a given type. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `field` plus exactly one of `value` (exact), `values` (exact, composite \u2014 one value per field; a single-element array is the same as `value`), `from`+`to` (range), or `prefix`. `values` with more than one entry, or a comma-joined `field`, ONLY works for a lookup the schema itself declared over several fields together \u2014 check list_schemas' lookupFields for a fieldNames entry, then pass those field names comma-joined as `field`; `from`/`to`/`prefix` are not valid there. Works on sensitive fields too. Optionally narrow an exact match to a window with `sortFrom`/`sortTo`.\n \u2022 List by type: omit `field`; optionally filter by `userId` or `scope` (`namespace:value`).\nReturns a `{ data, nextCursor }` page: `data` holds up to `limit` records (default 3, max 100 \u2014 raise it in one call when you can accept the payload), and a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page. A composite lookup given fewer than its full field count returns records grouped by the unspecified fields, ordered within each group. Mode is auto-detected from the arguments present.",
|
|
9076
9170
|
inputSchema: inputSchema2,
|
|
9077
9171
|
handler: async (args) => {
|
|
9078
9172
|
const limit = args.limit ?? MCP_DEFAULT_LIMIT2;
|
|
9079
9173
|
const type = args.type;
|
|
9080
9174
|
const field = args.field;
|
|
9081
9175
|
const value = args.value;
|
|
9176
|
+
const values = args.values;
|
|
9082
9177
|
const from = args.from;
|
|
9083
9178
|
const to = args.to;
|
|
9084
9179
|
const prefix = args.prefix;
|
|
9180
|
+
const sortFrom = args.sortFrom;
|
|
9181
|
+
const sortTo = args.sortTo;
|
|
9085
9182
|
const startFrom = args.startFrom;
|
|
9183
|
+
if (!field && (value !== void 0 || values !== void 0 || from !== void 0 || to !== void 0 || prefix !== void 0 || sortFrom !== void 0 || sortTo !== void 0)) {
|
|
9184
|
+
return toolError(
|
|
9185
|
+
"record_query",
|
|
9186
|
+
new Error(
|
|
9187
|
+
"'value'/'values'/'from'/'to'/'prefix'/'sortFrom'/'sortTo' require 'field' \u2014 without it, list mode runs and silently ignores them. Pass 'field' to run a lookup, or drop these to list by type."
|
|
9188
|
+
)
|
|
9189
|
+
);
|
|
9190
|
+
}
|
|
9086
9191
|
try {
|
|
9087
9192
|
let page;
|
|
9088
9193
|
if (field) {
|
|
9194
|
+
const fieldNames = field.split(",").map((f) => f.trim()).filter(Boolean);
|
|
9195
|
+
const normalizedField = fieldNames.join(",");
|
|
9196
|
+
const isCompositeField = fieldNames.length > 1;
|
|
9089
9197
|
const hasEquality = value !== void 0;
|
|
9198
|
+
const hasComposite = values !== void 0;
|
|
9090
9199
|
const hasRange = from !== void 0 || to !== void 0;
|
|
9091
9200
|
const hasPrefix = prefix !== void 0;
|
|
9092
|
-
const modes = Number(hasEquality) + Number(hasRange) + Number(hasPrefix);
|
|
9201
|
+
const modes = Number(hasEquality) + Number(hasComposite) + Number(hasRange) + Number(hasPrefix);
|
|
9093
9202
|
if (modes === 0) {
|
|
9094
9203
|
return toolError(
|
|
9095
9204
|
"record_query",
|
|
9096
9205
|
new Error(
|
|
9097
|
-
`lookup on field '${field}' needs one of: 'value' (exact), 'from'+'to' (range), or 'prefix'.`
|
|
9206
|
+
`lookup on field '${field}' needs one of: 'value' (exact), 'values' (composite exact), 'from'+'to' (range), or 'prefix'.`
|
|
9098
9207
|
)
|
|
9099
9208
|
);
|
|
9100
9209
|
}
|
|
9101
9210
|
if (modes > 1) {
|
|
9102
9211
|
return toolError(
|
|
9103
9212
|
"record_query",
|
|
9104
|
-
new Error(
|
|
9213
|
+
new Error(
|
|
9214
|
+
"'value', 'values', 'from'/'to', and 'prefix' are mutually exclusive \u2014 provide exactly one."
|
|
9215
|
+
)
|
|
9105
9216
|
);
|
|
9106
9217
|
}
|
|
9107
9218
|
if (hasRange && !(from !== void 0 && to !== void 0)) {
|
|
9108
9219
|
return toolError("record_query", new Error("range lookup requires both 'from' and 'to'."));
|
|
9109
9220
|
}
|
|
9221
|
+
if (isCompositeField && (hasRange || hasPrefix)) {
|
|
9222
|
+
return toolError(
|
|
9223
|
+
"record_query",
|
|
9224
|
+
new Error(
|
|
9225
|
+
`'field' names ${fieldNames.length} fields ('${normalizedField}') \u2014 a composite lookup is exact-match only ('value' or 'values'), not 'from'/'to'/'prefix'.`
|
|
9226
|
+
)
|
|
9227
|
+
);
|
|
9228
|
+
}
|
|
9229
|
+
if (hasComposite && values.length > fieldNames.length) {
|
|
9230
|
+
return toolError(
|
|
9231
|
+
"record_query",
|
|
9232
|
+
new Error(
|
|
9233
|
+
`'values' has ${values.length} entries but 'field' names only ${fieldNames.length} field(s) ('${normalizedField}') \u2014 supply at most one value per field, in order (fewer only as a leading run).`
|
|
9234
|
+
)
|
|
9235
|
+
);
|
|
9236
|
+
}
|
|
9237
|
+
if (sortFrom !== void 0 || sortTo !== void 0) {
|
|
9238
|
+
if (!(hasEquality || hasComposite)) {
|
|
9239
|
+
return toolError(
|
|
9240
|
+
"record_query",
|
|
9241
|
+
new Error("'sortFrom'/'sortTo' narrow a 'value' or 'values' match only \u2014 not 'from'/'to'/'prefix'.")
|
|
9242
|
+
);
|
|
9243
|
+
}
|
|
9244
|
+
if (hasComposite && values.length < fieldNames.length) {
|
|
9245
|
+
return toolError(
|
|
9246
|
+
"record_query",
|
|
9247
|
+
new Error(
|
|
9248
|
+
`'sortFrom'/'sortTo' with 'values' requires a value for every field named in 'field' (got ${values.length} of ${fieldNames.length}) \u2014 a partial/grouped match has no single continuous ordering to window.`
|
|
9249
|
+
)
|
|
9250
|
+
);
|
|
9251
|
+
}
|
|
9252
|
+
}
|
|
9110
9253
|
page = await client.records.lookupRecordsByBody({
|
|
9111
9254
|
type,
|
|
9112
|
-
field,
|
|
9255
|
+
field: normalizedField,
|
|
9113
9256
|
value,
|
|
9257
|
+
values,
|
|
9114
9258
|
from,
|
|
9115
9259
|
to,
|
|
9116
9260
|
prefix,
|
|
9261
|
+
sortFrom,
|
|
9262
|
+
sortTo,
|
|
9117
9263
|
order: args.order,
|
|
9118
9264
|
startFrom,
|
|
9119
9265
|
limit
|
|
9120
9266
|
});
|
|
9121
9267
|
log.debug(
|
|
9122
|
-
{ tool: "record_query", mode: "lookup", type, field, returned: pageItems(page).length },
|
|
9268
|
+
{ tool: "record_query", mode: "lookup", type, field: normalizedField, returned: pageItems(page).length },
|
|
9123
9269
|
"record_query lookup ok"
|
|
9124
9270
|
);
|
|
9125
9271
|
} else {
|
|
@@ -9152,14 +9298,14 @@ var record_query_default = recordQuery;
|
|
|
9152
9298
|
var import_zod3 = require("zod");
|
|
9153
9299
|
|
|
9154
9300
|
// src/tools/resolve-external-id.ts
|
|
9155
|
-
function validateSelector(sel, entity) {
|
|
9301
|
+
function validateSelector(sel, entity, fieldName) {
|
|
9156
9302
|
const hasId = sel.id !== void 0 && sel.id !== "";
|
|
9157
9303
|
const hasExt = sel.externalId !== void 0 && sel.externalId !== "";
|
|
9158
9304
|
if (hasId && hasExt) {
|
|
9159
|
-
return `Provide either
|
|
9305
|
+
return `Provide either ${fieldName} or externalId (not both) to identify the ${entity}.`;
|
|
9160
9306
|
}
|
|
9161
9307
|
if (!hasId && !hasExt) {
|
|
9162
|
-
return `Provide
|
|
9308
|
+
return `Provide ${fieldName}, or externalId + type, to identify the ${entity}.`;
|
|
9163
9309
|
}
|
|
9164
9310
|
if (hasExt && (sel.type === void 0 || sel.type === "")) {
|
|
9165
9311
|
return "type is required when selecting by externalId (externalId is unique within a type).";
|
|
@@ -9167,7 +9313,7 @@ function validateSelector(sel, entity) {
|
|
|
9167
9313
|
return void 0;
|
|
9168
9314
|
}
|
|
9169
9315
|
async function resolveRecordIdByExternalId(client, sel) {
|
|
9170
|
-
const err = validateSelector(sel, "record");
|
|
9316
|
+
const err = validateSelector(sel, "record", "id");
|
|
9171
9317
|
if (err) return { error: err };
|
|
9172
9318
|
if (sel.id) return { id: sel.id };
|
|
9173
9319
|
const page = await client.records.lookupRecordsByBody({
|
|
@@ -9183,7 +9329,7 @@ async function resolveRecordIdByExternalId(client, sel) {
|
|
|
9183
9329
|
return { id: items[0].id };
|
|
9184
9330
|
}
|
|
9185
9331
|
async function resolveDocumentIdByExternalId(client, sel) {
|
|
9186
|
-
const err = validateSelector(sel, "document");
|
|
9332
|
+
const err = validateSelector(sel, "document", "documentId");
|
|
9187
9333
|
if (err) return { error: err };
|
|
9188
9334
|
if (sel.id) return { id: sel.id };
|
|
9189
9335
|
const page = await client.documents.lookupDocumentsByBody({
|
|
@@ -10058,7 +10204,7 @@ var inputSchema18 = {
|
|
|
10058
10204
|
var currentIdentity = ({ log, apiKey, environment }) => ({
|
|
10059
10205
|
name: "current_identity",
|
|
10060
10206
|
title: "Current identity (tenant + principal scope)",
|
|
10061
|
-
description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, principalLabel, and (for scoped credentials) allowedActions plus dataScope \u2014 the credential's reach as { userId, scopes[] }, where each scope is a `namespace:value` string (e.g. \"org:<uuid>\"). Use this when the user asks 'what can you do here?'
|
|
10207
|
+
description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, principalLabel, and (for scoped credentials) allowedActions plus dataScope \u2014 the credential's reach as { userId, scopes[] }, where each scope is a `namespace:value` string (e.g. \"org:<uuid>\"). Also reports mcpServerVersion (this server's own package version) and sdkVersion (the bundled @vectros-ai/sdk version) so a caller can tell what build it's talking to. Use this when the user asks 'what can you do here?', 'what tenant am I in?', or 'what version is this?'. Calls GET /v1/ping under the hood.",
|
|
10062
10208
|
inputSchema: inputSchema18,
|
|
10063
10209
|
handler: async () => {
|
|
10064
10210
|
try {
|
|
@@ -10536,7 +10682,7 @@ var identityResource = ({ log, apiKey, environment }) => ({
|
|
|
10536
10682
|
name: "identity",
|
|
10537
10683
|
uri: "vectros://identity",
|
|
10538
10684
|
title: "Current identity (tenant + principal scope)",
|
|
10539
|
-
description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, tenantId, environment, principalType, principalKeyId, principalLabel,
|
|
10685
|
+
description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, tenantId, environment, principalType, principalKeyId, principalLabel, (for scoped credentials) allowedActions + dataScope ({ userId, scopes[] }), plus mcpServerVersion and sdkVersion (this build's own version and the bundled @vectros-ai/sdk version). The /v1/ping backing call ships the extended shape today; the version fields are always client-derived.",
|
|
10540
10686
|
mimeType: "application/json",
|
|
10541
10687
|
read: async () => {
|
|
10542
10688
|
const identity = await resolveIdentity({ log, apiKey, environment });
|