@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/cli-http.js
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
// src/server.ts
|
|
27
27
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
28
28
|
|
|
29
|
-
//
|
|
29
|
+
// node_modules/@vectros-ai/sdk/dist/index.mjs
|
|
30
30
|
var __defProp2 = Object.defineProperty;
|
|
31
31
|
var __export = (target, all) => {
|
|
32
32
|
for (var name in all)
|
|
@@ -2455,7 +2455,7 @@ var AuthClient = class {
|
|
|
2455
2455
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/admin/access-log");
|
|
2456
2456
|
}
|
|
2457
2457
|
/**
|
|
2458
|
-
* Lists
|
|
2458
|
+
* 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.
|
|
2459
2459
|
*
|
|
2460
2460
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
2461
2461
|
*
|
|
@@ -2838,7 +2838,7 @@ var AuthClient = class {
|
|
|
2838
2838
|
);
|
|
2839
2839
|
}
|
|
2840
2840
|
/**
|
|
2841
|
-
* 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.
|
|
2841
|
+
* 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.
|
|
2842
2842
|
*
|
|
2843
2843
|
* @param {Vectros.CreateAccessProfileRequest} request
|
|
2844
2844
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3256,7 +3256,7 @@ var AuthClient = class {
|
|
|
3256
3256
|
);
|
|
3257
3257
|
}
|
|
3258
3258
|
/**
|
|
3259
|
-
* 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
|
|
3259
|
+
* 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.
|
|
3260
3260
|
*
|
|
3261
3261
|
* @param {Vectros.UpdateAccessProfileRequest} request
|
|
3262
3262
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3329,7 +3329,7 @@ var AuthClient = class {
|
|
|
3329
3329
|
);
|
|
3330
3330
|
}
|
|
3331
3331
|
/**
|
|
3332
|
-
* 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.
|
|
3332
|
+
* 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.
|
|
3333
3333
|
*
|
|
3334
3334
|
* @param {Vectros.DeleteAccessProfileRequest} request
|
|
3335
3335
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4183,7 +4183,7 @@ var AuthClient = class {
|
|
|
4183
4183
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/auth/token");
|
|
4184
4184
|
}
|
|
4185
4185
|
/**
|
|
4186
|
-
* 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 `
|
|
4186
|
+
* 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.
|
|
4187
4187
|
*
|
|
4188
4188
|
* @param {Vectros.CreateInviteRequest} request
|
|
4189
4189
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4254,7 +4254,7 @@ var AuthClient = class {
|
|
|
4254
4254
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/users/invite");
|
|
4255
4255
|
}
|
|
4256
4256
|
/**
|
|
4257
|
-
* 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.
|
|
4257
|
+
* 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.
|
|
4258
4258
|
*
|
|
4259
4259
|
* @param {Vectros.CreateInviteRequest} request
|
|
4260
4260
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4588,7 +4588,7 @@ var DocumentsClient = class {
|
|
|
4588
4588
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
4589
4589
|
* scope: "group:eng-team",
|
|
4590
4590
|
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
4591
|
-
* startFrom: "
|
|
4591
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
4592
4592
|
* })
|
|
4593
4593
|
*/
|
|
4594
4594
|
listDocuments(request = {}, requestOptions) {
|
|
@@ -4636,7 +4636,7 @@ var DocumentsClient = class {
|
|
|
4636
4636
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
|
|
4637
4637
|
}
|
|
4638
4638
|
/**
|
|
4639
|
-
* 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.
|
|
4639
|
+
* 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.
|
|
4640
4640
|
*
|
|
4641
4641
|
* @param {Vectros.IngestDocumentRequest} request
|
|
4642
4642
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4898,6 +4898,7 @@ var DocumentsClient = class {
|
|
|
4898
4898
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4899
4899
|
*
|
|
4900
4900
|
* @throws {@link Vectros.BadRequestError}
|
|
4901
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
4901
4902
|
* @throws {@link Vectros.NotFoundError}
|
|
4902
4903
|
* @throws {@link Vectros.ConflictError}
|
|
4903
4904
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -4945,6 +4946,8 @@ var DocumentsClient = class {
|
|
|
4945
4946
|
switch (_response.error.statusCode) {
|
|
4946
4947
|
case 400:
|
|
4947
4948
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4949
|
+
case 403:
|
|
4950
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4948
4951
|
case 404:
|
|
4949
4952
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4950
4953
|
case 409:
|
|
@@ -4962,25 +4965,29 @@ var DocumentsClient = class {
|
|
|
4962
4965
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
|
|
4963
4966
|
}
|
|
4964
4967
|
/**
|
|
4965
|
-
* 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.
|
|
4968
|
+
* 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.
|
|
4966
4969
|
*
|
|
4967
4970
|
* @param {Vectros.LookupDocumentsRequest} request
|
|
4968
4971
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4969
4972
|
*
|
|
4973
|
+
* @throws {@link Vectros.BadRequestError}
|
|
4974
|
+
*
|
|
4970
4975
|
* @example
|
|
4971
4976
|
* await client.documents.lookupDocuments({
|
|
4972
4977
|
* type: "invoice",
|
|
4973
4978
|
* field: "po_number",
|
|
4974
4979
|
* value: "PO-1001",
|
|
4975
4980
|
* prefix: "PO-2024",
|
|
4976
|
-
* startFrom: "
|
|
4981
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl",
|
|
4982
|
+
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
4983
|
+
* scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
|
4977
4984
|
* })
|
|
4978
4985
|
*/
|
|
4979
4986
|
lookupDocuments(request, requestOptions) {
|
|
4980
4987
|
return HttpResponsePromise.fromPromise(this.__lookupDocuments(request, requestOptions));
|
|
4981
4988
|
}
|
|
4982
4989
|
async __lookupDocuments(request, requestOptions) {
|
|
4983
|
-
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order } = request;
|
|
4990
|
+
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order, userId, scope } = request;
|
|
4984
4991
|
const _queryParams = {
|
|
4985
4992
|
type: type_,
|
|
4986
4993
|
field,
|
|
@@ -4990,7 +4997,9 @@ var DocumentsClient = class {
|
|
|
4990
4997
|
prefix,
|
|
4991
4998
|
startFrom,
|
|
4992
4999
|
limit,
|
|
4993
|
-
order: order != null ? order : void 0
|
|
5000
|
+
order: order != null ? order : void 0,
|
|
5001
|
+
userId,
|
|
5002
|
+
scope
|
|
4994
5003
|
};
|
|
4995
5004
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
4996
5005
|
const _headers = mergeHeaders(
|
|
@@ -5016,11 +5025,16 @@ var DocumentsClient = class {
|
|
|
5016
5025
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
5017
5026
|
}
|
|
5018
5027
|
if (_response.error.reason === "status-code") {
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5028
|
+
switch (_response.error.statusCode) {
|
|
5029
|
+
case 400:
|
|
5030
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5031
|
+
default:
|
|
5032
|
+
throw new VectrosError({
|
|
5033
|
+
statusCode: _response.error.statusCode,
|
|
5034
|
+
body: _response.error.body,
|
|
5035
|
+
rawResponse: _response.rawResponse
|
|
5036
|
+
});
|
|
5037
|
+
}
|
|
5024
5038
|
}
|
|
5025
5039
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/lookup");
|
|
5026
5040
|
}
|
|
@@ -5340,7 +5354,7 @@ var FoldersClient = class {
|
|
|
5340
5354
|
* parentFolderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
5341
5355
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
5342
5356
|
* scope: "group:eng-team",
|
|
5343
|
-
* startFrom: "
|
|
5357
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
5344
5358
|
* })
|
|
5345
5359
|
*/
|
|
5346
5360
|
listFolders(request = {}, requestOptions) {
|
|
@@ -5388,7 +5402,7 @@ var FoldersClient = class {
|
|
|
5388
5402
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
|
|
5389
5403
|
}
|
|
5390
5404
|
/**
|
|
5391
|
-
* 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.
|
|
5405
|
+
* 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.
|
|
5392
5406
|
*
|
|
5393
5407
|
* @param {Vectros.CreateFolderRequest} request
|
|
5394
5408
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -5517,6 +5531,7 @@ var FoldersClient = class {
|
|
|
5517
5531
|
* @param {Vectros.UpdateFolderRequest} request
|
|
5518
5532
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5519
5533
|
*
|
|
5534
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5520
5535
|
* @throws {@link Vectros.NotFoundError}
|
|
5521
5536
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
5522
5537
|
*
|
|
@@ -5561,6 +5576,8 @@ var FoldersClient = class {
|
|
|
5561
5576
|
}
|
|
5562
5577
|
if (_response.error.reason === "status-code") {
|
|
5563
5578
|
switch (_response.error.statusCode) {
|
|
5579
|
+
case 403:
|
|
5580
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5564
5581
|
case 404:
|
|
5565
5582
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5566
5583
|
case 429:
|
|
@@ -5643,6 +5660,7 @@ var FoldersClient = class {
|
|
|
5643
5660
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5644
5661
|
*
|
|
5645
5662
|
* @throws {@link Vectros.BadRequestError}
|
|
5663
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5646
5664
|
* @throws {@link Vectros.NotFoundError}
|
|
5647
5665
|
* @throws {@link Vectros.ConflictError}
|
|
5648
5666
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -5690,6 +5708,8 @@ var FoldersClient = class {
|
|
|
5690
5708
|
switch (_response.error.statusCode) {
|
|
5691
5709
|
case 400:
|
|
5692
5710
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5711
|
+
case 403:
|
|
5712
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5693
5713
|
case 404:
|
|
5694
5714
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5695
5715
|
case 409:
|
|
@@ -5777,7 +5797,8 @@ var IdentityClient = class {
|
|
|
5777
5797
|
*
|
|
5778
5798
|
* @example
|
|
5779
5799
|
* await client.identity.listEntities({
|
|
5780
|
-
* namespace: "team"
|
|
5800
|
+
* namespace: "team",
|
|
5801
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
5781
5802
|
* })
|
|
5782
5803
|
*/
|
|
5783
5804
|
listEntities(request, requestOptions) {
|
|
@@ -5846,7 +5867,7 @@ var IdentityClient = class {
|
|
|
5846
5867
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
|
|
5847
5868
|
}
|
|
5848
5869
|
/**
|
|
5849
|
-
* 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.
|
|
5870
|
+
* 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.
|
|
5850
5871
|
*
|
|
5851
5872
|
* @param {Vectros.CreateEntityRequest} request
|
|
5852
5873
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6290,7 +6311,7 @@ var IdentityClient = class {
|
|
|
6290
6311
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
|
|
6291
6312
|
}
|
|
6292
6313
|
/**
|
|
6293
|
-
* 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.
|
|
6314
|
+
* 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.
|
|
6294
6315
|
*
|
|
6295
6316
|
* @param {Vectros.UpdateNamespaceRequest} request
|
|
6296
6317
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6303,7 +6324,8 @@ var IdentityClient = class {
|
|
|
6303
6324
|
* await client.identity.updateNamespace({
|
|
6304
6325
|
* namespace: "team",
|
|
6305
6326
|
* body: {
|
|
6306
|
-
* namespace: "team"
|
|
6327
|
+
* namespace: "team",
|
|
6328
|
+
* specificityRank: 1500
|
|
6307
6329
|
* }
|
|
6308
6330
|
* })
|
|
6309
6331
|
*/
|
|
@@ -6468,7 +6490,7 @@ var IdentityClient = class {
|
|
|
6468
6490
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
|
|
6469
6491
|
}
|
|
6470
6492
|
/**
|
|
6471
|
-
* 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.
|
|
6493
|
+
* 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.
|
|
6472
6494
|
*
|
|
6473
6495
|
* @param {Vectros.NamespaceRequest} request
|
|
6474
6496
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6479,7 +6501,8 @@ var IdentityClient = class {
|
|
|
6479
6501
|
*
|
|
6480
6502
|
* @example
|
|
6481
6503
|
* await client.identity.registerNamespace({
|
|
6482
|
-
* namespace: "team"
|
|
6504
|
+
* namespace: "team",
|
|
6505
|
+
* specificityRank: 1500
|
|
6483
6506
|
* })
|
|
6484
6507
|
*/
|
|
6485
6508
|
registerNamespace(request, requestOptions) {
|
|
@@ -6539,7 +6562,7 @@ var IdentityClient = class {
|
|
|
6539
6562
|
* @example
|
|
6540
6563
|
* await client.identity.listUsers({
|
|
6541
6564
|
* externalId: "usr_12345",
|
|
6542
|
-
* startFrom: "
|
|
6565
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl",
|
|
6543
6566
|
* type: "person_v1",
|
|
6544
6567
|
* field: "team",
|
|
6545
6568
|
* value: "engineering",
|
|
@@ -6596,7 +6619,7 @@ var IdentityClient = class {
|
|
|
6596
6619
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
|
|
6597
6620
|
}
|
|
6598
6621
|
/**
|
|
6599
|
-
* 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.
|
|
6622
|
+
* 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.
|
|
6600
6623
|
*
|
|
6601
6624
|
* @param {Vectros.CreateUserRequest} request
|
|
6602
6625
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6720,11 +6743,12 @@ var IdentityClient = class {
|
|
|
6720
6743
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users/{id}");
|
|
6721
6744
|
}
|
|
6722
6745
|
/**
|
|
6723
|
-
* 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.
|
|
6746
|
+
* 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.
|
|
6724
6747
|
*
|
|
6725
6748
|
* @param {Vectros.UpdateUserRequest} request
|
|
6726
6749
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6727
6750
|
*
|
|
6751
|
+
* @throws {@link Vectros.BadRequestError}
|
|
6728
6752
|
* @throws {@link Vectros.NotFoundError}
|
|
6729
6753
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
6730
6754
|
*
|
|
@@ -6769,6 +6793,8 @@ var IdentityClient = class {
|
|
|
6769
6793
|
}
|
|
6770
6794
|
if (_response.error.reason === "status-code") {
|
|
6771
6795
|
switch (_response.error.statusCode) {
|
|
6796
|
+
case 400:
|
|
6797
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6772
6798
|
case 404:
|
|
6773
6799
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6774
6800
|
case 429:
|
|
@@ -7416,7 +7442,7 @@ var RecordsClient = class {
|
|
|
7416
7442
|
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
7417
7443
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
7418
7444
|
* scope: "group:eng-team",
|
|
7419
|
-
* startFrom: "
|
|
7445
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
7420
7446
|
* })
|
|
7421
7447
|
*/
|
|
7422
7448
|
listRecords(request = {}, requestOptions) {
|
|
@@ -7467,7 +7493,7 @@ var RecordsClient = class {
|
|
|
7467
7493
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
|
|
7468
7494
|
}
|
|
7469
7495
|
/**
|
|
7470
|
-
* 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.
|
|
7496
|
+
* 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.
|
|
7471
7497
|
*
|
|
7472
7498
|
* @param {Vectros.CreateRecordRequest} request
|
|
7473
7499
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -7604,6 +7630,7 @@ var RecordsClient = class {
|
|
|
7604
7630
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7605
7631
|
*
|
|
7606
7632
|
* @throws {@link Vectros.BadRequestError}
|
|
7633
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
7607
7634
|
* @throws {@link Vectros.NotFoundError}
|
|
7608
7635
|
* @throws {@link Vectros.ConflictError}
|
|
7609
7636
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -7652,6 +7679,8 @@ var RecordsClient = class {
|
|
|
7652
7679
|
switch (_response.error.statusCode) {
|
|
7653
7680
|
case 400:
|
|
7654
7681
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7682
|
+
case 403:
|
|
7683
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7655
7684
|
case 404:
|
|
7656
7685
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7657
7686
|
case 409:
|
|
@@ -7733,6 +7762,7 @@ var RecordsClient = class {
|
|
|
7733
7762
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7734
7763
|
*
|
|
7735
7764
|
* @throws {@link Vectros.BadRequestError}
|
|
7765
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
7736
7766
|
* @throws {@link Vectros.NotFoundError}
|
|
7737
7767
|
* @throws {@link Vectros.ConflictError}
|
|
7738
7768
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
@@ -7783,6 +7813,8 @@ var RecordsClient = class {
|
|
|
7783
7813
|
switch (_response.error.statusCode) {
|
|
7784
7814
|
case 400:
|
|
7785
7815
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7816
|
+
case 403:
|
|
7817
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7786
7818
|
case 404:
|
|
7787
7819
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7788
7820
|
case 409:
|
|
@@ -7800,7 +7832,15 @@ var RecordsClient = class {
|
|
|
7800
7832
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/records/{id}");
|
|
7801
7833
|
}
|
|
7802
7834
|
/**
|
|
7803
|
-
* 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.
|
|
7835
|
+
* 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.
|
|
7836
|
+
*
|
|
7837
|
+
* 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`.
|
|
7838
|
+
*
|
|
7839
|
+
* 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.
|
|
7840
|
+
*
|
|
7841
|
+
* 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.
|
|
7842
|
+
*
|
|
7843
|
+
* 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.
|
|
7804
7844
|
*
|
|
7805
7845
|
* @param {Vectros.LookupRecordsRequest} request
|
|
7806
7846
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -7812,22 +7852,40 @@ var RecordsClient = class {
|
|
|
7812
7852
|
* type: "intake_form",
|
|
7813
7853
|
* field: "email",
|
|
7814
7854
|
* value: "jane@example.com",
|
|
7855
|
+
* values: ["open"],
|
|
7815
7856
|
* prefix: "jane",
|
|
7816
|
-
* startFrom: "
|
|
7857
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
7817
7858
|
* })
|
|
7818
7859
|
*/
|
|
7819
7860
|
lookupRecords(request, requestOptions) {
|
|
7820
7861
|
return HttpResponsePromise.fromPromise(this.__lookupRecords(request, requestOptions));
|
|
7821
7862
|
}
|
|
7822
7863
|
async __lookupRecords(request, requestOptions) {
|
|
7823
|
-
const {
|
|
7864
|
+
const {
|
|
7865
|
+
type: type_,
|
|
7866
|
+
field,
|
|
7867
|
+
value,
|
|
7868
|
+
values,
|
|
7869
|
+
from: from_,
|
|
7870
|
+
to,
|
|
7871
|
+
prefix,
|
|
7872
|
+
sortFrom,
|
|
7873
|
+
sortTo,
|
|
7874
|
+
startFrom,
|
|
7875
|
+
limit,
|
|
7876
|
+
includePayload,
|
|
7877
|
+
order
|
|
7878
|
+
} = request;
|
|
7824
7879
|
const _queryParams = {
|
|
7825
7880
|
type: type_,
|
|
7826
7881
|
field,
|
|
7827
7882
|
value,
|
|
7883
|
+
values,
|
|
7828
7884
|
from: from_,
|
|
7829
7885
|
to,
|
|
7830
7886
|
prefix,
|
|
7887
|
+
sortFrom,
|
|
7888
|
+
sortTo,
|
|
7831
7889
|
startFrom,
|
|
7832
7890
|
limit,
|
|
7833
7891
|
includePayload,
|
|
@@ -7871,7 +7929,7 @@ var RecordsClient = class {
|
|
|
7871
7929
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records/lookup");
|
|
7872
7930
|
}
|
|
7873
7931
|
/**
|
|
7874
|
-
* 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.
|
|
7932
|
+
* 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.
|
|
7875
7933
|
*
|
|
7876
7934
|
* @param {Vectros.RecordLookupRequest} request
|
|
7877
7935
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8058,13 +8116,15 @@ var SchemasClient = class {
|
|
|
8058
8116
|
* @param {Vectros.ListSchemasRequest} request
|
|
8059
8117
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8060
8118
|
*
|
|
8119
|
+
* @throws {@link Vectros.BadRequestError}
|
|
8120
|
+
*
|
|
8061
8121
|
* @example
|
|
8062
8122
|
* await client.schemas.listSchemas({
|
|
8063
8123
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
8064
8124
|
* scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
|
8065
8125
|
* surface: "document",
|
|
8066
8126
|
* recordType: "intake_form",
|
|
8067
|
-
* startFrom: "
|
|
8127
|
+
* startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
|
|
8068
8128
|
* })
|
|
8069
8129
|
*/
|
|
8070
8130
|
listSchemas(request = {}, requestOptions) {
|
|
@@ -8104,16 +8164,21 @@ var SchemasClient = class {
|
|
|
8104
8164
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
8105
8165
|
}
|
|
8106
8166
|
if (_response.error.reason === "status-code") {
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8167
|
+
switch (_response.error.statusCode) {
|
|
8168
|
+
case 400:
|
|
8169
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8170
|
+
default:
|
|
8171
|
+
throw new VectrosError({
|
|
8172
|
+
statusCode: _response.error.statusCode,
|
|
8173
|
+
body: _response.error.body,
|
|
8174
|
+
rawResponse: _response.rawResponse
|
|
8175
|
+
});
|
|
8176
|
+
}
|
|
8112
8177
|
}
|
|
8113
8178
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
|
|
8114
8179
|
}
|
|
8115
8180
|
/**
|
|
8116
|
-
* 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:
|
|
8181
|
+
* 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.
|
|
8117
8182
|
*
|
|
8118
8183
|
* @param {Vectros.CreateSchemaRequest} request
|
|
8119
8184
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8257,12 +8322,13 @@ var SchemasClient = class {
|
|
|
8257
8322
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas/{id}");
|
|
8258
8323
|
}
|
|
8259
8324
|
/**
|
|
8260
|
-
* 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:
|
|
8325
|
+
* 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.
|
|
8261
8326
|
*
|
|
8262
8327
|
* @param {Vectros.UpdateSchemaRequest} request
|
|
8263
8328
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8264
8329
|
*
|
|
8265
8330
|
* @throws {@link Vectros.BadRequestError}
|
|
8331
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
8266
8332
|
* @throws {@link Vectros.NotFoundError}
|
|
8267
8333
|
* @throws {@link Vectros.TooManyRequestsError}
|
|
8268
8334
|
*
|
|
@@ -8311,6 +8377,8 @@ var SchemasClient = class {
|
|
|
8311
8377
|
switch (_response.error.statusCode) {
|
|
8312
8378
|
case 400:
|
|
8313
8379
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8380
|
+
case 403:
|
|
8381
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8314
8382
|
case 404:
|
|
8315
8383
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8316
8384
|
case 429:
|
|
@@ -8326,7 +8394,7 @@ var SchemasClient = class {
|
|
|
8326
8394
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
|
|
8327
8395
|
}
|
|
8328
8396
|
/**
|
|
8329
|
-
* 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:
|
|
8397
|
+
* 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.
|
|
8330
8398
|
*
|
|
8331
8399
|
* @param {Vectros.DeleteSchemaRequest} request
|
|
8332
8400
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8623,8 +8691,8 @@ function warnOnSuboptimalKey(key, log) {
|
|
|
8623
8691
|
|
|
8624
8692
|
// src/build-info.ts
|
|
8625
8693
|
var BUILD_INFO = {
|
|
8626
|
-
mcpServer: true ? "0.
|
|
8627
|
-
sdk: true ? "0.
|
|
8694
|
+
mcpServer: true ? "0.13.0" : "dev",
|
|
8695
|
+
sdk: true ? "0.38.0" : "dev"
|
|
8628
8696
|
};
|
|
8629
8697
|
|
|
8630
8698
|
// src/log.ts
|
|
@@ -8664,7 +8732,9 @@ async function resolveIdentity({
|
|
|
8664
8732
|
const derived = {
|
|
8665
8733
|
status: "ok",
|
|
8666
8734
|
environment: deriveEnvironment(environment),
|
|
8667
|
-
principalType: derivePrincipalType(apiKey)
|
|
8735
|
+
principalType: derivePrincipalType(apiKey),
|
|
8736
|
+
mcpServerVersion: BUILD_INFO.mcpServer,
|
|
8737
|
+
sdkVersion: BUILD_INFO.sdk
|
|
8668
8738
|
};
|
|
8669
8739
|
if (!apiKey || !environment) {
|
|
8670
8740
|
log.debug({ component: "identity", mode: "derived-only" }, "identity derived (no fetch)");
|
|
@@ -8692,7 +8762,13 @@ async function resolveIdentity({
|
|
|
8692
8762
|
);
|
|
8693
8763
|
}
|
|
8694
8764
|
}
|
|
8695
|
-
const merged = {
|
|
8765
|
+
const merged = {
|
|
8766
|
+
...derived,
|
|
8767
|
+
...extended,
|
|
8768
|
+
status: "ok",
|
|
8769
|
+
mcpServerVersion: derived.mcpServerVersion,
|
|
8770
|
+
sdkVersion: derived.sdkVersion
|
|
8771
|
+
};
|
|
8696
8772
|
log.debug(
|
|
8697
8773
|
{
|
|
8698
8774
|
component: "identity",
|
|
@@ -9014,14 +9090,23 @@ var import_zod2 = require("zod");
|
|
|
9014
9090
|
function pageItems(page) {
|
|
9015
9091
|
return page.data ?? [];
|
|
9016
9092
|
}
|
|
9093
|
+
var MAX_PAGES = 100;
|
|
9094
|
+
var MAX_ROWS = 1e6;
|
|
9017
9095
|
async function drainPages(fetchPage) {
|
|
9018
9096
|
const all = [];
|
|
9019
9097
|
let startFrom;
|
|
9098
|
+
let pages = 0;
|
|
9020
9099
|
for (; ; ) {
|
|
9021
9100
|
const page = await fetchPage(startFrom);
|
|
9022
|
-
|
|
9101
|
+
pages++;
|
|
9102
|
+
if (page.data?.length) for (const item of page.data) all.push(item);
|
|
9023
9103
|
const next = page.nextCursor;
|
|
9024
9104
|
if (!next) break;
|
|
9105
|
+
if (pages > MAX_PAGES || all.length > MAX_ROWS) {
|
|
9106
|
+
throw new Error(
|
|
9107
|
+
`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.`
|
|
9108
|
+
);
|
|
9109
|
+
}
|
|
9025
9110
|
startFrom = next;
|
|
9026
9111
|
}
|
|
9027
9112
|
return all;
|
|
@@ -9032,14 +9117,23 @@ var MCP_DEFAULT_LIMIT2 = 3;
|
|
|
9032
9117
|
var MCP_MAX_LIMIT2 = 100;
|
|
9033
9118
|
var inputSchema2 = {
|
|
9034
9119
|
type: import_zod2.z.string().min(1, "type (record type) is required").describe('Record type / schema name (e.g. "patient", "clinical_note").'),
|
|
9035
|
-
// Lookup-mode args — provide `field` plus EXACTLY ONE of: value | from+to | prefix.
|
|
9120
|
+
// Lookup-mode args — provide `field` plus EXACTLY ONE of: value | values | from+to | prefix.
|
|
9036
9121
|
field: import_zod2.z.string().optional().describe(
|
|
9037
|
-
'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.)'
|
|
9122
|
+
'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.'
|
|
9123
|
+
),
|
|
9124
|
+
value: import_zod2.z.string().optional().describe(
|
|
9125
|
+
"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)."
|
|
9126
|
+
),
|
|
9127
|
+
values: import_zod2.z.array(import_zod2.z.string()).min(1).max(3).optional().describe(
|
|
9128
|
+
'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).'
|
|
9038
9129
|
),
|
|
9039
|
-
value: import_zod2.z.string().optional().describe("Lookup mode (equality): exact-match value for `field`."),
|
|
9040
9130
|
from: import_zod2.z.string().optional().describe("Lookup mode (range): inclusive lower bound; requires `to`. Non-sensitive fields only."),
|
|
9041
9131
|
to: import_zod2.z.string().optional().describe("Lookup mode (range): inclusive upper bound; requires `from`."),
|
|
9042
9132
|
prefix: import_zod2.z.string().optional().describe("Lookup mode (prefix): match values starting with this. String, non-sensitive fields only."),
|
|
9133
|
+
sortFrom: import_zod2.z.string().optional().describe(
|
|
9134
|
+
"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`."
|
|
9135
|
+
),
|
|
9136
|
+
sortTo: import_zod2.z.string().optional().describe("Lookup mode (equality/composite only): inclusive upper bound on the sort key; pairs with `sortFrom`."),
|
|
9043
9137
|
order: import_zod2.z.enum(["asc", "desc"]).optional().describe(
|
|
9044
9138
|
"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."
|
|
9045
9139
|
),
|
|
@@ -9056,54 +9150,106 @@ var inputSchema2 = {
|
|
|
9056
9150
|
var recordQuery = ({ client, log }) => ({
|
|
9057
9151
|
name: "record_query",
|
|
9058
9152
|
title: "Record query (list or lookup)",
|
|
9059
|
-
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
|
|
9153
|
+
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.",
|
|
9060
9154
|
inputSchema: inputSchema2,
|
|
9061
9155
|
handler: async (args) => {
|
|
9062
9156
|
const limit = args.limit ?? MCP_DEFAULT_LIMIT2;
|
|
9063
9157
|
const type = args.type;
|
|
9064
9158
|
const field = args.field;
|
|
9065
9159
|
const value = args.value;
|
|
9160
|
+
const values = args.values;
|
|
9066
9161
|
const from = args.from;
|
|
9067
9162
|
const to = args.to;
|
|
9068
9163
|
const prefix = args.prefix;
|
|
9164
|
+
const sortFrom = args.sortFrom;
|
|
9165
|
+
const sortTo = args.sortTo;
|
|
9069
9166
|
const startFrom = args.startFrom;
|
|
9167
|
+
if (!field && (value !== void 0 || values !== void 0 || from !== void 0 || to !== void 0 || prefix !== void 0 || sortFrom !== void 0 || sortTo !== void 0)) {
|
|
9168
|
+
return toolError(
|
|
9169
|
+
"record_query",
|
|
9170
|
+
new Error(
|
|
9171
|
+
"'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."
|
|
9172
|
+
)
|
|
9173
|
+
);
|
|
9174
|
+
}
|
|
9070
9175
|
try {
|
|
9071
9176
|
let page;
|
|
9072
9177
|
if (field) {
|
|
9178
|
+
const fieldNames = field.split(",").map((f) => f.trim()).filter(Boolean);
|
|
9179
|
+
const normalizedField = fieldNames.join(",");
|
|
9180
|
+
const isCompositeField = fieldNames.length > 1;
|
|
9073
9181
|
const hasEquality = value !== void 0;
|
|
9182
|
+
const hasComposite = values !== void 0;
|
|
9074
9183
|
const hasRange = from !== void 0 || to !== void 0;
|
|
9075
9184
|
const hasPrefix = prefix !== void 0;
|
|
9076
|
-
const modes = Number(hasEquality) + Number(hasRange) + Number(hasPrefix);
|
|
9185
|
+
const modes = Number(hasEquality) + Number(hasComposite) + Number(hasRange) + Number(hasPrefix);
|
|
9077
9186
|
if (modes === 0) {
|
|
9078
9187
|
return toolError(
|
|
9079
9188
|
"record_query",
|
|
9080
9189
|
new Error(
|
|
9081
|
-
`lookup on field '${field}' needs one of: 'value' (exact), 'from'+'to' (range), or 'prefix'.`
|
|
9190
|
+
`lookup on field '${field}' needs one of: 'value' (exact), 'values' (composite exact), 'from'+'to' (range), or 'prefix'.`
|
|
9082
9191
|
)
|
|
9083
9192
|
);
|
|
9084
9193
|
}
|
|
9085
9194
|
if (modes > 1) {
|
|
9086
9195
|
return toolError(
|
|
9087
9196
|
"record_query",
|
|
9088
|
-
new Error(
|
|
9197
|
+
new Error(
|
|
9198
|
+
"'value', 'values', 'from'/'to', and 'prefix' are mutually exclusive \u2014 provide exactly one."
|
|
9199
|
+
)
|
|
9089
9200
|
);
|
|
9090
9201
|
}
|
|
9091
9202
|
if (hasRange && !(from !== void 0 && to !== void 0)) {
|
|
9092
9203
|
return toolError("record_query", new Error("range lookup requires both 'from' and 'to'."));
|
|
9093
9204
|
}
|
|
9205
|
+
if (isCompositeField && (hasRange || hasPrefix)) {
|
|
9206
|
+
return toolError(
|
|
9207
|
+
"record_query",
|
|
9208
|
+
new Error(
|
|
9209
|
+
`'field' names ${fieldNames.length} fields ('${normalizedField}') \u2014 a composite lookup is exact-match only ('value' or 'values'), not 'from'/'to'/'prefix'.`
|
|
9210
|
+
)
|
|
9211
|
+
);
|
|
9212
|
+
}
|
|
9213
|
+
if (hasComposite && values.length > fieldNames.length) {
|
|
9214
|
+
return toolError(
|
|
9215
|
+
"record_query",
|
|
9216
|
+
new Error(
|
|
9217
|
+
`'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).`
|
|
9218
|
+
)
|
|
9219
|
+
);
|
|
9220
|
+
}
|
|
9221
|
+
if (sortFrom !== void 0 || sortTo !== void 0) {
|
|
9222
|
+
if (!(hasEquality || hasComposite)) {
|
|
9223
|
+
return toolError(
|
|
9224
|
+
"record_query",
|
|
9225
|
+
new Error("'sortFrom'/'sortTo' narrow a 'value' or 'values' match only \u2014 not 'from'/'to'/'prefix'.")
|
|
9226
|
+
);
|
|
9227
|
+
}
|
|
9228
|
+
if (hasComposite && values.length < fieldNames.length) {
|
|
9229
|
+
return toolError(
|
|
9230
|
+
"record_query",
|
|
9231
|
+
new Error(
|
|
9232
|
+
`'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.`
|
|
9233
|
+
)
|
|
9234
|
+
);
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9094
9237
|
page = await client.records.lookupRecordsByBody({
|
|
9095
9238
|
type,
|
|
9096
|
-
field,
|
|
9239
|
+
field: normalizedField,
|
|
9097
9240
|
value,
|
|
9241
|
+
values,
|
|
9098
9242
|
from,
|
|
9099
9243
|
to,
|
|
9100
9244
|
prefix,
|
|
9245
|
+
sortFrom,
|
|
9246
|
+
sortTo,
|
|
9101
9247
|
order: args.order,
|
|
9102
9248
|
startFrom,
|
|
9103
9249
|
limit
|
|
9104
9250
|
});
|
|
9105
9251
|
log.debug(
|
|
9106
|
-
{ tool: "record_query", mode: "lookup", type, field, returned: pageItems(page).length },
|
|
9252
|
+
{ tool: "record_query", mode: "lookup", type, field: normalizedField, returned: pageItems(page).length },
|
|
9107
9253
|
"record_query lookup ok"
|
|
9108
9254
|
);
|
|
9109
9255
|
} else {
|
|
@@ -9136,14 +9282,14 @@ var record_query_default = recordQuery;
|
|
|
9136
9282
|
var import_zod3 = require("zod");
|
|
9137
9283
|
|
|
9138
9284
|
// src/tools/resolve-external-id.ts
|
|
9139
|
-
function validateSelector(sel, entity) {
|
|
9285
|
+
function validateSelector(sel, entity, fieldName) {
|
|
9140
9286
|
const hasId = sel.id !== void 0 && sel.id !== "";
|
|
9141
9287
|
const hasExt = sel.externalId !== void 0 && sel.externalId !== "";
|
|
9142
9288
|
if (hasId && hasExt) {
|
|
9143
|
-
return `Provide either
|
|
9289
|
+
return `Provide either ${fieldName} or externalId (not both) to identify the ${entity}.`;
|
|
9144
9290
|
}
|
|
9145
9291
|
if (!hasId && !hasExt) {
|
|
9146
|
-
return `Provide
|
|
9292
|
+
return `Provide ${fieldName}, or externalId + type, to identify the ${entity}.`;
|
|
9147
9293
|
}
|
|
9148
9294
|
if (hasExt && (sel.type === void 0 || sel.type === "")) {
|
|
9149
9295
|
return "type is required when selecting by externalId (externalId is unique within a type).";
|
|
@@ -9151,7 +9297,7 @@ function validateSelector(sel, entity) {
|
|
|
9151
9297
|
return void 0;
|
|
9152
9298
|
}
|
|
9153
9299
|
async function resolveRecordIdByExternalId(client, sel) {
|
|
9154
|
-
const err = validateSelector(sel, "record");
|
|
9300
|
+
const err = validateSelector(sel, "record", "id");
|
|
9155
9301
|
if (err) return { error: err };
|
|
9156
9302
|
if (sel.id) return { id: sel.id };
|
|
9157
9303
|
const page = await client.records.lookupRecordsByBody({
|
|
@@ -9167,7 +9313,7 @@ async function resolveRecordIdByExternalId(client, sel) {
|
|
|
9167
9313
|
return { id: items[0].id };
|
|
9168
9314
|
}
|
|
9169
9315
|
async function resolveDocumentIdByExternalId(client, sel) {
|
|
9170
|
-
const err = validateSelector(sel, "document");
|
|
9316
|
+
const err = validateSelector(sel, "document", "documentId");
|
|
9171
9317
|
if (err) return { error: err };
|
|
9172
9318
|
if (sel.id) return { id: sel.id };
|
|
9173
9319
|
const page = await client.documents.lookupDocumentsByBody({
|
|
@@ -10042,7 +10188,7 @@ var inputSchema18 = {
|
|
|
10042
10188
|
var currentIdentity = ({ log, apiKey, environment }) => ({
|
|
10043
10189
|
name: "current_identity",
|
|
10044
10190
|
title: "Current identity (tenant + principal scope)",
|
|
10045
|
-
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?'
|
|
10191
|
+
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.",
|
|
10046
10192
|
inputSchema: inputSchema18,
|
|
10047
10193
|
handler: async () => {
|
|
10048
10194
|
try {
|
|
@@ -10520,7 +10666,7 @@ var identityResource = ({ log, apiKey, environment }) => ({
|
|
|
10520
10666
|
name: "identity",
|
|
10521
10667
|
uri: "vectros://identity",
|
|
10522
10668
|
title: "Current identity (tenant + principal scope)",
|
|
10523
|
-
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,
|
|
10669
|
+
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.",
|
|
10524
10670
|
mimeType: "application/json",
|
|
10525
10671
|
read: async () => {
|
|
10526
10672
|
const identity = await resolveIdentity({ log, apiKey, environment });
|