@vectros-ai/cli 0.5.1 → 0.6.4
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/AUTHORING.md +12 -0
- package/CHANGELOG.md +74 -0
- package/README.md +18 -0
- package/dist/cli.js +1260 -217
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1260 -217
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -2537,6 +2537,7 @@ var AuthClient = class {
|
|
|
2537
2537
|
* @throws {@link Vectros.BadRequestError}
|
|
2538
2538
|
* @throws {@link Vectros.ForbiddenError}
|
|
2539
2539
|
* @throws {@link Vectros.NotFoundError}
|
|
2540
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2540
2541
|
*
|
|
2541
2542
|
* @example
|
|
2542
2543
|
* await client.auth.createScopedKey({
|
|
@@ -2584,6 +2585,8 @@ var AuthClient = class {
|
|
|
2584
2585
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2585
2586
|
case 404:
|
|
2586
2587
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2588
|
+
case 429:
|
|
2589
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2587
2590
|
default:
|
|
2588
2591
|
throw new VectrosError({
|
|
2589
2592
|
statusCode: _response.error.statusCode,
|
|
@@ -2660,6 +2663,7 @@ var AuthClient = class {
|
|
|
2660
2663
|
*
|
|
2661
2664
|
* @throws {@link Vectros.ForbiddenError}
|
|
2662
2665
|
* @throws {@link Vectros.NotFoundError}
|
|
2666
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2663
2667
|
*
|
|
2664
2668
|
* @example
|
|
2665
2669
|
* await client.auth.revokeScopedKey({
|
|
@@ -2700,6 +2704,8 @@ var AuthClient = class {
|
|
|
2700
2704
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2701
2705
|
case 404:
|
|
2702
2706
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2707
|
+
case 429:
|
|
2708
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2703
2709
|
default:
|
|
2704
2710
|
throw new VectrosError({
|
|
2705
2711
|
statusCode: _response.error.statusCode,
|
|
@@ -2855,7 +2861,7 @@ var AuthClient = class {
|
|
|
2855
2861
|
);
|
|
2856
2862
|
}
|
|
2857
2863
|
/**
|
|
2858
|
-
* 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. 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` may set only `orgId` and `clientId`; 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.
|
|
2864
|
+
* 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` may set only `orgId` and `clientId`; 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.
|
|
2859
2865
|
*
|
|
2860
2866
|
* @param {Vectros.CreateAccessProfileRequest} request
|
|
2861
2867
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -2863,6 +2869,7 @@ var AuthClient = class {
|
|
|
2863
2869
|
* @throws {@link Vectros.BadRequestError}
|
|
2864
2870
|
* @throws {@link Vectros.ForbiddenError}
|
|
2865
2871
|
* @throws {@link Vectros.NotFoundError}
|
|
2872
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2866
2873
|
*
|
|
2867
2874
|
* @example
|
|
2868
2875
|
* await client.auth.createAccessProfile({
|
|
@@ -2876,7 +2883,10 @@ var AuthClient = class {
|
|
|
2876
2883
|
return HttpResponsePromise.fromPromise(this.__createAccessProfile(request, requestOptions));
|
|
2877
2884
|
}
|
|
2878
2885
|
async __createAccessProfile(request, requestOptions) {
|
|
2879
|
-
const { contextId, body: _body } = request;
|
|
2886
|
+
const { contextId, upsert, body: _body } = request;
|
|
2887
|
+
const _queryParams = {
|
|
2888
|
+
upsert
|
|
2889
|
+
};
|
|
2880
2890
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
2881
2891
|
const _headers = mergeHeaders(
|
|
2882
2892
|
_authRequest.headers,
|
|
@@ -2891,7 +2901,7 @@ var AuthClient = class {
|
|
|
2891
2901
|
method: "POST",
|
|
2892
2902
|
headers: _headers,
|
|
2893
2903
|
contentType: "application/json",
|
|
2894
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
2904
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
2895
2905
|
requestType: "json",
|
|
2896
2906
|
body: _body,
|
|
2897
2907
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
@@ -2911,6 +2921,8 @@ var AuthClient = class {
|
|
|
2911
2921
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2912
2922
|
case 404:
|
|
2913
2923
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2924
|
+
case 429:
|
|
2925
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2914
2926
|
default:
|
|
2915
2927
|
throw new VectrosError({
|
|
2916
2928
|
statusCode: _response.error.statusCode,
|
|
@@ -2984,24 +2996,31 @@ var AuthClient = class {
|
|
|
2984
2996
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/app-contexts");
|
|
2985
2997
|
}
|
|
2986
2998
|
/**
|
|
2987
|
-
* Creates a new app context. This call is idempotent by `contextId`: if an app context with the same `contextId` already exists, the existing app context is returned (with status 200) instead of creating a duplicate. The reserved `contextId` value `vectros-admin` cannot be created through this endpoint; it is provisioned automatically for your account. Requires the `app-contexts:c` scope.
|
|
2999
|
+
* Creates a new app context. This call is idempotent by `contextId`: if an app context with the same `contextId` already exists, the existing app context 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 context was returned) tells the two apart. To overwrite an existing context's `name`/`description` instead of returning it unchanged, set `?upsert=true` (this also requires the `app-contexts:u` scope). The reserved `contextId` value `vectros-admin` cannot be created through this endpoint; it is provisioned automatically for your account. Requires the `app-contexts:c` scope.
|
|
2988
3000
|
*
|
|
2989
|
-
* @param {Vectros.
|
|
3001
|
+
* @param {Vectros.CreateAppContextRequest} request
|
|
2990
3002
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
2991
3003
|
*
|
|
2992
3004
|
* @throws {@link Vectros.BadRequestError}
|
|
2993
3005
|
* @throws {@link Vectros.ForbiddenError}
|
|
3006
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2994
3007
|
*
|
|
2995
3008
|
* @example
|
|
2996
3009
|
* await client.auth.createAppContext({
|
|
2997
|
-
*
|
|
2998
|
-
*
|
|
3010
|
+
* body: {
|
|
3011
|
+
* contextId: "myapp",
|
|
3012
|
+
* name: "My Internal App"
|
|
3013
|
+
* }
|
|
2999
3014
|
* })
|
|
3000
3015
|
*/
|
|
3001
3016
|
createAppContext(request, requestOptions) {
|
|
3002
3017
|
return HttpResponsePromise.fromPromise(this.__createAppContext(request, requestOptions));
|
|
3003
3018
|
}
|
|
3004
3019
|
async __createAppContext(request, requestOptions) {
|
|
3020
|
+
const { upsert, body: _body } = request;
|
|
3021
|
+
const _queryParams = {
|
|
3022
|
+
upsert
|
|
3023
|
+
};
|
|
3005
3024
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
3006
3025
|
const _headers = mergeHeaders(
|
|
3007
3026
|
_authRequest.headers,
|
|
@@ -3016,9 +3035,9 @@ var AuthClient = class {
|
|
|
3016
3035
|
method: "POST",
|
|
3017
3036
|
headers: _headers,
|
|
3018
3037
|
contentType: "application/json",
|
|
3019
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
3038
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
3020
3039
|
requestType: "json",
|
|
3021
|
-
body:
|
|
3040
|
+
body: _body,
|
|
3022
3041
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
3023
3042
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
3024
3043
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -3034,6 +3053,8 @@ var AuthClient = class {
|
|
|
3034
3053
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
3035
3054
|
case 403:
|
|
3036
3055
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3056
|
+
case 429:
|
|
3057
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3037
3058
|
default:
|
|
3038
3059
|
throw new VectrosError({
|
|
3039
3060
|
statusCode: _response.error.statusCode,
|
|
@@ -3112,7 +3133,7 @@ var AuthClient = class {
|
|
|
3112
3133
|
);
|
|
3113
3134
|
}
|
|
3114
3135
|
/**
|
|
3115
|
-
* Creates a new role under the given app context. This call is idempotent by `roleId`: if a role with the same `roleId` already exists, the existing role is returned (with status 200) instead of creating a duplicate. If you use a scoped credential, the role's scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
|
|
3136
|
+
* Creates a new role under the given app context. This call is idempotent by `roleId`: if a role with the same `roleId` already exists, the existing role 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 role was returned) tells the two apart. To overwrite an existing role's `name`/`description`/`scopes` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope). If you use a scoped credential, the role's scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
|
|
3116
3137
|
*
|
|
3117
3138
|
* @param {Vectros.CreateRoleRequest} request
|
|
3118
3139
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3120,6 +3141,7 @@ var AuthClient = class {
|
|
|
3120
3141
|
* @throws {@link Vectros.BadRequestError}
|
|
3121
3142
|
* @throws {@link Vectros.ForbiddenError}
|
|
3122
3143
|
* @throws {@link Vectros.NotFoundError}
|
|
3144
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3123
3145
|
*
|
|
3124
3146
|
* @example
|
|
3125
3147
|
* await client.auth.createRole({
|
|
@@ -3137,7 +3159,10 @@ var AuthClient = class {
|
|
|
3137
3159
|
return HttpResponsePromise.fromPromise(this.__createRole(request, requestOptions));
|
|
3138
3160
|
}
|
|
3139
3161
|
async __createRole(request, requestOptions) {
|
|
3140
|
-
const { contextId, body: _body } = request;
|
|
3162
|
+
const { contextId, upsert, body: _body } = request;
|
|
3163
|
+
const _queryParams = {
|
|
3164
|
+
upsert
|
|
3165
|
+
};
|
|
3141
3166
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
3142
3167
|
const _headers = mergeHeaders(
|
|
3143
3168
|
_authRequest.headers,
|
|
@@ -3152,7 +3177,7 @@ var AuthClient = class {
|
|
|
3152
3177
|
method: "POST",
|
|
3153
3178
|
headers: _headers,
|
|
3154
3179
|
contentType: "application/json",
|
|
3155
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
3180
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
3156
3181
|
requestType: "json",
|
|
3157
3182
|
body: _body,
|
|
3158
3183
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
@@ -3172,6 +3197,8 @@ var AuthClient = class {
|
|
|
3172
3197
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3173
3198
|
case 404:
|
|
3174
3199
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3200
|
+
case 429:
|
|
3201
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3175
3202
|
default:
|
|
3176
3203
|
throw new VectrosError({
|
|
3177
3204
|
statusCode: _response.error.statusCode,
|
|
@@ -3259,6 +3286,7 @@ var AuthClient = class {
|
|
|
3259
3286
|
*
|
|
3260
3287
|
* @throws {@link Vectros.ForbiddenError}
|
|
3261
3288
|
* @throws {@link Vectros.NotFoundError}
|
|
3289
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3262
3290
|
*
|
|
3263
3291
|
* @example
|
|
3264
3292
|
* await client.auth.updateAccessProfile({
|
|
@@ -3306,6 +3334,8 @@ var AuthClient = class {
|
|
|
3306
3334
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3307
3335
|
case 404:
|
|
3308
3336
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3337
|
+
case 429:
|
|
3338
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3309
3339
|
default:
|
|
3310
3340
|
throw new VectrosError({
|
|
3311
3341
|
statusCode: _response.error.statusCode,
|
|
@@ -3329,6 +3359,7 @@ var AuthClient = class {
|
|
|
3329
3359
|
*
|
|
3330
3360
|
* @throws {@link Vectros.ForbiddenError}
|
|
3331
3361
|
* @throws {@link Vectros.NotFoundError}
|
|
3362
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3332
3363
|
*
|
|
3333
3364
|
* @example
|
|
3334
3365
|
* await client.auth.deleteAccessProfile({
|
|
@@ -3370,6 +3401,8 @@ var AuthClient = class {
|
|
|
3370
3401
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3371
3402
|
case 404:
|
|
3372
3403
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3404
|
+
case 429:
|
|
3405
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3373
3406
|
default:
|
|
3374
3407
|
throw new VectrosError({
|
|
3375
3408
|
statusCode: _response.error.statusCode,
|
|
@@ -3451,6 +3484,7 @@ var AuthClient = class {
|
|
|
3451
3484
|
*
|
|
3452
3485
|
* @throws {@link Vectros.ForbiddenError}
|
|
3453
3486
|
* @throws {@link Vectros.NotFoundError}
|
|
3487
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3454
3488
|
*
|
|
3455
3489
|
* @example
|
|
3456
3490
|
* await client.auth.updateAppContext({
|
|
@@ -3498,6 +3532,8 @@ var AuthClient = class {
|
|
|
3498
3532
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3499
3533
|
case 404:
|
|
3500
3534
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3535
|
+
case 429:
|
|
3536
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3501
3537
|
default:
|
|
3502
3538
|
throw new VectrosError({
|
|
3503
3539
|
statusCode: _response.error.statusCode,
|
|
@@ -3517,6 +3553,7 @@ var AuthClient = class {
|
|
|
3517
3553
|
* @throws {@link Vectros.BadRequestError}
|
|
3518
3554
|
* @throws {@link Vectros.ForbiddenError}
|
|
3519
3555
|
* @throws {@link Vectros.NotFoundError}
|
|
3556
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3520
3557
|
*
|
|
3521
3558
|
* @example
|
|
3522
3559
|
* await client.auth.deleteAppContext({
|
|
@@ -3562,6 +3599,8 @@ var AuthClient = class {
|
|
|
3562
3599
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3563
3600
|
case 404:
|
|
3564
3601
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3602
|
+
case 429:
|
|
3603
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3565
3604
|
default:
|
|
3566
3605
|
throw new VectrosError({
|
|
3567
3606
|
statusCode: _response.error.statusCode,
|
|
@@ -3649,6 +3688,7 @@ var AuthClient = class {
|
|
|
3649
3688
|
*
|
|
3650
3689
|
* @throws {@link Vectros.ForbiddenError}
|
|
3651
3690
|
* @throws {@link Vectros.NotFoundError}
|
|
3691
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3652
3692
|
*
|
|
3653
3693
|
* @example
|
|
3654
3694
|
* await client.auth.updateRole({
|
|
@@ -3700,6 +3740,8 @@ var AuthClient = class {
|
|
|
3700
3740
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3701
3741
|
case 404:
|
|
3702
3742
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3743
|
+
case 429:
|
|
3744
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3703
3745
|
default:
|
|
3704
3746
|
throw new VectrosError({
|
|
3705
3747
|
statusCode: _response.error.statusCode,
|
|
@@ -3723,6 +3765,7 @@ var AuthClient = class {
|
|
|
3723
3765
|
*
|
|
3724
3766
|
* @throws {@link Vectros.ForbiddenError}
|
|
3725
3767
|
* @throws {@link Vectros.NotFoundError}
|
|
3768
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3726
3769
|
*
|
|
3727
3770
|
* @example
|
|
3728
3771
|
* await client.auth.deleteRole({
|
|
@@ -3764,6 +3807,8 @@ var AuthClient = class {
|
|
|
3764
3807
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3765
3808
|
case 404:
|
|
3766
3809
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3810
|
+
case 429:
|
|
3811
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3767
3812
|
default:
|
|
3768
3813
|
throw new VectrosError({
|
|
3769
3814
|
statusCode: _response.error.statusCode,
|
|
@@ -4095,6 +4140,7 @@ var AuthClient = class {
|
|
|
4095
4140
|
*
|
|
4096
4141
|
* @throws {@link Vectros.BadRequestError}
|
|
4097
4142
|
* @throws {@link Vectros.ForbiddenError}
|
|
4143
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4098
4144
|
*
|
|
4099
4145
|
* @example
|
|
4100
4146
|
* await client.auth.mintToken({
|
|
@@ -4147,6 +4193,8 @@ var AuthClient = class {
|
|
|
4147
4193
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4148
4194
|
case 403:
|
|
4149
4195
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4196
|
+
case 429:
|
|
4197
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4150
4198
|
default:
|
|
4151
4199
|
throw new VectrosError({
|
|
4152
4200
|
statusCode: _response.error.statusCode,
|
|
@@ -4167,6 +4215,7 @@ var AuthClient = class {
|
|
|
4167
4215
|
* @throws {@link Vectros.ForbiddenError}
|
|
4168
4216
|
* @throws {@link Vectros.NotFoundError}
|
|
4169
4217
|
* @throws {@link Vectros.ConflictError}
|
|
4218
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4170
4219
|
*
|
|
4171
4220
|
* @example
|
|
4172
4221
|
* await client.auth.createInvite({
|
|
@@ -4215,6 +4264,8 @@ var AuthClient = class {
|
|
|
4215
4264
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4216
4265
|
case 409:
|
|
4217
4266
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4267
|
+
case 429:
|
|
4268
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4218
4269
|
default:
|
|
4219
4270
|
throw new VectrosError({
|
|
4220
4271
|
statusCode: _response.error.statusCode,
|
|
@@ -4234,6 +4285,7 @@ var AuthClient = class {
|
|
|
4234
4285
|
* @throws {@link Vectros.BadRequestError}
|
|
4235
4286
|
* @throws {@link Vectros.ForbiddenError}
|
|
4236
4287
|
* @throws {@link Vectros.NotFoundError}
|
|
4288
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4237
4289
|
*
|
|
4238
4290
|
* @example
|
|
4239
4291
|
* await client.auth.resendInvite({
|
|
@@ -4280,6 +4332,8 @@ var AuthClient = class {
|
|
|
4280
4332
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4281
4333
|
case 404:
|
|
4282
4334
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4335
|
+
case 429:
|
|
4336
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4283
4337
|
default:
|
|
4284
4338
|
throw new VectrosError({
|
|
4285
4339
|
statusCode: _response.error.statusCode,
|
|
@@ -4302,6 +4356,7 @@ var ComplianceClient = class {
|
|
|
4302
4356
|
* @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4303
4357
|
*
|
|
4304
4358
|
* @throws {@link Vectros.ForbiddenError}
|
|
4359
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4305
4360
|
* @throws {@link Vectros.NotImplementedError}
|
|
4306
4361
|
*
|
|
4307
4362
|
* @example
|
|
@@ -4343,6 +4398,8 @@ var ComplianceClient = class {
|
|
|
4343
4398
|
switch (_response.error.statusCode) {
|
|
4344
4399
|
case 403:
|
|
4345
4400
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4401
|
+
case 429:
|
|
4402
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4346
4403
|
case 501:
|
|
4347
4404
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
4348
4405
|
default:
|
|
@@ -4423,6 +4480,7 @@ var ComplianceClient = class {
|
|
|
4423
4480
|
* @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4424
4481
|
*
|
|
4425
4482
|
* @throws {@link Vectros.ForbiddenError}
|
|
4483
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4426
4484
|
* @throws {@link Vectros.NotImplementedError}
|
|
4427
4485
|
*
|
|
4428
4486
|
* @example
|
|
@@ -4462,6 +4520,8 @@ var ComplianceClient = class {
|
|
|
4462
4520
|
switch (_response.error.statusCode) {
|
|
4463
4521
|
case 403:
|
|
4464
4522
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4523
|
+
case 429:
|
|
4524
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4465
4525
|
case 501:
|
|
4466
4526
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
4467
4527
|
default:
|
|
@@ -4601,22 +4661,30 @@ var DocumentsClient = class {
|
|
|
4601
4661
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
|
|
4602
4662
|
}
|
|
4603
4663
|
/**
|
|
4604
|
-
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Requires the `documents:c` scope.
|
|
4664
|
+
* 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.
|
|
4605
4665
|
*
|
|
4606
|
-
* @param {Vectros.
|
|
4666
|
+
* @param {Vectros.IngestDocumentRequest} request
|
|
4607
4667
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4608
4668
|
*
|
|
4609
4669
|
* @throws {@link Vectros.BadRequestError}
|
|
4670
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
4671
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4610
4672
|
*
|
|
4611
4673
|
* @example
|
|
4612
4674
|
* await client.documents.ingestDocument({
|
|
4613
|
-
*
|
|
4675
|
+
* body: {
|
|
4676
|
+
* title: "Patient Intake Form \u2014 Jane Doe"
|
|
4677
|
+
* }
|
|
4614
4678
|
* })
|
|
4615
4679
|
*/
|
|
4616
4680
|
ingestDocument(request, requestOptions) {
|
|
4617
4681
|
return HttpResponsePromise.fromPromise(this.__ingestDocument(request, requestOptions));
|
|
4618
4682
|
}
|
|
4619
4683
|
async __ingestDocument(request, requestOptions) {
|
|
4684
|
+
const { upsert, body: _body } = request;
|
|
4685
|
+
const _queryParams = {
|
|
4686
|
+
upsert
|
|
4687
|
+
};
|
|
4620
4688
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
4621
4689
|
const _headers = mergeHeaders(
|
|
4622
4690
|
_authRequest.headers,
|
|
@@ -4631,9 +4699,9 @@ var DocumentsClient = class {
|
|
|
4631
4699
|
method: "POST",
|
|
4632
4700
|
headers: _headers,
|
|
4633
4701
|
contentType: "application/json",
|
|
4634
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
4702
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
4635
4703
|
requestType: "json",
|
|
4636
|
-
body:
|
|
4704
|
+
body: _body,
|
|
4637
4705
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
4638
4706
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
4639
4707
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -4647,6 +4715,10 @@ var DocumentsClient = class {
|
|
|
4647
4715
|
switch (_response.error.statusCode) {
|
|
4648
4716
|
case 400:
|
|
4649
4717
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4718
|
+
case 403:
|
|
4719
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4720
|
+
case 429:
|
|
4721
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4650
4722
|
default:
|
|
4651
4723
|
throw new VectrosError({
|
|
4652
4724
|
statusCode: _response.error.statusCode,
|
|
@@ -4721,6 +4793,7 @@ var DocumentsClient = class {
|
|
|
4721
4793
|
* @throws {@link Vectros.BadRequestError}
|
|
4722
4794
|
* @throws {@link Vectros.NotFoundError}
|
|
4723
4795
|
* @throws {@link Vectros.ConflictError}
|
|
4796
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4724
4797
|
*
|
|
4725
4798
|
* @example
|
|
4726
4799
|
* await client.documents.updateDocument({
|
|
@@ -4769,6 +4842,8 @@ var DocumentsClient = class {
|
|
|
4769
4842
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4770
4843
|
case 409:
|
|
4771
4844
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4845
|
+
case 429:
|
|
4846
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4772
4847
|
default:
|
|
4773
4848
|
throw new VectrosError({
|
|
4774
4849
|
statusCode: _response.error.statusCode,
|
|
@@ -4786,6 +4861,7 @@ var DocumentsClient = class {
|
|
|
4786
4861
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4787
4862
|
*
|
|
4788
4863
|
* @throws {@link Vectros.NotFoundError}
|
|
4864
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4789
4865
|
*
|
|
4790
4866
|
* @example
|
|
4791
4867
|
* await client.documents.deleteDocument({
|
|
@@ -4824,6 +4900,8 @@ var DocumentsClient = class {
|
|
|
4824
4900
|
switch (_response.error.statusCode) {
|
|
4825
4901
|
case 404:
|
|
4826
4902
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4903
|
+
case 429:
|
|
4904
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4827
4905
|
default:
|
|
4828
4906
|
throw new VectrosError({
|
|
4829
4907
|
statusCode: _response.error.statusCode,
|
|
@@ -4843,6 +4921,7 @@ var DocumentsClient = class {
|
|
|
4843
4921
|
* @throws {@link Vectros.BadRequestError}
|
|
4844
4922
|
* @throws {@link Vectros.NotFoundError}
|
|
4845
4923
|
* @throws {@link Vectros.ConflictError}
|
|
4924
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4846
4925
|
*
|
|
4847
4926
|
* @example
|
|
4848
4927
|
* await client.documents.patchDocument({
|
|
@@ -4891,6 +4970,8 @@ var DocumentsClient = class {
|
|
|
4891
4970
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4892
4971
|
case 409:
|
|
4893
4972
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4973
|
+
case 429:
|
|
4974
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4894
4975
|
default:
|
|
4895
4976
|
throw new VectrosError({
|
|
4896
4977
|
statusCode: _response.error.statusCode,
|
|
@@ -4902,7 +4983,7 @@ var DocumentsClient = class {
|
|
|
4902
4983
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
|
|
4903
4984
|
}
|
|
4904
4985
|
/**
|
|
4905
|
-
* Finds documents of a given type by
|
|
4986
|
+
* 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.
|
|
4906
4987
|
*
|
|
4907
4988
|
* @param {Vectros.LookupDocumentsRequest} request
|
|
4908
4989
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4971,6 +5052,7 @@ var DocumentsClient = class {
|
|
|
4971
5052
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4972
5053
|
*
|
|
4973
5054
|
* @throws {@link Vectros.BadRequestError}
|
|
5055
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4974
5056
|
*
|
|
4975
5057
|
* @example
|
|
4976
5058
|
* await client.documents.lookupDocumentsByBody({
|
|
@@ -5012,6 +5094,8 @@ var DocumentsClient = class {
|
|
|
5012
5094
|
switch (_response.error.statusCode) {
|
|
5013
5095
|
case 400:
|
|
5014
5096
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5097
|
+
case 429:
|
|
5098
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5015
5099
|
default:
|
|
5016
5100
|
throw new VectrosError({
|
|
5017
5101
|
statusCode: _response.error.statusCode,
|
|
@@ -5194,12 +5278,14 @@ var DocumentsClient = class {
|
|
|
5194
5278
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/versions");
|
|
5195
5279
|
}
|
|
5196
5280
|
/**
|
|
5197
|
-
* Starts a file-based document by returning a short-lived presigned S3 PUT URL. Upload the file bytes directly to `uploadUrl`; the document is then automatically queued for text extraction and asynchronous indexing. Requires the `documents:c` scope.
|
|
5281
|
+
* Starts a file-based document by returning a short-lived presigned S3 PUT URL. Upload the file bytes directly to `uploadUrl`; the document is then automatically queued for text extraction and asynchronous indexing. Supplying an `externalId` makes this idempotent — re-initiating an upload with the same `externalId` re-issues a fresh presigned URL to the SAME existing document/object (so a re-upload inherently replaces the file body) rather than creating a duplicate. The response's `created` field (and the HTTP status — 201 when a new document was minted, 200 when an existing one was matched) tells the two apart. With `?upsert=true`, the submitted `payload`/`title` are also applied to the matched document (file-body divergence cannot be diffed at upload-init — the bytes have not arrived yet — so the re-upload itself replaces the body; `?upsert=true` requires the `documents:u` scope). Requires the `documents:c` scope.
|
|
5198
5282
|
*
|
|
5199
5283
|
* @param {Vectros.FileUploadRequest} request
|
|
5200
5284
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5201
5285
|
*
|
|
5202
5286
|
* @throws {@link Vectros.BadRequestError}
|
|
5287
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5288
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5203
5289
|
*
|
|
5204
5290
|
* @example
|
|
5205
5291
|
* await client.documents.uploadDocument({
|
|
@@ -5211,6 +5297,10 @@ var DocumentsClient = class {
|
|
|
5211
5297
|
return HttpResponsePromise.fromPromise(this.__uploadDocument(request, requestOptions));
|
|
5212
5298
|
}
|
|
5213
5299
|
async __uploadDocument(request, requestOptions) {
|
|
5300
|
+
const { upsert, ..._body } = request;
|
|
5301
|
+
const _queryParams = {
|
|
5302
|
+
upsert
|
|
5303
|
+
};
|
|
5214
5304
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5215
5305
|
const _headers = mergeHeaders(
|
|
5216
5306
|
_authRequest.headers,
|
|
@@ -5225,9 +5315,9 @@ var DocumentsClient = class {
|
|
|
5225
5315
|
method: "POST",
|
|
5226
5316
|
headers: _headers,
|
|
5227
5317
|
contentType: "application/json",
|
|
5228
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5318
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5229
5319
|
requestType: "json",
|
|
5230
|
-
body:
|
|
5320
|
+
body: _body,
|
|
5231
5321
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5232
5322
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5233
5323
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5241,6 +5331,10 @@ var DocumentsClient = class {
|
|
|
5241
5331
|
switch (_response.error.statusCode) {
|
|
5242
5332
|
case 400:
|
|
5243
5333
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5334
|
+
case 403:
|
|
5335
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5336
|
+
case 429:
|
|
5337
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5244
5338
|
default:
|
|
5245
5339
|
throw new VectrosError({
|
|
5246
5340
|
statusCode: _response.error.statusCode,
|
|
@@ -5317,22 +5411,30 @@ var FoldersClient = class {
|
|
|
5317
5411
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
|
|
5318
5412
|
}
|
|
5319
5413
|
/**
|
|
5320
|
-
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Requires the `folders:c` scope.
|
|
5414
|
+
* 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.
|
|
5321
5415
|
*
|
|
5322
|
-
* @param {Vectros.
|
|
5416
|
+
* @param {Vectros.CreateFolderRequest} request
|
|
5323
5417
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5324
5418
|
*
|
|
5325
5419
|
* @throws {@link Vectros.BadRequestError}
|
|
5420
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5421
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5326
5422
|
*
|
|
5327
5423
|
* @example
|
|
5328
5424
|
* await client.folders.createFolder({
|
|
5329
|
-
*
|
|
5425
|
+
* body: {
|
|
5426
|
+
* name: "Patient Records 2024"
|
|
5427
|
+
* }
|
|
5330
5428
|
* })
|
|
5331
5429
|
*/
|
|
5332
5430
|
createFolder(request, requestOptions) {
|
|
5333
5431
|
return HttpResponsePromise.fromPromise(this.__createFolder(request, requestOptions));
|
|
5334
5432
|
}
|
|
5335
5433
|
async __createFolder(request, requestOptions) {
|
|
5434
|
+
const { upsert, body: _body } = request;
|
|
5435
|
+
const _queryParams = {
|
|
5436
|
+
upsert
|
|
5437
|
+
};
|
|
5336
5438
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5337
5439
|
const _headers = mergeHeaders(
|
|
5338
5440
|
_authRequest.headers,
|
|
@@ -5347,9 +5449,9 @@ var FoldersClient = class {
|
|
|
5347
5449
|
method: "POST",
|
|
5348
5450
|
headers: _headers,
|
|
5349
5451
|
contentType: "application/json",
|
|
5350
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5452
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5351
5453
|
requestType: "json",
|
|
5352
|
-
body:
|
|
5454
|
+
body: _body,
|
|
5353
5455
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5354
5456
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5355
5457
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5363,6 +5465,10 @@ var FoldersClient = class {
|
|
|
5363
5465
|
switch (_response.error.statusCode) {
|
|
5364
5466
|
case 400:
|
|
5365
5467
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5468
|
+
case 403:
|
|
5469
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5470
|
+
case 429:
|
|
5471
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5366
5472
|
default:
|
|
5367
5473
|
throw new VectrosError({
|
|
5368
5474
|
statusCode: _response.error.statusCode,
|
|
@@ -5435,6 +5541,7 @@ var FoldersClient = class {
|
|
|
5435
5541
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5436
5542
|
*
|
|
5437
5543
|
* @throws {@link Vectros.NotFoundError}
|
|
5544
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5438
5545
|
*
|
|
5439
5546
|
* @example
|
|
5440
5547
|
* await client.folders.updateFolder({
|
|
@@ -5479,6 +5586,8 @@ var FoldersClient = class {
|
|
|
5479
5586
|
switch (_response.error.statusCode) {
|
|
5480
5587
|
case 404:
|
|
5481
5588
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5589
|
+
case 429:
|
|
5590
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5482
5591
|
default:
|
|
5483
5592
|
throw new VectrosError({
|
|
5484
5593
|
statusCode: _response.error.statusCode,
|
|
@@ -5497,6 +5606,7 @@ var FoldersClient = class {
|
|
|
5497
5606
|
*
|
|
5498
5607
|
* @throws {@link Vectros.BadRequestError}
|
|
5499
5608
|
* @throws {@link Vectros.NotFoundError}
|
|
5609
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5500
5610
|
*
|
|
5501
5611
|
* @example
|
|
5502
5612
|
* await client.folders.deleteFolder({
|
|
@@ -5537,6 +5647,8 @@ var FoldersClient = class {
|
|
|
5537
5647
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5538
5648
|
case 404:
|
|
5539
5649
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5650
|
+
case 429:
|
|
5651
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5540
5652
|
default:
|
|
5541
5653
|
throw new VectrosError({
|
|
5542
5654
|
statusCode: _response.error.statusCode,
|
|
@@ -5556,6 +5668,7 @@ var FoldersClient = class {
|
|
|
5556
5668
|
* @throws {@link Vectros.BadRequestError}
|
|
5557
5669
|
* @throws {@link Vectros.NotFoundError}
|
|
5558
5670
|
* @throws {@link Vectros.ConflictError}
|
|
5671
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5559
5672
|
*
|
|
5560
5673
|
* @example
|
|
5561
5674
|
* await client.folders.patchFolder({
|
|
@@ -5604,6 +5717,8 @@ var FoldersClient = class {
|
|
|
5604
5717
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5605
5718
|
case 409:
|
|
5606
5719
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
5720
|
+
case 429:
|
|
5721
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5607
5722
|
default:
|
|
5608
5723
|
throw new VectrosError({
|
|
5609
5724
|
statusCode: _response.error.statusCode,
|
|
@@ -5760,22 +5875,30 @@ var IdentityClient = class {
|
|
|
5760
5875
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/clients");
|
|
5761
5876
|
}
|
|
5762
5877
|
/**
|
|
5763
|
-
* Creates a new client identity in your account. This call is idempotent on `externalId`: if a client with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. Requires the `clients:c` scope.
|
|
5878
|
+
* Creates a new client identity in your account. This call is idempotent on `externalId`: if a client 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 client was returned) tells the two apart. To overwrite an existing client's content instead of returning it unchanged, set `?upsert=true` (this also requires the `clients:u` scope). Requires the `clients:c` scope.
|
|
5764
5879
|
*
|
|
5765
|
-
* @param {Vectros.
|
|
5880
|
+
* @param {Vectros.CreateClientRequest} request
|
|
5766
5881
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5767
5882
|
*
|
|
5768
5883
|
* @throws {@link Vectros.BadRequestError}
|
|
5884
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5885
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5769
5886
|
*
|
|
5770
5887
|
* @example
|
|
5771
5888
|
* await client.identity.createClient({
|
|
5772
|
-
*
|
|
5889
|
+
* body: {
|
|
5890
|
+
* externalId: "patient_789"
|
|
5891
|
+
* }
|
|
5773
5892
|
* })
|
|
5774
5893
|
*/
|
|
5775
5894
|
createClient(request, requestOptions) {
|
|
5776
5895
|
return HttpResponsePromise.fromPromise(this.__createClient(request, requestOptions));
|
|
5777
5896
|
}
|
|
5778
5897
|
async __createClient(request, requestOptions) {
|
|
5898
|
+
const { upsert, body: _body } = request;
|
|
5899
|
+
const _queryParams = {
|
|
5900
|
+
upsert
|
|
5901
|
+
};
|
|
5779
5902
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5780
5903
|
const _headers = mergeHeaders(
|
|
5781
5904
|
_authRequest.headers,
|
|
@@ -5790,9 +5913,9 @@ var IdentityClient = class {
|
|
|
5790
5913
|
method: "POST",
|
|
5791
5914
|
headers: _headers,
|
|
5792
5915
|
contentType: "application/json",
|
|
5793
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5916
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5794
5917
|
requestType: "json",
|
|
5795
|
-
body:
|
|
5918
|
+
body: _body,
|
|
5796
5919
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5797
5920
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5798
5921
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5806,6 +5929,10 @@ var IdentityClient = class {
|
|
|
5806
5929
|
switch (_response.error.statusCode) {
|
|
5807
5930
|
case 400:
|
|
5808
5931
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5932
|
+
case 403:
|
|
5933
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5934
|
+
case 429:
|
|
5935
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5809
5936
|
default:
|
|
5810
5937
|
throw new VectrosError({
|
|
5811
5938
|
statusCode: _response.error.statusCode,
|
|
@@ -5878,6 +6005,7 @@ var IdentityClient = class {
|
|
|
5878
6005
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5879
6006
|
*
|
|
5880
6007
|
* @throws {@link Vectros.NotFoundError}
|
|
6008
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5881
6009
|
*
|
|
5882
6010
|
* @example
|
|
5883
6011
|
* await client.identity.updateClient({
|
|
@@ -5922,6 +6050,8 @@ var IdentityClient = class {
|
|
|
5922
6050
|
switch (_response.error.statusCode) {
|
|
5923
6051
|
case 404:
|
|
5924
6052
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6053
|
+
case 429:
|
|
6054
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5925
6055
|
default:
|
|
5926
6056
|
throw new VectrosError({
|
|
5927
6057
|
statusCode: _response.error.statusCode,
|
|
@@ -5939,6 +6069,7 @@ var IdentityClient = class {
|
|
|
5939
6069
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5940
6070
|
*
|
|
5941
6071
|
* @throws {@link Vectros.NotFoundError}
|
|
6072
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5942
6073
|
*
|
|
5943
6074
|
* @example
|
|
5944
6075
|
* await client.identity.deleteClient({
|
|
@@ -5977,6 +6108,8 @@ var IdentityClient = class {
|
|
|
5977
6108
|
switch (_response.error.statusCode) {
|
|
5978
6109
|
case 404:
|
|
5979
6110
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6111
|
+
case 429:
|
|
6112
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5980
6113
|
default:
|
|
5981
6114
|
throw new VectrosError({
|
|
5982
6115
|
statusCode: _response.error.statusCode,
|
|
@@ -5994,6 +6127,7 @@ var IdentityClient = class {
|
|
|
5994
6127
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5995
6128
|
*
|
|
5996
6129
|
* @throws {@link Vectros.BadRequestError}
|
|
6130
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5997
6131
|
*
|
|
5998
6132
|
* @example
|
|
5999
6133
|
* await client.identity.lookupClients({
|
|
@@ -6035,6 +6169,8 @@ var IdentityClient = class {
|
|
|
6035
6169
|
switch (_response.error.statusCode) {
|
|
6036
6170
|
case 400:
|
|
6037
6171
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6172
|
+
case 429:
|
|
6173
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6038
6174
|
default:
|
|
6039
6175
|
throw new VectrosError({
|
|
6040
6176
|
statusCode: _response.error.statusCode,
|
|
@@ -6183,22 +6319,30 @@ var IdentityClient = class {
|
|
|
6183
6319
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/orgs");
|
|
6184
6320
|
}
|
|
6185
6321
|
/**
|
|
6186
|
-
* Creates a new organization in your account. This call is idempotent on `externalId`: if an organization with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. Requires the `orgs:c` scope.
|
|
6322
|
+
* Creates a new organization in your account. This call is idempotent on `externalId`: if an organization 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 organization was returned) tells the two apart. To overwrite an existing organization's content instead of returning it unchanged, set `?upsert=true` (this also requires the `orgs:u` scope). Requires the `orgs:c` scope.
|
|
6187
6323
|
*
|
|
6188
|
-
* @param {Vectros.
|
|
6324
|
+
* @param {Vectros.CreateOrgRequest} request
|
|
6189
6325
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6190
6326
|
*
|
|
6191
6327
|
* @throws {@link Vectros.BadRequestError}
|
|
6328
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
6329
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6192
6330
|
*
|
|
6193
6331
|
* @example
|
|
6194
6332
|
* await client.identity.createOrg({
|
|
6195
|
-
*
|
|
6333
|
+
* body: {
|
|
6334
|
+
* externalId: "clinic_001"
|
|
6335
|
+
* }
|
|
6196
6336
|
* })
|
|
6197
6337
|
*/
|
|
6198
6338
|
createOrg(request, requestOptions) {
|
|
6199
6339
|
return HttpResponsePromise.fromPromise(this.__createOrg(request, requestOptions));
|
|
6200
6340
|
}
|
|
6201
6341
|
async __createOrg(request, requestOptions) {
|
|
6342
|
+
const { upsert, body: _body } = request;
|
|
6343
|
+
const _queryParams = {
|
|
6344
|
+
upsert
|
|
6345
|
+
};
|
|
6202
6346
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
6203
6347
|
const _headers = mergeHeaders(
|
|
6204
6348
|
_authRequest.headers,
|
|
@@ -6213,9 +6357,9 @@ var IdentityClient = class {
|
|
|
6213
6357
|
method: "POST",
|
|
6214
6358
|
headers: _headers,
|
|
6215
6359
|
contentType: "application/json",
|
|
6216
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
6360
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
6217
6361
|
requestType: "json",
|
|
6218
|
-
body:
|
|
6362
|
+
body: _body,
|
|
6219
6363
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
6220
6364
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
6221
6365
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -6229,6 +6373,10 @@ var IdentityClient = class {
|
|
|
6229
6373
|
switch (_response.error.statusCode) {
|
|
6230
6374
|
case 400:
|
|
6231
6375
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6376
|
+
case 403:
|
|
6377
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
6378
|
+
case 429:
|
|
6379
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6232
6380
|
default:
|
|
6233
6381
|
throw new VectrosError({
|
|
6234
6382
|
statusCode: _response.error.statusCode,
|
|
@@ -6301,6 +6449,7 @@ var IdentityClient = class {
|
|
|
6301
6449
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6302
6450
|
*
|
|
6303
6451
|
* @throws {@link Vectros.NotFoundError}
|
|
6452
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6304
6453
|
*
|
|
6305
6454
|
* @example
|
|
6306
6455
|
* await client.identity.updateOrg({
|
|
@@ -6345,6 +6494,8 @@ var IdentityClient = class {
|
|
|
6345
6494
|
switch (_response.error.statusCode) {
|
|
6346
6495
|
case 404:
|
|
6347
6496
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6497
|
+
case 429:
|
|
6498
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6348
6499
|
default:
|
|
6349
6500
|
throw new VectrosError({
|
|
6350
6501
|
statusCode: _response.error.statusCode,
|
|
@@ -6362,6 +6513,7 @@ var IdentityClient = class {
|
|
|
6362
6513
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6363
6514
|
*
|
|
6364
6515
|
* @throws {@link Vectros.NotFoundError}
|
|
6516
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6365
6517
|
*
|
|
6366
6518
|
* @example
|
|
6367
6519
|
* await client.identity.deleteOrg({
|
|
@@ -6400,6 +6552,8 @@ var IdentityClient = class {
|
|
|
6400
6552
|
switch (_response.error.statusCode) {
|
|
6401
6553
|
case 404:
|
|
6402
6554
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6555
|
+
case 429:
|
|
6556
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6403
6557
|
default:
|
|
6404
6558
|
throw new VectrosError({
|
|
6405
6559
|
statusCode: _response.error.statusCode,
|
|
@@ -6417,6 +6571,7 @@ var IdentityClient = class {
|
|
|
6417
6571
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6418
6572
|
*
|
|
6419
6573
|
* @throws {@link Vectros.BadRequestError}
|
|
6574
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6420
6575
|
*
|
|
6421
6576
|
* @example
|
|
6422
6577
|
* await client.identity.lookupOrgs({
|
|
@@ -6458,6 +6613,8 @@ var IdentityClient = class {
|
|
|
6458
6613
|
switch (_response.error.statusCode) {
|
|
6459
6614
|
case 400:
|
|
6460
6615
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6616
|
+
case 429:
|
|
6617
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6461
6618
|
default:
|
|
6462
6619
|
throw new VectrosError({
|
|
6463
6620
|
statusCode: _response.error.statusCode,
|
|
@@ -6592,22 +6749,30 @@ var IdentityClient = class {
|
|
|
6592
6749
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
|
|
6593
6750
|
}
|
|
6594
6751
|
/**
|
|
6595
|
-
* 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. Requires the `users:c` scope.
|
|
6752
|
+
* 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.
|
|
6596
6753
|
*
|
|
6597
|
-
* @param {Vectros.
|
|
6754
|
+
* @param {Vectros.CreateUserRequest} request
|
|
6598
6755
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6599
6756
|
*
|
|
6600
6757
|
* @throws {@link Vectros.BadRequestError}
|
|
6758
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
6759
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6601
6760
|
*
|
|
6602
6761
|
* @example
|
|
6603
6762
|
* await client.identity.createUser({
|
|
6604
|
-
*
|
|
6763
|
+
* body: {
|
|
6764
|
+
* externalId: "usr_12345"
|
|
6765
|
+
* }
|
|
6605
6766
|
* })
|
|
6606
6767
|
*/
|
|
6607
6768
|
createUser(request, requestOptions) {
|
|
6608
6769
|
return HttpResponsePromise.fromPromise(this.__createUser(request, requestOptions));
|
|
6609
6770
|
}
|
|
6610
6771
|
async __createUser(request, requestOptions) {
|
|
6772
|
+
const { upsert, body: _body } = request;
|
|
6773
|
+
const _queryParams = {
|
|
6774
|
+
upsert
|
|
6775
|
+
};
|
|
6611
6776
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
6612
6777
|
const _headers = mergeHeaders(
|
|
6613
6778
|
_authRequest.headers,
|
|
@@ -6622,9 +6787,9 @@ var IdentityClient = class {
|
|
|
6622
6787
|
method: "POST",
|
|
6623
6788
|
headers: _headers,
|
|
6624
6789
|
contentType: "application/json",
|
|
6625
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
6790
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
6626
6791
|
requestType: "json",
|
|
6627
|
-
body:
|
|
6792
|
+
body: _body,
|
|
6628
6793
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
6629
6794
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
6630
6795
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -6638,6 +6803,10 @@ var IdentityClient = class {
|
|
|
6638
6803
|
switch (_response.error.statusCode) {
|
|
6639
6804
|
case 400:
|
|
6640
6805
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6806
|
+
case 403:
|
|
6807
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
6808
|
+
case 429:
|
|
6809
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6641
6810
|
default:
|
|
6642
6811
|
throw new VectrosError({
|
|
6643
6812
|
statusCode: _response.error.statusCode,
|
|
@@ -6710,6 +6879,7 @@ var IdentityClient = class {
|
|
|
6710
6879
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6711
6880
|
*
|
|
6712
6881
|
* @throws {@link Vectros.NotFoundError}
|
|
6882
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6713
6883
|
*
|
|
6714
6884
|
* @example
|
|
6715
6885
|
* await client.identity.updateUser({
|
|
@@ -6754,6 +6924,8 @@ var IdentityClient = class {
|
|
|
6754
6924
|
switch (_response.error.statusCode) {
|
|
6755
6925
|
case 404:
|
|
6756
6926
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6927
|
+
case 429:
|
|
6928
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6757
6929
|
default:
|
|
6758
6930
|
throw new VectrosError({
|
|
6759
6931
|
statusCode: _response.error.statusCode,
|
|
@@ -6771,6 +6943,7 @@ var IdentityClient = class {
|
|
|
6771
6943
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6772
6944
|
*
|
|
6773
6945
|
* @throws {@link Vectros.NotFoundError}
|
|
6946
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6774
6947
|
*
|
|
6775
6948
|
* @example
|
|
6776
6949
|
* await client.identity.deleteUser({
|
|
@@ -6809,6 +6982,8 @@ var IdentityClient = class {
|
|
|
6809
6982
|
switch (_response.error.statusCode) {
|
|
6810
6983
|
case 404:
|
|
6811
6984
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6985
|
+
case 429:
|
|
6986
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6812
6987
|
default:
|
|
6813
6988
|
throw new VectrosError({
|
|
6814
6989
|
statusCode: _response.error.statusCode,
|
|
@@ -6826,6 +7001,7 @@ var IdentityClient = class {
|
|
|
6826
7001
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6827
7002
|
*
|
|
6828
7003
|
* @throws {@link Vectros.BadRequestError}
|
|
7004
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6829
7005
|
*
|
|
6830
7006
|
* @example
|
|
6831
7007
|
* await client.identity.lookupUsers({
|
|
@@ -6867,6 +7043,8 @@ var IdentityClient = class {
|
|
|
6867
7043
|
switch (_response.error.statusCode) {
|
|
6868
7044
|
case 400:
|
|
6869
7045
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7046
|
+
case 429:
|
|
7047
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6870
7048
|
default:
|
|
6871
7049
|
throw new VectrosError({
|
|
6872
7050
|
statusCode: _response.error.statusCode,
|
|
@@ -7203,6 +7381,7 @@ var RecordsClient = class {
|
|
|
7203
7381
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7204
7382
|
*
|
|
7205
7383
|
* @throws {@link Vectros.ForbiddenError}
|
|
7384
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7206
7385
|
* @throws {@link Vectros.NotImplementedError}
|
|
7207
7386
|
*
|
|
7208
7387
|
* @example
|
|
@@ -7242,6 +7421,8 @@ var RecordsClient = class {
|
|
|
7242
7421
|
switch (_response.error.statusCode) {
|
|
7243
7422
|
case 403:
|
|
7244
7423
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7424
|
+
case 429:
|
|
7425
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7245
7426
|
case 501:
|
|
7246
7427
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7247
7428
|
default:
|
|
@@ -7261,6 +7442,7 @@ var RecordsClient = class {
|
|
|
7261
7442
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7262
7443
|
*
|
|
7263
7444
|
* @throws {@link Vectros.ForbiddenError}
|
|
7445
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7264
7446
|
* @throws {@link Vectros.NotImplementedError}
|
|
7265
7447
|
*
|
|
7266
7448
|
* @example
|
|
@@ -7300,6 +7482,8 @@ var RecordsClient = class {
|
|
|
7300
7482
|
switch (_response.error.statusCode) {
|
|
7301
7483
|
case 403:
|
|
7302
7484
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7485
|
+
case 429:
|
|
7486
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7303
7487
|
case 501:
|
|
7304
7488
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7305
7489
|
default:
|
|
@@ -7319,6 +7503,7 @@ var RecordsClient = class {
|
|
|
7319
7503
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7320
7504
|
*
|
|
7321
7505
|
* @throws {@link Vectros.ForbiddenError}
|
|
7506
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7322
7507
|
* @throws {@link Vectros.NotImplementedError}
|
|
7323
7508
|
*
|
|
7324
7509
|
* @example
|
|
@@ -7358,6 +7543,8 @@ var RecordsClient = class {
|
|
|
7358
7543
|
switch (_response.error.statusCode) {
|
|
7359
7544
|
case 403:
|
|
7360
7545
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7546
|
+
case 429:
|
|
7547
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7361
7548
|
case 501:
|
|
7362
7549
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7363
7550
|
default:
|
|
@@ -7435,29 +7622,36 @@ var RecordsClient = class {
|
|
|
7435
7622
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
|
|
7436
7623
|
}
|
|
7437
7624
|
/**
|
|
7438
|
-
* 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. Requires the `records:c:<type>` scope.
|
|
7625
|
+
* 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.
|
|
7439
7626
|
*
|
|
7440
|
-
* @param {Vectros.
|
|
7627
|
+
* @param {Vectros.CreateRecordRequest} request
|
|
7441
7628
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7442
7629
|
*
|
|
7443
7630
|
* @throws {@link Vectros.BadRequestError}
|
|
7444
7631
|
* @throws {@link Vectros.ForbiddenError}
|
|
7632
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7445
7633
|
*
|
|
7446
7634
|
* @example
|
|
7447
7635
|
* await client.records.createRecord({
|
|
7448
|
-
*
|
|
7449
|
-
*
|
|
7450
|
-
*
|
|
7451
|
-
*
|
|
7452
|
-
*
|
|
7453
|
-
*
|
|
7454
|
-
*
|
|
7636
|
+
* body: {
|
|
7637
|
+
* typeName: "intake_form",
|
|
7638
|
+
* schemaId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
|
7639
|
+
* payload: {
|
|
7640
|
+
* "first_name": "Jane",
|
|
7641
|
+
* "email": "jane@example.com"
|
|
7642
|
+
* },
|
|
7643
|
+
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
7644
|
+
* }
|
|
7455
7645
|
* })
|
|
7456
7646
|
*/
|
|
7457
7647
|
createRecord(request, requestOptions) {
|
|
7458
7648
|
return HttpResponsePromise.fromPromise(this.__createRecord(request, requestOptions));
|
|
7459
7649
|
}
|
|
7460
7650
|
async __createRecord(request, requestOptions) {
|
|
7651
|
+
const { upsert, body: _body } = request;
|
|
7652
|
+
const _queryParams = {
|
|
7653
|
+
upsert
|
|
7654
|
+
};
|
|
7461
7655
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
7462
7656
|
const _headers = mergeHeaders(
|
|
7463
7657
|
_authRequest.headers,
|
|
@@ -7472,9 +7666,9 @@ var RecordsClient = class {
|
|
|
7472
7666
|
method: "POST",
|
|
7473
7667
|
headers: _headers,
|
|
7474
7668
|
contentType: "application/json",
|
|
7475
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
7669
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
7476
7670
|
requestType: "json",
|
|
7477
|
-
body:
|
|
7671
|
+
body: _body,
|
|
7478
7672
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
7479
7673
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
7480
7674
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -7490,6 +7684,8 @@ var RecordsClient = class {
|
|
|
7490
7684
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7491
7685
|
case 403:
|
|
7492
7686
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7687
|
+
case 429:
|
|
7688
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7493
7689
|
default:
|
|
7494
7690
|
throw new VectrosError({
|
|
7495
7691
|
statusCode: _response.error.statusCode,
|
|
@@ -7564,6 +7760,7 @@ var RecordsClient = class {
|
|
|
7564
7760
|
* @throws {@link Vectros.BadRequestError}
|
|
7565
7761
|
* @throws {@link Vectros.NotFoundError}
|
|
7566
7762
|
* @throws {@link Vectros.ConflictError}
|
|
7763
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7567
7764
|
*
|
|
7568
7765
|
* @example
|
|
7569
7766
|
* await client.records.updateRecord({
|
|
@@ -7610,6 +7807,8 @@ var RecordsClient = class {
|
|
|
7610
7807
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7611
7808
|
case 409:
|
|
7612
7809
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
7810
|
+
case 429:
|
|
7811
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7613
7812
|
default:
|
|
7614
7813
|
throw new VectrosError({
|
|
7615
7814
|
statusCode: _response.error.statusCode,
|
|
@@ -7627,6 +7826,7 @@ var RecordsClient = class {
|
|
|
7627
7826
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7628
7827
|
*
|
|
7629
7828
|
* @throws {@link Vectros.NotFoundError}
|
|
7829
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7630
7830
|
*
|
|
7631
7831
|
* @example
|
|
7632
7832
|
* await client.records.deleteRecord({
|
|
@@ -7665,6 +7865,8 @@ var RecordsClient = class {
|
|
|
7665
7865
|
switch (_response.error.statusCode) {
|
|
7666
7866
|
case 404:
|
|
7667
7867
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7868
|
+
case 429:
|
|
7869
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7668
7870
|
default:
|
|
7669
7871
|
throw new VectrosError({
|
|
7670
7872
|
statusCode: _response.error.statusCode,
|
|
@@ -7684,6 +7886,7 @@ var RecordsClient = class {
|
|
|
7684
7886
|
* @throws {@link Vectros.BadRequestError}
|
|
7685
7887
|
* @throws {@link Vectros.NotFoundError}
|
|
7686
7888
|
* @throws {@link Vectros.ConflictError}
|
|
7889
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7687
7890
|
*
|
|
7688
7891
|
* @example
|
|
7689
7892
|
* await client.records.patchRecord({
|
|
@@ -7735,6 +7938,8 @@ var RecordsClient = class {
|
|
|
7735
7938
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7736
7939
|
case 409:
|
|
7737
7940
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
7941
|
+
case 429:
|
|
7942
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7738
7943
|
default:
|
|
7739
7944
|
throw new VectrosError({
|
|
7740
7945
|
statusCode: _response.error.statusCode,
|
|
@@ -7823,6 +8028,7 @@ var RecordsClient = class {
|
|
|
7823
8028
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7824
8029
|
*
|
|
7825
8030
|
* @throws {@link Vectros.BadRequestError}
|
|
8031
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7826
8032
|
*
|
|
7827
8033
|
* @example
|
|
7828
8034
|
* await client.records.lookupRecordsByBody({
|
|
@@ -7864,6 +8070,8 @@ var RecordsClient = class {
|
|
|
7864
8070
|
switch (_response.error.statusCode) {
|
|
7865
8071
|
case 400:
|
|
7866
8072
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8073
|
+
case 429:
|
|
8074
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7867
8075
|
default:
|
|
7868
8076
|
throw new VectrosError({
|
|
7869
8077
|
statusCode: _response.error.statusCode,
|
|
@@ -8056,42 +8264,50 @@ var SchemasClient = class {
|
|
|
8056
8264
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
|
|
8057
8265
|
}
|
|
8058
8266
|
/**
|
|
8059
|
-
* 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. Requires the `schemas:w` scope.
|
|
8267
|
+
* 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:w` scope; only legal schema changes are applied — migration-locked changes are rejected). Requires the `schemas:w` scope.
|
|
8060
8268
|
*
|
|
8061
|
-
* @param {Vectros.
|
|
8269
|
+
* @param {Vectros.CreateSchemaRequest} request
|
|
8062
8270
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8063
8271
|
*
|
|
8064
8272
|
* @throws {@link Vectros.BadRequestError}
|
|
8273
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
8274
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8065
8275
|
*
|
|
8066
8276
|
* @example
|
|
8067
8277
|
* await client.schemas.createSchema({
|
|
8068
|
-
*
|
|
8069
|
-
*
|
|
8070
|
-
*
|
|
8071
|
-
*
|
|
8072
|
-
*
|
|
8073
|
-
*
|
|
8074
|
-
*
|
|
8075
|
-
*
|
|
8076
|
-
*
|
|
8077
|
-
*
|
|
8078
|
-
*
|
|
8079
|
-
*
|
|
8080
|
-
*
|
|
8081
|
-
*
|
|
8082
|
-
*
|
|
8083
|
-
*
|
|
8084
|
-
*
|
|
8085
|
-
*
|
|
8086
|
-
*
|
|
8087
|
-
*
|
|
8088
|
-
*
|
|
8278
|
+
* body: {
|
|
8279
|
+
* typeName: "intake_form",
|
|
8280
|
+
* displayName: "Client Intake Form",
|
|
8281
|
+
* description: "Captures initial client information",
|
|
8282
|
+
* fields: [{
|
|
8283
|
+
* fieldId: "first_name",
|
|
8284
|
+
* fieldType: "string",
|
|
8285
|
+
* required: true,
|
|
8286
|
+
* searchable: true
|
|
8287
|
+
* }, {
|
|
8288
|
+
* fieldId: "email",
|
|
8289
|
+
* fieldType: "string",
|
|
8290
|
+
* required: true
|
|
8291
|
+
* }],
|
|
8292
|
+
* lookupFields: [{
|
|
8293
|
+
* fieldName: "email",
|
|
8294
|
+
* unique: true
|
|
8295
|
+
* }],
|
|
8296
|
+
* capabilities: {
|
|
8297
|
+
* "auditHistory": true
|
|
8298
|
+
* },
|
|
8299
|
+
* allowedSurfaces: ["record"]
|
|
8300
|
+
* }
|
|
8089
8301
|
* })
|
|
8090
8302
|
*/
|
|
8091
8303
|
createSchema(request, requestOptions) {
|
|
8092
8304
|
return HttpResponsePromise.fromPromise(this.__createSchema(request, requestOptions));
|
|
8093
8305
|
}
|
|
8094
8306
|
async __createSchema(request, requestOptions) {
|
|
8307
|
+
const { upsert, body: _body } = request;
|
|
8308
|
+
const _queryParams = {
|
|
8309
|
+
upsert
|
|
8310
|
+
};
|
|
8095
8311
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
8096
8312
|
const _headers = mergeHeaders(
|
|
8097
8313
|
_authRequest.headers,
|
|
@@ -8106,9 +8322,9 @@ var SchemasClient = class {
|
|
|
8106
8322
|
method: "POST",
|
|
8107
8323
|
headers: _headers,
|
|
8108
8324
|
contentType: "application/json",
|
|
8109
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
8325
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
8110
8326
|
requestType: "json",
|
|
8111
|
-
body:
|
|
8327
|
+
body: _body,
|
|
8112
8328
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
8113
8329
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
8114
8330
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -8122,6 +8338,10 @@ var SchemasClient = class {
|
|
|
8122
8338
|
switch (_response.error.statusCode) {
|
|
8123
8339
|
case 400:
|
|
8124
8340
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8341
|
+
case 403:
|
|
8342
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8343
|
+
case 429:
|
|
8344
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8125
8345
|
default:
|
|
8126
8346
|
throw new VectrosError({
|
|
8127
8347
|
statusCode: _response.error.statusCode,
|
|
@@ -8195,6 +8415,7 @@ var SchemasClient = class {
|
|
|
8195
8415
|
*
|
|
8196
8416
|
* @throws {@link Vectros.BadRequestError}
|
|
8197
8417
|
* @throws {@link Vectros.NotFoundError}
|
|
8418
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8198
8419
|
*
|
|
8199
8420
|
* @example
|
|
8200
8421
|
* await client.schemas.updateSchema({
|
|
@@ -8243,6 +8464,8 @@ var SchemasClient = class {
|
|
|
8243
8464
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8244
8465
|
case 404:
|
|
8245
8466
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8467
|
+
case 429:
|
|
8468
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8246
8469
|
default:
|
|
8247
8470
|
throw new VectrosError({
|
|
8248
8471
|
statusCode: _response.error.statusCode,
|
|
@@ -8261,6 +8484,7 @@ var SchemasClient = class {
|
|
|
8261
8484
|
*
|
|
8262
8485
|
* @throws {@link Vectros.NotFoundError}
|
|
8263
8486
|
* @throws {@link Vectros.ConflictError}
|
|
8487
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8264
8488
|
*
|
|
8265
8489
|
* @example
|
|
8266
8490
|
* await client.schemas.deleteSchema({
|
|
@@ -8301,6 +8525,8 @@ var SchemasClient = class {
|
|
|
8301
8525
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8302
8526
|
case 409:
|
|
8303
8527
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
8528
|
+
case 429:
|
|
8529
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8304
8530
|
default:
|
|
8305
8531
|
throw new VectrosError({
|
|
8306
8532
|
statusCode: _response.error.statusCode,
|
|
@@ -8382,6 +8608,7 @@ var SearchClient = class {
|
|
|
8382
8608
|
*
|
|
8383
8609
|
* @throws {@link Vectros.BadRequestError}
|
|
8384
8610
|
* @throws {@link Vectros.ForbiddenError}
|
|
8611
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8385
8612
|
*
|
|
8386
8613
|
* @example
|
|
8387
8614
|
* await client.search.content({
|
|
@@ -8424,6 +8651,8 @@ var SearchClient = class {
|
|
|
8424
8651
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8425
8652
|
case 403:
|
|
8426
8653
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8654
|
+
case 429:
|
|
8655
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8427
8656
|
default:
|
|
8428
8657
|
throw new VectrosError({
|
|
8429
8658
|
statusCode: _response.error.statusCode,
|
|
@@ -8661,11 +8890,36 @@ var BlueprintServicePrincipalSchema = import_zod.z.object({
|
|
|
8661
8890
|
externalId: import_zod.z.string().min(1),
|
|
8662
8891
|
displayName: import_zod.z.string().min(1)
|
|
8663
8892
|
}).strict();
|
|
8664
|
-
var
|
|
8893
|
+
var SeedCommonShape = {
|
|
8894
|
+
/** The schema typeName this seed instantiates (should match a declared schema). */
|
|
8665
8895
|
typeName: import_zod.z.string().min(1),
|
|
8666
|
-
|
|
8896
|
+
/**
|
|
8897
|
+
* Stable, caller-supplied id — the loader's idempotency key AND the value other
|
|
8898
|
+
* seeds resolve a `reference` against (across surfaces: a record seed may
|
|
8899
|
+
* reference a document seed by its externalId, and vice versa).
|
|
8900
|
+
*/
|
|
8901
|
+
externalId: import_zod.z.string().min(1)
|
|
8902
|
+
};
|
|
8903
|
+
var RecordSeedSchema = import_zod.z.object({
|
|
8904
|
+
surface: import_zod.z.literal("record"),
|
|
8905
|
+
...SeedCommonShape,
|
|
8906
|
+
/** The record payload, validated against the bound schema. */
|
|
8667
8907
|
fields: import_zod.z.record(import_zod.z.unknown())
|
|
8668
8908
|
}).strict();
|
|
8909
|
+
var DocumentSeedSchema = import_zod.z.object({
|
|
8910
|
+
surface: import_zod.z.literal("document"),
|
|
8911
|
+
...SeedCommonShape,
|
|
8912
|
+
/** Human-readable document title — REQUIRED by the text-ingest path. */
|
|
8913
|
+
title: import_zod.z.string().min(1),
|
|
8914
|
+
/** Raw text content to ingest + index — REQUIRED and non-empty (the platform rejects a blank ingest). */
|
|
8915
|
+
text: import_zod.z.string().min(1),
|
|
8916
|
+
/** Optional structured payload bound to the schema (the document's `fields`). */
|
|
8917
|
+
fields: import_zod.z.record(import_zod.z.unknown()).optional()
|
|
8918
|
+
}).strict();
|
|
8919
|
+
var BlueprintSeedRecordSchema = import_zod.z.discriminatedUnion("surface", [
|
|
8920
|
+
RecordSeedSchema,
|
|
8921
|
+
DocumentSeedSchema
|
|
8922
|
+
]);
|
|
8669
8923
|
var SELF_TOKEN_RE = /\$\{\{\s*self\.[A-Za-z_]\w*\s*\}\}/;
|
|
8670
8924
|
function lintSelfTokenPlacement(value, ctx) {
|
|
8671
8925
|
const walk = (node, path4, inRoleDataScope) => {
|
|
@@ -8721,6 +8975,23 @@ function lintIdentityRefsDeclared(value, ctx) {
|
|
|
8721
8975
|
};
|
|
8722
8976
|
walk(value, []);
|
|
8723
8977
|
}
|
|
8978
|
+
function lintSeedSurfaces(value, ctx) {
|
|
8979
|
+
const bp = value;
|
|
8980
|
+
if (!Array.isArray(bp.seed)) return;
|
|
8981
|
+
const byType = new Map((bp.schemas ?? []).map((s) => [s.typeName, s]));
|
|
8982
|
+
bp.seed.forEach((seed, i) => {
|
|
8983
|
+
const schema = byType.get(seed.typeName);
|
|
8984
|
+
if (!schema) return;
|
|
8985
|
+
const allowed = schema.allowedSurfaces ?? ["record"];
|
|
8986
|
+
if (!allowed.includes(seed.surface ?? "record")) {
|
|
8987
|
+
ctx.addIssue({
|
|
8988
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8989
|
+
path: ["seed", i, "surface"],
|
|
8990
|
+
message: `seed '${seed.externalId}' uses surface '${seed.surface ?? "record"}', but schema '${seed.typeName}' allows only [${allowed.join(", ")}]`
|
|
8991
|
+
});
|
|
8992
|
+
}
|
|
8993
|
+
});
|
|
8994
|
+
}
|
|
8724
8995
|
var BlueprintSchema = import_zod.z.object({
|
|
8725
8996
|
/** Stable blueprint id (the `--blueprint <name>` selector + idempotency key). */
|
|
8726
8997
|
name: import_zod.z.string().min(1),
|
|
@@ -8743,6 +9014,7 @@ var BlueprintSchema = import_zod.z.object({
|
|
|
8743
9014
|
}).strict().superRefine((bp, ctx) => {
|
|
8744
9015
|
lintSelfTokenPlacement(bp, ctx);
|
|
8745
9016
|
lintIdentityRefsDeclared(bp, ctx);
|
|
9017
|
+
lintSeedSurfaces(bp, ctx);
|
|
8746
9018
|
});
|
|
8747
9019
|
function formatIssuePath(path4) {
|
|
8748
9020
|
let out = "";
|
|
@@ -9140,6 +9412,7 @@ var taskManagement = {
|
|
|
9140
9412
|
},
|
|
9141
9413
|
seed: [
|
|
9142
9414
|
{
|
|
9415
|
+
surface: "record",
|
|
9143
9416
|
typeName: "task",
|
|
9144
9417
|
externalId: "seed-welcome",
|
|
9145
9418
|
fields: {
|
|
@@ -9367,6 +9640,7 @@ var codingAgentMemory = {
|
|
|
9367
9640
|
// Seeded FIRST so the convention below resolves its reference to it — the
|
|
9368
9641
|
// loader creates seeds in array order, and a reference target must exist when
|
|
9369
9642
|
// the referencing record is written.
|
|
9643
|
+
surface: "record",
|
|
9370
9644
|
typeName: "decision",
|
|
9371
9645
|
externalId: "seed-use-vectros-for-memory",
|
|
9372
9646
|
fields: {
|
|
@@ -9382,6 +9656,7 @@ var codingAgentMemory = {
|
|
|
9382
9656
|
// Demonstrates a live typed link at bootstrap: this convention references the
|
|
9383
9657
|
// decision above by its externalId, so "open the decision behind this rule"
|
|
9384
9658
|
// works the moment the blueprint is applied.
|
|
9659
|
+
surface: "record",
|
|
9385
9660
|
typeName: "convention",
|
|
9386
9661
|
externalId: "seed-record-the-why",
|
|
9387
9662
|
fields: {
|
|
@@ -9396,41 +9671,722 @@ var codingAgentMemory = {
|
|
|
9396
9671
|
]
|
|
9397
9672
|
};
|
|
9398
9673
|
var coding_agent_memory_default = codingAgentMemory;
|
|
9399
|
-
var
|
|
9400
|
-
name: "
|
|
9674
|
+
var agenticSdlc = {
|
|
9675
|
+
name: "agentic-sdlc",
|
|
9401
9676
|
version: "1.0.0",
|
|
9402
|
-
description: "A
|
|
9403
|
-
contextId: "
|
|
9404
|
-
contextName: "
|
|
9677
|
+
description: "A whole-SDLC system of record for an AI development team \u2014 decisions, designs, references, runbooks, post-mortems (as documents) plus controls, conventions, gotchas, and a glossary (as records), cross-linked and recalled by meaning.",
|
|
9678
|
+
contextId: "agentic-sdlc",
|
|
9679
|
+
contextName: "Agentic SDLC Knowledge Base",
|
|
9405
9680
|
schemas: [
|
|
9681
|
+
// ============================ DOCUMENTS ============================
|
|
9682
|
+
// Content-dominant: the markdown body is the artifact; fields are metadata.
|
|
9683
|
+
// Each binds the `document` surface and is ingested via `document_ingest`.
|
|
9406
9684
|
{
|
|
9407
|
-
|
|
9408
|
-
|
|
9685
|
+
// An architecture/product DECISION (an ADR). The body is the prose —
|
|
9686
|
+
// Context / Decision / Consequences — and is what `rag_ask` answers over;
|
|
9687
|
+
// the fields below are filter/sort metadata + the supersede chain. The
|
|
9688
|
+
// anchor of the graph: most other types link back to a decision.
|
|
9689
|
+
typeName: "decision",
|
|
9690
|
+
displayName: "Decision (ADR)",
|
|
9409
9691
|
indexMode: "HYBRID",
|
|
9410
|
-
|
|
9692
|
+
allowedSurfaces: ["document"],
|
|
9693
|
+
// A document carries an INTRINSIC title (the ingest title) + body; the schema
|
|
9694
|
+
// declares only the metadata BEYOND those. (No typed `title` field — that
|
|
9695
|
+
// would duplicate the document's own title.)
|
|
9411
9696
|
fields: [
|
|
9412
9697
|
{
|
|
9413
|
-
fieldId: "
|
|
9698
|
+
fieldId: "summary",
|
|
9414
9699
|
fieldType: "string",
|
|
9415
|
-
required: true,
|
|
9416
9700
|
searchable: true,
|
|
9417
|
-
|
|
9418
|
-
renderHints: { label: "
|
|
9701
|
+
description: "A one-paragraph abstract of the decision. The full reasoning is the document body.",
|
|
9702
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9419
9703
|
},
|
|
9420
9704
|
{
|
|
9421
|
-
fieldId: "
|
|
9705
|
+
fieldId: "status",
|
|
9706
|
+
fieldType: "enum",
|
|
9707
|
+
filterable: true,
|
|
9708
|
+
enumValues: ["proposed", "accepted", "superseded", "deprecated"],
|
|
9709
|
+
renderHints: { label: "Status", widget: "select", order: 3 }
|
|
9710
|
+
},
|
|
9711
|
+
{
|
|
9712
|
+
fieldId: "area",
|
|
9422
9713
|
fieldType: "string",
|
|
9423
|
-
|
|
9424
|
-
description:
|
|
9425
|
-
|
|
9426
|
-
renderHints: { label: "Body", widget: "textarea", order: 2, section: "Note" }
|
|
9714
|
+
filterable: true,
|
|
9715
|
+
description: 'Subsystem the decision applies to (e.g. "search", "auth", "billing").',
|
|
9716
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9427
9717
|
},
|
|
9428
9718
|
{
|
|
9429
9719
|
fieldId: "tags",
|
|
9430
9720
|
fieldType: "array",
|
|
9431
9721
|
filterable: true,
|
|
9432
|
-
description: 'Freeform
|
|
9433
|
-
renderHints: { label: "Tags", order:
|
|
9722
|
+
description: 'Freeform labels (e.g. "security", "schema"). Search-side filter.',
|
|
9723
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9724
|
+
},
|
|
9725
|
+
{
|
|
9726
|
+
// Self-reference (document → document): the decision this one supersedes.
|
|
9727
|
+
fieldId: "supersedes",
|
|
9728
|
+
fieldType: "reference",
|
|
9729
|
+
targetTypeName: "decision",
|
|
9730
|
+
targetSurface: "document",
|
|
9731
|
+
targetField: "externalId",
|
|
9732
|
+
cardinality: "one",
|
|
9733
|
+
description: "The decision this one supersedes (by externalId).",
|
|
9734
|
+
renderHints: { label: "Supersedes", order: 6 }
|
|
9735
|
+
},
|
|
9736
|
+
{
|
|
9737
|
+
fieldId: "date",
|
|
9738
|
+
fieldType: "date",
|
|
9739
|
+
description: "ISO-8601 decision date. Range-queryable / sortable.",
|
|
9740
|
+
renderHints: { label: "Date", widget: "date", order: 7 }
|
|
9741
|
+
}
|
|
9742
|
+
],
|
|
9743
|
+
lookupFields: ["status", "area", "supersedes", { fieldName: "date", rangeEnabled: true }]
|
|
9744
|
+
},
|
|
9745
|
+
{
|
|
9746
|
+
// A DESIGN doc or spec — the exploration that drives a decision. Distinct
|
|
9747
|
+
// from `decision` (a different browse genre + it links to the decision it
|
|
9748
|
+
// informs). Body = the design narrative.
|
|
9749
|
+
typeName: "design",
|
|
9750
|
+
displayName: "Design",
|
|
9751
|
+
indexMode: "HYBRID",
|
|
9752
|
+
allowedSurfaces: ["document"],
|
|
9753
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9754
|
+
fields: [
|
|
9755
|
+
{
|
|
9756
|
+
fieldId: "summary",
|
|
9757
|
+
fieldType: "string",
|
|
9758
|
+
searchable: true,
|
|
9759
|
+
description: "A one-paragraph abstract. The full design is the document body.",
|
|
9760
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9761
|
+
},
|
|
9762
|
+
{
|
|
9763
|
+
fieldId: "status",
|
|
9764
|
+
fieldType: "enum",
|
|
9765
|
+
filterable: true,
|
|
9766
|
+
enumValues: ["draft", "active", "implemented", "superseded"],
|
|
9767
|
+
renderHints: { label: "Status", widget: "select", order: 3 }
|
|
9768
|
+
},
|
|
9769
|
+
{
|
|
9770
|
+
fieldId: "area",
|
|
9771
|
+
fieldType: "string",
|
|
9772
|
+
filterable: true,
|
|
9773
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9774
|
+
},
|
|
9775
|
+
{
|
|
9776
|
+
fieldId: "tags",
|
|
9777
|
+
fieldType: "array",
|
|
9778
|
+
filterable: true,
|
|
9779
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9780
|
+
},
|
|
9781
|
+
{
|
|
9782
|
+
// Cross-document edge: the decision this design informs/produces.
|
|
9783
|
+
fieldId: "relatedDecision",
|
|
9784
|
+
fieldType: "reference",
|
|
9785
|
+
targetTypeName: "decision",
|
|
9786
|
+
targetSurface: "document",
|
|
9787
|
+
targetField: "externalId",
|
|
9788
|
+
cardinality: "one",
|
|
9789
|
+
description: "The decision this design informs (by externalId).",
|
|
9790
|
+
renderHints: { label: "Related decision", order: 6 }
|
|
9791
|
+
},
|
|
9792
|
+
{
|
|
9793
|
+
// Self-reference: a design supersedes an earlier design/spec.
|
|
9794
|
+
fieldId: "supersedes",
|
|
9795
|
+
fieldType: "reference",
|
|
9796
|
+
targetTypeName: "design",
|
|
9797
|
+
targetSurface: "document",
|
|
9798
|
+
targetField: "externalId",
|
|
9799
|
+
cardinality: "one",
|
|
9800
|
+
description: "The design this one supersedes (by externalId).",
|
|
9801
|
+
renderHints: { label: "Supersedes", order: 7 }
|
|
9802
|
+
},
|
|
9803
|
+
{
|
|
9804
|
+
fieldId: "updatedOn",
|
|
9805
|
+
fieldType: "date",
|
|
9806
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
9807
|
+
renderHints: { label: "Updated on", widget: "date", order: 8 }
|
|
9808
|
+
}
|
|
9809
|
+
],
|
|
9810
|
+
lookupFields: ["status", "area", "relatedDecision", "supersedes", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
9811
|
+
},
|
|
9812
|
+
{
|
|
9813
|
+
// A REFERENCE doc — maintained "how it works / how to": guides, onboarding,
|
|
9814
|
+
// API docs, process docs. Body = the prose. Distinct shape: a `category`
|
|
9815
|
+
// (DRY sub-labels — onboarding/api/process are same shape) and `lastReviewed`
|
|
9816
|
+
// (freshness is the whole game for reference material).
|
|
9817
|
+
typeName: "reference",
|
|
9818
|
+
displayName: "Reference",
|
|
9819
|
+
indexMode: "HYBRID",
|
|
9820
|
+
allowedSurfaces: ["document"],
|
|
9821
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9822
|
+
fields: [
|
|
9823
|
+
{
|
|
9824
|
+
fieldId: "summary",
|
|
9825
|
+
fieldType: "string",
|
|
9826
|
+
searchable: true,
|
|
9827
|
+
description: "A one-paragraph abstract. The full reference is the document body.",
|
|
9828
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9829
|
+
},
|
|
9830
|
+
{
|
|
9831
|
+
// The sub-kind, as a filterable field (not a separate schema — these are
|
|
9832
|
+
// the same shape, differing only by label, so a field is the DRY choice).
|
|
9833
|
+
fieldId: "category",
|
|
9834
|
+
fieldType: "enum",
|
|
9835
|
+
filterable: true,
|
|
9836
|
+
enumValues: ["guide", "onboarding", "api", "process", "other"],
|
|
9837
|
+
renderHints: { label: "Category", widget: "select", order: 3 }
|
|
9838
|
+
},
|
|
9839
|
+
{
|
|
9840
|
+
fieldId: "area",
|
|
9841
|
+
fieldType: "string",
|
|
9842
|
+
filterable: true,
|
|
9843
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9844
|
+
},
|
|
9845
|
+
{
|
|
9846
|
+
fieldId: "tags",
|
|
9847
|
+
fieldType: "array",
|
|
9848
|
+
filterable: true,
|
|
9849
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9850
|
+
},
|
|
9851
|
+
{
|
|
9852
|
+
fieldId: "status",
|
|
9853
|
+
fieldType: "enum",
|
|
9854
|
+
filterable: true,
|
|
9855
|
+
enumValues: ["active", "superseded"],
|
|
9856
|
+
renderHints: { label: "Status", widget: "select", order: 6 }
|
|
9857
|
+
},
|
|
9858
|
+
{
|
|
9859
|
+
// Optional cross-document edge: the decision behind this reference.
|
|
9860
|
+
fieldId: "relatedDecision",
|
|
9861
|
+
fieldType: "reference",
|
|
9862
|
+
targetTypeName: "decision",
|
|
9863
|
+
targetSurface: "document",
|
|
9864
|
+
targetField: "externalId",
|
|
9865
|
+
cardinality: "one",
|
|
9866
|
+
description: "The decision behind this reference, if any (by externalId).",
|
|
9867
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9868
|
+
},
|
|
9869
|
+
{
|
|
9870
|
+
// Freshness — "references not reviewed since X". The reference-doc signal.
|
|
9871
|
+
fieldId: "lastReviewed",
|
|
9872
|
+
fieldType: "date",
|
|
9873
|
+
description: "ISO-8601 \u2014 when this reference was last verified current. Range-queryable.",
|
|
9874
|
+
renderHints: { label: "Last reviewed", widget: "date", order: 8 }
|
|
9875
|
+
}
|
|
9876
|
+
],
|
|
9877
|
+
lookupFields: ["category", "area", "status", "relatedDecision", { fieldName: "lastReviewed", rangeEnabled: true }]
|
|
9878
|
+
},
|
|
9879
|
+
{
|
|
9880
|
+
// A RUNBOOK — a step-by-step operational procedure (deploy, release, recover).
|
|
9881
|
+
// Body = the procedure. Distinct browse genre, and often BORN FROM a
|
|
9882
|
+
// post-mortem (its resolution, codified) — a cross-document edge.
|
|
9883
|
+
typeName: "runbook",
|
|
9884
|
+
displayName: "Runbook",
|
|
9885
|
+
indexMode: "HYBRID",
|
|
9886
|
+
allowedSurfaces: ["document"],
|
|
9887
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9888
|
+
fields: [
|
|
9889
|
+
{
|
|
9890
|
+
fieldId: "summary",
|
|
9891
|
+
fieldType: "string",
|
|
9892
|
+
searchable: true,
|
|
9893
|
+
description: "When to use this runbook \u2014 the trigger. The steps are the document body.",
|
|
9894
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9895
|
+
},
|
|
9896
|
+
{
|
|
9897
|
+
fieldId: "area",
|
|
9898
|
+
fieldType: "string",
|
|
9899
|
+
filterable: true,
|
|
9900
|
+
renderHints: { label: "Area", widget: "text", order: 3 }
|
|
9901
|
+
},
|
|
9902
|
+
{
|
|
9903
|
+
fieldId: "tags",
|
|
9904
|
+
fieldType: "array",
|
|
9905
|
+
filterable: true,
|
|
9906
|
+
renderHints: { label: "Tags", order: 4 }
|
|
9907
|
+
},
|
|
9908
|
+
{
|
|
9909
|
+
fieldId: "status",
|
|
9910
|
+
fieldType: "enum",
|
|
9911
|
+
filterable: true,
|
|
9912
|
+
enumValues: ["active", "retired"],
|
|
9913
|
+
renderHints: { label: "Status", widget: "select", order: 5 }
|
|
9914
|
+
},
|
|
9915
|
+
{
|
|
9916
|
+
// Cross-document edge: the post-mortem whose resolution this runbook codifies.
|
|
9917
|
+
fieldId: "bornFrom",
|
|
9918
|
+
fieldType: "reference",
|
|
9919
|
+
targetTypeName: "postmortem",
|
|
9920
|
+
targetSurface: "document",
|
|
9921
|
+
targetField: "externalId",
|
|
9922
|
+
cardinality: "one",
|
|
9923
|
+
description: "The post-mortem this runbook was codified from (by externalId).",
|
|
9924
|
+
renderHints: { label: "Born from (post-mortem)", order: 6 }
|
|
9925
|
+
},
|
|
9926
|
+
{
|
|
9927
|
+
fieldId: "relatedDecision",
|
|
9928
|
+
fieldType: "reference",
|
|
9929
|
+
targetTypeName: "decision",
|
|
9930
|
+
targetSurface: "document",
|
|
9931
|
+
targetField: "externalId",
|
|
9932
|
+
cardinality: "one",
|
|
9933
|
+
description: "A decision this runbook implements, if any (by externalId).",
|
|
9934
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9935
|
+
},
|
|
9936
|
+
{
|
|
9937
|
+
fieldId: "updatedOn",
|
|
9938
|
+
fieldType: "date",
|
|
9939
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
9940
|
+
renderHints: { label: "Updated on", widget: "date", order: 8 }
|
|
9941
|
+
}
|
|
9942
|
+
],
|
|
9943
|
+
lookupFields: ["area", "status", "bornFrom", "relatedDecision", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
9944
|
+
},
|
|
9945
|
+
{
|
|
9946
|
+
// A POST-MORTEM — what broke and the durable lesson. Body = the writeup
|
|
9947
|
+
// (impact / root cause / resolution / lesson). Distinct shape: `severity` +
|
|
9948
|
+
// `occurredOn` (the incident timeline). "Have we hit this before?" lives here.
|
|
9949
|
+
typeName: "postmortem",
|
|
9950
|
+
displayName: "Post-mortem",
|
|
9951
|
+
indexMode: "HYBRID",
|
|
9952
|
+
allowedSurfaces: ["document"],
|
|
9953
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9954
|
+
fields: [
|
|
9955
|
+
{
|
|
9956
|
+
fieldId: "summary",
|
|
9957
|
+
fieldType: "string",
|
|
9958
|
+
searchable: true,
|
|
9959
|
+
description: "What happened, in brief. The full analysis (impact/root cause/resolution/lesson) is the body.",
|
|
9960
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9961
|
+
},
|
|
9962
|
+
{
|
|
9963
|
+
fieldId: "severity",
|
|
9964
|
+
fieldType: "enum",
|
|
9965
|
+
filterable: true,
|
|
9966
|
+
enumValues: ["low", "medium", "high", "critical"],
|
|
9967
|
+
renderHints: { label: "Severity", widget: "select", order: 3 }
|
|
9968
|
+
},
|
|
9969
|
+
{
|
|
9970
|
+
fieldId: "status",
|
|
9971
|
+
fieldType: "enum",
|
|
9972
|
+
filterable: true,
|
|
9973
|
+
enumValues: ["open", "mitigated", "resolved"],
|
|
9974
|
+
renderHints: { label: "Status", widget: "select", order: 4 }
|
|
9975
|
+
},
|
|
9976
|
+
{
|
|
9977
|
+
fieldId: "area",
|
|
9978
|
+
fieldType: "string",
|
|
9979
|
+
filterable: true,
|
|
9980
|
+
renderHints: { label: "Area", widget: "text", order: 5 }
|
|
9981
|
+
},
|
|
9982
|
+
{
|
|
9983
|
+
fieldId: "tags",
|
|
9984
|
+
fieldType: "array",
|
|
9985
|
+
filterable: true,
|
|
9986
|
+
renderHints: { label: "Tags", order: 6 }
|
|
9987
|
+
},
|
|
9988
|
+
{
|
|
9989
|
+
fieldId: "relatedDecision",
|
|
9990
|
+
fieldType: "reference",
|
|
9991
|
+
targetTypeName: "decision",
|
|
9992
|
+
targetSurface: "document",
|
|
9993
|
+
targetField: "externalId",
|
|
9994
|
+
cardinality: "one",
|
|
9995
|
+
description: "A decision implicated in or addressed by this incident (by externalId).",
|
|
9996
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9997
|
+
},
|
|
9998
|
+
{
|
|
9999
|
+
fieldId: "occurredOn",
|
|
10000
|
+
fieldType: "date",
|
|
10001
|
+
description: 'ISO-8601 \u2014 when it happened. Range-queryable \u2014 "incidents this month".',
|
|
10002
|
+
renderHints: { label: "Occurred on", widget: "date", order: 8 }
|
|
10003
|
+
}
|
|
10004
|
+
],
|
|
10005
|
+
lookupFields: ["severity", "status", "area", "relatedDecision", { fieldName: "occurredOn", rangeEnabled: true }]
|
|
10006
|
+
},
|
|
10007
|
+
// ============================= RECORDS =============================
|
|
10008
|
+
// Structure-dominant: the typed fields are the artifact. Short, exact-queryable.
|
|
10009
|
+
{
|
|
10010
|
+
// A governance CONTROL — a policy/standard/control the codebase must satisfy,
|
|
10011
|
+
// WITH its evidence. The compliance instrument: it records what enforces it
|
|
10012
|
+
// (`evidence`), the runbook that VERIFIES it (cross-surface → document), and
|
|
10013
|
+
// the decision that mandates it. "Which critical controls are active, and how
|
|
10014
|
+
// is each proven?"
|
|
10015
|
+
typeName: "control",
|
|
10016
|
+
displayName: "Control",
|
|
10017
|
+
indexMode: "HYBRID",
|
|
10018
|
+
fields: [
|
|
10019
|
+
{
|
|
10020
|
+
fieldId: "title",
|
|
10021
|
+
fieldType: "string",
|
|
10022
|
+
required: true,
|
|
10023
|
+
searchable: true,
|
|
10024
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10025
|
+
renderHints: { label: "Title", widget: "text", order: 1, displayField: true }
|
|
10026
|
+
},
|
|
10027
|
+
{
|
|
10028
|
+
fieldId: "statement",
|
|
10029
|
+
fieldType: "string",
|
|
10030
|
+
searchable: true,
|
|
10031
|
+
description: "The requirement \u2014 what must always hold.",
|
|
10032
|
+
renderHints: { label: "Statement", widget: "textarea", order: 2 }
|
|
10033
|
+
},
|
|
10034
|
+
{
|
|
10035
|
+
fieldId: "rationale",
|
|
10036
|
+
fieldType: "string",
|
|
10037
|
+
searchable: true,
|
|
10038
|
+
description: "Why the control exists \u2014 the risk it prevents.",
|
|
10039
|
+
renderHints: { label: "Rationale", widget: "textarea", order: 3 }
|
|
10040
|
+
},
|
|
10041
|
+
{
|
|
10042
|
+
// The policy → implementation spectrum in one filterable field.
|
|
10043
|
+
fieldId: "kind",
|
|
10044
|
+
fieldType: "enum",
|
|
10045
|
+
filterable: true,
|
|
10046
|
+
enumValues: ["policy", "standard", "control"],
|
|
10047
|
+
renderHints: { label: "Kind", widget: "select", order: 4 }
|
|
10048
|
+
},
|
|
10049
|
+
{
|
|
10050
|
+
// Ordinal, but EQUALITY (range/prefix order is lexical, so low<critical
|
|
10051
|
+
// would sort alphabetically). Enumerate "all critical controls" by equality.
|
|
10052
|
+
fieldId: "criticality",
|
|
10053
|
+
fieldType: "enum",
|
|
10054
|
+
filterable: true,
|
|
10055
|
+
enumValues: ["low", "medium", "high", "critical"],
|
|
10056
|
+
renderHints: { label: "Criticality", widget: "select", order: 5 }
|
|
10057
|
+
},
|
|
10058
|
+
{
|
|
10059
|
+
fieldId: "evidence",
|
|
10060
|
+
fieldType: "string",
|
|
10061
|
+
searchable: true,
|
|
10062
|
+
description: "What enforces or proves the control inline (e.g. an architecture test or gate).",
|
|
10063
|
+
renderHints: { label: "Evidence", widget: "textarea", order: 6 }
|
|
10064
|
+
},
|
|
10065
|
+
{
|
|
10066
|
+
fieldId: "status",
|
|
10067
|
+
fieldType: "enum",
|
|
10068
|
+
filterable: true,
|
|
10069
|
+
enumValues: ["draft", "active", "retired"],
|
|
10070
|
+
renderHints: { label: "Status", widget: "select", order: 7 }
|
|
10071
|
+
},
|
|
10072
|
+
{
|
|
10073
|
+
fieldId: "area",
|
|
10074
|
+
fieldType: "string",
|
|
10075
|
+
filterable: true,
|
|
10076
|
+
renderHints: { label: "Area", widget: "text", order: 8 }
|
|
10077
|
+
},
|
|
10078
|
+
{
|
|
10079
|
+
fieldId: "tags",
|
|
10080
|
+
fieldType: "array",
|
|
10081
|
+
filterable: true,
|
|
10082
|
+
renderHints: { label: "Tags", order: 9 }
|
|
10083
|
+
},
|
|
10084
|
+
{
|
|
10085
|
+
// Cross-surface edge (record → document): the runbook that proves the control.
|
|
10086
|
+
fieldId: "verifiedBy",
|
|
10087
|
+
fieldType: "reference",
|
|
10088
|
+
targetTypeName: "runbook",
|
|
10089
|
+
targetSurface: "document",
|
|
10090
|
+
targetField: "externalId",
|
|
10091
|
+
cardinality: "one",
|
|
10092
|
+
description: "The runbook that verifies this control (by externalId).",
|
|
10093
|
+
renderHints: { label: "Verified by (runbook)", order: 10 }
|
|
10094
|
+
},
|
|
10095
|
+
{
|
|
10096
|
+
// Cross-surface edge (record → document): the decision that mandates it.
|
|
10097
|
+
fieldId: "relatedDecision",
|
|
10098
|
+
fieldType: "reference",
|
|
10099
|
+
targetTypeName: "decision",
|
|
10100
|
+
targetSurface: "document",
|
|
10101
|
+
targetField: "externalId",
|
|
10102
|
+
cardinality: "one",
|
|
10103
|
+
description: "The decision that mandates this control (by externalId).",
|
|
10104
|
+
renderHints: { label: "Related decision", order: 11 }
|
|
10105
|
+
},
|
|
10106
|
+
{
|
|
10107
|
+
fieldId: "reviewedOn",
|
|
10108
|
+
fieldType: "date",
|
|
10109
|
+
description: "ISO-8601 last-reviewed date. Range-queryable.",
|
|
10110
|
+
renderHints: { label: "Reviewed on", widget: "date", order: 12 }
|
|
10111
|
+
}
|
|
10112
|
+
],
|
|
10113
|
+
lookupFields: [
|
|
10114
|
+
"kind",
|
|
10115
|
+
"criticality",
|
|
10116
|
+
"status",
|
|
10117
|
+
"area",
|
|
10118
|
+
"verifiedBy",
|
|
10119
|
+
"relatedDecision",
|
|
10120
|
+
{ fieldName: "reviewedOn", rangeEnabled: true }
|
|
10121
|
+
]
|
|
10122
|
+
},
|
|
10123
|
+
{
|
|
10124
|
+
// A CONVENTION — a must-follow operating rule the team teaches its agents. The
|
|
10125
|
+
// durable, shareable operating-memory. Distinct fields capture how we actually
|
|
10126
|
+
// write these: the `rule` (imperative), the `why` (rationale), and `howToApply`
|
|
10127
|
+
// (the concrete application) are SEPARATE fields, not one blob — so an agent can
|
|
10128
|
+
// recall the rule, the reasoning, and the how independently.
|
|
10129
|
+
typeName: "convention",
|
|
10130
|
+
displayName: "Convention",
|
|
10131
|
+
indexMode: "HYBRID",
|
|
10132
|
+
fields: [
|
|
10133
|
+
{
|
|
10134
|
+
fieldId: "title",
|
|
10135
|
+
fieldType: "string",
|
|
10136
|
+
required: true,
|
|
10137
|
+
searchable: true,
|
|
10138
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10139
|
+
renderHints: { label: "Title", widget: "text", order: 1, displayField: true }
|
|
10140
|
+
},
|
|
10141
|
+
{
|
|
10142
|
+
fieldId: "rule",
|
|
10143
|
+
fieldType: "string",
|
|
10144
|
+
searchable: true,
|
|
10145
|
+
description: "The convention itself, stated as an imperative.",
|
|
10146
|
+
renderHints: { label: "Rule", widget: "textarea", order: 2 }
|
|
10147
|
+
},
|
|
10148
|
+
{
|
|
10149
|
+
fieldId: "why",
|
|
10150
|
+
fieldType: "string",
|
|
10151
|
+
searchable: true,
|
|
10152
|
+
description: "Why it matters \u2014 the trade-off / the antipattern it prevents.",
|
|
10153
|
+
renderHints: { label: "Why", widget: "textarea", order: 3 }
|
|
10154
|
+
},
|
|
10155
|
+
{
|
|
10156
|
+
fieldId: "howToApply",
|
|
10157
|
+
fieldType: "string",
|
|
10158
|
+
searchable: true,
|
|
10159
|
+
description: "How to comply in practice \u2014 the concrete application steps.",
|
|
10160
|
+
renderHints: { label: "How to apply", widget: "textarea", order: 4 }
|
|
10161
|
+
},
|
|
10162
|
+
{
|
|
10163
|
+
fieldId: "area",
|
|
10164
|
+
fieldType: "string",
|
|
10165
|
+
filterable: true,
|
|
10166
|
+
renderHints: { label: "Area", widget: "text", order: 5 }
|
|
10167
|
+
},
|
|
10168
|
+
{
|
|
10169
|
+
fieldId: "status",
|
|
10170
|
+
fieldType: "enum",
|
|
10171
|
+
filterable: true,
|
|
10172
|
+
enumValues: ["active", "retired"],
|
|
10173
|
+
renderHints: { label: "Status", widget: "select", order: 6 }
|
|
10174
|
+
},
|
|
10175
|
+
{
|
|
10176
|
+
fieldId: "tags",
|
|
10177
|
+
fieldType: "array",
|
|
10178
|
+
filterable: true,
|
|
10179
|
+
renderHints: { label: "Tags", order: 7 }
|
|
10180
|
+
},
|
|
10181
|
+
{
|
|
10182
|
+
// Cross-surface edge (record → document): the decision that established it.
|
|
10183
|
+
fieldId: "establishedBy",
|
|
10184
|
+
fieldType: "reference",
|
|
10185
|
+
targetTypeName: "decision",
|
|
10186
|
+
targetSurface: "document",
|
|
10187
|
+
targetField: "externalId",
|
|
10188
|
+
cardinality: "one",
|
|
10189
|
+
description: "The decision that established this convention (by externalId).",
|
|
10190
|
+
renderHints: { label: "Established by (decision)", order: 8 }
|
|
10191
|
+
},
|
|
10192
|
+
{
|
|
10193
|
+
fieldId: "updatedOn",
|
|
10194
|
+
fieldType: "date",
|
|
10195
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
10196
|
+
renderHints: { label: "Updated on", widget: "date", order: 9 }
|
|
10197
|
+
}
|
|
10198
|
+
],
|
|
10199
|
+
lookupFields: ["area", "status", "establishedBy", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
10200
|
+
},
|
|
10201
|
+
{
|
|
10202
|
+
// A GOTCHA / sharp edge: a symptom, its cause, and the fix. A tight typed
|
|
10203
|
+
// triple — found by meaning (semantic search on the symptom) + area/status.
|
|
10204
|
+
// The most standalone type; no typed edge.
|
|
10205
|
+
typeName: "gotcha",
|
|
10206
|
+
displayName: "Gotcha",
|
|
10207
|
+
indexMode: "HYBRID",
|
|
10208
|
+
fields: [
|
|
10209
|
+
{
|
|
10210
|
+
fieldId: "symptom",
|
|
10211
|
+
fieldType: "string",
|
|
10212
|
+
required: true,
|
|
10213
|
+
searchable: true,
|
|
10214
|
+
validation: { minLength: 1, maxLength: 500 },
|
|
10215
|
+
renderHints: { label: "Symptom", widget: "textarea", order: 1, displayField: true }
|
|
10216
|
+
},
|
|
10217
|
+
{
|
|
10218
|
+
fieldId: "cause",
|
|
10219
|
+
fieldType: "string",
|
|
10220
|
+
searchable: true,
|
|
10221
|
+
renderHints: { label: "Cause", widget: "textarea", order: 2 }
|
|
10222
|
+
},
|
|
10223
|
+
{
|
|
10224
|
+
fieldId: "fix",
|
|
10225
|
+
fieldType: "string",
|
|
10226
|
+
searchable: true,
|
|
10227
|
+
renderHints: { label: "Fix", widget: "textarea", order: 3 }
|
|
10228
|
+
},
|
|
10229
|
+
{
|
|
10230
|
+
fieldId: "area",
|
|
10231
|
+
fieldType: "string",
|
|
10232
|
+
filterable: true,
|
|
10233
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
10234
|
+
},
|
|
10235
|
+
{
|
|
10236
|
+
fieldId: "status",
|
|
10237
|
+
fieldType: "enum",
|
|
10238
|
+
filterable: true,
|
|
10239
|
+
enumValues: ["active", "resolved"],
|
|
10240
|
+
renderHints: { label: "Status", widget: "select", order: 5 }
|
|
10241
|
+
},
|
|
10242
|
+
{
|
|
10243
|
+
fieldId: "tags",
|
|
10244
|
+
fieldType: "array",
|
|
10245
|
+
filterable: true,
|
|
10246
|
+
renderHints: { label: "Tags", order: 6 }
|
|
10247
|
+
},
|
|
10248
|
+
{
|
|
10249
|
+
fieldId: "discoveredOn",
|
|
10250
|
+
fieldType: "date",
|
|
10251
|
+
description: "ISO-8601 \u2014 when first hit. Range-queryable.",
|
|
10252
|
+
renderHints: { label: "Discovered on", widget: "date", order: 7 }
|
|
10253
|
+
}
|
|
10254
|
+
],
|
|
10255
|
+
lookupFields: ["area", "status", { fieldName: "discoveredOn", rangeEnabled: true }]
|
|
10256
|
+
},
|
|
10257
|
+
{
|
|
10258
|
+
// A glossary TERM — a definition keyed by the term itself. Structure-dominant:
|
|
10259
|
+
// `term` is a UNIQUE exact-lookup key (the showcase of a uniqueness constraint),
|
|
10260
|
+
// `definition` is the RAG body, `aliases` catch alternate names. Links to the
|
|
10261
|
+
// decision that defines/establishes the concept where there is one.
|
|
10262
|
+
typeName: "term",
|
|
10263
|
+
displayName: "Glossary term",
|
|
10264
|
+
indexMode: "HYBRID",
|
|
10265
|
+
fields: [
|
|
10266
|
+
{
|
|
10267
|
+
fieldId: "term",
|
|
10268
|
+
fieldType: "string",
|
|
10269
|
+
required: true,
|
|
10270
|
+
searchable: true,
|
|
10271
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10272
|
+
renderHints: { label: "Term", widget: "text", order: 1, displayField: true }
|
|
10273
|
+
},
|
|
10274
|
+
{
|
|
10275
|
+
fieldId: "definition",
|
|
10276
|
+
fieldType: "string",
|
|
10277
|
+
searchable: true,
|
|
10278
|
+
description: "What the term means \u2014 the RAG-able body.",
|
|
10279
|
+
renderHints: { label: "Definition", widget: "textarea", order: 2 }
|
|
10280
|
+
},
|
|
10281
|
+
{
|
|
10282
|
+
fieldId: "aliases",
|
|
10283
|
+
fieldType: "array",
|
|
10284
|
+
filterable: true,
|
|
10285
|
+
description: "Alternate names / abbreviations for the same concept.",
|
|
10286
|
+
renderHints: { label: "Aliases", order: 3 }
|
|
10287
|
+
},
|
|
10288
|
+
{
|
|
10289
|
+
fieldId: "area",
|
|
10290
|
+
fieldType: "string",
|
|
10291
|
+
filterable: true,
|
|
10292
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
10293
|
+
},
|
|
10294
|
+
{
|
|
10295
|
+
fieldId: "tags",
|
|
10296
|
+
fieldType: "array",
|
|
10297
|
+
filterable: true,
|
|
10298
|
+
renderHints: { label: "Tags", order: 5 }
|
|
10299
|
+
},
|
|
10300
|
+
{
|
|
10301
|
+
fieldId: "relatedDecision",
|
|
10302
|
+
fieldType: "reference",
|
|
10303
|
+
targetTypeName: "decision",
|
|
10304
|
+
targetSurface: "document",
|
|
10305
|
+
targetField: "externalId",
|
|
10306
|
+
cardinality: "one",
|
|
10307
|
+
description: "A decision that defines or establishes this term (by externalId).",
|
|
10308
|
+
renderHints: { label: "Related decision", order: 6 }
|
|
10309
|
+
},
|
|
10310
|
+
{
|
|
10311
|
+
fieldId: "updatedOn",
|
|
10312
|
+
fieldType: "date",
|
|
10313
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
10314
|
+
renderHints: { label: "Updated on", widget: "date", order: 7 }
|
|
10315
|
+
}
|
|
10316
|
+
],
|
|
10317
|
+
// `term` is a UNIQUE equality lookup — exact "define X" + a one-per-term
|
|
10318
|
+
// guarantee. `area`/`relatedDecision` enumerate; `updatedOn` is the range row.
|
|
10319
|
+
lookupFields: [
|
|
10320
|
+
{ fieldName: "term", unique: true },
|
|
10321
|
+
"area",
|
|
10322
|
+
"relatedDecision",
|
|
10323
|
+
{ fieldName: "updatedOn", rangeEnabled: true }
|
|
10324
|
+
]
|
|
10325
|
+
}
|
|
10326
|
+
],
|
|
10327
|
+
// Least-privilege, data-plane only. r/c/u records + search + schema discovery +
|
|
10328
|
+
// inference:r (grounded recall over the document bodies) + document/folder r/c
|
|
10329
|
+
// (the content artifacts are documents). NO :d — knowledge is superseded/retired
|
|
10330
|
+
// via a status flip, so the trail of how the team's thinking evolved stays intact.
|
|
10331
|
+
accessProfile: {
|
|
10332
|
+
allowedActions: [
|
|
10333
|
+
"records:r",
|
|
10334
|
+
"records:c",
|
|
10335
|
+
"records:u",
|
|
10336
|
+
"search:r",
|
|
10337
|
+
"schemas:r",
|
|
10338
|
+
"inference:r",
|
|
10339
|
+
"documents:r",
|
|
10340
|
+
"documents:c",
|
|
10341
|
+
"folders:r",
|
|
10342
|
+
"folders:c"
|
|
10343
|
+
]
|
|
10344
|
+
},
|
|
10345
|
+
servicePrincipal: {
|
|
10346
|
+
externalId: "agentic-sdlc",
|
|
10347
|
+
displayName: "Agentic SDLC Knowledge Base"
|
|
10348
|
+
}
|
|
10349
|
+
// No bundled seed in this version: the content artifacts live on the document
|
|
10350
|
+
// surface and the cross-surface graph is populated by the ingest agent
|
|
10351
|
+
// (document_ingest / record_create), not the bootstrap seed step. Production
|
|
10352
|
+
// contexts provision with `vectros bootstrap --no-seed` regardless.
|
|
10353
|
+
};
|
|
10354
|
+
var agentic_sdlc_default = agenticSdlc;
|
|
10355
|
+
var secondBrain = {
|
|
10356
|
+
name: "second-brain",
|
|
10357
|
+
version: "1.0.0",
|
|
10358
|
+
description: "A personal knowledge base \u2014 capture notes, ideas, and links, then ask them anything.",
|
|
10359
|
+
contextId: "second-brain",
|
|
10360
|
+
contextName: "Second Brain",
|
|
10361
|
+
schemas: [
|
|
10362
|
+
{
|
|
10363
|
+
typeName: "note",
|
|
10364
|
+
displayName: "Note",
|
|
10365
|
+
indexMode: "HYBRID",
|
|
10366
|
+
// keyword on title + semantic on body — recall by meaning
|
|
10367
|
+
fields: [
|
|
10368
|
+
{
|
|
10369
|
+
fieldId: "title",
|
|
10370
|
+
fieldType: "string",
|
|
10371
|
+
required: true,
|
|
10372
|
+
searchable: true,
|
|
10373
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10374
|
+
renderHints: { label: "Title", widget: "text", order: 1, section: "Note", displayField: true }
|
|
10375
|
+
},
|
|
10376
|
+
{
|
|
10377
|
+
fieldId: "body",
|
|
10378
|
+
fieldType: "string",
|
|
10379
|
+
searchable: true,
|
|
10380
|
+
description: "The note itself \u2014 the RAG-able body you ask questions against.",
|
|
10381
|
+
validation: { maxLength: 2e4 },
|
|
10382
|
+
renderHints: { label: "Body", widget: "textarea", order: 2, section: "Note" }
|
|
10383
|
+
},
|
|
10384
|
+
{
|
|
10385
|
+
fieldId: "tags",
|
|
10386
|
+
fieldType: "array",
|
|
10387
|
+
filterable: true,
|
|
10388
|
+
description: 'Freeform string labels for filtering (e.g. "idea", "reading", "work").',
|
|
10389
|
+
renderHints: { label: "Tags", order: 3, section: "Organize" }
|
|
9434
10390
|
},
|
|
9435
10391
|
{
|
|
9436
10392
|
// An enum (not freeform) so enumeration-by-source is reliable — a
|
|
@@ -9491,6 +10447,7 @@ var secondBrain = {
|
|
|
9491
10447
|
},
|
|
9492
10448
|
seed: [
|
|
9493
10449
|
{
|
|
10450
|
+
surface: "record",
|
|
9494
10451
|
typeName: "note",
|
|
9495
10452
|
externalId: "seed-welcome",
|
|
9496
10453
|
fields: {
|
|
@@ -9622,6 +10579,7 @@ var clinicalIntake = {
|
|
|
9622
10579
|
},
|
|
9623
10580
|
seed: [
|
|
9624
10581
|
{
|
|
10582
|
+
surface: "record",
|
|
9625
10583
|
typeName: "intake",
|
|
9626
10584
|
externalId: "seed-synthetic-intake",
|
|
9627
10585
|
fields: {
|
|
@@ -9643,6 +10601,7 @@ var clinical_intake_default = clinicalIntake;
|
|
|
9643
10601
|
var BUNDLED_BLUEPRINTS = [
|
|
9644
10602
|
task_management_default,
|
|
9645
10603
|
coding_agent_memory_default,
|
|
10604
|
+
agentic_sdlc_default,
|
|
9646
10605
|
second_brain_default,
|
|
9647
10606
|
clinical_intake_default
|
|
9648
10607
|
];
|
|
@@ -10080,7 +11039,8 @@ async function resolveCognitoToken(env, explicit) {
|
|
|
10080
11039
|
async function resolveAuthContext(opts) {
|
|
10081
11040
|
const baseUrl = envToBaseUrl(opts.env, opts.baseUrl ?? process.env.VECTROS_API_BASE_URL);
|
|
10082
11041
|
const cognitoToken = await resolveCognitoToken(opts.env, opts.token);
|
|
10083
|
-
const
|
|
11042
|
+
const tenant = opts.tenant ?? "live";
|
|
11043
|
+
const bridge = opts.provisioning ? await mintBridgeToken({ cognitoToken, apiBaseUrl: baseUrl, tenant }) : await mintContextToken({ cognitoToken, apiBaseUrl: baseUrl, contextId: opts.context ?? "default", tenant });
|
|
10084
11044
|
const client = new VectrosClient({ token: bridge.token, environment: baseUrl });
|
|
10085
11045
|
const identity = await resolveIdentity({ log: opts.log, apiKey: bridge.token, environment: baseUrl });
|
|
10086
11046
|
return {
|
|
@@ -10090,7 +11050,8 @@ async function resolveAuthContext(opts) {
|
|
|
10090
11050
|
baseUrl,
|
|
10091
11051
|
env: opts.env,
|
|
10092
11052
|
identity,
|
|
10093
|
-
tenantId: typeof identity.tenantId === "string" ? identity.tenantId : void 0
|
|
11053
|
+
tenantId: typeof identity.tenantId === "string" ? identity.tenantId : void 0,
|
|
11054
|
+
tenant
|
|
10094
11055
|
};
|
|
10095
11056
|
}
|
|
10096
11057
|
|
|
@@ -10414,54 +11375,23 @@ function assertNoUnresolvedIdentities(blueprint) {
|
|
|
10414
11375
|
);
|
|
10415
11376
|
}
|
|
10416
11377
|
}
|
|
10417
|
-
var SchemaReconcileError = class extends Error {
|
|
10418
|
-
constructor(typeName, cause) {
|
|
10419
|
-
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
10420
|
-
super(
|
|
10421
|
-
`Schema '${typeName}' already exists but could not be reconciled to the blueprint: ${detail}
|
|
10422
|
-
If this is a migration-locked attribute (a lookup field's rangeEnabled/sortBy/sensitive, or the schema typeName), it cannot change on an existing schema \u2014 use a new fieldName/typeName for the new shape.`
|
|
10423
|
-
);
|
|
10424
|
-
this.name = "SchemaReconcileError";
|
|
10425
|
-
}
|
|
10426
|
-
};
|
|
10427
|
-
function isAlreadyExistsError(e) {
|
|
10428
|
-
if (typeof e !== "object" || e === null) return false;
|
|
10429
|
-
const err = e;
|
|
10430
|
-
const status = err.statusCode;
|
|
10431
|
-
const text = `${err.message ?? ""} ${err.body?.message ?? ""}`.toLowerCase();
|
|
10432
|
-
return (status === 409 || status === 400) && text.includes("already exists");
|
|
10433
|
-
}
|
|
10434
|
-
async function findExistingSchemaId(client, typeName, owner) {
|
|
10435
|
-
let startFrom;
|
|
10436
|
-
for (; ; ) {
|
|
10437
|
-
const page = await client.schemas.listSchemas({
|
|
10438
|
-
userId: owner.userId,
|
|
10439
|
-
orgId: owner.orgId,
|
|
10440
|
-
limit: 100,
|
|
10441
|
-
startFrom
|
|
10442
|
-
});
|
|
10443
|
-
const match = (page.data ?? []).find((s) => s.typeName === typeName);
|
|
10444
|
-
if (match?.id) return match.id;
|
|
10445
|
-
const next = page.nextCursor;
|
|
10446
|
-
if (!next) return void 0;
|
|
10447
|
-
startFrom = next;
|
|
10448
|
-
}
|
|
10449
|
-
}
|
|
10450
11378
|
async function runLoader(client, input) {
|
|
10451
|
-
const { blueprint, tenantId, machineId, rotate = false, vectrosDir, log } = input;
|
|
11379
|
+
const { blueprint, tenantId, machineId, rotate = false, skipSeed = false, vectrosDir, log } = input;
|
|
10452
11380
|
assertScopeGate(blueprint.accessProfile.allowedActions);
|
|
10453
11381
|
for (const clauses of Object.values(blueprint.roles ?? {})) {
|
|
10454
11382
|
for (const clause of clauses) assertScopeGate(clause.allowedActions);
|
|
10455
11383
|
}
|
|
10456
11384
|
assertNoUnresolvedIdentities(blueprint);
|
|
10457
|
-
await client.auth.createAppContext({ contextId: blueprint.contextId, name: contextNameOf(blueprint) });
|
|
11385
|
+
await client.auth.createAppContext({ body: { contextId: blueprint.contextId, name: contextNameOf(blueprint) } });
|
|
10458
11386
|
log.debug({ component: "loader", contextId: blueprint.contextId }, "app-context ensured");
|
|
10459
11387
|
const user = await client.identity.createUser({
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
11388
|
+
body: {
|
|
11389
|
+
externalId: blueprint.servicePrincipal.externalId,
|
|
11390
|
+
type: "SERVICE",
|
|
11391
|
+
// SDK 0.18+ (identity-access rework): UserRequest's free-form attribute bag
|
|
11392
|
+
// was renamed `metadata` → `payload`. Same semantics (arbitrary key/value).
|
|
11393
|
+
payload: { displayName: blueprint.servicePrincipal.displayName }
|
|
11394
|
+
}
|
|
10465
11395
|
});
|
|
10466
11396
|
const userId = user.id;
|
|
10467
11397
|
if (!userId) {
|
|
@@ -10496,23 +11426,9 @@ async function runLoader(client, input) {
|
|
|
10496
11426
|
orgId: s.orgId,
|
|
10497
11427
|
clientId: s.clientId
|
|
10498
11428
|
};
|
|
10499
|
-
|
|
10500
|
-
try {
|
|
10501
|
-
resp = await ctxClient.schemas.createSchema(schemaBody);
|
|
10502
|
-
} catch (e) {
|
|
10503
|
-
if (!isAlreadyExistsError(e)) throw e;
|
|
10504
|
-
if (s.clientId) throw e;
|
|
10505
|
-
const existingId = await findExistingSchemaId(ctxClient, s.typeName, { userId: s.userId, orgId: s.orgId });
|
|
10506
|
-
if (!existingId) throw e;
|
|
10507
|
-
try {
|
|
10508
|
-
resp = await ctxClient.schemas.updateSchema({ id: existingId, body: schemaBody });
|
|
10509
|
-
} catch (ue) {
|
|
10510
|
-
throw new SchemaReconcileError(s.typeName, ue);
|
|
10511
|
-
}
|
|
10512
|
-
log.debug({ component: "loader", typeName: s.typeName, schemaId: existingId }, "schema existed; reconciled to declared shape (update)");
|
|
10513
|
-
}
|
|
11429
|
+
const resp = await ctxClient.schemas.createSchema({ upsert: true, body: schemaBody });
|
|
10514
11430
|
if (resp.id) schemaIds[s.typeName] = resp.id;
|
|
10515
|
-
log.debug({ component: "loader", typeName: s.typeName, schemaId: resp.id }, "schema ensured");
|
|
11431
|
+
log.debug({ component: "loader", typeName: s.typeName, schemaId: resp.id }, "schema ensured (upsert)");
|
|
10516
11432
|
}
|
|
10517
11433
|
const profileBody = {
|
|
10518
11434
|
principalId: `usr_${userId}`,
|
|
@@ -10588,25 +11504,40 @@ async function runLoader(client, input) {
|
|
|
10588
11504
|
log.debug({ component: "loader", keyName, keyAction }, "scoped key resolved");
|
|
10589
11505
|
let seededCount = 0;
|
|
10590
11506
|
const seededRecordIds = [];
|
|
10591
|
-
|
|
11507
|
+
const seededDocumentIds = [];
|
|
11508
|
+
for (const rec of skipSeed ? [] : blueprint.seed ?? []) {
|
|
10592
11509
|
const schemaId = schemaIds[rec.typeName];
|
|
10593
11510
|
if (!schemaId) {
|
|
10594
11511
|
log.warn({ component: "loader", typeName: rec.typeName }, "seed skipped \u2014 no schemaId for typeName");
|
|
10595
11512
|
continue;
|
|
10596
11513
|
}
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
|
|
11514
|
+
if (rec.surface === "document") {
|
|
11515
|
+
const created = await ctxClient.documents.ingestDocument({
|
|
11516
|
+
body: {
|
|
11517
|
+
title: rec.title,
|
|
11518
|
+
text: rec.text,
|
|
11519
|
+
schemaId,
|
|
11520
|
+
externalId: rec.externalId,
|
|
11521
|
+
// Optional structured payload (the document's `fields`); omitted when absent.
|
|
11522
|
+
payload: rec.fields,
|
|
11523
|
+
// Retain the raw text so a seeded document is retrievable via
|
|
11524
|
+
// GET /v1/documents/{id}/text (mirrors the MCP document_ingest default) —
|
|
11525
|
+
// a seed's text IS its content, worth keeping for the getting-started graph.
|
|
11526
|
+
storeText: true
|
|
11527
|
+
}
|
|
11528
|
+
});
|
|
11529
|
+
if (created.id) seededDocumentIds.push(created.id);
|
|
11530
|
+
} else {
|
|
11531
|
+
const created = await ctxClient.records.createRecord({
|
|
11532
|
+
body: {
|
|
11533
|
+
typeName: rec.typeName,
|
|
11534
|
+
schemaId,
|
|
11535
|
+
externalId: rec.externalId,
|
|
11536
|
+
payload: rec.fields
|
|
11537
|
+
}
|
|
11538
|
+
});
|
|
11539
|
+
if (created.id) seededRecordIds.push(created.id);
|
|
11540
|
+
}
|
|
10610
11541
|
seededCount++;
|
|
10611
11542
|
}
|
|
10612
11543
|
return {
|
|
@@ -10619,10 +11550,11 @@ async function runLoader(client, input) {
|
|
|
10619
11550
|
schemaIds,
|
|
10620
11551
|
roleIds,
|
|
10621
11552
|
seededCount,
|
|
10622
|
-
seededRecordIds
|
|
11553
|
+
seededRecordIds,
|
|
11554
|
+
seededDocumentIds
|
|
10623
11555
|
};
|
|
10624
11556
|
}
|
|
10625
|
-
function buildPlan(blueprint) {
|
|
11557
|
+
function buildPlan(blueprint, opts = {}) {
|
|
10626
11558
|
const steps = [];
|
|
10627
11559
|
steps.push({ kind: "context", summary: `context '${blueprint.contextId}' (${contextNameOf(blueprint)})` });
|
|
10628
11560
|
steps.push({
|
|
@@ -10654,9 +11586,14 @@ function buildPlan(blueprint) {
|
|
|
10654
11586
|
});
|
|
10655
11587
|
}
|
|
10656
11588
|
steps.push({ kind: "key", summary: `key ${blueprint.name}-<machine> (mint 1 scoped ssk_*)` });
|
|
10657
|
-
const
|
|
10658
|
-
if (
|
|
10659
|
-
|
|
11589
|
+
const seeds = blueprint.seed ?? [];
|
|
11590
|
+
if (seeds.length > 0 && !opts.noSeed) {
|
|
11591
|
+
const docs = seeds.filter((s) => s.surface === "document").length;
|
|
11592
|
+
const recs = seeds.length - docs;
|
|
11593
|
+
const parts = [];
|
|
11594
|
+
if (recs > 0) parts.push(`${recs} record${recs === 1 ? "" : "s"}`);
|
|
11595
|
+
if (docs > 0) parts.push(`${docs} document${docs === 1 ? "" : "s"}`);
|
|
11596
|
+
steps.push({ kind: "seed", summary: `seed ${parts.join(" + ")}` });
|
|
10660
11597
|
}
|
|
10661
11598
|
return steps;
|
|
10662
11599
|
}
|
|
@@ -10780,7 +11717,9 @@ function parseBootstrapArgs(argv) {
|
|
|
10780
11717
|
rotate: false,
|
|
10781
11718
|
useScopedToken: false,
|
|
10782
11719
|
blankSlate: false,
|
|
11720
|
+
noSeed: false,
|
|
10783
11721
|
client: "desktop",
|
|
11722
|
+
tenant: "live",
|
|
10784
11723
|
help: false
|
|
10785
11724
|
};
|
|
10786
11725
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -10828,6 +11767,20 @@ function parseBootstrapArgs(argv) {
|
|
|
10828
11767
|
case "--blank-slate":
|
|
10829
11768
|
args.blankSlate = true;
|
|
10830
11769
|
break;
|
|
11770
|
+
case "--no-seed":
|
|
11771
|
+
args.noSeed = true;
|
|
11772
|
+
break;
|
|
11773
|
+
case "--tenant": {
|
|
11774
|
+
const v = argv[++i];
|
|
11775
|
+
if (v !== "test" && v !== "live") {
|
|
11776
|
+
throw new Error(`--tenant must be 'test' or 'live' (got '${v ?? ""}')`);
|
|
11777
|
+
}
|
|
11778
|
+
args.tenant = v;
|
|
11779
|
+
break;
|
|
11780
|
+
}
|
|
11781
|
+
case "--test":
|
|
11782
|
+
args.tenant = "test";
|
|
11783
|
+
break;
|
|
10831
11784
|
case "--help":
|
|
10832
11785
|
case "-h":
|
|
10833
11786
|
args.help = true;
|
|
@@ -10838,11 +11791,26 @@ function parseBootstrapArgs(argv) {
|
|
|
10838
11791
|
}
|
|
10839
11792
|
return args;
|
|
10840
11793
|
}
|
|
11794
|
+
function shouldOfferSeedOptOut(args, blueprint, isTty) {
|
|
11795
|
+
return !args.noSeed && (blueprint.seed?.length ?? 0) > 0 && !args.yes && !args.print && isTty;
|
|
11796
|
+
}
|
|
11797
|
+
function seedDeclined(answer) {
|
|
11798
|
+
const a = answer.trim().toLowerCase();
|
|
11799
|
+
return a === "n" || a === "no";
|
|
11800
|
+
}
|
|
11801
|
+
function seedSummaryLine(opts) {
|
|
11802
|
+
if (opts.noSeed) {
|
|
11803
|
+
return opts.declinedInteractively ? " \u2714 Seeded 0 record(s) \u2014 skipped (you declined sample data)\n" : " \u2714 Seeded 0 record(s) \u2014 skipped (--no-seed)\n";
|
|
11804
|
+
}
|
|
11805
|
+
return opts.seededCount ? ` \u2714 Seeded ${opts.seededCount} record(s)
|
|
11806
|
+
` : "";
|
|
11807
|
+
}
|
|
10841
11808
|
var BOOTSTRAP_HELP = `vectros bootstrap \u2014 provision a least-privilege MCP credential.
|
|
10842
11809
|
|
|
10843
11810
|
Usage:
|
|
10844
|
-
vectros bootstrap [--blueprint <name> | --blank] [--env staging|production]
|
|
10845
|
-
[--
|
|
11811
|
+
vectros bootstrap [--blueprint <name> | --blank] [--no-seed] [--env staging|production]
|
|
11812
|
+
[--tenant test|live | --test] [--client desktop|code]
|
|
11813
|
+
[--yes] [--print] [--rotate]
|
|
10846
11814
|
[--token <t> | env VECTROS_BOOTSTRAP_TOKEN]
|
|
10847
11815
|
[--base-url <url>] [--use-scoped-token]
|
|
10848
11816
|
|
|
@@ -10851,7 +11819,17 @@ Options:
|
|
|
10851
11819
|
OR a path to your own blueprint YAML/JSON (./my.yaml) \u2014 the "copy &
|
|
10852
11820
|
own" path. File blueprints get the identical scope gate (no override).
|
|
10853
11821
|
--blank Credential only (read-only data-plane profile, no schemas).
|
|
11822
|
+
--no-seed Provision the blueprint's schemas, profile and key but SKIP its
|
|
11823
|
+
sample seed records \u2014 the right choice for a production context
|
|
11824
|
+
(a blueprint's seeds are illustrative, not real data). Unlike
|
|
11825
|
+
--blank, the schemas are still created.
|
|
10854
11826
|
--env staging|production Target environment (default: production).
|
|
11827
|
+
--tenant test|live Which tenant the minted key scopes to (default: live).
|
|
11828
|
+
'test' provisions into your isolated test tenant \u2014 a
|
|
11829
|
+
dry-run before pointing real data at the same blueprint.
|
|
11830
|
+
The tenant rides the key (ssk_test_* vs ssk_live_*), so
|
|
11831
|
+
the MCP/client config is otherwise identical.
|
|
11832
|
+
--test Shorthand for --tenant test.
|
|
10855
11833
|
--base-url <url> Override the API base URL (beats --env + VECTROS_API_BASE_URL).
|
|
10856
11834
|
--client <desktop|code> MCP host to configure (default: desktop). 'desktop' merges
|
|
10857
11835
|
claude_desktop_config.json (also works for Cursor/Cline);
|
|
@@ -10920,6 +11898,21 @@ async function resolveBridgeCognitoToken(args, prompt, isTty, resolveCognito = r
|
|
|
10920
11898
|
if (!pasted) throw new Error("No token entered.");
|
|
10921
11899
|
return pasted;
|
|
10922
11900
|
}
|
|
11901
|
+
function buildRemintForContext(opts) {
|
|
11902
|
+
const mintContext = opts.mintContext ?? mintContextToken;
|
|
11903
|
+
return async (contextId) => {
|
|
11904
|
+
const ctxToken = await mintContext({
|
|
11905
|
+
cognitoToken: opts.cognitoToken,
|
|
11906
|
+
apiBaseUrl: opts.apiBaseUrl,
|
|
11907
|
+
contextId,
|
|
11908
|
+
tenant: opts.tenant
|
|
11909
|
+
});
|
|
11910
|
+
return new VectrosClient({
|
|
11911
|
+
token: ctxToken.token,
|
|
11912
|
+
environment: opts.apiBaseUrl
|
|
11913
|
+
});
|
|
11914
|
+
};
|
|
11915
|
+
}
|
|
10923
11916
|
async function runBootstrapCli(argv, deps = {}) {
|
|
10924
11917
|
const log = deps.log ?? createLogger2();
|
|
10925
11918
|
let args;
|
|
@@ -10971,7 +11964,20 @@ ${BOOTSTRAP_HELP}
|
|
|
10971
11964
|
Blueprint: ${blueprint.name}
|
|
10972
11965
|
\u2714 Scope gate: [${gate.accepted.join(", ")}] \u2014 all data-plane \u2713
|
|
10973
11966
|
`);
|
|
10974
|
-
|
|
11967
|
+
let noSeed = args.noSeed;
|
|
11968
|
+
let seedDeclinedInteractively = false;
|
|
11969
|
+
if (shouldOfferSeedOptOut(args, blueprint, isTty)) {
|
|
11970
|
+
const ans = await promptCtx.prompt(
|
|
11971
|
+
`
|
|
11972
|
+
Seed ${blueprint.seed?.length} sample record(s) into this context? [Y/n]
|
|
11973
|
+
(Choose 'n' for a production context \u2014 sample data is illustrative only): `
|
|
11974
|
+
);
|
|
11975
|
+
if (seedDeclined(ans)) {
|
|
11976
|
+
noSeed = true;
|
|
11977
|
+
seedDeclinedInteractively = true;
|
|
11978
|
+
}
|
|
11979
|
+
}
|
|
11980
|
+
const planSteps = buildPlan(blueprint, { noSeed });
|
|
10975
11981
|
process.stdout.write(`
|
|
10976
11982
|
${renderPlan(blueprint, planSteps)}
|
|
10977
11983
|
`);
|
|
@@ -10988,12 +11994,17 @@ ${renderPlan(blueprint, planSteps)}
|
|
|
10988
11994
|
isTty,
|
|
10989
11995
|
deps.resolveCognitoToken
|
|
10990
11996
|
);
|
|
10991
|
-
const
|
|
11997
|
+
const mintBridge = deps.mintBridgeToken ?? mintBridgeToken;
|
|
11998
|
+
const mintContext = deps.mintContextToken ?? mintContextToken;
|
|
11999
|
+
const bridge = await mintBridge({
|
|
10992
12000
|
cognitoToken,
|
|
10993
12001
|
apiBaseUrl: baseUrl,
|
|
10994
|
-
useScopedToken: args.useScopedToken
|
|
12002
|
+
useScopedToken: args.useScopedToken,
|
|
12003
|
+
// Tenant rides the key (ssk_test_* vs ssk_live_*), not the base URL.
|
|
12004
|
+
tenant: args.tenant
|
|
10995
12005
|
});
|
|
10996
|
-
process.stdout.write(
|
|
12006
|
+
process.stdout.write(` \u2714 Bootstrap token minted (5-min TTL, ${args.tenant} tenant)
|
|
12007
|
+
`);
|
|
10997
12008
|
const client = new VectrosClient({ token: bridge.token, environment: baseUrl });
|
|
10998
12009
|
const identity = await resolveIdentity({ log, apiKey: bridge.token, environment: baseUrl });
|
|
10999
12010
|
const tenantId = identity.tenantId;
|
|
@@ -11008,19 +12019,22 @@ ${renderPlan(blueprint, planSteps)}
|
|
|
11008
12019
|
tenantId,
|
|
11009
12020
|
machineId,
|
|
11010
12021
|
rotate: args.rotate,
|
|
11011
|
-
|
|
11012
|
-
|
|
11013
|
-
|
|
11014
|
-
|
|
11015
|
-
|
|
11016
|
-
|
|
11017
|
-
},
|
|
12022
|
+
skipSeed: noSeed,
|
|
12023
|
+
remintForContext: buildRemintForContext({
|
|
12024
|
+
cognitoToken,
|
|
12025
|
+
apiBaseUrl: baseUrl,
|
|
12026
|
+
tenant: args.tenant,
|
|
12027
|
+
mintContext
|
|
12028
|
+
}),
|
|
11018
12029
|
log
|
|
11019
12030
|
});
|
|
11020
12031
|
process.stdout.write(
|
|
11021
|
-
` \u2714 AccessProfile + key (${result.keyAction}) \u2192 ${result.keyName}
|
|
11022
|
-
` + (
|
|
11023
|
-
|
|
12032
|
+
` \u2714 AccessProfile + ${args.tenant} key (${result.keyAction}) \u2192 ${result.keyName}
|
|
12033
|
+
` + seedSummaryLine({
|
|
12034
|
+
noSeed,
|
|
12035
|
+
declinedInteractively: seedDeclinedInteractively,
|
|
12036
|
+
seededCount: result.seededCount
|
|
12037
|
+
})
|
|
11024
12038
|
);
|
|
11025
12039
|
const entry = buildVectrosServerEntry({ apiKey: result.rawKey, apiBaseUrl: baseUrl });
|
|
11026
12040
|
const isCode = args.client === "code";
|
|
@@ -11231,7 +12245,8 @@ servicePrincipal:
|
|
|
11231
12245
|
displayName: ${name}
|
|
11232
12246
|
|
|
11233
12247
|
seed:
|
|
11234
|
-
-
|
|
12248
|
+
- surface: record # 'record' (createRecord) or 'document' (text-ingest: needs title + text)
|
|
12249
|
+
typeName: thing
|
|
11235
12250
|
externalId: seed-welcome # stable \u2192 idempotent; re-apply converges
|
|
11236
12251
|
fields: { title: "Hello from ${name}" }
|
|
11237
12252
|
`;
|
|
@@ -11579,6 +12594,7 @@ async function withAuth(opts, deps, body) {
|
|
|
11579
12594
|
token: opts.token,
|
|
11580
12595
|
context: opts.context,
|
|
11581
12596
|
provisioning: opts.provisioning,
|
|
12597
|
+
tenant: opts.tenant,
|
|
11582
12598
|
useScopedToken: opts.useScopedToken,
|
|
11583
12599
|
log
|
|
11584
12600
|
});
|
|
@@ -11855,19 +12871,23 @@ async function createIdentity(client, opts, payload) {
|
|
|
11855
12871
|
switch (opts.type) {
|
|
11856
12872
|
case "user":
|
|
11857
12873
|
return client.identity.createUser({
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
|
|
12874
|
+
body: {
|
|
12875
|
+
externalId,
|
|
12876
|
+
email: opts.email,
|
|
12877
|
+
type: opts.service ? "SERVICE" : "HUMAN",
|
|
12878
|
+
payload
|
|
12879
|
+
}
|
|
11862
12880
|
});
|
|
11863
12881
|
case "org":
|
|
11864
|
-
return client.identity.createOrg({ externalId, name: opts.name, payload });
|
|
12882
|
+
return client.identity.createOrg({ body: { externalId, name: opts.name, payload } });
|
|
11865
12883
|
case "client":
|
|
11866
12884
|
return client.identity.createClient({
|
|
11867
|
-
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
12885
|
+
body: {
|
|
12886
|
+
externalId,
|
|
12887
|
+
name: opts.name,
|
|
12888
|
+
orgId: opts.org,
|
|
12889
|
+
payload
|
|
12890
|
+
}
|
|
11871
12891
|
});
|
|
11872
12892
|
}
|
|
11873
12893
|
}
|
|
@@ -12308,8 +13328,10 @@ async function runContextCreate(opts, deps = {}) {
|
|
|
12308
13328
|
const client = auth.client;
|
|
12309
13329
|
try {
|
|
12310
13330
|
const ctx = await client.auth.createAppContext({
|
|
12311
|
-
|
|
12312
|
-
|
|
13331
|
+
body: {
|
|
13332
|
+
contextId: opts.contextId,
|
|
13333
|
+
name: opts.name ?? opts.contextId
|
|
13334
|
+
}
|
|
12313
13335
|
});
|
|
12314
13336
|
if (opts.json) {
|
|
12315
13337
|
process.stdout.write(`${formatJson(ctx)}
|
|
@@ -12620,23 +13642,22 @@ async function runAssertions(client, deps, blueprint, tenantId, result) {
|
|
|
12620
13642
|
}
|
|
12621
13643
|
}
|
|
12622
13644
|
for (const rec of blueprint.seed ?? []) {
|
|
13645
|
+
const isDoc = rec.surface === "document";
|
|
13646
|
+
const op = isDoc ? "lookupDocuments" : "lookupRecords";
|
|
13647
|
+
const noun = isDoc ? "document" : "record";
|
|
12623
13648
|
try {
|
|
12624
|
-
const page = await client.records.lookupRecords({
|
|
12625
|
-
type: rec.typeName,
|
|
12626
|
-
field: "externalId",
|
|
12627
|
-
value: rec.externalId
|
|
12628
|
-
});
|
|
13649
|
+
const page = isDoc ? await client.documents.lookupDocuments({ type: rec.typeName, field: "externalId", value: rec.externalId }) : await client.records.lookupRecords({ type: rec.typeName, field: "externalId", value: rec.externalId });
|
|
12629
13650
|
const ok = (page.data ?? []).length >= 1;
|
|
12630
13651
|
assertions.push({
|
|
12631
13652
|
name: `seed-externalId:${rec.externalId}`,
|
|
12632
13653
|
ok,
|
|
12633
|
-
detail: ok ? `'${rec.typeName}' seed resolves by externalId '${rec.externalId}'` : `'${rec.typeName}' seed externalId '${rec.externalId}' resolved 0
|
|
13654
|
+
detail: ok ? `'${rec.typeName}' seed resolves by externalId '${rec.externalId}'` : `'${rec.typeName}' seed externalId '${rec.externalId}' resolved 0 ${noun}s \u2014 externalId is not first-class (written only in payload?)`
|
|
12634
13655
|
});
|
|
12635
13656
|
} catch (e) {
|
|
12636
13657
|
assertions.push({
|
|
12637
13658
|
name: `seed-externalId:${rec.externalId}`,
|
|
12638
13659
|
ok: false,
|
|
12639
|
-
detail:
|
|
13660
|
+
detail: `${op}(externalId='${rec.externalId}') failed: ${errMsg(e)}`
|
|
12640
13661
|
});
|
|
12641
13662
|
}
|
|
12642
13663
|
}
|
|
@@ -12694,6 +13715,14 @@ async function runTeardown(client, blueprint, machineId, snapshot, result) {
|
|
|
12694
13715
|
steps.push({ step: `delete record ${id}`, ok: false, error: errMsg(e) });
|
|
12695
13716
|
}
|
|
12696
13717
|
}
|
|
13718
|
+
for (const id of result.seededDocumentIds) {
|
|
13719
|
+
try {
|
|
13720
|
+
await client.documents.deleteDocument({ id });
|
|
13721
|
+
steps.push({ step: `delete document ${id}`, ok: true });
|
|
13722
|
+
} catch (e) {
|
|
13723
|
+
steps.push({ step: `delete document ${id}`, ok: false, error: errMsg(e) });
|
|
13724
|
+
}
|
|
13725
|
+
}
|
|
12697
13726
|
const principalId = `usr_${result.servicePrincipalUserId}`;
|
|
12698
13727
|
if (snapshot.failed) {
|
|
12699
13728
|
steps.push({ step: `delete access profile ${principalId}`, ok: true, skipped: true, error: "skipped \u2014 pre-apply snapshot failed; cannot prove ownership" });
|
|
@@ -12828,7 +13857,7 @@ function renderReport(blueprint, env, report) {
|
|
|
12828
13857
|
if (report.applied) {
|
|
12829
13858
|
const a = report.applied;
|
|
12830
13859
|
lines.push(
|
|
12831
|
-
` \u2714 applied \u2014 key ${a.keyName} (${a.keyAction}), ${Object.keys(a.schemaIds).length} schema(s)` + (a.seededCount ? `, ${a.seededCount} seed
|
|
13860
|
+
` \u2714 applied \u2014 key ${a.keyName} (${a.keyAction}), ${Object.keys(a.schemaIds).length} schema(s)` + (a.seededCount ? `, ${a.seededCount} seed(s)` : "")
|
|
12832
13861
|
);
|
|
12833
13862
|
} else {
|
|
12834
13863
|
lines.push(` \u2716 apply failed \u2014 ${report.error ?? "unknown error"}`);
|
|
@@ -12891,7 +13920,10 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
|
|
|
12891
13920
|
const ctxToken = await mintContextToken({
|
|
12892
13921
|
cognitoToken: auth.cognitoToken,
|
|
12893
13922
|
apiBaseUrl: auth.baseUrl,
|
|
12894
|
-
contextId
|
|
13923
|
+
contextId,
|
|
13924
|
+
// Same tenant as the bootstrap token (auth.tenant) — the in-context
|
|
13925
|
+
// load must land in the tenant the run targets.
|
|
13926
|
+
tenant: auth.tenant
|
|
12895
13927
|
});
|
|
12896
13928
|
return new VectrosClient({
|
|
12897
13929
|
token: ctxToken.token,
|
|
@@ -12929,9 +13961,9 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
|
|
|
12929
13961
|
|
|
12930
13962
|
// src/build-info.ts
|
|
12931
13963
|
var BUILD_INFO = {
|
|
12932
|
-
cli: true ? "0.
|
|
12933
|
-
sdk: true ? "0.
|
|
12934
|
-
blueprints: true ? "0.
|
|
13964
|
+
cli: true ? "0.6.4" : "dev",
|
|
13965
|
+
sdk: true ? "0.31.0" : "dev",
|
|
13966
|
+
blueprints: true ? "0.6.2" : "dev"
|
|
12935
13967
|
};
|
|
12936
13968
|
function formatBuildInfo() {
|
|
12937
13969
|
return `vectros ${BUILD_INFO.cli} (sdk ${BUILD_INFO.sdk}, blueprints ${BUILD_INFO.blueprints})`;
|
|
@@ -12979,10 +14011,21 @@ function buildProgram(deps = {}) {
|
|
|
12979
14011
|
addCommonAuthOptions(whoami).action(async (flags) => {
|
|
12980
14012
|
process.exit(await runWhoami(toCommonOptions(flags), deps));
|
|
12981
14013
|
});
|
|
12982
|
-
const blueprintTest = program.command("blueprint-test").description("Apply a blueprint to a live env, assert it provisioned a working credential, then tear it down.").argument("<file>", "blueprint file path (./my.yaml) or a bundled blueprint name").option("--keep", "leave the provisioned graph in place (skip teardown) for inspection");
|
|
14014
|
+
const blueprintTest = program.command("blueprint-test").description("Apply a blueprint to a live env, assert it provisioned a working credential, then tear it down.").argument("<file>", "blueprint file path (./my.yaml) or a bundled blueprint name").option("--keep", "leave the provisioned graph in place (skip teardown) for inspection").option("--tenant <tenant>", "target tenant for the run: 'test' or 'live' (default live)");
|
|
12983
14015
|
addCommonAuthOptions(blueprintTest).action(
|
|
12984
14016
|
async (file, flags) => {
|
|
12985
|
-
|
|
14017
|
+
if (flags.tenant !== void 0 && flags.tenant !== "test" && flags.tenant !== "live") {
|
|
14018
|
+
process.stderr.write(` \u2716 --tenant must be 'test' or 'live' (got '${flags.tenant}')
|
|
14019
|
+
`);
|
|
14020
|
+
process.exit(2);
|
|
14021
|
+
}
|
|
14022
|
+
process.exit(
|
|
14023
|
+
await runBlueprintTest(
|
|
14024
|
+
file,
|
|
14025
|
+
{ ...toCommonOptions(flags), keep: Boolean(flags.keep), tenant: flags.tenant },
|
|
14026
|
+
deps
|
|
14027
|
+
)
|
|
14028
|
+
);
|
|
12986
14029
|
}
|
|
12987
14030
|
);
|
|
12988
14031
|
registerKeyCommands(program, deps);
|