@postman-cse/onboarding-bootstrap 2.1.0 → 2.1.2
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/dist/action.cjs +305 -87
- package/dist/cli.cjs +305 -87
- package/dist/index.cjs +305 -87
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -298375,9 +298375,19 @@ function collectParameterChecks(root, pathItem, operation, version2, operationId
|
|
|
298375
298375
|
if (defaultSerialization) warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
298376
298376
|
continue;
|
|
298377
298377
|
}
|
|
298378
|
-
if (location2 === "path"
|
|
298379
|
-
|
|
298380
|
-
|
|
298378
|
+
if (location2 === "path") {
|
|
298379
|
+
const containingSegment = pathTemplate.split("/").find((segment) => segment.includes(`{${name}}`));
|
|
298380
|
+
if (containingSegment !== void 0 && containingSegment !== `{${name}}`) {
|
|
298381
|
+
const segmentParts = containingSegment.split(/(\{[^}]+\})/).filter(Boolean);
|
|
298382
|
+
let extractable = true;
|
|
298383
|
+
for (let partIndex = 0; partIndex < segmentParts.length - 1; partIndex += 1) {
|
|
298384
|
+
if (/^\{[^}]+\}$/.test(segmentParts[partIndex]) && /^\{[^}]+\}$/.test(segmentParts[partIndex + 1])) extractable = false;
|
|
298385
|
+
}
|
|
298386
|
+
if (!extractable) {
|
|
298387
|
+
warnings.push(`CONTRACT_PATH_PARAM_COMPOUND_SEGMENT_NOT_VALIDATED: path parameter ${name} of ${operationId} is in an ambiguous adjacent-parameter path segment and is not schema-validated`);
|
|
298388
|
+
continue;
|
|
298389
|
+
}
|
|
298390
|
+
}
|
|
298381
298391
|
}
|
|
298382
298392
|
const scalarSchema = packedScalarSchema(packed);
|
|
298383
298393
|
if (scalarSchema !== void 0) {
|
|
@@ -299097,7 +299107,7 @@ function createContractScript(operation, warnings = []) {
|
|
|
299097
299107
|
' function requestPathSegments() { var raw = ""; try { raw = typeof pm.request.url.getPath === "function" ? String(pm.request.url.getPath() || "") : ""; } catch (ignored) {} if (!raw) { var path = pm.request.url.path; raw = Array.isArray(path) ? "/" + path.join("/") : String(path || ""); } return raw.split("?")[0].split("#")[0].split("/").filter(function (segment) { return segment.length > 0; }); }',
|
|
299098
299108
|
// Server path prefixes sit ahead of the template segments, so the
|
|
299099
299109
|
// template aligns against the trailing request segments.
|
|
299100
|
-
' function pathParamValue(name) { var template = String(contract.path).split("/").filter(function (segment) { return segment.length > 0; }); var actual = requestPathSegments(); var offset = actual.length - template.length; if (offset < 0) return undefined; for (var i = 0; i < template.length; i += 1) {
|
|
299110
|
+
' function pathParamValue(name) { var template = String(contract.path).split("/").filter(function (segment) { return segment.length > 0; }); var actual = requestPathSegments(); var offset = actual.length - template.length; if (offset < 0) return undefined; var token = "{" + name + "}"; for (var i = 0; i < template.length; i += 1) { var seg = template[i]; var actualSeg = actual[offset + i]; if (actualSeg === undefined) continue; if (seg === token) { try { return decodeURIComponent(actualSeg); } catch (ignored) { return actualSeg; } } if (seg.indexOf(token) === -1) continue; var chunks = [], j = 0, bad = false; while (j < seg.length) { if (seg.charAt(j) === "{") { var close = seg.indexOf("}", j); if (close === -1) { bad = true; break; } chunks.push({ p: seg.slice(j + 1, close) }); j = close + 1; } else { var nb = seg.indexOf("{", j); var lit = nb === -1 ? seg.slice(j) : seg.slice(j, nb); chunks.push({ l: lit }); j = nb === -1 ? seg.length : nb; } } if (bad) return undefined; var pos = 0, found, ok = true; for (var c = 0; c < chunks.length; c += 1) { var ch = chunks[c]; if (ch.l !== undefined) { if (actualSeg.indexOf(ch.l, pos) === pos) pos += ch.l.length; else { ok = false; break; } } else { var nextLit = (chunks[c + 1] && chunks[c + 1].l !== undefined) ? chunks[c + 1].l : undefined; var isLast = c === chunks.length - 1; var end; if (isLast) { end = actualSeg.length; } else if (nextLit === undefined) { ok = false; break; } else { var idx = actualSeg.indexOf(nextLit, pos + 1); if (idx === -1) { ok = false; break; } end = idx; } if (end <= pos) { ok = false; break; } if (ch.p === name) found = actualSeg.slice(pos, end); pos = end; } } if (ok && pos === actualSeg.length && found !== undefined) { try { return decodeURIComponent(found); } catch (ignored) { return found; } } } return undefined; }',
|
|
299101
299111
|
' function isPlaceholder(value) { var text = String(value).trim(); return /^<[^<>]*>$/.test(text) || text.indexOf("{{") !== -1; }',
|
|
299102
299112
|
' function splitDelimited(value, decode) { if (decode === "csv") return value.split(","); if (decode === "ssv") return value.split(/%20| /); return value.split(/%7C|\\|/i); }',
|
|
299103
299113
|
" function decodeComponent(value) { try { return decodeURIComponent(value); } catch (ignored) { return value; } }",
|
|
@@ -299529,7 +299539,7 @@ function extractGitRepoUrl(value) {
|
|
|
299529
299539
|
}
|
|
299530
299540
|
var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
299531
299541
|
static GENERATION_LOCKED_MAX_RETRIES = 5;
|
|
299532
|
-
static GENERATION_POLL_ATTEMPTS =
|
|
299542
|
+
static GENERATION_POLL_ATTEMPTS = 90;
|
|
299533
299543
|
static GENERATION_POLL_DELAY_MS = 2e3;
|
|
299534
299544
|
gateway;
|
|
299535
299545
|
sleep;
|
|
@@ -299904,6 +299914,40 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
299904
299914
|
const u = String(uid ?? "").trim();
|
|
299905
299915
|
return u.includes("-") ? u.slice(u.indexOf("-") + 1) : u;
|
|
299906
299916
|
}
|
|
299917
|
+
/**
|
|
299918
|
+
* PATCH a freshly-created item's `/scripts`, tolerating the two transient
|
|
299919
|
+
* failures this immediate-after-create write is prone to on the shared gateway:
|
|
299920
|
+
* - `404 RESOURCE_NOT_FOUND` — the create write returns the assigned id, but
|
|
299921
|
+
* an immediate PATCH can hit a replica that has not yet observed the create
|
|
299922
|
+
* (read-after-write lag, live-observed on org-mode teams).
|
|
299923
|
+
* - a downstream `5xx` (e.g. `500 ESOCKETTIMEDOUT`) — a Bifrost/gateway read
|
|
299924
|
+
* timeout, not a durable rejection.
|
|
299925
|
+
* `op:add /scripts` is idempotent (overwrites), so retrying either is safe.
|
|
299926
|
+
* This is a deeper, longer-backoff budget than the gateway client's inner
|
|
299927
|
+
* transient retry, to wait out a longer platform hiccup on this fragile write.
|
|
299928
|
+
* Non-transient errors (e.g. 4xx schema rejections) surface immediately.
|
|
299929
|
+
*/
|
|
299930
|
+
async patchNewItemScripts(cid, itemId, scripts) {
|
|
299931
|
+
const maxAttempts = 6;
|
|
299932
|
+
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
299933
|
+
try {
|
|
299934
|
+
await this.gateway.requestJson({
|
|
299935
|
+
service: "collection",
|
|
299936
|
+
method: "patch",
|
|
299937
|
+
path: `/v3/collections/${cid}/items/${itemId}`,
|
|
299938
|
+
headers: { "X-Entity-Type": "http-request" },
|
|
299939
|
+
body: [{ op: "add", path: "/scripts", value: scripts }]
|
|
299940
|
+
});
|
|
299941
|
+
return;
|
|
299942
|
+
} catch (error2) {
|
|
299943
|
+
const retriable = error2 instanceof HttpError && (error2.status === 404 || error2.status >= 500);
|
|
299944
|
+
if (!retriable || attempt === maxAttempts - 1) {
|
|
299945
|
+
throw error2;
|
|
299946
|
+
}
|
|
299947
|
+
await this.sleep(Math.min(2e3, 300 * 2 ** attempt));
|
|
299948
|
+
}
|
|
299949
|
+
}
|
|
299950
|
+
}
|
|
299907
299951
|
/**
|
|
299908
299952
|
* Apply tag slugs via the dedicated `tagging` service:
|
|
299909
299953
|
* `PUT /v1/tags/collections/:uid` (full uid), body `{ tags:[{ slug }] }` — the
|
|
@@ -300021,26 +300065,14 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
300021
300065
|
});
|
|
300022
300066
|
const newItemId = String(asRecord7(created?.data)?.id ?? "").trim();
|
|
300023
300067
|
if (!newItemId) return;
|
|
300024
|
-
await this.
|
|
300025
|
-
|
|
300026
|
-
|
|
300027
|
-
|
|
300028
|
-
|
|
300029
|
-
|
|
300030
|
-
|
|
300031
|
-
|
|
300032
|
-
path: "/scripts",
|
|
300033
|
-
value: toV3Scripts([
|
|
300034
|
-
'if (pm.environment.get("CI") === "true") { return; }',
|
|
300035
|
-
"const body = pm.response.json();",
|
|
300036
|
-
"if (body.SecretString) {",
|
|
300037
|
-
" const secrets = JSON.parse(body.SecretString);",
|
|
300038
|
-
" Object.entries(secrets).forEach(([k, v]) => pm.collectionVariables.set(k, v));",
|
|
300039
|
-
"}"
|
|
300040
|
-
])
|
|
300041
|
-
}
|
|
300042
|
-
]
|
|
300043
|
-
});
|
|
300068
|
+
await this.patchNewItemScripts(cid, newItemId, toV3Scripts([
|
|
300069
|
+
'if (pm.environment.get("CI") === "true") { return; }',
|
|
300070
|
+
"const body = pm.response.json();",
|
|
300071
|
+
"if (body.SecretString) {",
|
|
300072
|
+
" const secrets = JSON.parse(body.SecretString);",
|
|
300073
|
+
" Object.entries(secrets).forEach(([k, v]) => pm.collectionVariables.set(k, v));",
|
|
300074
|
+
"}"
|
|
300075
|
+
]));
|
|
300044
300076
|
}
|
|
300045
300077
|
// --- workspace roles + member resolution (live-proven 2026-06-30) ---
|
|
300046
300078
|
//
|
|
@@ -300199,26 +300231,14 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
300199
300231
|
});
|
|
300200
300232
|
const newItemId = String(asRecord7(created?.data)?.id ?? "").trim();
|
|
300201
300233
|
if (newItemId) {
|
|
300202
|
-
await this.
|
|
300203
|
-
|
|
300204
|
-
|
|
300205
|
-
|
|
300206
|
-
|
|
300207
|
-
|
|
300208
|
-
|
|
300209
|
-
|
|
300210
|
-
path: "/scripts",
|
|
300211
|
-
value: toV3Scripts([
|
|
300212
|
-
'if (pm.environment.get("CI") === "true") { return; }',
|
|
300213
|
-
"const body = pm.response.json();",
|
|
300214
|
-
"if (body.SecretString) {",
|
|
300215
|
-
" const secrets = JSON.parse(body.SecretString);",
|
|
300216
|
-
" Object.entries(secrets).forEach(([k, v]) => pm.collectionVariables.set(k, v));",
|
|
300217
|
-
"}"
|
|
300218
|
-
])
|
|
300219
|
-
}
|
|
300220
|
-
]
|
|
300221
|
-
});
|
|
300234
|
+
await this.patchNewItemScripts(cid, newItemId, toV3Scripts([
|
|
300235
|
+
'if (pm.environment.get("CI") === "true") { return; }',
|
|
300236
|
+
"const body = pm.response.json();",
|
|
300237
|
+
"if (body.SecretString) {",
|
|
300238
|
+
" const secrets = JSON.parse(body.SecretString);",
|
|
300239
|
+
" Object.entries(secrets).forEach(([k, v]) => pm.collectionVariables.set(k, v));",
|
|
300240
|
+
"}"
|
|
300241
|
+
]));
|
|
300222
300242
|
}
|
|
300223
300243
|
}
|
|
300224
300244
|
return plan.warnings;
|
|
@@ -301054,7 +301074,7 @@ function resolveActionVersion(explicit) {
|
|
|
301054
301074
|
if (explicit) {
|
|
301055
301075
|
return explicit;
|
|
301056
301076
|
}
|
|
301057
|
-
return "2.1.
|
|
301077
|
+
return "2.1.2" ? "2.1.2" : "unknown";
|
|
301058
301078
|
}
|
|
301059
301079
|
function telemetryDisabled(env) {
|
|
301060
301080
|
const flag = String(env.POSTMAN_ACTIONS_TELEMETRY ?? "").trim().toLowerCase();
|
|
@@ -313638,27 +313658,28 @@ function classifyNamedType(named) {
|
|
|
313638
313658
|
function describeType(type) {
|
|
313639
313659
|
let current = type;
|
|
313640
313660
|
let nonNull = false;
|
|
313641
|
-
let list = false;
|
|
313642
|
-
let listItemNonNull = false;
|
|
313643
313661
|
if ((0, import_graphql.isNonNullType)(current)) {
|
|
313644
313662
|
nonNull = true;
|
|
313645
313663
|
current = current.ofType;
|
|
313646
313664
|
}
|
|
313647
|
-
|
|
313648
|
-
|
|
313665
|
+
const lists = [];
|
|
313666
|
+
while ((0, import_graphql.isListType)(current)) {
|
|
313649
313667
|
current = current.ofType;
|
|
313668
|
+
let itemNonNull = false;
|
|
313650
313669
|
if ((0, import_graphql.isNonNullType)(current)) {
|
|
313651
|
-
|
|
313670
|
+
itemNonNull = true;
|
|
313652
313671
|
current = current.ofType;
|
|
313653
313672
|
}
|
|
313673
|
+
lists.push({ itemNonNull });
|
|
313654
313674
|
}
|
|
313655
313675
|
const named = (0, import_graphql.getNamedType)(current);
|
|
313656
313676
|
return {
|
|
313657
313677
|
name: named.name,
|
|
313658
313678
|
kind: classifyNamedType(named),
|
|
313659
313679
|
nonNull,
|
|
313660
|
-
list,
|
|
313661
|
-
listItemNonNull
|
|
313680
|
+
list: lists.length > 0,
|
|
313681
|
+
listItemNonNull: lists.length > 0 ? lists[0].itemNonNull : false,
|
|
313682
|
+
lists
|
|
313662
313683
|
};
|
|
313663
313684
|
}
|
|
313664
313685
|
function describeArgument(arg) {
|
|
@@ -313695,7 +313716,7 @@ function collectRootOperations(rootType, kind, schema, shapes) {
|
|
|
313695
313716
|
}
|
|
313696
313717
|
if (returns.kind === "union") {
|
|
313697
313718
|
opWarnings.push(
|
|
313698
|
-
`
|
|
313719
|
+
`GQL_UNION_MEMBER_FIELDS_NOT_EXPANDED: ${kind}.${fieldName} returns union ${returns.name}; its __typename is validated (object + declared member name) but member-specific fields are not expanded or asserted`
|
|
313699
313720
|
);
|
|
313700
313721
|
}
|
|
313701
313722
|
if (returns.kind === "unknown") {
|
|
@@ -313759,9 +313780,12 @@ function parseGraphQLSchema(content, opts = {}) {
|
|
|
313759
313780
|
}
|
|
313760
313781
|
for (const operation of operations) warnings.push(...operation.warnings);
|
|
313761
313782
|
const enumValues = {};
|
|
313783
|
+
const unionMembers = {};
|
|
313762
313784
|
for (const namedType of Object.values(schema.getTypeMap())) {
|
|
313763
313785
|
if ((0, import_graphql.isEnumType)(namedType)) {
|
|
313764
313786
|
enumValues[namedType.name] = namedType.getValues().map((value) => value.name);
|
|
313787
|
+
} else if ((0, import_graphql.isUnionType)(namedType)) {
|
|
313788
|
+
unionMembers[namedType.name] = namedType.getTypes().map((member) => member.name).sort((x, y) => x.localeCompare(y));
|
|
313765
313789
|
}
|
|
313766
313790
|
}
|
|
313767
313791
|
return {
|
|
@@ -313769,6 +313793,7 @@ function parseGraphQLSchema(content, opts = {}) {
|
|
|
313769
313793
|
operations,
|
|
313770
313794
|
objectShapes,
|
|
313771
313795
|
enumValues,
|
|
313796
|
+
unionMembers,
|
|
313772
313797
|
warnings
|
|
313773
313798
|
};
|
|
313774
313799
|
}
|
|
@@ -313776,6 +313801,7 @@ function parseGraphQLSchema(content, opts = {}) {
|
|
|
313776
313801
|
// src/lib/protocols/graphql/selection.ts
|
|
313777
313802
|
var SELECTION_DEPTH = 1;
|
|
313778
313803
|
function selectFields(typeRef, index, depth) {
|
|
313804
|
+
if (typeRef.kind === "union") return [];
|
|
313779
313805
|
if (typeRef.kind !== "object" && typeRef.kind !== "interface") return null;
|
|
313780
313806
|
const shape = index.objectShapes[typeRef.name];
|
|
313781
313807
|
if (!shape) return [];
|
|
@@ -313809,8 +313835,8 @@ var DEFAULT_URL = "{{baseUrl}}/graphql";
|
|
|
313809
313835
|
function argTypeSdl(arg) {
|
|
313810
313836
|
const ref = arg.type;
|
|
313811
313837
|
let inner = ref.name;
|
|
313812
|
-
|
|
313813
|
-
inner = ref.
|
|
313838
|
+
for (let i = ref.lists.length - 1; i >= 0; i -= 1) {
|
|
313839
|
+
inner = ref.lists[i].itemNonNull ? `[${inner}!]` : `[${inner}]`;
|
|
313814
313840
|
}
|
|
313815
313841
|
return ref.nonNull ? `${inner}!` : inner;
|
|
313816
313842
|
}
|
|
@@ -313979,12 +314005,25 @@ function buildShapeAssertions(operation, index, warnings) {
|
|
|
313979
314005
|
return emitValueAssertions("value", operation.returns, selection, operation.id, index, warnings);
|
|
313980
314006
|
}
|
|
313981
314007
|
function emitValueAssertions(accessor, ref, selection, ctx, index, warnings) {
|
|
313982
|
-
if (ref.
|
|
313983
|
-
const
|
|
313984
|
-
const
|
|
314008
|
+
if (ref.lists.length > 0) {
|
|
314009
|
+
const [outer, ...rest] = ref.lists;
|
|
314010
|
+
const innerRef = {
|
|
314011
|
+
...ref,
|
|
314012
|
+
lists: rest,
|
|
314013
|
+
list: rest.length > 0,
|
|
314014
|
+
listItemNonNull: rest.length > 0 ? rest[0].itemNonNull : false
|
|
314015
|
+
};
|
|
314016
|
+
const elementLines = emitValueAssertions("__el", innerRef, selection, `${ctx} (list element)`, index, warnings);
|
|
313985
314017
|
const lines = [`pm.expect(${accessor}, ${JSON.stringify(`${ctx}: expected a list`)}).to.be.an("array");`];
|
|
313986
|
-
|
|
313987
|
-
|
|
314018
|
+
const body = [];
|
|
314019
|
+
if (outer.itemNonNull) {
|
|
314020
|
+
body.push(`pm.expect(__el, ${JSON.stringify(`${ctx} (list element): a non-null list item ([T!]) was null`)}).to.not.be.null;`);
|
|
314021
|
+
body.push(...elementLines);
|
|
314022
|
+
} else if (elementLines.length > 0) {
|
|
314023
|
+
body.push("if (__el === null || __el === undefined) return;", ...elementLines);
|
|
314024
|
+
}
|
|
314025
|
+
if (body.length > 0) {
|
|
314026
|
+
lines.push(`${accessor}.forEach(function (__el) {`, ...body.map((line) => ` ${line}`), "});");
|
|
313988
314027
|
}
|
|
313989
314028
|
return lines;
|
|
313990
314029
|
}
|
|
@@ -314002,8 +314041,22 @@ function emitValueAssertions(accessor, ref, selection, ctx, index, warnings) {
|
|
|
314002
314041
|
return lines;
|
|
314003
314042
|
}
|
|
314004
314043
|
if (ref.kind === "union") {
|
|
314005
|
-
|
|
314006
|
-
|
|
314044
|
+
const members = index.unionMembers[ref.name];
|
|
314045
|
+
const objMsg = JSON.stringify(ctx + ": expected union " + ref.name + " value as an object");
|
|
314046
|
+
const presentMsg = JSON.stringify(ctx + ": union " + ref.name + " value must carry __typename");
|
|
314047
|
+
const stringMsg = JSON.stringify(ctx + ": union " + ref.name + " __typename must be a string");
|
|
314048
|
+
const lines = [
|
|
314049
|
+
"pm.expect(" + accessor + ", " + objMsg + ').to.be.an("object");',
|
|
314050
|
+
"pm.expect(" + accessor + ", " + presentMsg + ').to.have.property("__typename");',
|
|
314051
|
+
"pm.expect(" + accessor + " && " + accessor + ".__typename, " + stringMsg + ').to.be.a("string");'
|
|
314052
|
+
];
|
|
314053
|
+
if (members && members.length > 0) {
|
|
314054
|
+
const memberMsg = JSON.stringify(ctx + ": __typename is not a declared member of union " + ref.name);
|
|
314055
|
+
lines.push("pm.expect(" + accessor + " && " + accessor + ".__typename, " + memberMsg + ").to.be.oneOf(" + JSON.stringify(members) + ");");
|
|
314056
|
+
} else {
|
|
314057
|
+
warnings.push("GQL_UNION_MEMBERS_UNKNOWN: " + ctx + " union " + ref.name + " member set was not resolved; only object + string __typename is asserted");
|
|
314058
|
+
}
|
|
314059
|
+
return lines;
|
|
314007
314060
|
}
|
|
314008
314061
|
warnings.push(`GQL_UNKNOWN_RETURN_TYPE: ${ctx} return type ${ref.name} could not be classified; only presence is asserted`);
|
|
314009
314062
|
return [];
|
|
@@ -314014,6 +314067,7 @@ function emitFieldAssertions(objectAccessor, parentTypeName, field, ctx, index,
|
|
|
314014
314067
|
const lines = [];
|
|
314015
314068
|
if (field.type.nonNull) {
|
|
314016
314069
|
lines.push(`pm.expect(${objectAccessor}, ${JSON.stringify(`${parentTypeName} is missing non-null field '${field.name}'`)}).to.have.property(${propName});`);
|
|
314070
|
+
lines.push(`pm.expect(${prop}, ${JSON.stringify(`${parentTypeName}.${field.name} is declared non-null but was null`)}).to.not.be.null;`);
|
|
314017
314071
|
}
|
|
314018
314072
|
const valueLines = emitValueAssertions(prop, field.type, field.selection, `${ctx}.${field.name}`, index, warnings);
|
|
314019
314073
|
if (valueLines.length > 0) {
|
|
@@ -314119,19 +314173,25 @@ function asArray6(value) {
|
|
|
314119
314173
|
}
|
|
314120
314174
|
var SCALAR_JSON_TYPE = {
|
|
314121
314175
|
double: { jsonType: "double" },
|
|
314122
|
-
float
|
|
314123
|
-
|
|
314124
|
-
|
|
314125
|
-
|
|
314126
|
-
|
|
314127
|
-
|
|
314128
|
-
|
|
314129
|
-
|
|
314130
|
-
|
|
314131
|
-
|
|
314132
|
-
|
|
314133
|
-
|
|
314134
|
-
|
|
314176
|
+
// proto float is float32; carry a format so the runtime enforces float32 range
|
|
314177
|
+
// (a finite double like 3.5e38 overflows float32 and must fail).
|
|
314178
|
+
float: { jsonType: "double", jsonFormat: "proto-float32" },
|
|
314179
|
+
// 32-bit integers JSON-encode as numbers; `intType` carries the exact protobuf
|
|
314180
|
+
// integer domain so the runtime range/sign-checks it (not just integrality).
|
|
314181
|
+
int32: { jsonType: "number", intType: "int32" },
|
|
314182
|
+
sint32: { jsonType: "number", intType: "sint32" },
|
|
314183
|
+
sfixed32: { jsonType: "number", intType: "sfixed32" },
|
|
314184
|
+
fixed32: { jsonType: "number", intType: "fixed32" },
|
|
314185
|
+
uint32: { jsonType: "number", intType: "uint32" },
|
|
314186
|
+
// 64-bit integers are JSON-encoded as strings by the proto JSON mapping and by
|
|
314187
|
+
// protobufjs default toObject; `intType` carries the exact domain so the runtime
|
|
314188
|
+
// lexically validates and RANGE-checks the string (string comparison avoids JS
|
|
314189
|
+
// double precision loss beyond 2^53).
|
|
314190
|
+
int64: { jsonType: "string", intType: "int64" },
|
|
314191
|
+
uint64: { jsonType: "string", intType: "uint64" },
|
|
314192
|
+
sint64: { jsonType: "string", intType: "sint64" },
|
|
314193
|
+
fixed64: { jsonType: "string", intType: "fixed64" },
|
|
314194
|
+
sfixed64: { jsonType: "string", intType: "sfixed64" },
|
|
314135
314195
|
bool: { jsonType: "boolean" },
|
|
314136
314196
|
string: { jsonType: "string" },
|
|
314137
314197
|
// bytes are base64 strings in proto JSON.
|
|
@@ -314142,11 +314202,11 @@ var WELL_KNOWN_JSON_TYPE = {
|
|
|
314142
314202
|
"google.protobuf.Duration": { jsonType: "string", jsonFormat: "proto-duration" },
|
|
314143
314203
|
"google.protobuf.FieldMask": { jsonType: "string", jsonFormat: "proto-field-mask" },
|
|
314144
314204
|
"google.protobuf.DoubleValue": { jsonType: "double", nullable: true },
|
|
314145
|
-
"google.protobuf.FloatValue": { jsonType: "double", nullable: true },
|
|
314146
|
-
"google.protobuf.Int32Value": { jsonType: "number", nullable: true },
|
|
314147
|
-
"google.protobuf.UInt32Value": { jsonType: "number", nullable: true },
|
|
314148
|
-
"google.protobuf.Int64Value": { jsonType: "string", nullable: true },
|
|
314149
|
-
"google.protobuf.UInt64Value": { jsonType: "string", nullable: true },
|
|
314205
|
+
"google.protobuf.FloatValue": { jsonType: "double", jsonFormat: "proto-float32", nullable: true },
|
|
314206
|
+
"google.protobuf.Int32Value": { jsonType: "number", intType: "int32", nullable: true },
|
|
314207
|
+
"google.protobuf.UInt32Value": { jsonType: "number", intType: "uint32", nullable: true },
|
|
314208
|
+
"google.protobuf.Int64Value": { jsonType: "string", intType: "int64", nullable: true },
|
|
314209
|
+
"google.protobuf.UInt64Value": { jsonType: "string", intType: "uint64", nullable: true },
|
|
314150
314210
|
"google.protobuf.BoolValue": { jsonType: "boolean", nullable: true },
|
|
314151
314211
|
"google.protobuf.StringValue": { jsonType: "string", nullable: true },
|
|
314152
314212
|
"google.protobuf.BytesValue": { jsonType: "string", jsonFormat: "proto-bytes", nullable: true },
|
|
@@ -314193,7 +314253,7 @@ function stripLeadingDot(name) {
|
|
|
314193
314253
|
}
|
|
314194
314254
|
function classifyValueType(protoType, resolved) {
|
|
314195
314255
|
const wkt = WELL_KNOWN_JSON_TYPE[stripLeadingDot(protoType)];
|
|
314196
|
-
if (wkt) return { jsonType: wkt.jsonType, jsonFormat: wkt.jsonFormat, nullable: wkt.nullable };
|
|
314256
|
+
if (wkt) return { jsonType: wkt.jsonType, jsonFormat: wkt.jsonFormat, nullable: wkt.nullable, intType: wkt.intType };
|
|
314197
314257
|
if (resolved && Array.isArray(resolved.fieldsArray)) {
|
|
314198
314258
|
return { jsonType: "object", messageType: stripLeadingDot(resolved.fullName) };
|
|
314199
314259
|
}
|
|
@@ -314201,9 +314261,14 @@ function classifyValueType(protoType, resolved) {
|
|
|
314201
314261
|
return { jsonType: "enum", enumType: stripLeadingDot(resolved.fullName) };
|
|
314202
314262
|
}
|
|
314203
314263
|
const scalar = SCALAR_JSON_TYPE[protoType];
|
|
314204
|
-
if (scalar) return { jsonType: scalar.jsonType, jsonFormat: scalar.jsonFormat };
|
|
314264
|
+
if (scalar) return { jsonType: scalar.jsonType, jsonFormat: scalar.jsonFormat, intType: scalar.intType };
|
|
314205
314265
|
return { jsonType: "unknown" };
|
|
314206
314266
|
}
|
|
314267
|
+
function classifyMapKey(keyType) {
|
|
314268
|
+
if (keyType === "bool") return "boolean";
|
|
314269
|
+
if (keyType && /^(?:u?int|sint|s?fixed)(?:32|64)$/.test(keyType)) return keyType;
|
|
314270
|
+
return void 0;
|
|
314271
|
+
}
|
|
314207
314272
|
function toLowerCamelCase(name) {
|
|
314208
314273
|
return name.replace(/_+([a-zA-Z0-9])/g, (_match, char) => char.toUpperCase()).replace(/_+$/g, "");
|
|
314209
314274
|
}
|
|
@@ -314232,6 +314297,7 @@ function fieldDescriptor(field, warnings, context) {
|
|
|
314232
314297
|
if (value.jsonType === "unknown") {
|
|
314233
314298
|
warnings.push(`PROTO_FIELD_TYPE_UNRESOLVED: map field ${context}.${field.name} has value type ${protoType} that could not be resolved; map values are not asserted`);
|
|
314234
314299
|
}
|
|
314300
|
+
const mapKeyType = classifyMapKey(field.keyType);
|
|
314235
314301
|
return {
|
|
314236
314302
|
name: String(field.name),
|
|
314237
314303
|
jsonName: protoJsonName(field),
|
|
@@ -314241,8 +314307,10 @@ function fieldDescriptor(field, warnings, context) {
|
|
|
314241
314307
|
map: true,
|
|
314242
314308
|
optional: Boolean(field.optional),
|
|
314243
314309
|
required: Boolean(field.required),
|
|
314310
|
+
...mapKeyType ? { mapKeyType } : {},
|
|
314244
314311
|
...value.jsonType !== "unknown" ? { mapValueType: value.jsonType } : {},
|
|
314245
314312
|
...value.jsonFormat ? { mapValueFormat: value.jsonFormat } : {},
|
|
314313
|
+
...value.intType ? { mapValueIntType: value.intType } : {},
|
|
314246
314314
|
...value.enumType ? { mapValueEnumType: value.enumType } : {},
|
|
314247
314315
|
...value.messageType ? { mapValueMessageType: value.messageType } : {}
|
|
314248
314316
|
};
|
|
@@ -314262,6 +314330,7 @@ function fieldDescriptor(field, warnings, context) {
|
|
|
314262
314330
|
optional: Boolean(field.optional),
|
|
314263
314331
|
required: Boolean(field.required),
|
|
314264
314332
|
...classified.nullable ? { nullable: true } : {},
|
|
314333
|
+
...classified.intType ? { intType: classified.intType } : {},
|
|
314265
314334
|
...classified.messageType ? { messageType: classified.messageType } : {},
|
|
314266
314335
|
...classified.enumType ? { enumType: classified.enumType } : {}
|
|
314267
314336
|
};
|
|
@@ -314497,13 +314566,16 @@ function buildShape(messageFullName, index, warnings, operationId, label, depth,
|
|
|
314497
314566
|
jsonName: field.jsonName,
|
|
314498
314567
|
jsonType: field.jsonType,
|
|
314499
314568
|
...field.jsonFormat ? { jsonFormat: field.jsonFormat } : {},
|
|
314569
|
+
...field.intType ? { intType: field.intType } : {},
|
|
314500
314570
|
repeated: field.repeated,
|
|
314501
314571
|
map: field.map,
|
|
314502
314572
|
required: field.required,
|
|
314503
314573
|
...field.nullable ? { nullable: true } : {},
|
|
314504
314574
|
...enumValues ? { enumValues } : {},
|
|
314575
|
+
...field.mapKeyType ? { mapKeyType: field.mapKeyType } : {},
|
|
314505
314576
|
...field.mapValueType ? { mapValueType: field.mapValueType } : {},
|
|
314506
314577
|
...field.mapValueFormat ? { mapValueFormat: field.mapValueFormat } : {},
|
|
314578
|
+
...field.mapValueIntType ? { mapValueIntType: field.mapValueIntType } : {},
|
|
314507
314579
|
...mapValueEnumValues ? { mapValueEnumValues } : {}
|
|
314508
314580
|
};
|
|
314509
314581
|
if (field.messageType && field.jsonType === "object" && !field.map) {
|
|
@@ -314570,18 +314642,38 @@ function createGrpcScript(spec) {
|
|
|
314570
314642
|
' if (expected === "any") return true;',
|
|
314571
314643
|
" return true;",
|
|
314572
314644
|
"}",
|
|
314645
|
+
'var GRPC_INT_SPECS = { int32:{s:true,b:32,min:"-2147483648",max:"2147483647"}, sint32:{s:true,b:32,min:"-2147483648",max:"2147483647"}, sfixed32:{s:true,b:32,min:"-2147483648",max:"2147483647"}, uint32:{s:false,b:32,min:"0",max:"4294967295"}, fixed32:{s:false,b:32,min:"0",max:"4294967295"}, int64:{s:true,b:64,min:"-9223372036854775808",max:"9223372036854775807"}, sint64:{s:true,b:64,min:"-9223372036854775808",max:"9223372036854775807"}, sfixed64:{s:true,b:64,min:"-9223372036854775808",max:"9223372036854775807"}, uint64:{s:false,b:64,min:"0",max:"18446744073709551615"}, fixed64:{s:false,b:64,min:"0",max:"18446744073709551615"} };',
|
|
314646
|
+
'function grpcDecStr(n) { var s = String(n); return (s.indexOf("e") === -1 && s.indexOf("E") === -1 && s.indexOf(".") === -1) ? s : null; }',
|
|
314647
|
+
'function grpcCmpIntStr(a, b) { var na = a.charAt(0) === "-", nb = b.charAt(0) === "-"; if (na !== nb) return na ? -1 : 1; var aa = (na ? a.slice(1) : a).replace(/^0+(?=[0-9])/, ""); var bb = (nb ? b.slice(1) : b).replace(/^0+(?=[0-9])/, ""); var mag; if (aa.length !== bb.length) mag = aa.length < bb.length ? -1 : 1; else mag = aa < bb ? -1 : (aa > bb ? 1 : 0); return na ? -mag : mag; }',
|
|
314648
|
+
'function grpcNormIntStr(s) { var neg = false; if (s.charAt(0) === "-") { neg = true; s = s.slice(1); } else if (s.charAt(0) === "+") { s = s.slice(1); } var ei = s.indexOf("e"); if (ei === -1) ei = s.indexOf("E"); var exp = 0; if (ei !== -1) { exp = parseInt(s.slice(ei + 1), 10); s = s.slice(0, ei); } var dot = s.indexOf("."); var intp = dot === -1 ? s : s.slice(0, dot); var frac = dot === -1 ? "" : s.slice(dot + 1); var digits = intp + frac; if (digits.length === 0) return null; if (/^0+$/.test(digits)) return "0"; if (exp >= 0) { var intpSize = intp === "0" ? 0 : intp.length; if (intpSize + exp > 20) return null; } var netExp = exp - frac.length; var out; if (netExp >= 0) { if (digits.length + netExp > 40) return null; out = digits; for (var z = 0; z < netExp; z++) out += "0"; } else { var cut = -netExp; var keepLen = digits.length - cut; var dropped = keepLen <= 0 ? digits : digits.slice(keepLen); for (var d = 0; d < dropped.length; d++) { if (dropped.charAt(d) !== "0") return null; } out = keepLen <= 0 ? "0" : digits.slice(0, keepLen); } var st = 0; while (st < out.length - 1 && out.charAt(st) === "0") st++; out = out.slice(st); if (out === "0") return "0"; if (out.length > 40) return null; return neg ? "-" + out : out; }',
|
|
314649
|
+
"function matchesInt(intType, value) {",
|
|
314650
|
+
" var spec = GRPC_INT_SPECS[intType]; if (!spec) return true;",
|
|
314651
|
+
" var num, canonical;",
|
|
314652
|
+
' if (typeof value === "number") { if (!Number.isFinite(value) || !Number.isInteger(value)) return false; num = value; canonical = grpcDecStr(value); }',
|
|
314653
|
+
' else if (typeof value === "string") { if (!/^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/.test(value)) return false; canonical = grpcNormIntStr(value); if (canonical === null) return false; num = Number(value); }',
|
|
314654
|
+
" else { return false; }",
|
|
314655
|
+
' if (canonical === "-0") canonical = "0";',
|
|
314656
|
+
' if (!spec.s && ((canonical !== null && canonical.charAt(0) === "-") || num < 0)) return false;',
|
|
314657
|
+
" if (spec.b === 32) return num >= Number(spec.min) && num <= Number(spec.max);",
|
|
314658
|
+
" if (canonical !== null) return grpcCmpIntStr(canonical, spec.min) >= 0 && grpcCmpIntStr(canonical, spec.max) <= 0;",
|
|
314659
|
+
" return false;",
|
|
314660
|
+
"}",
|
|
314661
|
+
'function matchesIntKey(intType, key) { var spec = GRPC_INT_SPECS[intType]; if (!spec) return true; if (!(spec.s ? /^[+-]?[0-9]+$/ : /^[0-9]+$/).test(key)) return false; var neg = key.charAt(0) === "-"; var body = (key.charAt(0) === "+" || key.charAt(0) === "-") ? key.slice(1) : key; if (body.length === 0) return false; var canon = neg ? "-" + body : body; return grpcCmpIntStr(canon, spec.min) >= 0 && grpcCmpIntStr(canon, spec.max) <= 0; }',
|
|
314662
|
+
"function matchesEnumNumber(n) { return Number.isInteger(n) && n >= -2147483648 && n <= 2147483647; }",
|
|
314573
314663
|
"function daysFromCivil(y, m, d) { y -= m <= 2 ? 1 : 0; var era = Math.floor(y / 400); var yoe = y - era * 400; var mp = m + (m > 2 ? -3 : 9); var doy = Math.floor((153 * mp + 2) / 5) + d - 1; var doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy; return era * 146097 + doe - 719468; }",
|
|
314574
314664
|
"function validDate(y, m, d) { if (y < 1 || y > 9999 || m < 1 || m > 12 || d < 1) return false; var mdays = [31, ((y % 4 === 0 && y % 100 !== 0) || y % 400 === 0) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; return d <= mdays[m - 1]; }",
|
|
314575
314665
|
'function validProtoTimestamp(value) { if (typeof value !== "string") return false; var m = value.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\\.([0-9]{1,9}))?(Z|[+-][0-9]{2}:[0-9]{2})$/); if (!m) return false; var y = Number(m[1]), mo = Number(m[2]), d = Number(m[3]), h = Number(m[4]), mi = Number(m[5]), s = Number(m[6]); if (!validDate(y, mo, d) || h > 23 || mi > 59 || s > 59) return false; var off = 0; if (m[8] !== "Z") { var sign = m[8][0] === "-" ? -1 : 1; var oh = Number(m[8].slice(1, 3)), om = Number(m[8].slice(4, 6)); if (oh > 23 || om > 59) return false; off = sign * (oh * 3600 + om * 60); } var sec = daysFromCivil(y, mo, d) * 86400 + h * 3600 + mi * 60 + s - off; return sec >= -62135596800 && sec <= 253402300799; }',
|
|
314576
314666
|
'function validProtoDuration(value) { if (typeof value !== "string") return false; var m = value.match(/^[+-]?(?:(0|[1-9][0-9]*)(?:\\.[0-9]{0,9})?|\\.[0-9]{0,9})s$/); if (!m) return false; return !m[1] || Number(m[1]) <= 315576000000; }',
|
|
314577
314667
|
'function validProtoFieldMask(value) { if (typeof value !== "string") return false; if (value === "") return true; var paths = value.split(","); for (var i = 0; i < paths.length; i++) { if (!/^[a-z][A-Za-z0-9]*(\\.[a-z][A-Za-z0-9]*)*$/.test(paths[i])) return false; } return true; }',
|
|
314578
314668
|
'function validProtoBytes(value) { if (typeof value !== "string") return false; if (!/^(?:[A-Za-z0-9+/]*|[A-Za-z0-9_-]*)={0,2}$/.test(value)) return false; var firstPad = value.indexOf("="); if (firstPad !== -1 && firstPad < value.length - (value.endsWith("==") ? 2 : 1)) return false; var pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0; var raw = value.length - pad; if (raw % 4 === 1) return false; return pad === 0 || (raw + pad) % 4 === 0 && pad === (4 - raw % 4) % 4; }',
|
|
314669
|
+
'function validProtoFloat32(value) { if (value === "NaN" || value === "Infinity" || value === "-Infinity") return true; var n = typeof value === "number" ? value : Number(value); if (!Number.isFinite(n)) return false; return Number.isFinite(Math.fround(n)); }',
|
|
314579
314670
|
"function matchesFormat(format, value) {",
|
|
314580
314671
|
" if (!format) return true;",
|
|
314581
314672
|
' if (format === "proto-timestamp") return validProtoTimestamp(value);',
|
|
314582
314673
|
' if (format === "proto-duration") return validProtoDuration(value);',
|
|
314583
314674
|
' if (format === "proto-field-mask") return validProtoFieldMask(value);',
|
|
314584
314675
|
' if (format === "proto-bytes") return validProtoBytes(value);',
|
|
314676
|
+
' if (format === "proto-float32") return validProtoFloat32(value);',
|
|
314585
314677
|
" return true;",
|
|
314586
314678
|
"}",
|
|
314587
314679
|
"function formatLabel(format) {",
|
|
@@ -314589,6 +314681,7 @@ function createGrpcScript(spec) {
|
|
|
314589
314681
|
' if (format === "proto-duration") return "a valid ProtoJSON Duration";',
|
|
314590
314682
|
' if (format === "proto-field-mask") return "a valid ProtoJSON FieldMask";',
|
|
314591
314683
|
' if (format === "proto-bytes") return "valid ProtoJSON base64 bytes";',
|
|
314684
|
+
' if (format === "proto-float32") return "a float32-representable number";',
|
|
314592
314685
|
' return format || "valid ProtoJSON";',
|
|
314593
314686
|
"}",
|
|
314594
314687
|
// Recursive shape checker: validates fields (with nested message descent,
|
|
@@ -314602,14 +314695,15 @@ function createGrpcScript(spec) {
|
|
|
314602
314695
|
' if (field.required && !present) { pm.expect.fail("gRPC response is missing required field " + label); return; }',
|
|
314603
314696
|
" if (!present) return;",
|
|
314604
314697
|
" var value = obj[key];",
|
|
314605
|
-
" if (
|
|
314698
|
+
" if (value === null) return;",
|
|
314606
314699
|
" if (field.repeated) {",
|
|
314607
314700
|
' if (!matchesScalar("array", value)) { pm.expect.fail("gRPC field " + label + " must be a repeated (array) value but was " + jsonTypeOf(value)); return; }',
|
|
314608
314701
|
" for (var i = 0; i < value.length; i++) {",
|
|
314609
314702
|
' var elem = value[i]; var elemLabel = label + "[" + i + "]";',
|
|
314610
314703
|
' if (field.shape) { if (!matchesScalar("object", elem)) { pm.expect.fail("gRPC repeated field " + elemLabel + " must be an object but was " + jsonTypeOf(elem)); } else { grpcCheckShape(elem, field.shape, elemLabel + "."); } continue; }',
|
|
314611
|
-
' if (field.enumValues && field.enumValues.length > 0) { if (typeof elem === "number") { if (!
|
|
314704
|
+
' if (field.enumValues && field.enumValues.length > 0) { if (typeof elem === "number") { if (!matchesEnumNumber(elem)) pm.expect.fail("gRPC repeated enum field " + elemLabel + " must be an int32-range integer but was " + elem); continue; } if (typeof elem !== "string") { pm.expect.fail("gRPC repeated enum field " + elemLabel + " must be a string or number but was " + jsonTypeOf(elem)); } else if (field.enumValues.indexOf(elem) === -1) { pm.expect.fail("gRPC repeated enum field " + elemLabel + " has value " + elem + " not in [" + field.enumValues.join(", ") + "]"); } continue; }',
|
|
314612
314705
|
' if (field.jsonType === "any") continue;',
|
|
314706
|
+
' if (field.intType) { if (!matchesInt(field.intType, elem)) pm.expect.fail("gRPC repeated field " + elemLabel + " must be a valid " + field.intType + " (in range) but was " + JSON.stringify(elem)); continue; }',
|
|
314613
314707
|
' if (!matchesScalar(field.jsonType, elem)) pm.expect.fail("gRPC repeated field " + elemLabel + " must be " + field.jsonType + " but was " + jsonTypeOf(elem));',
|
|
314614
314708
|
' else if (!matchesFormat(field.jsonFormat, elem)) pm.expect.fail("gRPC repeated field " + elemLabel + " must be " + formatLabel(field.jsonFormat));',
|
|
314615
314709
|
" }",
|
|
@@ -314617,17 +314711,28 @@ function createGrpcScript(spec) {
|
|
|
314617
314711
|
" }",
|
|
314618
314712
|
" if (field.map) {",
|
|
314619
314713
|
' if (!matchesScalar("object", value)) { pm.expect.fail("gRPC map field " + label + " must be an object but was " + jsonTypeOf(value)); return; }',
|
|
314620
|
-
|
|
314714
|
+
" var keys = Object.keys(value);",
|
|
314715
|
+
" for (var k = 0; k < keys.length; k++) {",
|
|
314716
|
+
' var mk = keys[k], mv = value[mk], mvLabel = label + "[" + mk + "]";',
|
|
314717
|
+
' if (field.mapKeyType === "boolean") { if (mk !== "true" && mk !== "false") pm.expect.fail("gRPC map key " + mvLabel + " must be the string true or false but was " + mk); }',
|
|
314718
|
+
' else if (field.mapKeyType) { if (!matchesIntKey(field.mapKeyType, mk)) pm.expect.fail("gRPC map key " + mvLabel + " must be a valid " + field.mapKeyType + " string (in range) but was " + mk); }',
|
|
314719
|
+
' if (field.mapValueShape && matchesScalar("object", mv)) { grpcCheckShape(mv, field.mapValueShape, mvLabel + "."); }',
|
|
314720
|
+
' else if (field.mapValueIntType) { if (!matchesInt(field.mapValueIntType, mv)) pm.expect.fail("gRPC map value " + mvLabel + " must be a valid " + field.mapValueIntType + " (in range) but was " + JSON.stringify(mv)); }',
|
|
314721
|
+
' else if (field.mapValueEnumValues && field.mapValueEnumValues.length > 0) { if (typeof mv === "number") { if (!matchesEnumNumber(mv)) pm.expect.fail("gRPC map enum value " + mvLabel + " must be an int32-range integer but was " + mv); } else if (typeof mv !== "string") { pm.expect.fail("gRPC map enum value " + mvLabel + " must be a string or number but was " + jsonTypeOf(mv)); } else if (field.mapValueEnumValues.indexOf(mv) === -1) { pm.expect.fail("gRPC map enum value " + mvLabel + " has value " + mv + " not in [" + field.mapValueEnumValues.join(", ") + "]"); } }',
|
|
314722
|
+
' else if (field.mapValueType && !matchesScalar(field.mapValueType, mv)) { pm.expect.fail("gRPC map value " + mvLabel + " must be " + field.mapValueType + " but was " + jsonTypeOf(mv)); }',
|
|
314723
|
+
' else if (field.mapValueType && !matchesFormat(field.mapValueFormat, mv)) { pm.expect.fail("gRPC map value " + mvLabel + " must be " + formatLabel(field.mapValueFormat)); }',
|
|
314724
|
+
" }",
|
|
314621
314725
|
" return;",
|
|
314622
314726
|
" }",
|
|
314623
314727
|
" if (field.enumValues && field.enumValues.length > 0) {",
|
|
314624
|
-
' if (typeof value === "number") { if (!
|
|
314728
|
+
' if (typeof value === "number") { if (!matchesEnumNumber(value)) pm.expect.fail("gRPC enum field " + label + " must be an int32-range integer but was " + value); return; }',
|
|
314625
314729
|
' if (typeof value !== "string") { pm.expect.fail("gRPC enum field " + label + " must be a string or number but was " + jsonTypeOf(value)); return; }',
|
|
314626
314730
|
' if (field.enumValues.indexOf(value) === -1) pm.expect.fail("gRPC enum field " + label + " has value " + value + " not in [" + field.enumValues.join(", ") + "]");',
|
|
314627
314731
|
" return;",
|
|
314628
314732
|
" }",
|
|
314629
314733
|
' if (field.jsonType === "any") return;',
|
|
314630
314734
|
' if (field.shape) { if (!matchesScalar("object", value)) { pm.expect.fail("gRPC field " + label + " must be an object but was " + jsonTypeOf(value)); return; } grpcCheckShape(value, field.shape, label + "."); return; }',
|
|
314735
|
+
' if (field.intType) { if (!matchesInt(field.intType, value)) pm.expect.fail("gRPC field " + label + " must be a valid " + field.intType + " (in range) but was " + JSON.stringify(value)); return; }',
|
|
314631
314736
|
' if (!matchesScalar(field.jsonType, value)) pm.expect.fail("gRPC field " + label + " must be " + field.jsonType + " but was " + jsonTypeOf(value));',
|
|
314632
314737
|
' else if (!matchesFormat(field.jsonFormat, value)) pm.expect.fail("gRPC field " + label + " must be " + formatLabel(field.jsonFormat));',
|
|
314633
314738
|
"}",
|
|
@@ -314677,6 +314782,103 @@ function methodPathOf(item) {
|
|
|
314677
314782
|
const value = payload?.methodPath;
|
|
314678
314783
|
return typeof value === "string" ? value : "";
|
|
314679
314784
|
}
|
|
314785
|
+
var GRPC_INT_SPECS = {
|
|
314786
|
+
int32: { signed: true, bits: 32, min: "-2147483648", max: "2147483647" },
|
|
314787
|
+
sint32: { signed: true, bits: 32, min: "-2147483648", max: "2147483647" },
|
|
314788
|
+
sfixed32: { signed: true, bits: 32, min: "-2147483648", max: "2147483647" },
|
|
314789
|
+
uint32: { signed: false, bits: 32, min: "0", max: "4294967295" },
|
|
314790
|
+
fixed32: { signed: false, bits: 32, min: "0", max: "4294967295" },
|
|
314791
|
+
int64: { signed: true, bits: 64, min: "-9223372036854775808", max: "9223372036854775807" },
|
|
314792
|
+
sint64: { signed: true, bits: 64, min: "-9223372036854775808", max: "9223372036854775807" },
|
|
314793
|
+
sfixed64: { signed: true, bits: 64, min: "-9223372036854775808", max: "9223372036854775807" },
|
|
314794
|
+
uint64: { signed: false, bits: 64, min: "0", max: "18446744073709551615" },
|
|
314795
|
+
fixed64: { signed: false, bits: 64, min: "0", max: "18446744073709551615" }
|
|
314796
|
+
};
|
|
314797
|
+
function grpcDecStr(n) {
|
|
314798
|
+
const s = String(n);
|
|
314799
|
+
return s.indexOf("e") === -1 && s.indexOf("E") === -1 && s.indexOf(".") === -1 ? s : null;
|
|
314800
|
+
}
|
|
314801
|
+
function grpcCmpIntStr(a, b) {
|
|
314802
|
+
const na = a.charAt(0) === "-";
|
|
314803
|
+
const nb = b.charAt(0) === "-";
|
|
314804
|
+
if (na !== nb) return na ? -1 : 1;
|
|
314805
|
+
const aa = (na ? a.slice(1) : a).replace(/^0+(?=[0-9])/, "");
|
|
314806
|
+
const bb = (nb ? b.slice(1) : b).replace(/^0+(?=[0-9])/, "");
|
|
314807
|
+
let mag;
|
|
314808
|
+
if (aa.length !== bb.length) mag = aa.length < bb.length ? -1 : 1;
|
|
314809
|
+
else mag = aa < bb ? -1 : aa > bb ? 1 : 0;
|
|
314810
|
+
return na ? -mag : mag;
|
|
314811
|
+
}
|
|
314812
|
+
function grpcNormIntStr(input) {
|
|
314813
|
+
let s = input;
|
|
314814
|
+
let neg = false;
|
|
314815
|
+
if (s.charAt(0) === "-") {
|
|
314816
|
+
neg = true;
|
|
314817
|
+
s = s.slice(1);
|
|
314818
|
+
} else if (s.charAt(0) === "+") {
|
|
314819
|
+
s = s.slice(1);
|
|
314820
|
+
}
|
|
314821
|
+
let ei = s.indexOf("e");
|
|
314822
|
+
if (ei === -1) ei = s.indexOf("E");
|
|
314823
|
+
let exp = 0;
|
|
314824
|
+
if (ei !== -1) {
|
|
314825
|
+
exp = parseInt(s.slice(ei + 1), 10);
|
|
314826
|
+
s = s.slice(0, ei);
|
|
314827
|
+
}
|
|
314828
|
+
const dot = s.indexOf(".");
|
|
314829
|
+
const intp = dot === -1 ? s : s.slice(0, dot);
|
|
314830
|
+
const frac = dot === -1 ? "" : s.slice(dot + 1);
|
|
314831
|
+
const digits = intp + frac;
|
|
314832
|
+
if (digits.length === 0) return null;
|
|
314833
|
+
if (/^0+$/.test(digits)) return "0";
|
|
314834
|
+
if (exp >= 0) {
|
|
314835
|
+
const intpSize = intp === "0" ? 0 : intp.length;
|
|
314836
|
+
if (intpSize + exp > 20) return null;
|
|
314837
|
+
}
|
|
314838
|
+
const netExp = exp - frac.length;
|
|
314839
|
+
let out;
|
|
314840
|
+
if (netExp >= 0) {
|
|
314841
|
+
if (digits.length + netExp > 40) return null;
|
|
314842
|
+
out = digits + "0".repeat(netExp);
|
|
314843
|
+
} else {
|
|
314844
|
+
const cut = -netExp;
|
|
314845
|
+
const keepLen = digits.length - cut;
|
|
314846
|
+
const dropped = keepLen <= 0 ? digits : digits.slice(keepLen);
|
|
314847
|
+
for (let d = 0; d < dropped.length; d += 1) {
|
|
314848
|
+
if (dropped.charAt(d) !== "0") return null;
|
|
314849
|
+
}
|
|
314850
|
+
out = keepLen <= 0 ? "0" : digits.slice(0, keepLen);
|
|
314851
|
+
}
|
|
314852
|
+
let st = 0;
|
|
314853
|
+
while (st < out.length - 1 && out.charAt(st) === "0") st += 1;
|
|
314854
|
+
out = out.slice(st);
|
|
314855
|
+
if (out === "0") return "0";
|
|
314856
|
+
if (out.length > 40) return null;
|
|
314857
|
+
return neg ? `-${out}` : out;
|
|
314858
|
+
}
|
|
314859
|
+
function matchesIntValue(intType, value) {
|
|
314860
|
+
const spec = GRPC_INT_SPECS[intType];
|
|
314861
|
+
if (!spec) return true;
|
|
314862
|
+
let num;
|
|
314863
|
+
let canonical;
|
|
314864
|
+
if (typeof value === "number") {
|
|
314865
|
+
if (!Number.isFinite(value) || !Number.isInteger(value)) return false;
|
|
314866
|
+
num = value;
|
|
314867
|
+
canonical = grpcDecStr(value);
|
|
314868
|
+
} else if (typeof value === "string") {
|
|
314869
|
+
if (!/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/.test(value)) return false;
|
|
314870
|
+
canonical = grpcNormIntStr(value);
|
|
314871
|
+
if (canonical === null) return false;
|
|
314872
|
+
num = Number(value);
|
|
314873
|
+
} else {
|
|
314874
|
+
return false;
|
|
314875
|
+
}
|
|
314876
|
+
if (canonical === "-0") canonical = "0";
|
|
314877
|
+
if (!spec.signed && (canonical !== null && canonical.charAt(0) === "-" || num < 0)) return false;
|
|
314878
|
+
if (spec.bits === 32) return num >= Number(spec.min) && num <= Number(spec.max);
|
|
314879
|
+
if (canonical !== null) return grpcCmpIntStr(canonical, spec.min) >= 0 && grpcCmpIntStr(canonical, spec.max) <= 0;
|
|
314880
|
+
return false;
|
|
314881
|
+
}
|
|
314680
314882
|
function matchesScalarValue(expected, value) {
|
|
314681
314883
|
const isJsonNumberString = (text) => /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/.test(text) && Number.isFinite(Number(text));
|
|
314682
314884
|
switch (expected) {
|
|
@@ -314765,6 +314967,12 @@ function validProtoBytes(value) {
|
|
|
314765
314967
|
if (raw % 4 === 1) return false;
|
|
314766
314968
|
return pad === 0 || (raw + pad) % 4 === 0 && pad === (4 - raw % 4) % 4;
|
|
314767
314969
|
}
|
|
314970
|
+
function validProtoFloat32(value) {
|
|
314971
|
+
if (value === "NaN" || value === "Infinity" || value === "-Infinity") return true;
|
|
314972
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
314973
|
+
if (!Number.isFinite(n)) return false;
|
|
314974
|
+
return Number.isFinite(Math.fround(n));
|
|
314975
|
+
}
|
|
314768
314976
|
function matchesFormatValue(format3, value) {
|
|
314769
314977
|
switch (format3) {
|
|
314770
314978
|
case void 0:
|
|
@@ -314777,6 +314985,8 @@ function matchesFormatValue(format3, value) {
|
|
|
314777
314985
|
return validProtoFieldMask(value);
|
|
314778
314986
|
case "proto-bytes":
|
|
314779
314987
|
return validProtoBytes(value);
|
|
314988
|
+
case "proto-float32":
|
|
314989
|
+
return validProtoFloat32(value);
|
|
314780
314990
|
default:
|
|
314781
314991
|
return true;
|
|
314782
314992
|
}
|
|
@@ -314811,6 +315021,12 @@ function staticRequestCheck(item, shape, methodPath2, warnings) {
|
|
|
314811
315021
|
continue;
|
|
314812
315022
|
}
|
|
314813
315023
|
if (field.jsonType === "any" || field.enumValues || field.map || field.shape) continue;
|
|
315024
|
+
if (field.intType) {
|
|
315025
|
+
if (!matchesIntValue(field.intType, value)) {
|
|
315026
|
+
warnings.push(`PROTO_REQUEST_FIELD_TYPE_MISMATCH: ${methodPath2} request field ${field.name} must be a valid ${field.intType} (in range)`);
|
|
315027
|
+
}
|
|
315028
|
+
continue;
|
|
315029
|
+
}
|
|
314814
315030
|
if (!matchesScalarValue(field.jsonType, value)) {
|
|
314815
315031
|
warnings.push(`PROTO_REQUEST_FIELD_TYPE_MISMATCH: ${methodPath2} request field ${field.name} must be ${field.jsonType}`);
|
|
314816
315032
|
} else if (!matchesFormatValue(field.jsonFormat, value)) {
|
|
@@ -314820,6 +315036,7 @@ function staticRequestCheck(item, shape, methodPath2, warnings) {
|
|
|
314820
315036
|
}
|
|
314821
315037
|
function instrumentGrpcCollection(collection, index) {
|
|
314822
315038
|
const warnings = [...index.warnings, ...index.operations.flatMap((operation) => operation.warnings)];
|
|
315039
|
+
warnings.push("GRPC_UNKNOWN_FIELDS_NOT_REJECTED: extra response JSON keys are not rejected (proto3 forward-compat + open well-known types; unknown wire fields are not surfaced by the binary->JSON decode)");
|
|
314823
315040
|
const specs = /* @__PURE__ */ new Map();
|
|
314824
315041
|
const requestShapes = /* @__PURE__ */ new Map();
|
|
314825
315042
|
for (const operation of index.operations) {
|
|
@@ -315326,6 +315543,7 @@ function createSoapScript(operation, warnings = []) {
|
|
|
315326
315543
|
` pm.expect(bodyText, "expected SOAP response element <" + soap.expectedResponseElement + "> not found").to.match(new RegExp(${JSON.stringify(responseRegex)}));`,
|
|
315327
315544
|
"});"
|
|
315328
315545
|
);
|
|
315546
|
+
warnings.push(`SOAP_RESPONSE_BODY_WRAPPER_ONLY: operation ${operation.name} asserts the SOAP envelope/body/fault and the top-level response element <${operation.expectedResponseElement}> but NOT its child element/scalar shapes (WSDL/XSD payload validation is out of scope)`);
|
|
315329
315547
|
} else if (operation.output) {
|
|
315330
315548
|
warnings.push(`SOAP_RESPONSE_ELEMENT_UNKNOWN: operation ${operation.name} has an output message but no resolvable response element; only Envelope/Body/Fault are asserted`);
|
|
315331
315549
|
}
|