@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.mjs
CHANGED
|
@@ -2514,6 +2514,7 @@ var AuthClient = class {
|
|
|
2514
2514
|
* @throws {@link Vectros.BadRequestError}
|
|
2515
2515
|
* @throws {@link Vectros.ForbiddenError}
|
|
2516
2516
|
* @throws {@link Vectros.NotFoundError}
|
|
2517
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2517
2518
|
*
|
|
2518
2519
|
* @example
|
|
2519
2520
|
* await client.auth.createScopedKey({
|
|
@@ -2561,6 +2562,8 @@ var AuthClient = class {
|
|
|
2561
2562
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2562
2563
|
case 404:
|
|
2563
2564
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2565
|
+
case 429:
|
|
2566
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2564
2567
|
default:
|
|
2565
2568
|
throw new VectrosError({
|
|
2566
2569
|
statusCode: _response.error.statusCode,
|
|
@@ -2637,6 +2640,7 @@ var AuthClient = class {
|
|
|
2637
2640
|
*
|
|
2638
2641
|
* @throws {@link Vectros.ForbiddenError}
|
|
2639
2642
|
* @throws {@link Vectros.NotFoundError}
|
|
2643
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2640
2644
|
*
|
|
2641
2645
|
* @example
|
|
2642
2646
|
* await client.auth.revokeScopedKey({
|
|
@@ -2677,6 +2681,8 @@ var AuthClient = class {
|
|
|
2677
2681
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2678
2682
|
case 404:
|
|
2679
2683
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2684
|
+
case 429:
|
|
2685
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2680
2686
|
default:
|
|
2681
2687
|
throw new VectrosError({
|
|
2682
2688
|
statusCode: _response.error.statusCode,
|
|
@@ -2832,7 +2838,7 @@ var AuthClient = class {
|
|
|
2832
2838
|
);
|
|
2833
2839
|
}
|
|
2834
2840
|
/**
|
|
2835
|
-
* 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.
|
|
2841
|
+
* Creates a new access profile under the given app context. This call is idempotent by `principalId`: if a profile with the same `principalId` already exists, the existing profile is returned (with status 200) instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing profile was returned) tells the two apart. To overwrite an existing profile's `scopes`/`roleId`, `identityOverrides`, and `status` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope). You must provide exactly one of `scopes` (an inline list of scopes) or `roleId` (a reference to a role); supplying both, or neither, is rejected. `identityOverrides` 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.
|
|
2836
2842
|
*
|
|
2837
2843
|
* @param {Vectros.CreateAccessProfileRequest} request
|
|
2838
2844
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -2840,6 +2846,7 @@ var AuthClient = class {
|
|
|
2840
2846
|
* @throws {@link Vectros.BadRequestError}
|
|
2841
2847
|
* @throws {@link Vectros.ForbiddenError}
|
|
2842
2848
|
* @throws {@link Vectros.NotFoundError}
|
|
2849
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2843
2850
|
*
|
|
2844
2851
|
* @example
|
|
2845
2852
|
* await client.auth.createAccessProfile({
|
|
@@ -2853,7 +2860,10 @@ var AuthClient = class {
|
|
|
2853
2860
|
return HttpResponsePromise.fromPromise(this.__createAccessProfile(request, requestOptions));
|
|
2854
2861
|
}
|
|
2855
2862
|
async __createAccessProfile(request, requestOptions) {
|
|
2856
|
-
const { contextId, body: _body } = request;
|
|
2863
|
+
const { contextId, upsert, body: _body } = request;
|
|
2864
|
+
const _queryParams = {
|
|
2865
|
+
upsert
|
|
2866
|
+
};
|
|
2857
2867
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
2858
2868
|
const _headers = mergeHeaders(
|
|
2859
2869
|
_authRequest.headers,
|
|
@@ -2868,7 +2878,7 @@ var AuthClient = class {
|
|
|
2868
2878
|
method: "POST",
|
|
2869
2879
|
headers: _headers,
|
|
2870
2880
|
contentType: "application/json",
|
|
2871
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
2881
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
2872
2882
|
requestType: "json",
|
|
2873
2883
|
body: _body,
|
|
2874
2884
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
@@ -2888,6 +2898,8 @@ var AuthClient = class {
|
|
|
2888
2898
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
2889
2899
|
case 404:
|
|
2890
2900
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
2901
|
+
case 429:
|
|
2902
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
2891
2903
|
default:
|
|
2892
2904
|
throw new VectrosError({
|
|
2893
2905
|
statusCode: _response.error.statusCode,
|
|
@@ -2961,24 +2973,31 @@ var AuthClient = class {
|
|
|
2961
2973
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/app-contexts");
|
|
2962
2974
|
}
|
|
2963
2975
|
/**
|
|
2964
|
-
* 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.
|
|
2976
|
+
* 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.
|
|
2965
2977
|
*
|
|
2966
|
-
* @param {Vectros.
|
|
2978
|
+
* @param {Vectros.CreateAppContextRequest} request
|
|
2967
2979
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
2968
2980
|
*
|
|
2969
2981
|
* @throws {@link Vectros.BadRequestError}
|
|
2970
2982
|
* @throws {@link Vectros.ForbiddenError}
|
|
2983
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
2971
2984
|
*
|
|
2972
2985
|
* @example
|
|
2973
2986
|
* await client.auth.createAppContext({
|
|
2974
|
-
*
|
|
2975
|
-
*
|
|
2987
|
+
* body: {
|
|
2988
|
+
* contextId: "myapp",
|
|
2989
|
+
* name: "My Internal App"
|
|
2990
|
+
* }
|
|
2976
2991
|
* })
|
|
2977
2992
|
*/
|
|
2978
2993
|
createAppContext(request, requestOptions) {
|
|
2979
2994
|
return HttpResponsePromise.fromPromise(this.__createAppContext(request, requestOptions));
|
|
2980
2995
|
}
|
|
2981
2996
|
async __createAppContext(request, requestOptions) {
|
|
2997
|
+
const { upsert, body: _body } = request;
|
|
2998
|
+
const _queryParams = {
|
|
2999
|
+
upsert
|
|
3000
|
+
};
|
|
2982
3001
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
2983
3002
|
const _headers = mergeHeaders(
|
|
2984
3003
|
_authRequest.headers,
|
|
@@ -2993,9 +3012,9 @@ var AuthClient = class {
|
|
|
2993
3012
|
method: "POST",
|
|
2994
3013
|
headers: _headers,
|
|
2995
3014
|
contentType: "application/json",
|
|
2996
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
3015
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
2997
3016
|
requestType: "json",
|
|
2998
|
-
body:
|
|
3017
|
+
body: _body,
|
|
2999
3018
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
3000
3019
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
3001
3020
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -3011,6 +3030,8 @@ var AuthClient = class {
|
|
|
3011
3030
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
3012
3031
|
case 403:
|
|
3013
3032
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3033
|
+
case 429:
|
|
3034
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3014
3035
|
default:
|
|
3015
3036
|
throw new VectrosError({
|
|
3016
3037
|
statusCode: _response.error.statusCode,
|
|
@@ -3089,7 +3110,7 @@ var AuthClient = class {
|
|
|
3089
3110
|
);
|
|
3090
3111
|
}
|
|
3091
3112
|
/**
|
|
3092
|
-
* 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.
|
|
3113
|
+
* 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.
|
|
3093
3114
|
*
|
|
3094
3115
|
* @param {Vectros.CreateRoleRequest} request
|
|
3095
3116
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -3097,6 +3118,7 @@ var AuthClient = class {
|
|
|
3097
3118
|
* @throws {@link Vectros.BadRequestError}
|
|
3098
3119
|
* @throws {@link Vectros.ForbiddenError}
|
|
3099
3120
|
* @throws {@link Vectros.NotFoundError}
|
|
3121
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3100
3122
|
*
|
|
3101
3123
|
* @example
|
|
3102
3124
|
* await client.auth.createRole({
|
|
@@ -3114,7 +3136,10 @@ var AuthClient = class {
|
|
|
3114
3136
|
return HttpResponsePromise.fromPromise(this.__createRole(request, requestOptions));
|
|
3115
3137
|
}
|
|
3116
3138
|
async __createRole(request, requestOptions) {
|
|
3117
|
-
const { contextId, body: _body } = request;
|
|
3139
|
+
const { contextId, upsert, body: _body } = request;
|
|
3140
|
+
const _queryParams = {
|
|
3141
|
+
upsert
|
|
3142
|
+
};
|
|
3118
3143
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
3119
3144
|
const _headers = mergeHeaders(
|
|
3120
3145
|
_authRequest.headers,
|
|
@@ -3129,7 +3154,7 @@ var AuthClient = class {
|
|
|
3129
3154
|
method: "POST",
|
|
3130
3155
|
headers: _headers,
|
|
3131
3156
|
contentType: "application/json",
|
|
3132
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
3157
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
3133
3158
|
requestType: "json",
|
|
3134
3159
|
body: _body,
|
|
3135
3160
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
@@ -3149,6 +3174,8 @@ var AuthClient = class {
|
|
|
3149
3174
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3150
3175
|
case 404:
|
|
3151
3176
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3177
|
+
case 429:
|
|
3178
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3152
3179
|
default:
|
|
3153
3180
|
throw new VectrosError({
|
|
3154
3181
|
statusCode: _response.error.statusCode,
|
|
@@ -3236,6 +3263,7 @@ var AuthClient = class {
|
|
|
3236
3263
|
*
|
|
3237
3264
|
* @throws {@link Vectros.ForbiddenError}
|
|
3238
3265
|
* @throws {@link Vectros.NotFoundError}
|
|
3266
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3239
3267
|
*
|
|
3240
3268
|
* @example
|
|
3241
3269
|
* await client.auth.updateAccessProfile({
|
|
@@ -3283,6 +3311,8 @@ var AuthClient = class {
|
|
|
3283
3311
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3284
3312
|
case 404:
|
|
3285
3313
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3314
|
+
case 429:
|
|
3315
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3286
3316
|
default:
|
|
3287
3317
|
throw new VectrosError({
|
|
3288
3318
|
statusCode: _response.error.statusCode,
|
|
@@ -3306,6 +3336,7 @@ var AuthClient = class {
|
|
|
3306
3336
|
*
|
|
3307
3337
|
* @throws {@link Vectros.ForbiddenError}
|
|
3308
3338
|
* @throws {@link Vectros.NotFoundError}
|
|
3339
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3309
3340
|
*
|
|
3310
3341
|
* @example
|
|
3311
3342
|
* await client.auth.deleteAccessProfile({
|
|
@@ -3347,6 +3378,8 @@ var AuthClient = class {
|
|
|
3347
3378
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3348
3379
|
case 404:
|
|
3349
3380
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3381
|
+
case 429:
|
|
3382
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3350
3383
|
default:
|
|
3351
3384
|
throw new VectrosError({
|
|
3352
3385
|
statusCode: _response.error.statusCode,
|
|
@@ -3428,6 +3461,7 @@ var AuthClient = class {
|
|
|
3428
3461
|
*
|
|
3429
3462
|
* @throws {@link Vectros.ForbiddenError}
|
|
3430
3463
|
* @throws {@link Vectros.NotFoundError}
|
|
3464
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3431
3465
|
*
|
|
3432
3466
|
* @example
|
|
3433
3467
|
* await client.auth.updateAppContext({
|
|
@@ -3475,6 +3509,8 @@ var AuthClient = class {
|
|
|
3475
3509
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3476
3510
|
case 404:
|
|
3477
3511
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3512
|
+
case 429:
|
|
3513
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3478
3514
|
default:
|
|
3479
3515
|
throw new VectrosError({
|
|
3480
3516
|
statusCode: _response.error.statusCode,
|
|
@@ -3494,6 +3530,7 @@ var AuthClient = class {
|
|
|
3494
3530
|
* @throws {@link Vectros.BadRequestError}
|
|
3495
3531
|
* @throws {@link Vectros.ForbiddenError}
|
|
3496
3532
|
* @throws {@link Vectros.NotFoundError}
|
|
3533
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3497
3534
|
*
|
|
3498
3535
|
* @example
|
|
3499
3536
|
* await client.auth.deleteAppContext({
|
|
@@ -3539,6 +3576,8 @@ var AuthClient = class {
|
|
|
3539
3576
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3540
3577
|
case 404:
|
|
3541
3578
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3579
|
+
case 429:
|
|
3580
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3542
3581
|
default:
|
|
3543
3582
|
throw new VectrosError({
|
|
3544
3583
|
statusCode: _response.error.statusCode,
|
|
@@ -3626,6 +3665,7 @@ var AuthClient = class {
|
|
|
3626
3665
|
*
|
|
3627
3666
|
* @throws {@link Vectros.ForbiddenError}
|
|
3628
3667
|
* @throws {@link Vectros.NotFoundError}
|
|
3668
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3629
3669
|
*
|
|
3630
3670
|
* @example
|
|
3631
3671
|
* await client.auth.updateRole({
|
|
@@ -3677,6 +3717,8 @@ var AuthClient = class {
|
|
|
3677
3717
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3678
3718
|
case 404:
|
|
3679
3719
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3720
|
+
case 429:
|
|
3721
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3680
3722
|
default:
|
|
3681
3723
|
throw new VectrosError({
|
|
3682
3724
|
statusCode: _response.error.statusCode,
|
|
@@ -3700,6 +3742,7 @@ var AuthClient = class {
|
|
|
3700
3742
|
*
|
|
3701
3743
|
* @throws {@link Vectros.ForbiddenError}
|
|
3702
3744
|
* @throws {@link Vectros.NotFoundError}
|
|
3745
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
3703
3746
|
*
|
|
3704
3747
|
* @example
|
|
3705
3748
|
* await client.auth.deleteRole({
|
|
@@ -3741,6 +3784,8 @@ var AuthClient = class {
|
|
|
3741
3784
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
3742
3785
|
case 404:
|
|
3743
3786
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
3787
|
+
case 429:
|
|
3788
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
3744
3789
|
default:
|
|
3745
3790
|
throw new VectrosError({
|
|
3746
3791
|
statusCode: _response.error.statusCode,
|
|
@@ -4072,6 +4117,7 @@ var AuthClient = class {
|
|
|
4072
4117
|
*
|
|
4073
4118
|
* @throws {@link Vectros.BadRequestError}
|
|
4074
4119
|
* @throws {@link Vectros.ForbiddenError}
|
|
4120
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4075
4121
|
*
|
|
4076
4122
|
* @example
|
|
4077
4123
|
* await client.auth.mintToken({
|
|
@@ -4124,6 +4170,8 @@ var AuthClient = class {
|
|
|
4124
4170
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4125
4171
|
case 403:
|
|
4126
4172
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4173
|
+
case 429:
|
|
4174
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4127
4175
|
default:
|
|
4128
4176
|
throw new VectrosError({
|
|
4129
4177
|
statusCode: _response.error.statusCode,
|
|
@@ -4144,6 +4192,7 @@ var AuthClient = class {
|
|
|
4144
4192
|
* @throws {@link Vectros.ForbiddenError}
|
|
4145
4193
|
* @throws {@link Vectros.NotFoundError}
|
|
4146
4194
|
* @throws {@link Vectros.ConflictError}
|
|
4195
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4147
4196
|
*
|
|
4148
4197
|
* @example
|
|
4149
4198
|
* await client.auth.createInvite({
|
|
@@ -4192,6 +4241,8 @@ var AuthClient = class {
|
|
|
4192
4241
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4193
4242
|
case 409:
|
|
4194
4243
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4244
|
+
case 429:
|
|
4245
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4195
4246
|
default:
|
|
4196
4247
|
throw new VectrosError({
|
|
4197
4248
|
statusCode: _response.error.statusCode,
|
|
@@ -4211,6 +4262,7 @@ var AuthClient = class {
|
|
|
4211
4262
|
* @throws {@link Vectros.BadRequestError}
|
|
4212
4263
|
* @throws {@link Vectros.ForbiddenError}
|
|
4213
4264
|
* @throws {@link Vectros.NotFoundError}
|
|
4265
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4214
4266
|
*
|
|
4215
4267
|
* @example
|
|
4216
4268
|
* await client.auth.resendInvite({
|
|
@@ -4257,6 +4309,8 @@ var AuthClient = class {
|
|
|
4257
4309
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4258
4310
|
case 404:
|
|
4259
4311
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4312
|
+
case 429:
|
|
4313
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4260
4314
|
default:
|
|
4261
4315
|
throw new VectrosError({
|
|
4262
4316
|
statusCode: _response.error.statusCode,
|
|
@@ -4279,6 +4333,7 @@ var ComplianceClient = class {
|
|
|
4279
4333
|
* @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4280
4334
|
*
|
|
4281
4335
|
* @throws {@link Vectros.ForbiddenError}
|
|
4336
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4282
4337
|
* @throws {@link Vectros.NotImplementedError}
|
|
4283
4338
|
*
|
|
4284
4339
|
* @example
|
|
@@ -4320,6 +4375,8 @@ var ComplianceClient = class {
|
|
|
4320
4375
|
switch (_response.error.statusCode) {
|
|
4321
4376
|
case 403:
|
|
4322
4377
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4378
|
+
case 429:
|
|
4379
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4323
4380
|
case 501:
|
|
4324
4381
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
4325
4382
|
default:
|
|
@@ -4400,6 +4457,7 @@ var ComplianceClient = class {
|
|
|
4400
4457
|
* @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4401
4458
|
*
|
|
4402
4459
|
* @throws {@link Vectros.ForbiddenError}
|
|
4460
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4403
4461
|
* @throws {@link Vectros.NotImplementedError}
|
|
4404
4462
|
*
|
|
4405
4463
|
* @example
|
|
@@ -4439,6 +4497,8 @@ var ComplianceClient = class {
|
|
|
4439
4497
|
switch (_response.error.statusCode) {
|
|
4440
4498
|
case 403:
|
|
4441
4499
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4500
|
+
case 429:
|
|
4501
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4442
4502
|
case 501:
|
|
4443
4503
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
4444
4504
|
default:
|
|
@@ -4578,22 +4638,30 @@ var DocumentsClient = class {
|
|
|
4578
4638
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
|
|
4579
4639
|
}
|
|
4580
4640
|
/**
|
|
4581
|
-
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Requires the `documents:c` scope.
|
|
4641
|
+
* 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.
|
|
4582
4642
|
*
|
|
4583
|
-
* @param {Vectros.
|
|
4643
|
+
* @param {Vectros.IngestDocumentRequest} request
|
|
4584
4644
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4585
4645
|
*
|
|
4586
4646
|
* @throws {@link Vectros.BadRequestError}
|
|
4647
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
4648
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4587
4649
|
*
|
|
4588
4650
|
* @example
|
|
4589
4651
|
* await client.documents.ingestDocument({
|
|
4590
|
-
*
|
|
4652
|
+
* body: {
|
|
4653
|
+
* title: "Patient Intake Form \u2014 Jane Doe"
|
|
4654
|
+
* }
|
|
4591
4655
|
* })
|
|
4592
4656
|
*/
|
|
4593
4657
|
ingestDocument(request, requestOptions) {
|
|
4594
4658
|
return HttpResponsePromise.fromPromise(this.__ingestDocument(request, requestOptions));
|
|
4595
4659
|
}
|
|
4596
4660
|
async __ingestDocument(request, requestOptions) {
|
|
4661
|
+
const { upsert, body: _body } = request;
|
|
4662
|
+
const _queryParams = {
|
|
4663
|
+
upsert
|
|
4664
|
+
};
|
|
4597
4665
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
4598
4666
|
const _headers = mergeHeaders(
|
|
4599
4667
|
_authRequest.headers,
|
|
@@ -4608,9 +4676,9 @@ var DocumentsClient = class {
|
|
|
4608
4676
|
method: "POST",
|
|
4609
4677
|
headers: _headers,
|
|
4610
4678
|
contentType: "application/json",
|
|
4611
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
4679
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
4612
4680
|
requestType: "json",
|
|
4613
|
-
body:
|
|
4681
|
+
body: _body,
|
|
4614
4682
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
4615
4683
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
4616
4684
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -4624,6 +4692,10 @@ var DocumentsClient = class {
|
|
|
4624
4692
|
switch (_response.error.statusCode) {
|
|
4625
4693
|
case 400:
|
|
4626
4694
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
4695
|
+
case 403:
|
|
4696
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
4697
|
+
case 429:
|
|
4698
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4627
4699
|
default:
|
|
4628
4700
|
throw new VectrosError({
|
|
4629
4701
|
statusCode: _response.error.statusCode,
|
|
@@ -4698,6 +4770,7 @@ var DocumentsClient = class {
|
|
|
4698
4770
|
* @throws {@link Vectros.BadRequestError}
|
|
4699
4771
|
* @throws {@link Vectros.NotFoundError}
|
|
4700
4772
|
* @throws {@link Vectros.ConflictError}
|
|
4773
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4701
4774
|
*
|
|
4702
4775
|
* @example
|
|
4703
4776
|
* await client.documents.updateDocument({
|
|
@@ -4746,6 +4819,8 @@ var DocumentsClient = class {
|
|
|
4746
4819
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4747
4820
|
case 409:
|
|
4748
4821
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4822
|
+
case 429:
|
|
4823
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4749
4824
|
default:
|
|
4750
4825
|
throw new VectrosError({
|
|
4751
4826
|
statusCode: _response.error.statusCode,
|
|
@@ -4763,6 +4838,7 @@ var DocumentsClient = class {
|
|
|
4763
4838
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4764
4839
|
*
|
|
4765
4840
|
* @throws {@link Vectros.NotFoundError}
|
|
4841
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4766
4842
|
*
|
|
4767
4843
|
* @example
|
|
4768
4844
|
* await client.documents.deleteDocument({
|
|
@@ -4801,6 +4877,8 @@ var DocumentsClient = class {
|
|
|
4801
4877
|
switch (_response.error.statusCode) {
|
|
4802
4878
|
case 404:
|
|
4803
4879
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4880
|
+
case 429:
|
|
4881
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4804
4882
|
default:
|
|
4805
4883
|
throw new VectrosError({
|
|
4806
4884
|
statusCode: _response.error.statusCode,
|
|
@@ -4820,6 +4898,7 @@ var DocumentsClient = class {
|
|
|
4820
4898
|
* @throws {@link Vectros.BadRequestError}
|
|
4821
4899
|
* @throws {@link Vectros.NotFoundError}
|
|
4822
4900
|
* @throws {@link Vectros.ConflictError}
|
|
4901
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4823
4902
|
*
|
|
4824
4903
|
* @example
|
|
4825
4904
|
* await client.documents.patchDocument({
|
|
@@ -4868,6 +4947,8 @@ var DocumentsClient = class {
|
|
|
4868
4947
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
4869
4948
|
case 409:
|
|
4870
4949
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
4950
|
+
case 429:
|
|
4951
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4871
4952
|
default:
|
|
4872
4953
|
throw new VectrosError({
|
|
4873
4954
|
statusCode: _response.error.statusCode,
|
|
@@ -4879,7 +4960,7 @@ var DocumentsClient = class {
|
|
|
4879
4960
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
|
|
4880
4961
|
}
|
|
4881
4962
|
/**
|
|
4882
|
-
* Finds documents of a given type by
|
|
4963
|
+
* 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.
|
|
4883
4964
|
*
|
|
4884
4965
|
* @param {Vectros.LookupDocumentsRequest} request
|
|
4885
4966
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4948,6 +5029,7 @@ var DocumentsClient = class {
|
|
|
4948
5029
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4949
5030
|
*
|
|
4950
5031
|
* @throws {@link Vectros.BadRequestError}
|
|
5032
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
4951
5033
|
*
|
|
4952
5034
|
* @example
|
|
4953
5035
|
* await client.documents.lookupDocumentsByBody({
|
|
@@ -4989,6 +5071,8 @@ var DocumentsClient = class {
|
|
|
4989
5071
|
switch (_response.error.statusCode) {
|
|
4990
5072
|
case 400:
|
|
4991
5073
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5074
|
+
case 429:
|
|
5075
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
4992
5076
|
default:
|
|
4993
5077
|
throw new VectrosError({
|
|
4994
5078
|
statusCode: _response.error.statusCode,
|
|
@@ -5171,12 +5255,14 @@ var DocumentsClient = class {
|
|
|
5171
5255
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/versions");
|
|
5172
5256
|
}
|
|
5173
5257
|
/**
|
|
5174
|
-
* 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.
|
|
5258
|
+
* 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.
|
|
5175
5259
|
*
|
|
5176
5260
|
* @param {Vectros.FileUploadRequest} request
|
|
5177
5261
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5178
5262
|
*
|
|
5179
5263
|
* @throws {@link Vectros.BadRequestError}
|
|
5264
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5265
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5180
5266
|
*
|
|
5181
5267
|
* @example
|
|
5182
5268
|
* await client.documents.uploadDocument({
|
|
@@ -5188,6 +5274,10 @@ var DocumentsClient = class {
|
|
|
5188
5274
|
return HttpResponsePromise.fromPromise(this.__uploadDocument(request, requestOptions));
|
|
5189
5275
|
}
|
|
5190
5276
|
async __uploadDocument(request, requestOptions) {
|
|
5277
|
+
const { upsert, ..._body } = request;
|
|
5278
|
+
const _queryParams = {
|
|
5279
|
+
upsert
|
|
5280
|
+
};
|
|
5191
5281
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5192
5282
|
const _headers = mergeHeaders(
|
|
5193
5283
|
_authRequest.headers,
|
|
@@ -5202,9 +5292,9 @@ var DocumentsClient = class {
|
|
|
5202
5292
|
method: "POST",
|
|
5203
5293
|
headers: _headers,
|
|
5204
5294
|
contentType: "application/json",
|
|
5205
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5295
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5206
5296
|
requestType: "json",
|
|
5207
|
-
body:
|
|
5297
|
+
body: _body,
|
|
5208
5298
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5209
5299
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5210
5300
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5218,6 +5308,10 @@ var DocumentsClient = class {
|
|
|
5218
5308
|
switch (_response.error.statusCode) {
|
|
5219
5309
|
case 400:
|
|
5220
5310
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5311
|
+
case 403:
|
|
5312
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5313
|
+
case 429:
|
|
5314
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5221
5315
|
default:
|
|
5222
5316
|
throw new VectrosError({
|
|
5223
5317
|
statusCode: _response.error.statusCode,
|
|
@@ -5294,22 +5388,30 @@ var FoldersClient = class {
|
|
|
5294
5388
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
|
|
5295
5389
|
}
|
|
5296
5390
|
/**
|
|
5297
|
-
* 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.
|
|
5391
|
+
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Folder creation is idempotent by (slug + parent): if a folder with the same slug already exists under the same parent, that existing folder is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing folder was returned) tells the two apart. To overwrite an existing folder's mutable fields instead of returning it unchanged, set `?upsert=true` (this also requires the `folders:u` scope). Requires the `folders:c` scope.
|
|
5298
5392
|
*
|
|
5299
|
-
* @param {Vectros.
|
|
5393
|
+
* @param {Vectros.CreateFolderRequest} request
|
|
5300
5394
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5301
5395
|
*
|
|
5302
5396
|
* @throws {@link Vectros.BadRequestError}
|
|
5397
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5398
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5303
5399
|
*
|
|
5304
5400
|
* @example
|
|
5305
5401
|
* await client.folders.createFolder({
|
|
5306
|
-
*
|
|
5402
|
+
* body: {
|
|
5403
|
+
* name: "Patient Records 2024"
|
|
5404
|
+
* }
|
|
5307
5405
|
* })
|
|
5308
5406
|
*/
|
|
5309
5407
|
createFolder(request, requestOptions) {
|
|
5310
5408
|
return HttpResponsePromise.fromPromise(this.__createFolder(request, requestOptions));
|
|
5311
5409
|
}
|
|
5312
5410
|
async __createFolder(request, requestOptions) {
|
|
5411
|
+
const { upsert, body: _body } = request;
|
|
5412
|
+
const _queryParams = {
|
|
5413
|
+
upsert
|
|
5414
|
+
};
|
|
5313
5415
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5314
5416
|
const _headers = mergeHeaders(
|
|
5315
5417
|
_authRequest.headers,
|
|
@@ -5324,9 +5426,9 @@ var FoldersClient = class {
|
|
|
5324
5426
|
method: "POST",
|
|
5325
5427
|
headers: _headers,
|
|
5326
5428
|
contentType: "application/json",
|
|
5327
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5429
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5328
5430
|
requestType: "json",
|
|
5329
|
-
body:
|
|
5431
|
+
body: _body,
|
|
5330
5432
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5331
5433
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5332
5434
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5340,6 +5442,10 @@ var FoldersClient = class {
|
|
|
5340
5442
|
switch (_response.error.statusCode) {
|
|
5341
5443
|
case 400:
|
|
5342
5444
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5445
|
+
case 403:
|
|
5446
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5447
|
+
case 429:
|
|
5448
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5343
5449
|
default:
|
|
5344
5450
|
throw new VectrosError({
|
|
5345
5451
|
statusCode: _response.error.statusCode,
|
|
@@ -5412,6 +5518,7 @@ var FoldersClient = class {
|
|
|
5412
5518
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5413
5519
|
*
|
|
5414
5520
|
* @throws {@link Vectros.NotFoundError}
|
|
5521
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5415
5522
|
*
|
|
5416
5523
|
* @example
|
|
5417
5524
|
* await client.folders.updateFolder({
|
|
@@ -5456,6 +5563,8 @@ var FoldersClient = class {
|
|
|
5456
5563
|
switch (_response.error.statusCode) {
|
|
5457
5564
|
case 404:
|
|
5458
5565
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5566
|
+
case 429:
|
|
5567
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5459
5568
|
default:
|
|
5460
5569
|
throw new VectrosError({
|
|
5461
5570
|
statusCode: _response.error.statusCode,
|
|
@@ -5474,6 +5583,7 @@ var FoldersClient = class {
|
|
|
5474
5583
|
*
|
|
5475
5584
|
* @throws {@link Vectros.BadRequestError}
|
|
5476
5585
|
* @throws {@link Vectros.NotFoundError}
|
|
5586
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5477
5587
|
*
|
|
5478
5588
|
* @example
|
|
5479
5589
|
* await client.folders.deleteFolder({
|
|
@@ -5514,6 +5624,8 @@ var FoldersClient = class {
|
|
|
5514
5624
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5515
5625
|
case 404:
|
|
5516
5626
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5627
|
+
case 429:
|
|
5628
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5517
5629
|
default:
|
|
5518
5630
|
throw new VectrosError({
|
|
5519
5631
|
statusCode: _response.error.statusCode,
|
|
@@ -5533,6 +5645,7 @@ var FoldersClient = class {
|
|
|
5533
5645
|
* @throws {@link Vectros.BadRequestError}
|
|
5534
5646
|
* @throws {@link Vectros.NotFoundError}
|
|
5535
5647
|
* @throws {@link Vectros.ConflictError}
|
|
5648
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5536
5649
|
*
|
|
5537
5650
|
* @example
|
|
5538
5651
|
* await client.folders.patchFolder({
|
|
@@ -5581,6 +5694,8 @@ var FoldersClient = class {
|
|
|
5581
5694
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
5582
5695
|
case 409:
|
|
5583
5696
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
5697
|
+
case 429:
|
|
5698
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5584
5699
|
default:
|
|
5585
5700
|
throw new VectrosError({
|
|
5586
5701
|
statusCode: _response.error.statusCode,
|
|
@@ -5737,22 +5852,30 @@ var IdentityClient = class {
|
|
|
5737
5852
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/clients");
|
|
5738
5853
|
}
|
|
5739
5854
|
/**
|
|
5740
|
-
* 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.
|
|
5855
|
+
* 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.
|
|
5741
5856
|
*
|
|
5742
|
-
* @param {Vectros.
|
|
5857
|
+
* @param {Vectros.CreateClientRequest} request
|
|
5743
5858
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5744
5859
|
*
|
|
5745
5860
|
* @throws {@link Vectros.BadRequestError}
|
|
5861
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
5862
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5746
5863
|
*
|
|
5747
5864
|
* @example
|
|
5748
5865
|
* await client.identity.createClient({
|
|
5749
|
-
*
|
|
5866
|
+
* body: {
|
|
5867
|
+
* externalId: "patient_789"
|
|
5868
|
+
* }
|
|
5750
5869
|
* })
|
|
5751
5870
|
*/
|
|
5752
5871
|
createClient(request, requestOptions) {
|
|
5753
5872
|
return HttpResponsePromise.fromPromise(this.__createClient(request, requestOptions));
|
|
5754
5873
|
}
|
|
5755
5874
|
async __createClient(request, requestOptions) {
|
|
5875
|
+
const { upsert, body: _body } = request;
|
|
5876
|
+
const _queryParams = {
|
|
5877
|
+
upsert
|
|
5878
|
+
};
|
|
5756
5879
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
5757
5880
|
const _headers = mergeHeaders(
|
|
5758
5881
|
_authRequest.headers,
|
|
@@ -5767,9 +5890,9 @@ var IdentityClient = class {
|
|
|
5767
5890
|
method: "POST",
|
|
5768
5891
|
headers: _headers,
|
|
5769
5892
|
contentType: "application/json",
|
|
5770
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
5893
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
5771
5894
|
requestType: "json",
|
|
5772
|
-
body:
|
|
5895
|
+
body: _body,
|
|
5773
5896
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
5774
5897
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
5775
5898
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -5783,6 +5906,10 @@ var IdentityClient = class {
|
|
|
5783
5906
|
switch (_response.error.statusCode) {
|
|
5784
5907
|
case 400:
|
|
5785
5908
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5909
|
+
case 403:
|
|
5910
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
5911
|
+
case 429:
|
|
5912
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5786
5913
|
default:
|
|
5787
5914
|
throw new VectrosError({
|
|
5788
5915
|
statusCode: _response.error.statusCode,
|
|
@@ -5855,6 +5982,7 @@ var IdentityClient = class {
|
|
|
5855
5982
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5856
5983
|
*
|
|
5857
5984
|
* @throws {@link Vectros.NotFoundError}
|
|
5985
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5858
5986
|
*
|
|
5859
5987
|
* @example
|
|
5860
5988
|
* await client.identity.updateClient({
|
|
@@ -5899,6 +6027,8 @@ var IdentityClient = class {
|
|
|
5899
6027
|
switch (_response.error.statusCode) {
|
|
5900
6028
|
case 404:
|
|
5901
6029
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6030
|
+
case 429:
|
|
6031
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5902
6032
|
default:
|
|
5903
6033
|
throw new VectrosError({
|
|
5904
6034
|
statusCode: _response.error.statusCode,
|
|
@@ -5916,6 +6046,7 @@ var IdentityClient = class {
|
|
|
5916
6046
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5917
6047
|
*
|
|
5918
6048
|
* @throws {@link Vectros.NotFoundError}
|
|
6049
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5919
6050
|
*
|
|
5920
6051
|
* @example
|
|
5921
6052
|
* await client.identity.deleteClient({
|
|
@@ -5954,6 +6085,8 @@ var IdentityClient = class {
|
|
|
5954
6085
|
switch (_response.error.statusCode) {
|
|
5955
6086
|
case 404:
|
|
5956
6087
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6088
|
+
case 429:
|
|
6089
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
5957
6090
|
default:
|
|
5958
6091
|
throw new VectrosError({
|
|
5959
6092
|
statusCode: _response.error.statusCode,
|
|
@@ -5971,6 +6104,7 @@ var IdentityClient = class {
|
|
|
5971
6104
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
5972
6105
|
*
|
|
5973
6106
|
* @throws {@link Vectros.BadRequestError}
|
|
6107
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
5974
6108
|
*
|
|
5975
6109
|
* @example
|
|
5976
6110
|
* await client.identity.lookupClients({
|
|
@@ -6012,6 +6146,8 @@ var IdentityClient = class {
|
|
|
6012
6146
|
switch (_response.error.statusCode) {
|
|
6013
6147
|
case 400:
|
|
6014
6148
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6149
|
+
case 429:
|
|
6150
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6015
6151
|
default:
|
|
6016
6152
|
throw new VectrosError({
|
|
6017
6153
|
statusCode: _response.error.statusCode,
|
|
@@ -6160,22 +6296,30 @@ var IdentityClient = class {
|
|
|
6160
6296
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/orgs");
|
|
6161
6297
|
}
|
|
6162
6298
|
/**
|
|
6163
|
-
* 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.
|
|
6299
|
+
* 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.
|
|
6164
6300
|
*
|
|
6165
|
-
* @param {Vectros.
|
|
6301
|
+
* @param {Vectros.CreateOrgRequest} request
|
|
6166
6302
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6167
6303
|
*
|
|
6168
6304
|
* @throws {@link Vectros.BadRequestError}
|
|
6305
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
6306
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6169
6307
|
*
|
|
6170
6308
|
* @example
|
|
6171
6309
|
* await client.identity.createOrg({
|
|
6172
|
-
*
|
|
6310
|
+
* body: {
|
|
6311
|
+
* externalId: "clinic_001"
|
|
6312
|
+
* }
|
|
6173
6313
|
* })
|
|
6174
6314
|
*/
|
|
6175
6315
|
createOrg(request, requestOptions) {
|
|
6176
6316
|
return HttpResponsePromise.fromPromise(this.__createOrg(request, requestOptions));
|
|
6177
6317
|
}
|
|
6178
6318
|
async __createOrg(request, requestOptions) {
|
|
6319
|
+
const { upsert, body: _body } = request;
|
|
6320
|
+
const _queryParams = {
|
|
6321
|
+
upsert
|
|
6322
|
+
};
|
|
6179
6323
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
6180
6324
|
const _headers = mergeHeaders(
|
|
6181
6325
|
_authRequest.headers,
|
|
@@ -6190,9 +6334,9 @@ var IdentityClient = class {
|
|
|
6190
6334
|
method: "POST",
|
|
6191
6335
|
headers: _headers,
|
|
6192
6336
|
contentType: "application/json",
|
|
6193
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
6337
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
6194
6338
|
requestType: "json",
|
|
6195
|
-
body:
|
|
6339
|
+
body: _body,
|
|
6196
6340
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
6197
6341
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
6198
6342
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -6206,6 +6350,10 @@ var IdentityClient = class {
|
|
|
6206
6350
|
switch (_response.error.statusCode) {
|
|
6207
6351
|
case 400:
|
|
6208
6352
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6353
|
+
case 403:
|
|
6354
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
6355
|
+
case 429:
|
|
6356
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6209
6357
|
default:
|
|
6210
6358
|
throw new VectrosError({
|
|
6211
6359
|
statusCode: _response.error.statusCode,
|
|
@@ -6278,6 +6426,7 @@ var IdentityClient = class {
|
|
|
6278
6426
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6279
6427
|
*
|
|
6280
6428
|
* @throws {@link Vectros.NotFoundError}
|
|
6429
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6281
6430
|
*
|
|
6282
6431
|
* @example
|
|
6283
6432
|
* await client.identity.updateOrg({
|
|
@@ -6322,6 +6471,8 @@ var IdentityClient = class {
|
|
|
6322
6471
|
switch (_response.error.statusCode) {
|
|
6323
6472
|
case 404:
|
|
6324
6473
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6474
|
+
case 429:
|
|
6475
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6325
6476
|
default:
|
|
6326
6477
|
throw new VectrosError({
|
|
6327
6478
|
statusCode: _response.error.statusCode,
|
|
@@ -6339,6 +6490,7 @@ var IdentityClient = class {
|
|
|
6339
6490
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6340
6491
|
*
|
|
6341
6492
|
* @throws {@link Vectros.NotFoundError}
|
|
6493
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6342
6494
|
*
|
|
6343
6495
|
* @example
|
|
6344
6496
|
* await client.identity.deleteOrg({
|
|
@@ -6377,6 +6529,8 @@ var IdentityClient = class {
|
|
|
6377
6529
|
switch (_response.error.statusCode) {
|
|
6378
6530
|
case 404:
|
|
6379
6531
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6532
|
+
case 429:
|
|
6533
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6380
6534
|
default:
|
|
6381
6535
|
throw new VectrosError({
|
|
6382
6536
|
statusCode: _response.error.statusCode,
|
|
@@ -6394,6 +6548,7 @@ var IdentityClient = class {
|
|
|
6394
6548
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6395
6549
|
*
|
|
6396
6550
|
* @throws {@link Vectros.BadRequestError}
|
|
6551
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6397
6552
|
*
|
|
6398
6553
|
* @example
|
|
6399
6554
|
* await client.identity.lookupOrgs({
|
|
@@ -6435,6 +6590,8 @@ var IdentityClient = class {
|
|
|
6435
6590
|
switch (_response.error.statusCode) {
|
|
6436
6591
|
case 400:
|
|
6437
6592
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6593
|
+
case 429:
|
|
6594
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6438
6595
|
default:
|
|
6439
6596
|
throw new VectrosError({
|
|
6440
6597
|
statusCode: _response.error.statusCode,
|
|
@@ -6569,22 +6726,30 @@ var IdentityClient = class {
|
|
|
6569
6726
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
|
|
6570
6727
|
}
|
|
6571
6728
|
/**
|
|
6572
|
-
* 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.
|
|
6729
|
+
* 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.
|
|
6573
6730
|
*
|
|
6574
|
-
* @param {Vectros.
|
|
6731
|
+
* @param {Vectros.CreateUserRequest} request
|
|
6575
6732
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6576
6733
|
*
|
|
6577
6734
|
* @throws {@link Vectros.BadRequestError}
|
|
6735
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
6736
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6578
6737
|
*
|
|
6579
6738
|
* @example
|
|
6580
6739
|
* await client.identity.createUser({
|
|
6581
|
-
*
|
|
6740
|
+
* body: {
|
|
6741
|
+
* externalId: "usr_12345"
|
|
6742
|
+
* }
|
|
6582
6743
|
* })
|
|
6583
6744
|
*/
|
|
6584
6745
|
createUser(request, requestOptions) {
|
|
6585
6746
|
return HttpResponsePromise.fromPromise(this.__createUser(request, requestOptions));
|
|
6586
6747
|
}
|
|
6587
6748
|
async __createUser(request, requestOptions) {
|
|
6749
|
+
const { upsert, body: _body } = request;
|
|
6750
|
+
const _queryParams = {
|
|
6751
|
+
upsert
|
|
6752
|
+
};
|
|
6588
6753
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
6589
6754
|
const _headers = mergeHeaders(
|
|
6590
6755
|
_authRequest.headers,
|
|
@@ -6599,9 +6764,9 @@ var IdentityClient = class {
|
|
|
6599
6764
|
method: "POST",
|
|
6600
6765
|
headers: _headers,
|
|
6601
6766
|
contentType: "application/json",
|
|
6602
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
6767
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
6603
6768
|
requestType: "json",
|
|
6604
|
-
body:
|
|
6769
|
+
body: _body,
|
|
6605
6770
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
6606
6771
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
6607
6772
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -6615,6 +6780,10 @@ var IdentityClient = class {
|
|
|
6615
6780
|
switch (_response.error.statusCode) {
|
|
6616
6781
|
case 400:
|
|
6617
6782
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
6783
|
+
case 403:
|
|
6784
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
6785
|
+
case 429:
|
|
6786
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6618
6787
|
default:
|
|
6619
6788
|
throw new VectrosError({
|
|
6620
6789
|
statusCode: _response.error.statusCode,
|
|
@@ -6687,6 +6856,7 @@ var IdentityClient = class {
|
|
|
6687
6856
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6688
6857
|
*
|
|
6689
6858
|
* @throws {@link Vectros.NotFoundError}
|
|
6859
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6690
6860
|
*
|
|
6691
6861
|
* @example
|
|
6692
6862
|
* await client.identity.updateUser({
|
|
@@ -6731,6 +6901,8 @@ var IdentityClient = class {
|
|
|
6731
6901
|
switch (_response.error.statusCode) {
|
|
6732
6902
|
case 404:
|
|
6733
6903
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6904
|
+
case 429:
|
|
6905
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6734
6906
|
default:
|
|
6735
6907
|
throw new VectrosError({
|
|
6736
6908
|
statusCode: _response.error.statusCode,
|
|
@@ -6748,6 +6920,7 @@ var IdentityClient = class {
|
|
|
6748
6920
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6749
6921
|
*
|
|
6750
6922
|
* @throws {@link Vectros.NotFoundError}
|
|
6923
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6751
6924
|
*
|
|
6752
6925
|
* @example
|
|
6753
6926
|
* await client.identity.deleteUser({
|
|
@@ -6786,6 +6959,8 @@ var IdentityClient = class {
|
|
|
6786
6959
|
switch (_response.error.statusCode) {
|
|
6787
6960
|
case 404:
|
|
6788
6961
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
6962
|
+
case 429:
|
|
6963
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6789
6964
|
default:
|
|
6790
6965
|
throw new VectrosError({
|
|
6791
6966
|
statusCode: _response.error.statusCode,
|
|
@@ -6803,6 +6978,7 @@ var IdentityClient = class {
|
|
|
6803
6978
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
6804
6979
|
*
|
|
6805
6980
|
* @throws {@link Vectros.BadRequestError}
|
|
6981
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
6806
6982
|
*
|
|
6807
6983
|
* @example
|
|
6808
6984
|
* await client.identity.lookupUsers({
|
|
@@ -6844,6 +7020,8 @@ var IdentityClient = class {
|
|
|
6844
7020
|
switch (_response.error.statusCode) {
|
|
6845
7021
|
case 400:
|
|
6846
7022
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7023
|
+
case 429:
|
|
7024
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
6847
7025
|
default:
|
|
6848
7026
|
throw new VectrosError({
|
|
6849
7027
|
statusCode: _response.error.statusCode,
|
|
@@ -7180,6 +7358,7 @@ var RecordsClient = class {
|
|
|
7180
7358
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7181
7359
|
*
|
|
7182
7360
|
* @throws {@link Vectros.ForbiddenError}
|
|
7361
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7183
7362
|
* @throws {@link Vectros.NotImplementedError}
|
|
7184
7363
|
*
|
|
7185
7364
|
* @example
|
|
@@ -7219,6 +7398,8 @@ var RecordsClient = class {
|
|
|
7219
7398
|
switch (_response.error.statusCode) {
|
|
7220
7399
|
case 403:
|
|
7221
7400
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7401
|
+
case 429:
|
|
7402
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7222
7403
|
case 501:
|
|
7223
7404
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7224
7405
|
default:
|
|
@@ -7238,6 +7419,7 @@ var RecordsClient = class {
|
|
|
7238
7419
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7239
7420
|
*
|
|
7240
7421
|
* @throws {@link Vectros.ForbiddenError}
|
|
7422
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7241
7423
|
* @throws {@link Vectros.NotImplementedError}
|
|
7242
7424
|
*
|
|
7243
7425
|
* @example
|
|
@@ -7277,6 +7459,8 @@ var RecordsClient = class {
|
|
|
7277
7459
|
switch (_response.error.statusCode) {
|
|
7278
7460
|
case 403:
|
|
7279
7461
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7462
|
+
case 429:
|
|
7463
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7280
7464
|
case 501:
|
|
7281
7465
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7282
7466
|
default:
|
|
@@ -7296,6 +7480,7 @@ var RecordsClient = class {
|
|
|
7296
7480
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7297
7481
|
*
|
|
7298
7482
|
* @throws {@link Vectros.ForbiddenError}
|
|
7483
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7299
7484
|
* @throws {@link Vectros.NotImplementedError}
|
|
7300
7485
|
*
|
|
7301
7486
|
* @example
|
|
@@ -7335,6 +7520,8 @@ var RecordsClient = class {
|
|
|
7335
7520
|
switch (_response.error.statusCode) {
|
|
7336
7521
|
case 403:
|
|
7337
7522
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7523
|
+
case 429:
|
|
7524
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7338
7525
|
case 501:
|
|
7339
7526
|
throw new NotImplementedError(_response.error.body, _response.rawResponse);
|
|
7340
7527
|
default:
|
|
@@ -7412,29 +7599,36 @@ var RecordsClient = class {
|
|
|
7412
7599
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
|
|
7413
7600
|
}
|
|
7414
7601
|
/**
|
|
7415
|
-
* 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.
|
|
7602
|
+
* 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.
|
|
7416
7603
|
*
|
|
7417
|
-
* @param {Vectros.
|
|
7604
|
+
* @param {Vectros.CreateRecordRequest} request
|
|
7418
7605
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7419
7606
|
*
|
|
7420
7607
|
* @throws {@link Vectros.BadRequestError}
|
|
7421
7608
|
* @throws {@link Vectros.ForbiddenError}
|
|
7609
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7422
7610
|
*
|
|
7423
7611
|
* @example
|
|
7424
7612
|
* await client.records.createRecord({
|
|
7425
|
-
*
|
|
7426
|
-
*
|
|
7427
|
-
*
|
|
7428
|
-
*
|
|
7429
|
-
*
|
|
7430
|
-
*
|
|
7431
|
-
*
|
|
7613
|
+
* body: {
|
|
7614
|
+
* typeName: "intake_form",
|
|
7615
|
+
* schemaId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
|
7616
|
+
* payload: {
|
|
7617
|
+
* "first_name": "Jane",
|
|
7618
|
+
* "email": "jane@example.com"
|
|
7619
|
+
* },
|
|
7620
|
+
* folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
7621
|
+
* }
|
|
7432
7622
|
* })
|
|
7433
7623
|
*/
|
|
7434
7624
|
createRecord(request, requestOptions) {
|
|
7435
7625
|
return HttpResponsePromise.fromPromise(this.__createRecord(request, requestOptions));
|
|
7436
7626
|
}
|
|
7437
7627
|
async __createRecord(request, requestOptions) {
|
|
7628
|
+
const { upsert, body: _body } = request;
|
|
7629
|
+
const _queryParams = {
|
|
7630
|
+
upsert
|
|
7631
|
+
};
|
|
7438
7632
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
7439
7633
|
const _headers = mergeHeaders(
|
|
7440
7634
|
_authRequest.headers,
|
|
@@ -7449,9 +7643,9 @@ var RecordsClient = class {
|
|
|
7449
7643
|
method: "POST",
|
|
7450
7644
|
headers: _headers,
|
|
7451
7645
|
contentType: "application/json",
|
|
7452
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
7646
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
7453
7647
|
requestType: "json",
|
|
7454
|
-
body:
|
|
7648
|
+
body: _body,
|
|
7455
7649
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
7456
7650
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
7457
7651
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -7467,6 +7661,8 @@ var RecordsClient = class {
|
|
|
7467
7661
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
7468
7662
|
case 403:
|
|
7469
7663
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
7664
|
+
case 429:
|
|
7665
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7470
7666
|
default:
|
|
7471
7667
|
throw new VectrosError({
|
|
7472
7668
|
statusCode: _response.error.statusCode,
|
|
@@ -7541,6 +7737,7 @@ var RecordsClient = class {
|
|
|
7541
7737
|
* @throws {@link Vectros.BadRequestError}
|
|
7542
7738
|
* @throws {@link Vectros.NotFoundError}
|
|
7543
7739
|
* @throws {@link Vectros.ConflictError}
|
|
7740
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7544
7741
|
*
|
|
7545
7742
|
* @example
|
|
7546
7743
|
* await client.records.updateRecord({
|
|
@@ -7587,6 +7784,8 @@ var RecordsClient = class {
|
|
|
7587
7784
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7588
7785
|
case 409:
|
|
7589
7786
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
7787
|
+
case 429:
|
|
7788
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7590
7789
|
default:
|
|
7591
7790
|
throw new VectrosError({
|
|
7592
7791
|
statusCode: _response.error.statusCode,
|
|
@@ -7604,6 +7803,7 @@ var RecordsClient = class {
|
|
|
7604
7803
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7605
7804
|
*
|
|
7606
7805
|
* @throws {@link Vectros.NotFoundError}
|
|
7806
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7607
7807
|
*
|
|
7608
7808
|
* @example
|
|
7609
7809
|
* await client.records.deleteRecord({
|
|
@@ -7642,6 +7842,8 @@ var RecordsClient = class {
|
|
|
7642
7842
|
switch (_response.error.statusCode) {
|
|
7643
7843
|
case 404:
|
|
7644
7844
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7845
|
+
case 429:
|
|
7846
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7645
7847
|
default:
|
|
7646
7848
|
throw new VectrosError({
|
|
7647
7849
|
statusCode: _response.error.statusCode,
|
|
@@ -7661,6 +7863,7 @@ var RecordsClient = class {
|
|
|
7661
7863
|
* @throws {@link Vectros.BadRequestError}
|
|
7662
7864
|
* @throws {@link Vectros.NotFoundError}
|
|
7663
7865
|
* @throws {@link Vectros.ConflictError}
|
|
7866
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7664
7867
|
*
|
|
7665
7868
|
* @example
|
|
7666
7869
|
* await client.records.patchRecord({
|
|
@@ -7712,6 +7915,8 @@ var RecordsClient = class {
|
|
|
7712
7915
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
7713
7916
|
case 409:
|
|
7714
7917
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
7918
|
+
case 429:
|
|
7919
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7715
7920
|
default:
|
|
7716
7921
|
throw new VectrosError({
|
|
7717
7922
|
statusCode: _response.error.statusCode,
|
|
@@ -7800,6 +8005,7 @@ var RecordsClient = class {
|
|
|
7800
8005
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
7801
8006
|
*
|
|
7802
8007
|
* @throws {@link Vectros.BadRequestError}
|
|
8008
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
7803
8009
|
*
|
|
7804
8010
|
* @example
|
|
7805
8011
|
* await client.records.lookupRecordsByBody({
|
|
@@ -7841,6 +8047,8 @@ var RecordsClient = class {
|
|
|
7841
8047
|
switch (_response.error.statusCode) {
|
|
7842
8048
|
case 400:
|
|
7843
8049
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8050
|
+
case 429:
|
|
8051
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
7844
8052
|
default:
|
|
7845
8053
|
throw new VectrosError({
|
|
7846
8054
|
statusCode: _response.error.statusCode,
|
|
@@ -8033,42 +8241,50 @@ var SchemasClient = class {
|
|
|
8033
8241
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
|
|
8034
8242
|
}
|
|
8035
8243
|
/**
|
|
8036
|
-
* 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.
|
|
8244
|
+
* 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.
|
|
8037
8245
|
*
|
|
8038
|
-
* @param {Vectros.
|
|
8246
|
+
* @param {Vectros.CreateSchemaRequest} request
|
|
8039
8247
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8040
8248
|
*
|
|
8041
8249
|
* @throws {@link Vectros.BadRequestError}
|
|
8250
|
+
* @throws {@link Vectros.ForbiddenError}
|
|
8251
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8042
8252
|
*
|
|
8043
8253
|
* @example
|
|
8044
8254
|
* await client.schemas.createSchema({
|
|
8045
|
-
*
|
|
8046
|
-
*
|
|
8047
|
-
*
|
|
8048
|
-
*
|
|
8049
|
-
*
|
|
8050
|
-
*
|
|
8051
|
-
*
|
|
8052
|
-
*
|
|
8053
|
-
*
|
|
8054
|
-
*
|
|
8055
|
-
*
|
|
8056
|
-
*
|
|
8057
|
-
*
|
|
8058
|
-
*
|
|
8059
|
-
*
|
|
8060
|
-
*
|
|
8061
|
-
*
|
|
8062
|
-
*
|
|
8063
|
-
*
|
|
8064
|
-
*
|
|
8065
|
-
*
|
|
8255
|
+
* body: {
|
|
8256
|
+
* typeName: "intake_form",
|
|
8257
|
+
* displayName: "Client Intake Form",
|
|
8258
|
+
* description: "Captures initial client information",
|
|
8259
|
+
* fields: [{
|
|
8260
|
+
* fieldId: "first_name",
|
|
8261
|
+
* fieldType: "string",
|
|
8262
|
+
* required: true,
|
|
8263
|
+
* searchable: true
|
|
8264
|
+
* }, {
|
|
8265
|
+
* fieldId: "email",
|
|
8266
|
+
* fieldType: "string",
|
|
8267
|
+
* required: true
|
|
8268
|
+
* }],
|
|
8269
|
+
* lookupFields: [{
|
|
8270
|
+
* fieldName: "email",
|
|
8271
|
+
* unique: true
|
|
8272
|
+
* }],
|
|
8273
|
+
* capabilities: {
|
|
8274
|
+
* "auditHistory": true
|
|
8275
|
+
* },
|
|
8276
|
+
* allowedSurfaces: ["record"]
|
|
8277
|
+
* }
|
|
8066
8278
|
* })
|
|
8067
8279
|
*/
|
|
8068
8280
|
createSchema(request, requestOptions) {
|
|
8069
8281
|
return HttpResponsePromise.fromPromise(this.__createSchema(request, requestOptions));
|
|
8070
8282
|
}
|
|
8071
8283
|
async __createSchema(request, requestOptions) {
|
|
8284
|
+
const { upsert, body: _body } = request;
|
|
8285
|
+
const _queryParams = {
|
|
8286
|
+
upsert
|
|
8287
|
+
};
|
|
8072
8288
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
8073
8289
|
const _headers = mergeHeaders(
|
|
8074
8290
|
_authRequest.headers,
|
|
@@ -8083,9 +8299,9 @@ var SchemasClient = class {
|
|
|
8083
8299
|
method: "POST",
|
|
8084
8300
|
headers: _headers,
|
|
8085
8301
|
contentType: "application/json",
|
|
8086
|
-
queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
|
|
8302
|
+
queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
|
|
8087
8303
|
requestType: "json",
|
|
8088
|
-
body:
|
|
8304
|
+
body: _body,
|
|
8089
8305
|
timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
|
|
8090
8306
|
maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
|
|
8091
8307
|
abortSignal: requestOptions?.abortSignal,
|
|
@@ -8099,6 +8315,10 @@ var SchemasClient = class {
|
|
|
8099
8315
|
switch (_response.error.statusCode) {
|
|
8100
8316
|
case 400:
|
|
8101
8317
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8318
|
+
case 403:
|
|
8319
|
+
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8320
|
+
case 429:
|
|
8321
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8102
8322
|
default:
|
|
8103
8323
|
throw new VectrosError({
|
|
8104
8324
|
statusCode: _response.error.statusCode,
|
|
@@ -8172,6 +8392,7 @@ var SchemasClient = class {
|
|
|
8172
8392
|
*
|
|
8173
8393
|
* @throws {@link Vectros.BadRequestError}
|
|
8174
8394
|
* @throws {@link Vectros.NotFoundError}
|
|
8395
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8175
8396
|
*
|
|
8176
8397
|
* @example
|
|
8177
8398
|
* await client.schemas.updateSchema({
|
|
@@ -8220,6 +8441,8 @@ var SchemasClient = class {
|
|
|
8220
8441
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8221
8442
|
case 404:
|
|
8222
8443
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8444
|
+
case 429:
|
|
8445
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8223
8446
|
default:
|
|
8224
8447
|
throw new VectrosError({
|
|
8225
8448
|
statusCode: _response.error.statusCode,
|
|
@@ -8238,6 +8461,7 @@ var SchemasClient = class {
|
|
|
8238
8461
|
*
|
|
8239
8462
|
* @throws {@link Vectros.NotFoundError}
|
|
8240
8463
|
* @throws {@link Vectros.ConflictError}
|
|
8464
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8241
8465
|
*
|
|
8242
8466
|
* @example
|
|
8243
8467
|
* await client.schemas.deleteSchema({
|
|
@@ -8278,6 +8502,8 @@ var SchemasClient = class {
|
|
|
8278
8502
|
throw new NotFoundError(_response.error.body, _response.rawResponse);
|
|
8279
8503
|
case 409:
|
|
8280
8504
|
throw new ConflictError(_response.error.body, _response.rawResponse);
|
|
8505
|
+
case 429:
|
|
8506
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8281
8507
|
default:
|
|
8282
8508
|
throw new VectrosError({
|
|
8283
8509
|
statusCode: _response.error.statusCode,
|
|
@@ -8359,6 +8585,7 @@ var SearchClient = class {
|
|
|
8359
8585
|
*
|
|
8360
8586
|
* @throws {@link Vectros.BadRequestError}
|
|
8361
8587
|
* @throws {@link Vectros.ForbiddenError}
|
|
8588
|
+
* @throws {@link Vectros.TooManyRequestsError}
|
|
8362
8589
|
*
|
|
8363
8590
|
* @example
|
|
8364
8591
|
* await client.search.content({
|
|
@@ -8401,6 +8628,8 @@ var SearchClient = class {
|
|
|
8401
8628
|
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8402
8629
|
case 403:
|
|
8403
8630
|
throw new ForbiddenError(_response.error.body, _response.rawResponse);
|
|
8631
|
+
case 429:
|
|
8632
|
+
throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
|
|
8404
8633
|
default:
|
|
8405
8634
|
throw new VectrosError({
|
|
8406
8635
|
statusCode: _response.error.statusCode,
|
|
@@ -8638,11 +8867,36 @@ var BlueprintServicePrincipalSchema = z.object({
|
|
|
8638
8867
|
externalId: z.string().min(1),
|
|
8639
8868
|
displayName: z.string().min(1)
|
|
8640
8869
|
}).strict();
|
|
8641
|
-
var
|
|
8870
|
+
var SeedCommonShape = {
|
|
8871
|
+
/** The schema typeName this seed instantiates (should match a declared schema). */
|
|
8642
8872
|
typeName: z.string().min(1),
|
|
8643
|
-
|
|
8873
|
+
/**
|
|
8874
|
+
* Stable, caller-supplied id — the loader's idempotency key AND the value other
|
|
8875
|
+
* seeds resolve a `reference` against (across surfaces: a record seed may
|
|
8876
|
+
* reference a document seed by its externalId, and vice versa).
|
|
8877
|
+
*/
|
|
8878
|
+
externalId: z.string().min(1)
|
|
8879
|
+
};
|
|
8880
|
+
var RecordSeedSchema = z.object({
|
|
8881
|
+
surface: z.literal("record"),
|
|
8882
|
+
...SeedCommonShape,
|
|
8883
|
+
/** The record payload, validated against the bound schema. */
|
|
8644
8884
|
fields: z.record(z.unknown())
|
|
8645
8885
|
}).strict();
|
|
8886
|
+
var DocumentSeedSchema = z.object({
|
|
8887
|
+
surface: z.literal("document"),
|
|
8888
|
+
...SeedCommonShape,
|
|
8889
|
+
/** Human-readable document title — REQUIRED by the text-ingest path. */
|
|
8890
|
+
title: z.string().min(1),
|
|
8891
|
+
/** Raw text content to ingest + index — REQUIRED and non-empty (the platform rejects a blank ingest). */
|
|
8892
|
+
text: z.string().min(1),
|
|
8893
|
+
/** Optional structured payload bound to the schema (the document's `fields`). */
|
|
8894
|
+
fields: z.record(z.unknown()).optional()
|
|
8895
|
+
}).strict();
|
|
8896
|
+
var BlueprintSeedRecordSchema = z.discriminatedUnion("surface", [
|
|
8897
|
+
RecordSeedSchema,
|
|
8898
|
+
DocumentSeedSchema
|
|
8899
|
+
]);
|
|
8646
8900
|
var SELF_TOKEN_RE = /\$\{\{\s*self\.[A-Za-z_]\w*\s*\}\}/;
|
|
8647
8901
|
function lintSelfTokenPlacement(value, ctx) {
|
|
8648
8902
|
const walk = (node, path4, inRoleDataScope) => {
|
|
@@ -8698,6 +8952,23 @@ function lintIdentityRefsDeclared(value, ctx) {
|
|
|
8698
8952
|
};
|
|
8699
8953
|
walk(value, []);
|
|
8700
8954
|
}
|
|
8955
|
+
function lintSeedSurfaces(value, ctx) {
|
|
8956
|
+
const bp = value;
|
|
8957
|
+
if (!Array.isArray(bp.seed)) return;
|
|
8958
|
+
const byType = new Map((bp.schemas ?? []).map((s) => [s.typeName, s]));
|
|
8959
|
+
bp.seed.forEach((seed, i) => {
|
|
8960
|
+
const schema = byType.get(seed.typeName);
|
|
8961
|
+
if (!schema) return;
|
|
8962
|
+
const allowed = schema.allowedSurfaces ?? ["record"];
|
|
8963
|
+
if (!allowed.includes(seed.surface ?? "record")) {
|
|
8964
|
+
ctx.addIssue({
|
|
8965
|
+
code: z.ZodIssueCode.custom,
|
|
8966
|
+
path: ["seed", i, "surface"],
|
|
8967
|
+
message: `seed '${seed.externalId}' uses surface '${seed.surface ?? "record"}', but schema '${seed.typeName}' allows only [${allowed.join(", ")}]`
|
|
8968
|
+
});
|
|
8969
|
+
}
|
|
8970
|
+
});
|
|
8971
|
+
}
|
|
8701
8972
|
var BlueprintSchema = z.object({
|
|
8702
8973
|
/** Stable blueprint id (the `--blueprint <name>` selector + idempotency key). */
|
|
8703
8974
|
name: z.string().min(1),
|
|
@@ -8720,6 +8991,7 @@ var BlueprintSchema = z.object({
|
|
|
8720
8991
|
}).strict().superRefine((bp, ctx) => {
|
|
8721
8992
|
lintSelfTokenPlacement(bp, ctx);
|
|
8722
8993
|
lintIdentityRefsDeclared(bp, ctx);
|
|
8994
|
+
lintSeedSurfaces(bp, ctx);
|
|
8723
8995
|
});
|
|
8724
8996
|
function formatIssuePath(path4) {
|
|
8725
8997
|
let out = "";
|
|
@@ -9117,6 +9389,7 @@ var taskManagement = {
|
|
|
9117
9389
|
},
|
|
9118
9390
|
seed: [
|
|
9119
9391
|
{
|
|
9392
|
+
surface: "record",
|
|
9120
9393
|
typeName: "task",
|
|
9121
9394
|
externalId: "seed-welcome",
|
|
9122
9395
|
fields: {
|
|
@@ -9344,6 +9617,7 @@ var codingAgentMemory = {
|
|
|
9344
9617
|
// Seeded FIRST so the convention below resolves its reference to it — the
|
|
9345
9618
|
// loader creates seeds in array order, and a reference target must exist when
|
|
9346
9619
|
// the referencing record is written.
|
|
9620
|
+
surface: "record",
|
|
9347
9621
|
typeName: "decision",
|
|
9348
9622
|
externalId: "seed-use-vectros-for-memory",
|
|
9349
9623
|
fields: {
|
|
@@ -9359,6 +9633,7 @@ var codingAgentMemory = {
|
|
|
9359
9633
|
// Demonstrates a live typed link at bootstrap: this convention references the
|
|
9360
9634
|
// decision above by its externalId, so "open the decision behind this rule"
|
|
9361
9635
|
// works the moment the blueprint is applied.
|
|
9636
|
+
surface: "record",
|
|
9362
9637
|
typeName: "convention",
|
|
9363
9638
|
externalId: "seed-record-the-why",
|
|
9364
9639
|
fields: {
|
|
@@ -9373,41 +9648,722 @@ var codingAgentMemory = {
|
|
|
9373
9648
|
]
|
|
9374
9649
|
};
|
|
9375
9650
|
var coding_agent_memory_default = codingAgentMemory;
|
|
9376
|
-
var
|
|
9377
|
-
name: "
|
|
9651
|
+
var agenticSdlc = {
|
|
9652
|
+
name: "agentic-sdlc",
|
|
9378
9653
|
version: "1.0.0",
|
|
9379
|
-
description: "A
|
|
9380
|
-
contextId: "
|
|
9381
|
-
contextName: "
|
|
9654
|
+
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.",
|
|
9655
|
+
contextId: "agentic-sdlc",
|
|
9656
|
+
contextName: "Agentic SDLC Knowledge Base",
|
|
9382
9657
|
schemas: [
|
|
9658
|
+
// ============================ DOCUMENTS ============================
|
|
9659
|
+
// Content-dominant: the markdown body is the artifact; fields are metadata.
|
|
9660
|
+
// Each binds the `document` surface and is ingested via `document_ingest`.
|
|
9383
9661
|
{
|
|
9384
|
-
|
|
9385
|
-
|
|
9662
|
+
// An architecture/product DECISION (an ADR). The body is the prose —
|
|
9663
|
+
// Context / Decision / Consequences — and is what `rag_ask` answers over;
|
|
9664
|
+
// the fields below are filter/sort metadata + the supersede chain. The
|
|
9665
|
+
// anchor of the graph: most other types link back to a decision.
|
|
9666
|
+
typeName: "decision",
|
|
9667
|
+
displayName: "Decision (ADR)",
|
|
9386
9668
|
indexMode: "HYBRID",
|
|
9387
|
-
|
|
9669
|
+
allowedSurfaces: ["document"],
|
|
9670
|
+
// A document carries an INTRINSIC title (the ingest title) + body; the schema
|
|
9671
|
+
// declares only the metadata BEYOND those. (No typed `title` field — that
|
|
9672
|
+
// would duplicate the document's own title.)
|
|
9388
9673
|
fields: [
|
|
9389
9674
|
{
|
|
9390
|
-
fieldId: "
|
|
9675
|
+
fieldId: "summary",
|
|
9391
9676
|
fieldType: "string",
|
|
9392
|
-
required: true,
|
|
9393
9677
|
searchable: true,
|
|
9394
|
-
|
|
9395
|
-
renderHints: { label: "
|
|
9678
|
+
description: "A one-paragraph abstract of the decision. The full reasoning is the document body.",
|
|
9679
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9396
9680
|
},
|
|
9397
9681
|
{
|
|
9398
|
-
fieldId: "
|
|
9682
|
+
fieldId: "status",
|
|
9683
|
+
fieldType: "enum",
|
|
9684
|
+
filterable: true,
|
|
9685
|
+
enumValues: ["proposed", "accepted", "superseded", "deprecated"],
|
|
9686
|
+
renderHints: { label: "Status", widget: "select", order: 3 }
|
|
9687
|
+
},
|
|
9688
|
+
{
|
|
9689
|
+
fieldId: "area",
|
|
9399
9690
|
fieldType: "string",
|
|
9400
|
-
|
|
9401
|
-
description:
|
|
9402
|
-
|
|
9403
|
-
renderHints: { label: "Body", widget: "textarea", order: 2, section: "Note" }
|
|
9691
|
+
filterable: true,
|
|
9692
|
+
description: 'Subsystem the decision applies to (e.g. "search", "auth", "billing").',
|
|
9693
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9404
9694
|
},
|
|
9405
9695
|
{
|
|
9406
9696
|
fieldId: "tags",
|
|
9407
9697
|
fieldType: "array",
|
|
9408
9698
|
filterable: true,
|
|
9409
|
-
description: 'Freeform
|
|
9410
|
-
renderHints: { label: "Tags", order:
|
|
9699
|
+
description: 'Freeform labels (e.g. "security", "schema"). Search-side filter.',
|
|
9700
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9701
|
+
},
|
|
9702
|
+
{
|
|
9703
|
+
// Self-reference (document → document): the decision this one supersedes.
|
|
9704
|
+
fieldId: "supersedes",
|
|
9705
|
+
fieldType: "reference",
|
|
9706
|
+
targetTypeName: "decision",
|
|
9707
|
+
targetSurface: "document",
|
|
9708
|
+
targetField: "externalId",
|
|
9709
|
+
cardinality: "one",
|
|
9710
|
+
description: "The decision this one supersedes (by externalId).",
|
|
9711
|
+
renderHints: { label: "Supersedes", order: 6 }
|
|
9712
|
+
},
|
|
9713
|
+
{
|
|
9714
|
+
fieldId: "date",
|
|
9715
|
+
fieldType: "date",
|
|
9716
|
+
description: "ISO-8601 decision date. Range-queryable / sortable.",
|
|
9717
|
+
renderHints: { label: "Date", widget: "date", order: 7 }
|
|
9718
|
+
}
|
|
9719
|
+
],
|
|
9720
|
+
lookupFields: ["status", "area", "supersedes", { fieldName: "date", rangeEnabled: true }]
|
|
9721
|
+
},
|
|
9722
|
+
{
|
|
9723
|
+
// A DESIGN doc or spec — the exploration that drives a decision. Distinct
|
|
9724
|
+
// from `decision` (a different browse genre + it links to the decision it
|
|
9725
|
+
// informs). Body = the design narrative.
|
|
9726
|
+
typeName: "design",
|
|
9727
|
+
displayName: "Design",
|
|
9728
|
+
indexMode: "HYBRID",
|
|
9729
|
+
allowedSurfaces: ["document"],
|
|
9730
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9731
|
+
fields: [
|
|
9732
|
+
{
|
|
9733
|
+
fieldId: "summary",
|
|
9734
|
+
fieldType: "string",
|
|
9735
|
+
searchable: true,
|
|
9736
|
+
description: "A one-paragraph abstract. The full design is the document body.",
|
|
9737
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9738
|
+
},
|
|
9739
|
+
{
|
|
9740
|
+
fieldId: "status",
|
|
9741
|
+
fieldType: "enum",
|
|
9742
|
+
filterable: true,
|
|
9743
|
+
enumValues: ["draft", "active", "implemented", "superseded"],
|
|
9744
|
+
renderHints: { label: "Status", widget: "select", order: 3 }
|
|
9745
|
+
},
|
|
9746
|
+
{
|
|
9747
|
+
fieldId: "area",
|
|
9748
|
+
fieldType: "string",
|
|
9749
|
+
filterable: true,
|
|
9750
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9751
|
+
},
|
|
9752
|
+
{
|
|
9753
|
+
fieldId: "tags",
|
|
9754
|
+
fieldType: "array",
|
|
9755
|
+
filterable: true,
|
|
9756
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9757
|
+
},
|
|
9758
|
+
{
|
|
9759
|
+
// Cross-document edge: the decision this design informs/produces.
|
|
9760
|
+
fieldId: "relatedDecision",
|
|
9761
|
+
fieldType: "reference",
|
|
9762
|
+
targetTypeName: "decision",
|
|
9763
|
+
targetSurface: "document",
|
|
9764
|
+
targetField: "externalId",
|
|
9765
|
+
cardinality: "one",
|
|
9766
|
+
description: "The decision this design informs (by externalId).",
|
|
9767
|
+
renderHints: { label: "Related decision", order: 6 }
|
|
9768
|
+
},
|
|
9769
|
+
{
|
|
9770
|
+
// Self-reference: a design supersedes an earlier design/spec.
|
|
9771
|
+
fieldId: "supersedes",
|
|
9772
|
+
fieldType: "reference",
|
|
9773
|
+
targetTypeName: "design",
|
|
9774
|
+
targetSurface: "document",
|
|
9775
|
+
targetField: "externalId",
|
|
9776
|
+
cardinality: "one",
|
|
9777
|
+
description: "The design this one supersedes (by externalId).",
|
|
9778
|
+
renderHints: { label: "Supersedes", order: 7 }
|
|
9779
|
+
},
|
|
9780
|
+
{
|
|
9781
|
+
fieldId: "updatedOn",
|
|
9782
|
+
fieldType: "date",
|
|
9783
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
9784
|
+
renderHints: { label: "Updated on", widget: "date", order: 8 }
|
|
9785
|
+
}
|
|
9786
|
+
],
|
|
9787
|
+
lookupFields: ["status", "area", "relatedDecision", "supersedes", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
9788
|
+
},
|
|
9789
|
+
{
|
|
9790
|
+
// A REFERENCE doc — maintained "how it works / how to": guides, onboarding,
|
|
9791
|
+
// API docs, process docs. Body = the prose. Distinct shape: a `category`
|
|
9792
|
+
// (DRY sub-labels — onboarding/api/process are same shape) and `lastReviewed`
|
|
9793
|
+
// (freshness is the whole game for reference material).
|
|
9794
|
+
typeName: "reference",
|
|
9795
|
+
displayName: "Reference",
|
|
9796
|
+
indexMode: "HYBRID",
|
|
9797
|
+
allowedSurfaces: ["document"],
|
|
9798
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9799
|
+
fields: [
|
|
9800
|
+
{
|
|
9801
|
+
fieldId: "summary",
|
|
9802
|
+
fieldType: "string",
|
|
9803
|
+
searchable: true,
|
|
9804
|
+
description: "A one-paragraph abstract. The full reference is the document body.",
|
|
9805
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9806
|
+
},
|
|
9807
|
+
{
|
|
9808
|
+
// The sub-kind, as a filterable field (not a separate schema — these are
|
|
9809
|
+
// the same shape, differing only by label, so a field is the DRY choice).
|
|
9810
|
+
fieldId: "category",
|
|
9811
|
+
fieldType: "enum",
|
|
9812
|
+
filterable: true,
|
|
9813
|
+
enumValues: ["guide", "onboarding", "api", "process", "other"],
|
|
9814
|
+
renderHints: { label: "Category", widget: "select", order: 3 }
|
|
9815
|
+
},
|
|
9816
|
+
{
|
|
9817
|
+
fieldId: "area",
|
|
9818
|
+
fieldType: "string",
|
|
9819
|
+
filterable: true,
|
|
9820
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
9821
|
+
},
|
|
9822
|
+
{
|
|
9823
|
+
fieldId: "tags",
|
|
9824
|
+
fieldType: "array",
|
|
9825
|
+
filterable: true,
|
|
9826
|
+
renderHints: { label: "Tags", order: 5 }
|
|
9827
|
+
},
|
|
9828
|
+
{
|
|
9829
|
+
fieldId: "status",
|
|
9830
|
+
fieldType: "enum",
|
|
9831
|
+
filterable: true,
|
|
9832
|
+
enumValues: ["active", "superseded"],
|
|
9833
|
+
renderHints: { label: "Status", widget: "select", order: 6 }
|
|
9834
|
+
},
|
|
9835
|
+
{
|
|
9836
|
+
// Optional cross-document edge: the decision behind this reference.
|
|
9837
|
+
fieldId: "relatedDecision",
|
|
9838
|
+
fieldType: "reference",
|
|
9839
|
+
targetTypeName: "decision",
|
|
9840
|
+
targetSurface: "document",
|
|
9841
|
+
targetField: "externalId",
|
|
9842
|
+
cardinality: "one",
|
|
9843
|
+
description: "The decision behind this reference, if any (by externalId).",
|
|
9844
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9845
|
+
},
|
|
9846
|
+
{
|
|
9847
|
+
// Freshness — "references not reviewed since X". The reference-doc signal.
|
|
9848
|
+
fieldId: "lastReviewed",
|
|
9849
|
+
fieldType: "date",
|
|
9850
|
+
description: "ISO-8601 \u2014 when this reference was last verified current. Range-queryable.",
|
|
9851
|
+
renderHints: { label: "Last reviewed", widget: "date", order: 8 }
|
|
9852
|
+
}
|
|
9853
|
+
],
|
|
9854
|
+
lookupFields: ["category", "area", "status", "relatedDecision", { fieldName: "lastReviewed", rangeEnabled: true }]
|
|
9855
|
+
},
|
|
9856
|
+
{
|
|
9857
|
+
// A RUNBOOK — a step-by-step operational procedure (deploy, release, recover).
|
|
9858
|
+
// Body = the procedure. Distinct browse genre, and often BORN FROM a
|
|
9859
|
+
// post-mortem (its resolution, codified) — a cross-document edge.
|
|
9860
|
+
typeName: "runbook",
|
|
9861
|
+
displayName: "Runbook",
|
|
9862
|
+
indexMode: "HYBRID",
|
|
9863
|
+
allowedSurfaces: ["document"],
|
|
9864
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9865
|
+
fields: [
|
|
9866
|
+
{
|
|
9867
|
+
fieldId: "summary",
|
|
9868
|
+
fieldType: "string",
|
|
9869
|
+
searchable: true,
|
|
9870
|
+
description: "When to use this runbook \u2014 the trigger. The steps are the document body.",
|
|
9871
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9872
|
+
},
|
|
9873
|
+
{
|
|
9874
|
+
fieldId: "area",
|
|
9875
|
+
fieldType: "string",
|
|
9876
|
+
filterable: true,
|
|
9877
|
+
renderHints: { label: "Area", widget: "text", order: 3 }
|
|
9878
|
+
},
|
|
9879
|
+
{
|
|
9880
|
+
fieldId: "tags",
|
|
9881
|
+
fieldType: "array",
|
|
9882
|
+
filterable: true,
|
|
9883
|
+
renderHints: { label: "Tags", order: 4 }
|
|
9884
|
+
},
|
|
9885
|
+
{
|
|
9886
|
+
fieldId: "status",
|
|
9887
|
+
fieldType: "enum",
|
|
9888
|
+
filterable: true,
|
|
9889
|
+
enumValues: ["active", "retired"],
|
|
9890
|
+
renderHints: { label: "Status", widget: "select", order: 5 }
|
|
9891
|
+
},
|
|
9892
|
+
{
|
|
9893
|
+
// Cross-document edge: the post-mortem whose resolution this runbook codifies.
|
|
9894
|
+
fieldId: "bornFrom",
|
|
9895
|
+
fieldType: "reference",
|
|
9896
|
+
targetTypeName: "postmortem",
|
|
9897
|
+
targetSurface: "document",
|
|
9898
|
+
targetField: "externalId",
|
|
9899
|
+
cardinality: "one",
|
|
9900
|
+
description: "The post-mortem this runbook was codified from (by externalId).",
|
|
9901
|
+
renderHints: { label: "Born from (post-mortem)", order: 6 }
|
|
9902
|
+
},
|
|
9903
|
+
{
|
|
9904
|
+
fieldId: "relatedDecision",
|
|
9905
|
+
fieldType: "reference",
|
|
9906
|
+
targetTypeName: "decision",
|
|
9907
|
+
targetSurface: "document",
|
|
9908
|
+
targetField: "externalId",
|
|
9909
|
+
cardinality: "one",
|
|
9910
|
+
description: "A decision this runbook implements, if any (by externalId).",
|
|
9911
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9912
|
+
},
|
|
9913
|
+
{
|
|
9914
|
+
fieldId: "updatedOn",
|
|
9915
|
+
fieldType: "date",
|
|
9916
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
9917
|
+
renderHints: { label: "Updated on", widget: "date", order: 8 }
|
|
9918
|
+
}
|
|
9919
|
+
],
|
|
9920
|
+
lookupFields: ["area", "status", "bornFrom", "relatedDecision", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
9921
|
+
},
|
|
9922
|
+
{
|
|
9923
|
+
// A POST-MORTEM — what broke and the durable lesson. Body = the writeup
|
|
9924
|
+
// (impact / root cause / resolution / lesson). Distinct shape: `severity` +
|
|
9925
|
+
// `occurredOn` (the incident timeline). "Have we hit this before?" lives here.
|
|
9926
|
+
typeName: "postmortem",
|
|
9927
|
+
displayName: "Post-mortem",
|
|
9928
|
+
indexMode: "HYBRID",
|
|
9929
|
+
allowedSurfaces: ["document"],
|
|
9930
|
+
// Intrinsic title + body; schema = metadata beyond those (no typed `title`).
|
|
9931
|
+
fields: [
|
|
9932
|
+
{
|
|
9933
|
+
fieldId: "summary",
|
|
9934
|
+
fieldType: "string",
|
|
9935
|
+
searchable: true,
|
|
9936
|
+
description: "What happened, in brief. The full analysis (impact/root cause/resolution/lesson) is the body.",
|
|
9937
|
+
renderHints: { label: "Summary", widget: "textarea", order: 2 }
|
|
9938
|
+
},
|
|
9939
|
+
{
|
|
9940
|
+
fieldId: "severity",
|
|
9941
|
+
fieldType: "enum",
|
|
9942
|
+
filterable: true,
|
|
9943
|
+
enumValues: ["low", "medium", "high", "critical"],
|
|
9944
|
+
renderHints: { label: "Severity", widget: "select", order: 3 }
|
|
9945
|
+
},
|
|
9946
|
+
{
|
|
9947
|
+
fieldId: "status",
|
|
9948
|
+
fieldType: "enum",
|
|
9949
|
+
filterable: true,
|
|
9950
|
+
enumValues: ["open", "mitigated", "resolved"],
|
|
9951
|
+
renderHints: { label: "Status", widget: "select", order: 4 }
|
|
9952
|
+
},
|
|
9953
|
+
{
|
|
9954
|
+
fieldId: "area",
|
|
9955
|
+
fieldType: "string",
|
|
9956
|
+
filterable: true,
|
|
9957
|
+
renderHints: { label: "Area", widget: "text", order: 5 }
|
|
9958
|
+
},
|
|
9959
|
+
{
|
|
9960
|
+
fieldId: "tags",
|
|
9961
|
+
fieldType: "array",
|
|
9962
|
+
filterable: true,
|
|
9963
|
+
renderHints: { label: "Tags", order: 6 }
|
|
9964
|
+
},
|
|
9965
|
+
{
|
|
9966
|
+
fieldId: "relatedDecision",
|
|
9967
|
+
fieldType: "reference",
|
|
9968
|
+
targetTypeName: "decision",
|
|
9969
|
+
targetSurface: "document",
|
|
9970
|
+
targetField: "externalId",
|
|
9971
|
+
cardinality: "one",
|
|
9972
|
+
description: "A decision implicated in or addressed by this incident (by externalId).",
|
|
9973
|
+
renderHints: { label: "Related decision", order: 7 }
|
|
9974
|
+
},
|
|
9975
|
+
{
|
|
9976
|
+
fieldId: "occurredOn",
|
|
9977
|
+
fieldType: "date",
|
|
9978
|
+
description: 'ISO-8601 \u2014 when it happened. Range-queryable \u2014 "incidents this month".',
|
|
9979
|
+
renderHints: { label: "Occurred on", widget: "date", order: 8 }
|
|
9980
|
+
}
|
|
9981
|
+
],
|
|
9982
|
+
lookupFields: ["severity", "status", "area", "relatedDecision", { fieldName: "occurredOn", rangeEnabled: true }]
|
|
9983
|
+
},
|
|
9984
|
+
// ============================= RECORDS =============================
|
|
9985
|
+
// Structure-dominant: the typed fields are the artifact. Short, exact-queryable.
|
|
9986
|
+
{
|
|
9987
|
+
// A governance CONTROL — a policy/standard/control the codebase must satisfy,
|
|
9988
|
+
// WITH its evidence. The compliance instrument: it records what enforces it
|
|
9989
|
+
// (`evidence`), the runbook that VERIFIES it (cross-surface → document), and
|
|
9990
|
+
// the decision that mandates it. "Which critical controls are active, and how
|
|
9991
|
+
// is each proven?"
|
|
9992
|
+
typeName: "control",
|
|
9993
|
+
displayName: "Control",
|
|
9994
|
+
indexMode: "HYBRID",
|
|
9995
|
+
fields: [
|
|
9996
|
+
{
|
|
9997
|
+
fieldId: "title",
|
|
9998
|
+
fieldType: "string",
|
|
9999
|
+
required: true,
|
|
10000
|
+
searchable: true,
|
|
10001
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10002
|
+
renderHints: { label: "Title", widget: "text", order: 1, displayField: true }
|
|
10003
|
+
},
|
|
10004
|
+
{
|
|
10005
|
+
fieldId: "statement",
|
|
10006
|
+
fieldType: "string",
|
|
10007
|
+
searchable: true,
|
|
10008
|
+
description: "The requirement \u2014 what must always hold.",
|
|
10009
|
+
renderHints: { label: "Statement", widget: "textarea", order: 2 }
|
|
10010
|
+
},
|
|
10011
|
+
{
|
|
10012
|
+
fieldId: "rationale",
|
|
10013
|
+
fieldType: "string",
|
|
10014
|
+
searchable: true,
|
|
10015
|
+
description: "Why the control exists \u2014 the risk it prevents.",
|
|
10016
|
+
renderHints: { label: "Rationale", widget: "textarea", order: 3 }
|
|
10017
|
+
},
|
|
10018
|
+
{
|
|
10019
|
+
// The policy → implementation spectrum in one filterable field.
|
|
10020
|
+
fieldId: "kind",
|
|
10021
|
+
fieldType: "enum",
|
|
10022
|
+
filterable: true,
|
|
10023
|
+
enumValues: ["policy", "standard", "control"],
|
|
10024
|
+
renderHints: { label: "Kind", widget: "select", order: 4 }
|
|
10025
|
+
},
|
|
10026
|
+
{
|
|
10027
|
+
// Ordinal, but EQUALITY (range/prefix order is lexical, so low<critical
|
|
10028
|
+
// would sort alphabetically). Enumerate "all critical controls" by equality.
|
|
10029
|
+
fieldId: "criticality",
|
|
10030
|
+
fieldType: "enum",
|
|
10031
|
+
filterable: true,
|
|
10032
|
+
enumValues: ["low", "medium", "high", "critical"],
|
|
10033
|
+
renderHints: { label: "Criticality", widget: "select", order: 5 }
|
|
10034
|
+
},
|
|
10035
|
+
{
|
|
10036
|
+
fieldId: "evidence",
|
|
10037
|
+
fieldType: "string",
|
|
10038
|
+
searchable: true,
|
|
10039
|
+
description: "What enforces or proves the control inline (e.g. an architecture test or gate).",
|
|
10040
|
+
renderHints: { label: "Evidence", widget: "textarea", order: 6 }
|
|
10041
|
+
},
|
|
10042
|
+
{
|
|
10043
|
+
fieldId: "status",
|
|
10044
|
+
fieldType: "enum",
|
|
10045
|
+
filterable: true,
|
|
10046
|
+
enumValues: ["draft", "active", "retired"],
|
|
10047
|
+
renderHints: { label: "Status", widget: "select", order: 7 }
|
|
10048
|
+
},
|
|
10049
|
+
{
|
|
10050
|
+
fieldId: "area",
|
|
10051
|
+
fieldType: "string",
|
|
10052
|
+
filterable: true,
|
|
10053
|
+
renderHints: { label: "Area", widget: "text", order: 8 }
|
|
10054
|
+
},
|
|
10055
|
+
{
|
|
10056
|
+
fieldId: "tags",
|
|
10057
|
+
fieldType: "array",
|
|
10058
|
+
filterable: true,
|
|
10059
|
+
renderHints: { label: "Tags", order: 9 }
|
|
10060
|
+
},
|
|
10061
|
+
{
|
|
10062
|
+
// Cross-surface edge (record → document): the runbook that proves the control.
|
|
10063
|
+
fieldId: "verifiedBy",
|
|
10064
|
+
fieldType: "reference",
|
|
10065
|
+
targetTypeName: "runbook",
|
|
10066
|
+
targetSurface: "document",
|
|
10067
|
+
targetField: "externalId",
|
|
10068
|
+
cardinality: "one",
|
|
10069
|
+
description: "The runbook that verifies this control (by externalId).",
|
|
10070
|
+
renderHints: { label: "Verified by (runbook)", order: 10 }
|
|
10071
|
+
},
|
|
10072
|
+
{
|
|
10073
|
+
// Cross-surface edge (record → document): the decision that mandates it.
|
|
10074
|
+
fieldId: "relatedDecision",
|
|
10075
|
+
fieldType: "reference",
|
|
10076
|
+
targetTypeName: "decision",
|
|
10077
|
+
targetSurface: "document",
|
|
10078
|
+
targetField: "externalId",
|
|
10079
|
+
cardinality: "one",
|
|
10080
|
+
description: "The decision that mandates this control (by externalId).",
|
|
10081
|
+
renderHints: { label: "Related decision", order: 11 }
|
|
10082
|
+
},
|
|
10083
|
+
{
|
|
10084
|
+
fieldId: "reviewedOn",
|
|
10085
|
+
fieldType: "date",
|
|
10086
|
+
description: "ISO-8601 last-reviewed date. Range-queryable.",
|
|
10087
|
+
renderHints: { label: "Reviewed on", widget: "date", order: 12 }
|
|
10088
|
+
}
|
|
10089
|
+
],
|
|
10090
|
+
lookupFields: [
|
|
10091
|
+
"kind",
|
|
10092
|
+
"criticality",
|
|
10093
|
+
"status",
|
|
10094
|
+
"area",
|
|
10095
|
+
"verifiedBy",
|
|
10096
|
+
"relatedDecision",
|
|
10097
|
+
{ fieldName: "reviewedOn", rangeEnabled: true }
|
|
10098
|
+
]
|
|
10099
|
+
},
|
|
10100
|
+
{
|
|
10101
|
+
// A CONVENTION — a must-follow operating rule the team teaches its agents. The
|
|
10102
|
+
// durable, shareable operating-memory. Distinct fields capture how we actually
|
|
10103
|
+
// write these: the `rule` (imperative), the `why` (rationale), and `howToApply`
|
|
10104
|
+
// (the concrete application) are SEPARATE fields, not one blob — so an agent can
|
|
10105
|
+
// recall the rule, the reasoning, and the how independently.
|
|
10106
|
+
typeName: "convention",
|
|
10107
|
+
displayName: "Convention",
|
|
10108
|
+
indexMode: "HYBRID",
|
|
10109
|
+
fields: [
|
|
10110
|
+
{
|
|
10111
|
+
fieldId: "title",
|
|
10112
|
+
fieldType: "string",
|
|
10113
|
+
required: true,
|
|
10114
|
+
searchable: true,
|
|
10115
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10116
|
+
renderHints: { label: "Title", widget: "text", order: 1, displayField: true }
|
|
10117
|
+
},
|
|
10118
|
+
{
|
|
10119
|
+
fieldId: "rule",
|
|
10120
|
+
fieldType: "string",
|
|
10121
|
+
searchable: true,
|
|
10122
|
+
description: "The convention itself, stated as an imperative.",
|
|
10123
|
+
renderHints: { label: "Rule", widget: "textarea", order: 2 }
|
|
10124
|
+
},
|
|
10125
|
+
{
|
|
10126
|
+
fieldId: "why",
|
|
10127
|
+
fieldType: "string",
|
|
10128
|
+
searchable: true,
|
|
10129
|
+
description: "Why it matters \u2014 the trade-off / the antipattern it prevents.",
|
|
10130
|
+
renderHints: { label: "Why", widget: "textarea", order: 3 }
|
|
10131
|
+
},
|
|
10132
|
+
{
|
|
10133
|
+
fieldId: "howToApply",
|
|
10134
|
+
fieldType: "string",
|
|
10135
|
+
searchable: true,
|
|
10136
|
+
description: "How to comply in practice \u2014 the concrete application steps.",
|
|
10137
|
+
renderHints: { label: "How to apply", widget: "textarea", order: 4 }
|
|
10138
|
+
},
|
|
10139
|
+
{
|
|
10140
|
+
fieldId: "area",
|
|
10141
|
+
fieldType: "string",
|
|
10142
|
+
filterable: true,
|
|
10143
|
+
renderHints: { label: "Area", widget: "text", order: 5 }
|
|
10144
|
+
},
|
|
10145
|
+
{
|
|
10146
|
+
fieldId: "status",
|
|
10147
|
+
fieldType: "enum",
|
|
10148
|
+
filterable: true,
|
|
10149
|
+
enumValues: ["active", "retired"],
|
|
10150
|
+
renderHints: { label: "Status", widget: "select", order: 6 }
|
|
10151
|
+
},
|
|
10152
|
+
{
|
|
10153
|
+
fieldId: "tags",
|
|
10154
|
+
fieldType: "array",
|
|
10155
|
+
filterable: true,
|
|
10156
|
+
renderHints: { label: "Tags", order: 7 }
|
|
10157
|
+
},
|
|
10158
|
+
{
|
|
10159
|
+
// Cross-surface edge (record → document): the decision that established it.
|
|
10160
|
+
fieldId: "establishedBy",
|
|
10161
|
+
fieldType: "reference",
|
|
10162
|
+
targetTypeName: "decision",
|
|
10163
|
+
targetSurface: "document",
|
|
10164
|
+
targetField: "externalId",
|
|
10165
|
+
cardinality: "one",
|
|
10166
|
+
description: "The decision that established this convention (by externalId).",
|
|
10167
|
+
renderHints: { label: "Established by (decision)", order: 8 }
|
|
10168
|
+
},
|
|
10169
|
+
{
|
|
10170
|
+
fieldId: "updatedOn",
|
|
10171
|
+
fieldType: "date",
|
|
10172
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
10173
|
+
renderHints: { label: "Updated on", widget: "date", order: 9 }
|
|
10174
|
+
}
|
|
10175
|
+
],
|
|
10176
|
+
lookupFields: ["area", "status", "establishedBy", { fieldName: "updatedOn", rangeEnabled: true }]
|
|
10177
|
+
},
|
|
10178
|
+
{
|
|
10179
|
+
// A GOTCHA / sharp edge: a symptom, its cause, and the fix. A tight typed
|
|
10180
|
+
// triple — found by meaning (semantic search on the symptom) + area/status.
|
|
10181
|
+
// The most standalone type; no typed edge.
|
|
10182
|
+
typeName: "gotcha",
|
|
10183
|
+
displayName: "Gotcha",
|
|
10184
|
+
indexMode: "HYBRID",
|
|
10185
|
+
fields: [
|
|
10186
|
+
{
|
|
10187
|
+
fieldId: "symptom",
|
|
10188
|
+
fieldType: "string",
|
|
10189
|
+
required: true,
|
|
10190
|
+
searchable: true,
|
|
10191
|
+
validation: { minLength: 1, maxLength: 500 },
|
|
10192
|
+
renderHints: { label: "Symptom", widget: "textarea", order: 1, displayField: true }
|
|
10193
|
+
},
|
|
10194
|
+
{
|
|
10195
|
+
fieldId: "cause",
|
|
10196
|
+
fieldType: "string",
|
|
10197
|
+
searchable: true,
|
|
10198
|
+
renderHints: { label: "Cause", widget: "textarea", order: 2 }
|
|
10199
|
+
},
|
|
10200
|
+
{
|
|
10201
|
+
fieldId: "fix",
|
|
10202
|
+
fieldType: "string",
|
|
10203
|
+
searchable: true,
|
|
10204
|
+
renderHints: { label: "Fix", widget: "textarea", order: 3 }
|
|
10205
|
+
},
|
|
10206
|
+
{
|
|
10207
|
+
fieldId: "area",
|
|
10208
|
+
fieldType: "string",
|
|
10209
|
+
filterable: true,
|
|
10210
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
10211
|
+
},
|
|
10212
|
+
{
|
|
10213
|
+
fieldId: "status",
|
|
10214
|
+
fieldType: "enum",
|
|
10215
|
+
filterable: true,
|
|
10216
|
+
enumValues: ["active", "resolved"],
|
|
10217
|
+
renderHints: { label: "Status", widget: "select", order: 5 }
|
|
10218
|
+
},
|
|
10219
|
+
{
|
|
10220
|
+
fieldId: "tags",
|
|
10221
|
+
fieldType: "array",
|
|
10222
|
+
filterable: true,
|
|
10223
|
+
renderHints: { label: "Tags", order: 6 }
|
|
10224
|
+
},
|
|
10225
|
+
{
|
|
10226
|
+
fieldId: "discoveredOn",
|
|
10227
|
+
fieldType: "date",
|
|
10228
|
+
description: "ISO-8601 \u2014 when first hit. Range-queryable.",
|
|
10229
|
+
renderHints: { label: "Discovered on", widget: "date", order: 7 }
|
|
10230
|
+
}
|
|
10231
|
+
],
|
|
10232
|
+
lookupFields: ["area", "status", { fieldName: "discoveredOn", rangeEnabled: true }]
|
|
10233
|
+
},
|
|
10234
|
+
{
|
|
10235
|
+
// A glossary TERM — a definition keyed by the term itself. Structure-dominant:
|
|
10236
|
+
// `term` is a UNIQUE exact-lookup key (the showcase of a uniqueness constraint),
|
|
10237
|
+
// `definition` is the RAG body, `aliases` catch alternate names. Links to the
|
|
10238
|
+
// decision that defines/establishes the concept where there is one.
|
|
10239
|
+
typeName: "term",
|
|
10240
|
+
displayName: "Glossary term",
|
|
10241
|
+
indexMode: "HYBRID",
|
|
10242
|
+
fields: [
|
|
10243
|
+
{
|
|
10244
|
+
fieldId: "term",
|
|
10245
|
+
fieldType: "string",
|
|
10246
|
+
required: true,
|
|
10247
|
+
searchable: true,
|
|
10248
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10249
|
+
renderHints: { label: "Term", widget: "text", order: 1, displayField: true }
|
|
10250
|
+
},
|
|
10251
|
+
{
|
|
10252
|
+
fieldId: "definition",
|
|
10253
|
+
fieldType: "string",
|
|
10254
|
+
searchable: true,
|
|
10255
|
+
description: "What the term means \u2014 the RAG-able body.",
|
|
10256
|
+
renderHints: { label: "Definition", widget: "textarea", order: 2 }
|
|
10257
|
+
},
|
|
10258
|
+
{
|
|
10259
|
+
fieldId: "aliases",
|
|
10260
|
+
fieldType: "array",
|
|
10261
|
+
filterable: true,
|
|
10262
|
+
description: "Alternate names / abbreviations for the same concept.",
|
|
10263
|
+
renderHints: { label: "Aliases", order: 3 }
|
|
10264
|
+
},
|
|
10265
|
+
{
|
|
10266
|
+
fieldId: "area",
|
|
10267
|
+
fieldType: "string",
|
|
10268
|
+
filterable: true,
|
|
10269
|
+
renderHints: { label: "Area", widget: "text", order: 4 }
|
|
10270
|
+
},
|
|
10271
|
+
{
|
|
10272
|
+
fieldId: "tags",
|
|
10273
|
+
fieldType: "array",
|
|
10274
|
+
filterable: true,
|
|
10275
|
+
renderHints: { label: "Tags", order: 5 }
|
|
10276
|
+
},
|
|
10277
|
+
{
|
|
10278
|
+
fieldId: "relatedDecision",
|
|
10279
|
+
fieldType: "reference",
|
|
10280
|
+
targetTypeName: "decision",
|
|
10281
|
+
targetSurface: "document",
|
|
10282
|
+
targetField: "externalId",
|
|
10283
|
+
cardinality: "one",
|
|
10284
|
+
description: "A decision that defines or establishes this term (by externalId).",
|
|
10285
|
+
renderHints: { label: "Related decision", order: 6 }
|
|
10286
|
+
},
|
|
10287
|
+
{
|
|
10288
|
+
fieldId: "updatedOn",
|
|
10289
|
+
fieldType: "date",
|
|
10290
|
+
description: "ISO-8601 \u2014 when last revised. Range-queryable.",
|
|
10291
|
+
renderHints: { label: "Updated on", widget: "date", order: 7 }
|
|
10292
|
+
}
|
|
10293
|
+
],
|
|
10294
|
+
// `term` is a UNIQUE equality lookup — exact "define X" + a one-per-term
|
|
10295
|
+
// guarantee. `area`/`relatedDecision` enumerate; `updatedOn` is the range row.
|
|
10296
|
+
lookupFields: [
|
|
10297
|
+
{ fieldName: "term", unique: true },
|
|
10298
|
+
"area",
|
|
10299
|
+
"relatedDecision",
|
|
10300
|
+
{ fieldName: "updatedOn", rangeEnabled: true }
|
|
10301
|
+
]
|
|
10302
|
+
}
|
|
10303
|
+
],
|
|
10304
|
+
// Least-privilege, data-plane only. r/c/u records + search + schema discovery +
|
|
10305
|
+
// inference:r (grounded recall over the document bodies) + document/folder r/c
|
|
10306
|
+
// (the content artifacts are documents). NO :d — knowledge is superseded/retired
|
|
10307
|
+
// via a status flip, so the trail of how the team's thinking evolved stays intact.
|
|
10308
|
+
accessProfile: {
|
|
10309
|
+
allowedActions: [
|
|
10310
|
+
"records:r",
|
|
10311
|
+
"records:c",
|
|
10312
|
+
"records:u",
|
|
10313
|
+
"search:r",
|
|
10314
|
+
"schemas:r",
|
|
10315
|
+
"inference:r",
|
|
10316
|
+
"documents:r",
|
|
10317
|
+
"documents:c",
|
|
10318
|
+
"folders:r",
|
|
10319
|
+
"folders:c"
|
|
10320
|
+
]
|
|
10321
|
+
},
|
|
10322
|
+
servicePrincipal: {
|
|
10323
|
+
externalId: "agentic-sdlc",
|
|
10324
|
+
displayName: "Agentic SDLC Knowledge Base"
|
|
10325
|
+
}
|
|
10326
|
+
// No bundled seed in this version: the content artifacts live on the document
|
|
10327
|
+
// surface and the cross-surface graph is populated by the ingest agent
|
|
10328
|
+
// (document_ingest / record_create), not the bootstrap seed step. Production
|
|
10329
|
+
// contexts provision with `vectros bootstrap --no-seed` regardless.
|
|
10330
|
+
};
|
|
10331
|
+
var agentic_sdlc_default = agenticSdlc;
|
|
10332
|
+
var secondBrain = {
|
|
10333
|
+
name: "second-brain",
|
|
10334
|
+
version: "1.0.0",
|
|
10335
|
+
description: "A personal knowledge base \u2014 capture notes, ideas, and links, then ask them anything.",
|
|
10336
|
+
contextId: "second-brain",
|
|
10337
|
+
contextName: "Second Brain",
|
|
10338
|
+
schemas: [
|
|
10339
|
+
{
|
|
10340
|
+
typeName: "note",
|
|
10341
|
+
displayName: "Note",
|
|
10342
|
+
indexMode: "HYBRID",
|
|
10343
|
+
// keyword on title + semantic on body — recall by meaning
|
|
10344
|
+
fields: [
|
|
10345
|
+
{
|
|
10346
|
+
fieldId: "title",
|
|
10347
|
+
fieldType: "string",
|
|
10348
|
+
required: true,
|
|
10349
|
+
searchable: true,
|
|
10350
|
+
validation: { minLength: 1, maxLength: 200 },
|
|
10351
|
+
renderHints: { label: "Title", widget: "text", order: 1, section: "Note", displayField: true }
|
|
10352
|
+
},
|
|
10353
|
+
{
|
|
10354
|
+
fieldId: "body",
|
|
10355
|
+
fieldType: "string",
|
|
10356
|
+
searchable: true,
|
|
10357
|
+
description: "The note itself \u2014 the RAG-able body you ask questions against.",
|
|
10358
|
+
validation: { maxLength: 2e4 },
|
|
10359
|
+
renderHints: { label: "Body", widget: "textarea", order: 2, section: "Note" }
|
|
10360
|
+
},
|
|
10361
|
+
{
|
|
10362
|
+
fieldId: "tags",
|
|
10363
|
+
fieldType: "array",
|
|
10364
|
+
filterable: true,
|
|
10365
|
+
description: 'Freeform string labels for filtering (e.g. "idea", "reading", "work").',
|
|
10366
|
+
renderHints: { label: "Tags", order: 3, section: "Organize" }
|
|
9411
10367
|
},
|
|
9412
10368
|
{
|
|
9413
10369
|
// An enum (not freeform) so enumeration-by-source is reliable — a
|
|
@@ -9468,6 +10424,7 @@ var secondBrain = {
|
|
|
9468
10424
|
},
|
|
9469
10425
|
seed: [
|
|
9470
10426
|
{
|
|
10427
|
+
surface: "record",
|
|
9471
10428
|
typeName: "note",
|
|
9472
10429
|
externalId: "seed-welcome",
|
|
9473
10430
|
fields: {
|
|
@@ -9599,6 +10556,7 @@ var clinicalIntake = {
|
|
|
9599
10556
|
},
|
|
9600
10557
|
seed: [
|
|
9601
10558
|
{
|
|
10559
|
+
surface: "record",
|
|
9602
10560
|
typeName: "intake",
|
|
9603
10561
|
externalId: "seed-synthetic-intake",
|
|
9604
10562
|
fields: {
|
|
@@ -9620,6 +10578,7 @@ var clinical_intake_default = clinicalIntake;
|
|
|
9620
10578
|
var BUNDLED_BLUEPRINTS = [
|
|
9621
10579
|
task_management_default,
|
|
9622
10580
|
coding_agent_memory_default,
|
|
10581
|
+
agentic_sdlc_default,
|
|
9623
10582
|
second_brain_default,
|
|
9624
10583
|
clinical_intake_default
|
|
9625
10584
|
];
|
|
@@ -10057,7 +11016,8 @@ async function resolveCognitoToken(env, explicit) {
|
|
|
10057
11016
|
async function resolveAuthContext(opts) {
|
|
10058
11017
|
const baseUrl = envToBaseUrl(opts.env, opts.baseUrl ?? process.env.VECTROS_API_BASE_URL);
|
|
10059
11018
|
const cognitoToken = await resolveCognitoToken(opts.env, opts.token);
|
|
10060
|
-
const
|
|
11019
|
+
const tenant = opts.tenant ?? "live";
|
|
11020
|
+
const bridge = opts.provisioning ? await mintBridgeToken({ cognitoToken, apiBaseUrl: baseUrl, tenant }) : await mintContextToken({ cognitoToken, apiBaseUrl: baseUrl, contextId: opts.context ?? "default", tenant });
|
|
10061
11021
|
const client = new VectrosClient({ token: bridge.token, environment: baseUrl });
|
|
10062
11022
|
const identity = await resolveIdentity({ log: opts.log, apiKey: bridge.token, environment: baseUrl });
|
|
10063
11023
|
return {
|
|
@@ -10067,7 +11027,8 @@ async function resolveAuthContext(opts) {
|
|
|
10067
11027
|
baseUrl,
|
|
10068
11028
|
env: opts.env,
|
|
10069
11029
|
identity,
|
|
10070
|
-
tenantId: typeof identity.tenantId === "string" ? identity.tenantId : void 0
|
|
11030
|
+
tenantId: typeof identity.tenantId === "string" ? identity.tenantId : void 0,
|
|
11031
|
+
tenant
|
|
10071
11032
|
};
|
|
10072
11033
|
}
|
|
10073
11034
|
|
|
@@ -10391,54 +11352,23 @@ function assertNoUnresolvedIdentities(blueprint) {
|
|
|
10391
11352
|
);
|
|
10392
11353
|
}
|
|
10393
11354
|
}
|
|
10394
|
-
var SchemaReconcileError = class extends Error {
|
|
10395
|
-
constructor(typeName, cause) {
|
|
10396
|
-
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
10397
|
-
super(
|
|
10398
|
-
`Schema '${typeName}' already exists but could not be reconciled to the blueprint: ${detail}
|
|
10399
|
-
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.`
|
|
10400
|
-
);
|
|
10401
|
-
this.name = "SchemaReconcileError";
|
|
10402
|
-
}
|
|
10403
|
-
};
|
|
10404
|
-
function isAlreadyExistsError(e) {
|
|
10405
|
-
if (typeof e !== "object" || e === null) return false;
|
|
10406
|
-
const err = e;
|
|
10407
|
-
const status = err.statusCode;
|
|
10408
|
-
const text = `${err.message ?? ""} ${err.body?.message ?? ""}`.toLowerCase();
|
|
10409
|
-
return (status === 409 || status === 400) && text.includes("already exists");
|
|
10410
|
-
}
|
|
10411
|
-
async function findExistingSchemaId(client, typeName, owner) {
|
|
10412
|
-
let startFrom;
|
|
10413
|
-
for (; ; ) {
|
|
10414
|
-
const page = await client.schemas.listSchemas({
|
|
10415
|
-
userId: owner.userId,
|
|
10416
|
-
orgId: owner.orgId,
|
|
10417
|
-
limit: 100,
|
|
10418
|
-
startFrom
|
|
10419
|
-
});
|
|
10420
|
-
const match = (page.data ?? []).find((s) => s.typeName === typeName);
|
|
10421
|
-
if (match?.id) return match.id;
|
|
10422
|
-
const next = page.nextCursor;
|
|
10423
|
-
if (!next) return void 0;
|
|
10424
|
-
startFrom = next;
|
|
10425
|
-
}
|
|
10426
|
-
}
|
|
10427
11355
|
async function runLoader(client, input) {
|
|
10428
|
-
const { blueprint, tenantId, machineId, rotate = false, vectrosDir, log } = input;
|
|
11356
|
+
const { blueprint, tenantId, machineId, rotate = false, skipSeed = false, vectrosDir, log } = input;
|
|
10429
11357
|
assertScopeGate(blueprint.accessProfile.allowedActions);
|
|
10430
11358
|
for (const clauses of Object.values(blueprint.roles ?? {})) {
|
|
10431
11359
|
for (const clause of clauses) assertScopeGate(clause.allowedActions);
|
|
10432
11360
|
}
|
|
10433
11361
|
assertNoUnresolvedIdentities(blueprint);
|
|
10434
|
-
await client.auth.createAppContext({ contextId: blueprint.contextId, name: contextNameOf(blueprint) });
|
|
11362
|
+
await client.auth.createAppContext({ body: { contextId: blueprint.contextId, name: contextNameOf(blueprint) } });
|
|
10435
11363
|
log.debug({ component: "loader", contextId: blueprint.contextId }, "app-context ensured");
|
|
10436
11364
|
const user = await client.identity.createUser({
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
11365
|
+
body: {
|
|
11366
|
+
externalId: blueprint.servicePrincipal.externalId,
|
|
11367
|
+
type: "SERVICE",
|
|
11368
|
+
// SDK 0.18+ (identity-access rework): UserRequest's free-form attribute bag
|
|
11369
|
+
// was renamed `metadata` → `payload`. Same semantics (arbitrary key/value).
|
|
11370
|
+
payload: { displayName: blueprint.servicePrincipal.displayName }
|
|
11371
|
+
}
|
|
10442
11372
|
});
|
|
10443
11373
|
const userId = user.id;
|
|
10444
11374
|
if (!userId) {
|
|
@@ -10473,23 +11403,9 @@ async function runLoader(client, input) {
|
|
|
10473
11403
|
orgId: s.orgId,
|
|
10474
11404
|
clientId: s.clientId
|
|
10475
11405
|
};
|
|
10476
|
-
|
|
10477
|
-
try {
|
|
10478
|
-
resp = await ctxClient.schemas.createSchema(schemaBody);
|
|
10479
|
-
} catch (e) {
|
|
10480
|
-
if (!isAlreadyExistsError(e)) throw e;
|
|
10481
|
-
if (s.clientId) throw e;
|
|
10482
|
-
const existingId = await findExistingSchemaId(ctxClient, s.typeName, { userId: s.userId, orgId: s.orgId });
|
|
10483
|
-
if (!existingId) throw e;
|
|
10484
|
-
try {
|
|
10485
|
-
resp = await ctxClient.schemas.updateSchema({ id: existingId, body: schemaBody });
|
|
10486
|
-
} catch (ue) {
|
|
10487
|
-
throw new SchemaReconcileError(s.typeName, ue);
|
|
10488
|
-
}
|
|
10489
|
-
log.debug({ component: "loader", typeName: s.typeName, schemaId: existingId }, "schema existed; reconciled to declared shape (update)");
|
|
10490
|
-
}
|
|
11406
|
+
const resp = await ctxClient.schemas.createSchema({ upsert: true, body: schemaBody });
|
|
10491
11407
|
if (resp.id) schemaIds[s.typeName] = resp.id;
|
|
10492
|
-
log.debug({ component: "loader", typeName: s.typeName, schemaId: resp.id }, "schema ensured");
|
|
11408
|
+
log.debug({ component: "loader", typeName: s.typeName, schemaId: resp.id }, "schema ensured (upsert)");
|
|
10493
11409
|
}
|
|
10494
11410
|
const profileBody = {
|
|
10495
11411
|
principalId: `usr_${userId}`,
|
|
@@ -10565,25 +11481,40 @@ async function runLoader(client, input) {
|
|
|
10565
11481
|
log.debug({ component: "loader", keyName, keyAction }, "scoped key resolved");
|
|
10566
11482
|
let seededCount = 0;
|
|
10567
11483
|
const seededRecordIds = [];
|
|
10568
|
-
|
|
11484
|
+
const seededDocumentIds = [];
|
|
11485
|
+
for (const rec of skipSeed ? [] : blueprint.seed ?? []) {
|
|
10569
11486
|
const schemaId = schemaIds[rec.typeName];
|
|
10570
11487
|
if (!schemaId) {
|
|
10571
11488
|
log.warn({ component: "loader", typeName: rec.typeName }, "seed skipped \u2014 no schemaId for typeName");
|
|
10572
11489
|
continue;
|
|
10573
11490
|
}
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
11491
|
+
if (rec.surface === "document") {
|
|
11492
|
+
const created = await ctxClient.documents.ingestDocument({
|
|
11493
|
+
body: {
|
|
11494
|
+
title: rec.title,
|
|
11495
|
+
text: rec.text,
|
|
11496
|
+
schemaId,
|
|
11497
|
+
externalId: rec.externalId,
|
|
11498
|
+
// Optional structured payload (the document's `fields`); omitted when absent.
|
|
11499
|
+
payload: rec.fields,
|
|
11500
|
+
// Retain the raw text so a seeded document is retrievable via
|
|
11501
|
+
// GET /v1/documents/{id}/text (mirrors the MCP document_ingest default) —
|
|
11502
|
+
// a seed's text IS its content, worth keeping for the getting-started graph.
|
|
11503
|
+
storeText: true
|
|
11504
|
+
}
|
|
11505
|
+
});
|
|
11506
|
+
if (created.id) seededDocumentIds.push(created.id);
|
|
11507
|
+
} else {
|
|
11508
|
+
const created = await ctxClient.records.createRecord({
|
|
11509
|
+
body: {
|
|
11510
|
+
typeName: rec.typeName,
|
|
11511
|
+
schemaId,
|
|
11512
|
+
externalId: rec.externalId,
|
|
11513
|
+
payload: rec.fields
|
|
11514
|
+
}
|
|
11515
|
+
});
|
|
11516
|
+
if (created.id) seededRecordIds.push(created.id);
|
|
11517
|
+
}
|
|
10587
11518
|
seededCount++;
|
|
10588
11519
|
}
|
|
10589
11520
|
return {
|
|
@@ -10596,10 +11527,11 @@ async function runLoader(client, input) {
|
|
|
10596
11527
|
schemaIds,
|
|
10597
11528
|
roleIds,
|
|
10598
11529
|
seededCount,
|
|
10599
|
-
seededRecordIds
|
|
11530
|
+
seededRecordIds,
|
|
11531
|
+
seededDocumentIds
|
|
10600
11532
|
};
|
|
10601
11533
|
}
|
|
10602
|
-
function buildPlan(blueprint) {
|
|
11534
|
+
function buildPlan(blueprint, opts = {}) {
|
|
10603
11535
|
const steps = [];
|
|
10604
11536
|
steps.push({ kind: "context", summary: `context '${blueprint.contextId}' (${contextNameOf(blueprint)})` });
|
|
10605
11537
|
steps.push({
|
|
@@ -10631,9 +11563,14 @@ function buildPlan(blueprint) {
|
|
|
10631
11563
|
});
|
|
10632
11564
|
}
|
|
10633
11565
|
steps.push({ kind: "key", summary: `key ${blueprint.name}-<machine> (mint 1 scoped ssk_*)` });
|
|
10634
|
-
const
|
|
10635
|
-
if (
|
|
10636
|
-
|
|
11566
|
+
const seeds = blueprint.seed ?? [];
|
|
11567
|
+
if (seeds.length > 0 && !opts.noSeed) {
|
|
11568
|
+
const docs = seeds.filter((s) => s.surface === "document").length;
|
|
11569
|
+
const recs = seeds.length - docs;
|
|
11570
|
+
const parts = [];
|
|
11571
|
+
if (recs > 0) parts.push(`${recs} record${recs === 1 ? "" : "s"}`);
|
|
11572
|
+
if (docs > 0) parts.push(`${docs} document${docs === 1 ? "" : "s"}`);
|
|
11573
|
+
steps.push({ kind: "seed", summary: `seed ${parts.join(" + ")}` });
|
|
10637
11574
|
}
|
|
10638
11575
|
return steps;
|
|
10639
11576
|
}
|
|
@@ -10757,7 +11694,9 @@ function parseBootstrapArgs(argv) {
|
|
|
10757
11694
|
rotate: false,
|
|
10758
11695
|
useScopedToken: false,
|
|
10759
11696
|
blankSlate: false,
|
|
11697
|
+
noSeed: false,
|
|
10760
11698
|
client: "desktop",
|
|
11699
|
+
tenant: "live",
|
|
10761
11700
|
help: false
|
|
10762
11701
|
};
|
|
10763
11702
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -10805,6 +11744,20 @@ function parseBootstrapArgs(argv) {
|
|
|
10805
11744
|
case "--blank-slate":
|
|
10806
11745
|
args.blankSlate = true;
|
|
10807
11746
|
break;
|
|
11747
|
+
case "--no-seed":
|
|
11748
|
+
args.noSeed = true;
|
|
11749
|
+
break;
|
|
11750
|
+
case "--tenant": {
|
|
11751
|
+
const v = argv[++i];
|
|
11752
|
+
if (v !== "test" && v !== "live") {
|
|
11753
|
+
throw new Error(`--tenant must be 'test' or 'live' (got '${v ?? ""}')`);
|
|
11754
|
+
}
|
|
11755
|
+
args.tenant = v;
|
|
11756
|
+
break;
|
|
11757
|
+
}
|
|
11758
|
+
case "--test":
|
|
11759
|
+
args.tenant = "test";
|
|
11760
|
+
break;
|
|
10808
11761
|
case "--help":
|
|
10809
11762
|
case "-h":
|
|
10810
11763
|
args.help = true;
|
|
@@ -10815,11 +11768,26 @@ function parseBootstrapArgs(argv) {
|
|
|
10815
11768
|
}
|
|
10816
11769
|
return args;
|
|
10817
11770
|
}
|
|
11771
|
+
function shouldOfferSeedOptOut(args, blueprint, isTty) {
|
|
11772
|
+
return !args.noSeed && (blueprint.seed?.length ?? 0) > 0 && !args.yes && !args.print && isTty;
|
|
11773
|
+
}
|
|
11774
|
+
function seedDeclined(answer) {
|
|
11775
|
+
const a = answer.trim().toLowerCase();
|
|
11776
|
+
return a === "n" || a === "no";
|
|
11777
|
+
}
|
|
11778
|
+
function seedSummaryLine(opts) {
|
|
11779
|
+
if (opts.noSeed) {
|
|
11780
|
+
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";
|
|
11781
|
+
}
|
|
11782
|
+
return opts.seededCount ? ` \u2714 Seeded ${opts.seededCount} record(s)
|
|
11783
|
+
` : "";
|
|
11784
|
+
}
|
|
10818
11785
|
var BOOTSTRAP_HELP = `vectros bootstrap \u2014 provision a least-privilege MCP credential.
|
|
10819
11786
|
|
|
10820
11787
|
Usage:
|
|
10821
|
-
vectros bootstrap [--blueprint <name> | --blank] [--env staging|production]
|
|
10822
|
-
[--
|
|
11788
|
+
vectros bootstrap [--blueprint <name> | --blank] [--no-seed] [--env staging|production]
|
|
11789
|
+
[--tenant test|live | --test] [--client desktop|code]
|
|
11790
|
+
[--yes] [--print] [--rotate]
|
|
10823
11791
|
[--token <t> | env VECTROS_BOOTSTRAP_TOKEN]
|
|
10824
11792
|
[--base-url <url>] [--use-scoped-token]
|
|
10825
11793
|
|
|
@@ -10828,7 +11796,17 @@ Options:
|
|
|
10828
11796
|
OR a path to your own blueprint YAML/JSON (./my.yaml) \u2014 the "copy &
|
|
10829
11797
|
own" path. File blueprints get the identical scope gate (no override).
|
|
10830
11798
|
--blank Credential only (read-only data-plane profile, no schemas).
|
|
11799
|
+
--no-seed Provision the blueprint's schemas, profile and key but SKIP its
|
|
11800
|
+
sample seed records \u2014 the right choice for a production context
|
|
11801
|
+
(a blueprint's seeds are illustrative, not real data). Unlike
|
|
11802
|
+
--blank, the schemas are still created.
|
|
10831
11803
|
--env staging|production Target environment (default: production).
|
|
11804
|
+
--tenant test|live Which tenant the minted key scopes to (default: live).
|
|
11805
|
+
'test' provisions into your isolated test tenant \u2014 a
|
|
11806
|
+
dry-run before pointing real data at the same blueprint.
|
|
11807
|
+
The tenant rides the key (ssk_test_* vs ssk_live_*), so
|
|
11808
|
+
the MCP/client config is otherwise identical.
|
|
11809
|
+
--test Shorthand for --tenant test.
|
|
10832
11810
|
--base-url <url> Override the API base URL (beats --env + VECTROS_API_BASE_URL).
|
|
10833
11811
|
--client <desktop|code> MCP host to configure (default: desktop). 'desktop' merges
|
|
10834
11812
|
claude_desktop_config.json (also works for Cursor/Cline);
|
|
@@ -10897,6 +11875,21 @@ async function resolveBridgeCognitoToken(args, prompt, isTty, resolveCognito = r
|
|
|
10897
11875
|
if (!pasted) throw new Error("No token entered.");
|
|
10898
11876
|
return pasted;
|
|
10899
11877
|
}
|
|
11878
|
+
function buildRemintForContext(opts) {
|
|
11879
|
+
const mintContext = opts.mintContext ?? mintContextToken;
|
|
11880
|
+
return async (contextId) => {
|
|
11881
|
+
const ctxToken = await mintContext({
|
|
11882
|
+
cognitoToken: opts.cognitoToken,
|
|
11883
|
+
apiBaseUrl: opts.apiBaseUrl,
|
|
11884
|
+
contextId,
|
|
11885
|
+
tenant: opts.tenant
|
|
11886
|
+
});
|
|
11887
|
+
return new VectrosClient({
|
|
11888
|
+
token: ctxToken.token,
|
|
11889
|
+
environment: opts.apiBaseUrl
|
|
11890
|
+
});
|
|
11891
|
+
};
|
|
11892
|
+
}
|
|
10900
11893
|
async function runBootstrapCli(argv, deps = {}) {
|
|
10901
11894
|
const log = deps.log ?? createLogger2();
|
|
10902
11895
|
let args;
|
|
@@ -10948,7 +11941,20 @@ ${BOOTSTRAP_HELP}
|
|
|
10948
11941
|
Blueprint: ${blueprint.name}
|
|
10949
11942
|
\u2714 Scope gate: [${gate.accepted.join(", ")}] \u2014 all data-plane \u2713
|
|
10950
11943
|
`);
|
|
10951
|
-
|
|
11944
|
+
let noSeed = args.noSeed;
|
|
11945
|
+
let seedDeclinedInteractively = false;
|
|
11946
|
+
if (shouldOfferSeedOptOut(args, blueprint, isTty)) {
|
|
11947
|
+
const ans = await promptCtx.prompt(
|
|
11948
|
+
`
|
|
11949
|
+
Seed ${blueprint.seed?.length} sample record(s) into this context? [Y/n]
|
|
11950
|
+
(Choose 'n' for a production context \u2014 sample data is illustrative only): `
|
|
11951
|
+
);
|
|
11952
|
+
if (seedDeclined(ans)) {
|
|
11953
|
+
noSeed = true;
|
|
11954
|
+
seedDeclinedInteractively = true;
|
|
11955
|
+
}
|
|
11956
|
+
}
|
|
11957
|
+
const planSteps = buildPlan(blueprint, { noSeed });
|
|
10952
11958
|
process.stdout.write(`
|
|
10953
11959
|
${renderPlan(blueprint, planSteps)}
|
|
10954
11960
|
`);
|
|
@@ -10965,12 +11971,17 @@ ${renderPlan(blueprint, planSteps)}
|
|
|
10965
11971
|
isTty,
|
|
10966
11972
|
deps.resolveCognitoToken
|
|
10967
11973
|
);
|
|
10968
|
-
const
|
|
11974
|
+
const mintBridge = deps.mintBridgeToken ?? mintBridgeToken;
|
|
11975
|
+
const mintContext = deps.mintContextToken ?? mintContextToken;
|
|
11976
|
+
const bridge = await mintBridge({
|
|
10969
11977
|
cognitoToken,
|
|
10970
11978
|
apiBaseUrl: baseUrl,
|
|
10971
|
-
useScopedToken: args.useScopedToken
|
|
11979
|
+
useScopedToken: args.useScopedToken,
|
|
11980
|
+
// Tenant rides the key (ssk_test_* vs ssk_live_*), not the base URL.
|
|
11981
|
+
tenant: args.tenant
|
|
10972
11982
|
});
|
|
10973
|
-
process.stdout.write(
|
|
11983
|
+
process.stdout.write(` \u2714 Bootstrap token minted (5-min TTL, ${args.tenant} tenant)
|
|
11984
|
+
`);
|
|
10974
11985
|
const client = new VectrosClient({ token: bridge.token, environment: baseUrl });
|
|
10975
11986
|
const identity = await resolveIdentity({ log, apiKey: bridge.token, environment: baseUrl });
|
|
10976
11987
|
const tenantId = identity.tenantId;
|
|
@@ -10985,19 +11996,22 @@ ${renderPlan(blueprint, planSteps)}
|
|
|
10985
11996
|
tenantId,
|
|
10986
11997
|
machineId,
|
|
10987
11998
|
rotate: args.rotate,
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
},
|
|
11999
|
+
skipSeed: noSeed,
|
|
12000
|
+
remintForContext: buildRemintForContext({
|
|
12001
|
+
cognitoToken,
|
|
12002
|
+
apiBaseUrl: baseUrl,
|
|
12003
|
+
tenant: args.tenant,
|
|
12004
|
+
mintContext
|
|
12005
|
+
}),
|
|
10995
12006
|
log
|
|
10996
12007
|
});
|
|
10997
12008
|
process.stdout.write(
|
|
10998
|
-
` \u2714 AccessProfile + key (${result.keyAction}) \u2192 ${result.keyName}
|
|
10999
|
-
` + (
|
|
11000
|
-
|
|
12009
|
+
` \u2714 AccessProfile + ${args.tenant} key (${result.keyAction}) \u2192 ${result.keyName}
|
|
12010
|
+
` + seedSummaryLine({
|
|
12011
|
+
noSeed,
|
|
12012
|
+
declinedInteractively: seedDeclinedInteractively,
|
|
12013
|
+
seededCount: result.seededCount
|
|
12014
|
+
})
|
|
11001
12015
|
);
|
|
11002
12016
|
const entry = buildVectrosServerEntry({ apiKey: result.rawKey, apiBaseUrl: baseUrl });
|
|
11003
12017
|
const isCode = args.client === "code";
|
|
@@ -11208,7 +12222,8 @@ servicePrincipal:
|
|
|
11208
12222
|
displayName: ${name}
|
|
11209
12223
|
|
|
11210
12224
|
seed:
|
|
11211
|
-
-
|
|
12225
|
+
- surface: record # 'record' (createRecord) or 'document' (text-ingest: needs title + text)
|
|
12226
|
+
typeName: thing
|
|
11212
12227
|
externalId: seed-welcome # stable \u2192 idempotent; re-apply converges
|
|
11213
12228
|
fields: { title: "Hello from ${name}" }
|
|
11214
12229
|
`;
|
|
@@ -11556,6 +12571,7 @@ async function withAuth(opts, deps, body) {
|
|
|
11556
12571
|
token: opts.token,
|
|
11557
12572
|
context: opts.context,
|
|
11558
12573
|
provisioning: opts.provisioning,
|
|
12574
|
+
tenant: opts.tenant,
|
|
11559
12575
|
useScopedToken: opts.useScopedToken,
|
|
11560
12576
|
log
|
|
11561
12577
|
});
|
|
@@ -11832,19 +12848,23 @@ async function createIdentity(client, opts, payload) {
|
|
|
11832
12848
|
switch (opts.type) {
|
|
11833
12849
|
case "user":
|
|
11834
12850
|
return client.identity.createUser({
|
|
11835
|
-
|
|
11836
|
-
|
|
11837
|
-
|
|
11838
|
-
|
|
12851
|
+
body: {
|
|
12852
|
+
externalId,
|
|
12853
|
+
email: opts.email,
|
|
12854
|
+
type: opts.service ? "SERVICE" : "HUMAN",
|
|
12855
|
+
payload
|
|
12856
|
+
}
|
|
11839
12857
|
});
|
|
11840
12858
|
case "org":
|
|
11841
|
-
return client.identity.createOrg({ externalId, name: opts.name, payload });
|
|
12859
|
+
return client.identity.createOrg({ body: { externalId, name: opts.name, payload } });
|
|
11842
12860
|
case "client":
|
|
11843
12861
|
return client.identity.createClient({
|
|
11844
|
-
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
12862
|
+
body: {
|
|
12863
|
+
externalId,
|
|
12864
|
+
name: opts.name,
|
|
12865
|
+
orgId: opts.org,
|
|
12866
|
+
payload
|
|
12867
|
+
}
|
|
11848
12868
|
});
|
|
11849
12869
|
}
|
|
11850
12870
|
}
|
|
@@ -12285,8 +13305,10 @@ async function runContextCreate(opts, deps = {}) {
|
|
|
12285
13305
|
const client = auth.client;
|
|
12286
13306
|
try {
|
|
12287
13307
|
const ctx = await client.auth.createAppContext({
|
|
12288
|
-
|
|
12289
|
-
|
|
13308
|
+
body: {
|
|
13309
|
+
contextId: opts.contextId,
|
|
13310
|
+
name: opts.name ?? opts.contextId
|
|
13311
|
+
}
|
|
12290
13312
|
});
|
|
12291
13313
|
if (opts.json) {
|
|
12292
13314
|
process.stdout.write(`${formatJson(ctx)}
|
|
@@ -12597,23 +13619,22 @@ async function runAssertions(client, deps, blueprint, tenantId, result) {
|
|
|
12597
13619
|
}
|
|
12598
13620
|
}
|
|
12599
13621
|
for (const rec of blueprint.seed ?? []) {
|
|
13622
|
+
const isDoc = rec.surface === "document";
|
|
13623
|
+
const op = isDoc ? "lookupDocuments" : "lookupRecords";
|
|
13624
|
+
const noun = isDoc ? "document" : "record";
|
|
12600
13625
|
try {
|
|
12601
|
-
const page = await client.records.lookupRecords({
|
|
12602
|
-
type: rec.typeName,
|
|
12603
|
-
field: "externalId",
|
|
12604
|
-
value: rec.externalId
|
|
12605
|
-
});
|
|
13626
|
+
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 });
|
|
12606
13627
|
const ok = (page.data ?? []).length >= 1;
|
|
12607
13628
|
assertions.push({
|
|
12608
13629
|
name: `seed-externalId:${rec.externalId}`,
|
|
12609
13630
|
ok,
|
|
12610
|
-
detail: ok ? `'${rec.typeName}' seed resolves by externalId '${rec.externalId}'` : `'${rec.typeName}' seed externalId '${rec.externalId}' resolved 0
|
|
13631
|
+
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?)`
|
|
12611
13632
|
});
|
|
12612
13633
|
} catch (e) {
|
|
12613
13634
|
assertions.push({
|
|
12614
13635
|
name: `seed-externalId:${rec.externalId}`,
|
|
12615
13636
|
ok: false,
|
|
12616
|
-
detail:
|
|
13637
|
+
detail: `${op}(externalId='${rec.externalId}') failed: ${errMsg(e)}`
|
|
12617
13638
|
});
|
|
12618
13639
|
}
|
|
12619
13640
|
}
|
|
@@ -12671,6 +13692,14 @@ async function runTeardown(client, blueprint, machineId, snapshot, result) {
|
|
|
12671
13692
|
steps.push({ step: `delete record ${id}`, ok: false, error: errMsg(e) });
|
|
12672
13693
|
}
|
|
12673
13694
|
}
|
|
13695
|
+
for (const id of result.seededDocumentIds) {
|
|
13696
|
+
try {
|
|
13697
|
+
await client.documents.deleteDocument({ id });
|
|
13698
|
+
steps.push({ step: `delete document ${id}`, ok: true });
|
|
13699
|
+
} catch (e) {
|
|
13700
|
+
steps.push({ step: `delete document ${id}`, ok: false, error: errMsg(e) });
|
|
13701
|
+
}
|
|
13702
|
+
}
|
|
12674
13703
|
const principalId = `usr_${result.servicePrincipalUserId}`;
|
|
12675
13704
|
if (snapshot.failed) {
|
|
12676
13705
|
steps.push({ step: `delete access profile ${principalId}`, ok: true, skipped: true, error: "skipped \u2014 pre-apply snapshot failed; cannot prove ownership" });
|
|
@@ -12805,7 +13834,7 @@ function renderReport(blueprint, env, report) {
|
|
|
12805
13834
|
if (report.applied) {
|
|
12806
13835
|
const a = report.applied;
|
|
12807
13836
|
lines.push(
|
|
12808
|
-
` \u2714 applied \u2014 key ${a.keyName} (${a.keyAction}), ${Object.keys(a.schemaIds).length} schema(s)` + (a.seededCount ? `, ${a.seededCount} seed
|
|
13837
|
+
` \u2714 applied \u2014 key ${a.keyName} (${a.keyAction}), ${Object.keys(a.schemaIds).length} schema(s)` + (a.seededCount ? `, ${a.seededCount} seed(s)` : "")
|
|
12809
13838
|
);
|
|
12810
13839
|
} else {
|
|
12811
13840
|
lines.push(` \u2716 apply failed \u2014 ${report.error ?? "unknown error"}`);
|
|
@@ -12868,7 +13897,10 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
|
|
|
12868
13897
|
const ctxToken = await mintContextToken({
|
|
12869
13898
|
cognitoToken: auth.cognitoToken,
|
|
12870
13899
|
apiBaseUrl: auth.baseUrl,
|
|
12871
|
-
contextId
|
|
13900
|
+
contextId,
|
|
13901
|
+
// Same tenant as the bootstrap token (auth.tenant) — the in-context
|
|
13902
|
+
// load must land in the tenant the run targets.
|
|
13903
|
+
tenant: auth.tenant
|
|
12872
13904
|
});
|
|
12873
13905
|
return new VectrosClient({
|
|
12874
13906
|
token: ctxToken.token,
|
|
@@ -12906,9 +13938,9 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
|
|
|
12906
13938
|
|
|
12907
13939
|
// src/build-info.ts
|
|
12908
13940
|
var BUILD_INFO = {
|
|
12909
|
-
cli: true ? "0.
|
|
12910
|
-
sdk: true ? "0.
|
|
12911
|
-
blueprints: true ? "0.
|
|
13941
|
+
cli: true ? "0.6.4" : "dev",
|
|
13942
|
+
sdk: true ? "0.31.0" : "dev",
|
|
13943
|
+
blueprints: true ? "0.6.2" : "dev"
|
|
12912
13944
|
};
|
|
12913
13945
|
function formatBuildInfo() {
|
|
12914
13946
|
return `vectros ${BUILD_INFO.cli} (sdk ${BUILD_INFO.sdk}, blueprints ${BUILD_INFO.blueprints})`;
|
|
@@ -12956,10 +13988,21 @@ function buildProgram(deps = {}) {
|
|
|
12956
13988
|
addCommonAuthOptions(whoami).action(async (flags) => {
|
|
12957
13989
|
process.exit(await runWhoami(toCommonOptions(flags), deps));
|
|
12958
13990
|
});
|
|
12959
|
-
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");
|
|
13991
|
+
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)");
|
|
12960
13992
|
addCommonAuthOptions(blueprintTest).action(
|
|
12961
13993
|
async (file, flags) => {
|
|
12962
|
-
|
|
13994
|
+
if (flags.tenant !== void 0 && flags.tenant !== "test" && flags.tenant !== "live") {
|
|
13995
|
+
process.stderr.write(` \u2716 --tenant must be 'test' or 'live' (got '${flags.tenant}')
|
|
13996
|
+
`);
|
|
13997
|
+
process.exit(2);
|
|
13998
|
+
}
|
|
13999
|
+
process.exit(
|
|
14000
|
+
await runBlueprintTest(
|
|
14001
|
+
file,
|
|
14002
|
+
{ ...toCommonOptions(flags), keep: Boolean(flags.keep), tenant: flags.tenant },
|
|
14003
|
+
deps
|
|
14004
|
+
)
|
|
14005
|
+
);
|
|
12963
14006
|
}
|
|
12964
14007
|
);
|
|
12965
14008
|
registerKeyCommands(program, deps);
|