@mnaoumov/typescript-lib 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -119,6 +119,7 @@ function nullableTypeGuard(isValue) {
119
119
  }
120
120
  function objectTypeGuard(propertyTypeGuards, options) {
121
121
  const shouldRejectUnknownKeys = options?.shouldRejectUnknownKeys ?? false;
122
+ const exactOptionalKeys = options?.exactOptionalKeys;
122
123
  return (value) => {
123
124
  if (!isObject(value)) {
124
125
  return false;
@@ -126,8 +127,15 @@ function objectTypeGuard(propertyTypeGuards, options) {
126
127
  if (shouldRejectUnknownKeys && Object.keys(value).some((key) => !Object.hasOwn(propertyTypeGuards, key))) {
127
128
  return false;
128
129
  }
129
- for (const key in propertyTypeGuards) {
130
- if (!propertyTypeGuards[key](Reflect.get(value, key))) {
130
+ const typeGuards = propertyTypeGuards;
131
+ for (const [key, typeGuard] of Object.entries(typeGuards)) {
132
+ if (exactOptionalKeys && !Object.hasOwn(value, key)) {
133
+ if (Object.hasOwn(exactOptionalKeys, key)) {
134
+ continue;
135
+ }
136
+ return false;
137
+ }
138
+ if (!typeGuard(Reflect.get(value, key))) {
131
139
  return false;
132
140
  }
133
141
  }
@@ -168,4 +176,4 @@ function isReadonlyArray(value) {
168
176
  optionalTypeGuard,
169
177
  unionTypeGuard
170
178
  });
171
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3R5cGUtZ3VhcmRzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHR5cGUgZ3VhcmRzLCBhbmQgY29tYmluYXRvcnMgdGhhdCBidWlsZCBhIHtAbGluayBUeXBlR3VhcmR9IG91dCBvZiBvdGhlcnMuXG4gKlxuICogVGhlIGNvbWJpbmF0b3JzIGhlcmUgd29yayBvbiBiYXJlIHR5cGUgZ3VhcmRzLiBUaGVpciBgYXBpLWNvbnRyYWN0YCBjb3VudGVycGFydHMgKGBhcnJheUd1YXJkYCwgYG9wdGlvbmFsR3VhcmRgLFxuICogLi4uKSB3b3JrIG9uIGFuIGBFeHBlY3RlZFR5cGVHdWFyZGAsIGEgdHlwZSBndWFyZCBwYWlyZWQgd2l0aCB0aGUgdGV4dCBhbiBpc3N1ZSBtZXNzYWdlIHJlcG9ydHMsIGFuZCB0aGVpciBuYW1lc1xuICogZHJvcCB0aGUgYFR5cGVgIHRoaXMgbGF5ZXIncyBuYW1lcyBjYXJyeS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEdlbmVyaWNGdW5jdGlvbiB9IGZyb20gJy4vZnVuY3Rpb24udHMnO1xuXG5pbXBvcnQgeyBub29wIH0gZnJvbSAnLi9mdW5jdGlvbi50cyc7XG5cbi8qKlxuICogQSB0eXBlIHRoYXQgcmVwcmVzZW50cyBhIGdlbmVyaWMgb2JqZWN0LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSBiYXNlIHR5cGUgdG8gaW50ZXJzZWN0IHdpdGguXG4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyaWNPYmplY3Q8VCA9IHVua25vd24+ID0gUmVjb3JkPHN0cmluZyB8IHN5bWJvbCwgdW5rbm93bj4gJiBUO1xuXG4vKipcbiAqIFRoZSB0eXBlIGEge0BsaW5rIFR5cGVHdWFyZH0gbmFycm93cyB0by4gRGlzdHJpYnV0ZXMgb3ZlciBhIHVuaW9uIG9mIGd1YXJkcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRUeXBlR3VhcmQgLSBUaGUgdHlwZSBndWFyZC5cbiAqL1xuZXhwb3J0IHR5cGUgR3VhcmRlZFR5cGU8VFR5cGVHdWFyZD4gPSBUVHlwZUd1YXJkIGV4dGVuZHMgKHZhbHVlOiB1bmtub3duKSA9PiB2YWx1ZSBpcyBpbmZlciBUID8gVCA6IG5ldmVyO1xuXG4vKipcbiAqIEEgdmFsdWUge0BsaW5rIGxpdGVyYWxUeXBlR3VhcmR9IGNhbiBjb21wYXJlIGFnYWluc3QuXG4gKi9cbmV4cG9ydCB0eXBlIExpdGVyYWwgPSBiaWdpbnQgfCBib29sZWFuIHwgbnVsbCB8IG51bWJlciB8IHN0cmluZyB8IHN5bWJvbCB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgb2JqZWN0VHlwZUd1YXJkfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPYmplY3RUeXBlR3VhcmRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgYSB2YWx1ZSBjYXJyeWluZyBhbiBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5IHRoYXQgbm8gcHJvcGVydHkgZ3VhcmQgbmFtZXMgaXMgcmVmdXNlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkUmVqZWN0VW5rbm93bktleXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIE9uZSB0eXBlIGd1YXJkIHBlciBwcm9wZXJ0eSBvZiBhbiBvYmplY3QgdHlwZSwgYXMge0BsaW5rIG9iamVjdFR5cGVHdWFyZH0gdGFrZXMgdGhlbS4gRXZlcnkga2V5IG9mIGBUYCBtdXN0IGJlXG4gKiBsaXN0ZWQuIFRoZSBndWFyZCBvZiBhbiBvcHRpb25hbCBwcm9wZXJ0eSBpcyB0eXBlZCB0byBuYXJyb3cgdG8gYHVuZGVmaW5lZGAgYXMgd2VsbCwgYnV0IGEgZ3VhcmQgdGhhdCByZWZ1c2VzXG4gKiBgdW5kZWZpbmVkYCBzdGlsbCBjb21waWxlcyB0aGVyZSwgc28gd2lkZW4gaXQgd2l0aCB7QGxpbmsgb3B0aW9uYWxUeXBlR3VhcmR9OiBhbiBhYnNlbnQgcHJvcGVydHkgcmVhZHMgYXNcbiAqIGB1bmRlZmluZWRgLCBhbmQgYSBndWFyZCByZWZ1c2luZyBpdCByZWZ1c2VzIHRoZSBvYmplY3QuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIG9iamVjdCB0eXBlLlxuICovXG5leHBvcnQgdHlwZSBQcm9wZXJ0eVR5cGVHdWFyZHM8VCBleHRlbmRzIG9iamVjdD4gPSB7XG4gIHJlYWRvbmx5IFtUS2V5IGluIGtleW9mIFRdLT86IFR5cGVHdWFyZDxQYXJ0aWFsPFBpY2s8VCwgVEtleT4+IGV4dGVuZHMgUGljazxULCBUS2V5PiA/IFRbVEtleV0gfCB1bmRlZmluZWQgOiBUW1RLZXldPjtcbn07XG5cbi8qKlxuICogQSBmdW5jdGlvbiBkZWNpZGluZyB3aGV0aGVyIGEgdmFsdWUgaXMgYSBgVGAuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgdGhlIGd1YXJkIG5hcnJvd3MgdG8uXG4gKi9cbmV4cG9ydCB0eXBlIFR5cGVHdWFyZDxUPiA9ICh2YWx1ZTogdW5rbm93bikgPT4gdmFsdWUgaXMgVDtcblxudHlwZSBOdWxsYWJsZUNvbnN0cmFpbnQ8VD4gPSBudWxsIGV4dGVuZHMgVCA/IHVua25vd24gOiB1bmRlZmluZWQgZXh0ZW5kcyBUID8gdW5rbm93biA6IG5ldmVyO1xuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbiBhcnJheSB3aG9zZSBldmVyeSBpdGVtIHRoZSBpdGVtIGd1YXJkIGFjY2VwdHMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgYW4gaXRlbS5cbiAqIEBwYXJhbSBpc0l0ZW0gLSBUaGUgZ3VhcmQgZm9yIG9uZSBpdGVtLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlUeXBlR3VhcmQ8VD4oaXNJdGVtOiBUeXBlR3VhcmQ8VD4pOiBUeXBlR3VhcmQ8VFtdPiB7XG4gIHJldHVybiAodmFsdWUpOiB2YWx1ZSBpcyBUW10gPT4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkoKGl0ZW0pID0+IGlzSXRlbShpdGVtKSk7XG59XG5cbi8qKlxuICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGB0cnVlYC4gVGhyb3dzIGlmIGl0IGlzIG5vdC5cbiAqXG4gKiBVc2UgaW4gcGxhY2Ugb2YgYC8qIHY4IGlnbm9yZSAqXFwvYCBmb3IgZGVmZW5zaXZlIGd1YXJkcyB0aGF0IHNob3VsZFxuICogbmV2ZXIgdHJpZ2dlciBhdCBydW50aW1lIGJ1dCB3b3VsZCBvdGhlcndpc2UgY3JlYXRlIHVuY292ZXJlZCBicmFuY2hlcy5cbiAqXG4gKiBAcGFyYW0gaXNUcnVlIC0gVGhlIGNvbmRpdGlvbiB0byBhc3NlcnQuXG4gKiBAcGFyYW0gZXJyb3JPck1lc3NhZ2UgLSBUaGUgZXJyb3Igb3IgbWVzc2FnZSB0byB0aHJvdyBpZiB0aGUgY29uZGl0aW9uIGlzIGBmYWxzZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoaXNUcnVlOiBib29sZWFuLCBlcnJvck9yTWVzc2FnZTogRXJyb3IgfCBzdHJpbmcpOiBhc3NlcnRzIGlzVHJ1ZSB7XG4gIGlmICghaXNUcnVlKSB7XG4gICAgdGhyb3cgdHlwZW9mIGVycm9yT3JNZXNzYWdlID09PSAnc3RyaW5nJyA/IG5ldyBFcnJvcihlcnJvck9yTWVzc2FnZSkgOiBlcnJvck9yTWVzc2FnZTtcbiAgfVxufVxuXG4vKipcbiAqIEFzc2VydHMgdGhhdCBhIHZhbHVlIGlzIGEgZ2VuZXJpYyBvYmplY3QsIG5hcnJvd2luZyBpdHMgdHlwZSBpbiBwbGFjZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUuXG4gKiBAcGFyYW0gX29iamVjdCAtIFRoZSB2YWx1ZSB0byBhc3NlcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRHZW5lcmljT2JqZWN0PFQ+KF9vYmplY3Q6IFQpOiBhc3NlcnRzIF9vYmplY3QgaXMgR2VuZXJpY09iamVjdDxUPiB7XG4gIG5vb3AoKTtcbn1cblxuLyoqXG4gKiBBc3NlcnRzIGF0IGNvbXBpbGUgdGltZSB0aGF0IGV2ZXJ5IGNhc2Ugb2YgYSBkaXNjcmltaW5hdGVkIHVuaW9uIGhhcyBiZWVuXG4gKiBoYW5kbGVkLiBQbGFjZSBhdCB0aGUgYGRlZmF1bHRgIGJyYW5jaCBvZiBhIGBzd2l0Y2hgIG92ZXIgYSB1bmlvbiBvciBlbnVtLlxuICpcbiAqIElmIGEgbmV3IHZhcmlhbnQgaXMgYWRkZWQgdG8gdGhlIHVuaW9uIHdpdGhvdXQgYSBtYXRjaGluZyBgY2FzZWAsIHRoZSBjYWxsXG4gKiB0byB7QGxpbmsgYXNzZXJ0TmV2ZXJ9IGZhaWxzIHRvIGNvbXBpbGUgYmVjYXVzZSBgdmFsdWVgIGlzIG5vIGxvbmdlciBgbmV2ZXJgLlxuICogSWYgcmVhY2hlZCBhdCBydW50aW1lIChlLmcuIGJlY2F1c2UgdGhlIHZhbHVlIHdhcyBieXBhc3NlZCB2aWEgSlNPTiBvciBhXG4gKiB0eXBlIGFzc2VydGlvbiksIGl0IHRocm93cyBhIGRlc2NyaXB0aXZlIGBFcnJvcmAuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBzd2l0Y2ggKG1vZGUpIHtcbiAqICAgY2FzZSAnYSc6IHJldHVybiBkb0EoKTtcbiAqICAgY2FzZSAnYic6IHJldHVybiBkb0IoKTtcbiAqICAgZGVmYXVsdDogYXNzZXJ0TmV2ZXIobW9kZSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgZXhoYXVzdGl2ZWx5LWhhbmRsZWQgdmFsdWUsIG5hcnJvd2VkIHRvIGBuZXZlcmAgYnkgY29udHJvbCBmbG93LlxuICogQHRocm93cyBBbHdheXMsIGlmIHJlYWNoZWQgYXQgcnVudGltZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5ldmVyKHZhbHVlOiBuZXZlcik6IG5ldmVyIHtcbiAgdGhyb3cgbmV3IEVycm9yKGBVbmhhbmRsZWQgdmFsdWU6ICR7U3RyaW5nKHZhbHVlKX1gKTtcbn1cblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgYSB2YWx1ZSBpcyBub3QgYG51bGxgIG9yIGB1bmRlZmluZWRgLCBuYXJyb3dpbmcgaXRzIHR5cGUgaW4gcGxhY2UuXG4gKlxuICogT25seSBjYWxsYWJsZSB3aGVuIGBUYCBpbmNsdWRlcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuIFBhc3NpbmcgYW4gYWxyZWFkeSBub24tbnVsbGFibGUgdHlwZSBpcyBhIGNvbXBpbGUgZXJyb3IuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIGVycm9yT3JNZXNzYWdlIC0gT3B0aW9uYWwge0BsaW5rIEVycm9yfSBvciBlcnJvciBtZXNzYWdlIHN0cmluZy5cbiAqIEB0aHJvd3MgSWYgdGhlIHZhbHVlIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vbk51bGxhYmxlPFQgZXh0ZW5kcyBOdWxsYWJsZUNvbnN0cmFpbnQ8VD4+KHZhbHVlOiBULCBlcnJvck9yTWVzc2FnZT86IEVycm9yIHwgc3RyaW5nKTogYXNzZXJ0cyB2YWx1ZSBpcyBOb25OdWxsYWJsZTxUPiB7XG4gIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXJyb3JPck1lc3NhZ2UgPz89IHZhbHVlID09PSBudWxsID8gJ1ZhbHVlIGlzIG51bGwnIDogJ1ZhbHVlIGlzIHVuZGVmaW5lZCc7XG4gIGNvbnN0IGVycm9yID0gdHlwZW9mIGVycm9yT3JNZXNzYWdlID09PSAnc3RyaW5nJyA/IG5ldyBFcnJvcihlcnJvck9yTWVzc2FnZSkgOiBlcnJvck9yTWVzc2FnZTtcbiAgdGhyb3cgZXJyb3I7XG59XG5cbi8qKlxuICogRW5zdXJlcyB0aGF0IGEgdmFsdWUgaXMgYSBnZW5lcmljIG9iamVjdCwgcmV0dXJuaW5nIGl0IHdpdGggbmFycm93ZWQgdHlwZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUuXG4gKiBAcGFyYW0gJG9iamVjdCAtIFRoZSB2YWx1ZSB0byBlbnN1cmUuXG4gKiBAcmV0dXJucyBUaGUgdmFsdWUgYXMgYSBnZW5lcmljIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZUdlbmVyaWNPYmplY3Q8VD4oJG9iamVjdDogVCk6IEdlbmVyaWNPYmplY3Q8VD4ge1xuICByZXR1cm4gJG9iamVjdCBhcyBHZW5lcmljT2JqZWN0PFQ+O1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhIHZhbHVlIGlzIG5vdCBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgYW5kIHJldHVybnMgaXQgd2l0aCBuYXJyb3dlZCB0eXBlLlxuICpcbiAqIE9ubHkgY2FsbGFibGUgd2hlbiBgVGAgaW5jbHVkZXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLiBQYXNzaW5nIGFuIGFscmVhZHkgbm9uLW51bGxhYmxlIHR5cGUgaXMgYSBjb21waWxlIGVycm9yLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSBlcnJvck9yTWVzc2FnZSAtIE9wdGlvbmFsIHtAbGluayBFcnJvcn0gb3IgZXJyb3IgbWVzc2FnZSBzdHJpbmcuXG4gKiBAcmV0dXJucyBUaGUgdmFsdWUgd2l0aCBgbnVsbGAgYW5kIGB1bmRlZmluZWRgIGV4Y2x1ZGVkIGZyb20gaXRzIHR5cGUuXG4gKiBAdGhyb3dzIElmIHRoZSB2YWx1ZSBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVOb25OdWxsYWJsZTxUIGV4dGVuZHMgTnVsbGFibGVDb25zdHJhaW50PFQ+Pih2YWx1ZTogVCwgZXJyb3JPck1lc3NhZ2U/OiBFcnJvciB8IHN0cmluZyk6IE5vbk51bGxhYmxlPFQ+IHtcbiAgYXNzZXJ0Tm9uTnVsbGFibGUodmFsdWUsIGVycm9yT3JNZXNzYWdlKTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbnkgZnVuY3Rpb24sIG5hcnJvd2VkIHRvIHRoZSBzaWduYXR1cmUgYFRGdW5jdGlvbmAuIE9ubHkgdGhhdCB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvblxuICogaXMgY2hlY2tlZDogYSBzaWduYXR1cmUgY2Fubm90IGJlIGNoZWNrZWQgYXQgcnVudGltZSwgc28gdGhlIGd1YXJkIHRydXN0cyBpdC5cbiAqXG4gKiBAdHlwZVBhcmFtIFRGdW5jdGlvbiAtIFRoZSBzaWduYXR1cmUgdGhlIGd1YXJkIG5hcnJvd3MgdG8uXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdW5jdGlvblR5cGVHdWFyZDxURnVuY3Rpb24gZXh0ZW5kcyBHZW5lcmljRnVuY3Rpb24+KCk6IFR5cGVHdWFyZDxURnVuY3Rpb24+IHtcbiAgcmV0dXJuICh2YWx1ZSk6IHZhbHVlIGlzIFRGdW5jdGlvbiA9PiBpc0Z1bmN0aW9uKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBndWFyZCBhY2NlcHRpbmcgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzcywgb3Igb2YgYSBjbGFzcyBkZXJpdmVkIGZyb20gaXQuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgYW4gaW5zdGFuY2UuXG4gKiBAcGFyYW0gY29uc3RydWN0b3IgLSBUaGUgY2xhc3MuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YW5jZU9mVHlwZUd1YXJkPFQ+KGNvbnN0cnVjdG9yOiBhYnN0cmFjdCBuZXcgKC4uLmFyZ3VtZW50c186IG5ldmVyW10pID0+IFQpOiBUeXBlR3VhcmQ8VD4ge1xuICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgVCA9PiB2YWx1ZSBpbnN0YW5jZW9mIGNvbnN0cnVjdG9yO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYSBib29sZWFuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgR2VuZXJpY0Z1bmN0aW9uIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGBudWxsYC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBgbnVsbGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudWxsIHtcbiAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYSBudW1iZXIuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYW4gb2JqZWN0OiBub3QgYG51bGxgLCBhbmQgbm90IGEgcHJpbWl0aXZlIG9yIGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3QodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBvYmplY3Qge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGFuIGFycmF5IG9mIHN0cmluZ3MuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgd2hvc2UgZXZlcnkgaXRlbSBpcyBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nQXJyYXkodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBzdHJpbmdbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5ldmVyeShpc1N0cmluZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBgdW5kZWZpbmVkYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgZ3VhcmQgYWNjZXB0aW5nIGV4YWN0bHkgdGhlIGtleXMgb2YgYSByZWNvcmQuIFR5cGluZyB0aGUgcmVjb3JkIG92ZXIgYSB1bmlvbiwgYXNcbiAqIGBsaXRlcmFsVHlwZUd1YXJkPE1vZGU+KHsgQTogdHJ1ZSwgQjogdHJ1ZSB9KWAsIG1ha2VzIGEgbWVtYmVyIGxhdGVyIGFkZGVkIHRvIHRoZSB1bmlvbiBmYWlsIHRvIGNvbXBpbGUgdW50aWxcbiAqIGl0IGlzIGxpc3RlZC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgYWNjZXB0ZWQgc3RyaW5ncy5cbiAqIEBwYXJhbSBsaXRlcmFscyAtIEEgcmVjb3JkIHdob3NlIGtleXMgYXJlIHRoZSBhY2NlcHRlZCBzdHJpbmdzLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGl0ZXJhbFR5cGVHdWFyZDxUIGV4dGVuZHMgc3RyaW5nPihsaXRlcmFsczogUmVhZG9ubHk8UmVjb3JkPFQsIHRydWU+Pik6IFR5cGVHdWFyZDxUPjtcbi8qKlxuICogQnVpbGRzIGEgZ3VhcmQgYWNjZXB0aW5nIGV4YWN0bHkgdGhlIGxpc3RlZCB2YWx1ZXMsIGNvbXBhcmVkIGFzIGBBcnJheS5wcm90b3R5cGUuaW5jbHVkZXNgIGNvbXBhcmVzIHRoZW0uXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIGFjY2VwdGVkIHZhbHVlcy5cbiAqIEBwYXJhbSBsaXRlcmFscyAtIFRoZSBhY2NlcHRlZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsVHlwZUd1YXJkPFQgZXh0ZW5kcyBMaXRlcmFsPihsaXRlcmFsczogcmVhZG9ubHkgVFtdKTogVHlwZUd1YXJkPFQ+O1xuLyoqXG4gKiBCdWlsZHMgYSBndWFyZCBhY2NlcHRpbmcgZXhhY3RseSB0aGUgbGlzdGVkIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gbGl0ZXJhbHMgLSBUaGUgYWNjZXB0ZWQgdmFsdWVzLCBhcyBhIGxpc3Qgb3IgYXMgdGhlIGtleXMgb2YgYSByZWNvcmQuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsVHlwZUd1YXJkKGxpdGVyYWxzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB0cnVlPj4gfCByZWFkb25seSBMaXRlcmFsW10pOiBUeXBlR3VhcmQ8TGl0ZXJhbD4ge1xuICBpZiAoaXNSZWFkb25seUFycmF5KGxpdGVyYWxzKSkge1xuICAgIGNvbnN0IGxpdGVyYWxMaXN0OiByZWFkb25seSB1bmtub3duW10gPSBsaXRlcmFscztcbiAgICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgTGl0ZXJhbCA9PiBsaXRlcmFsTGlzdC5pbmNsdWRlcyh2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgTGl0ZXJhbCA9PiBpc1N0cmluZyh2YWx1ZSkgJiYgT2JqZWN0Lmhhc093bihsaXRlcmFscywgdmFsdWUpO1xufVxuXG4vKipcbiAqIFdpZGVucyBhIGd1YXJkIHRvIGFsc28gYWNjZXB0IGBudWxsYC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSB0aGUgZ3VhcmQgbmFycm93cyB0by5cbiAqIEBwYXJhbSBpc1ZhbHVlIC0gVGhlIGd1YXJkIHRvIHdpZGVuLlxuICogQHJldHVybnMgQSBndWFyZCBhY2NlcHRpbmcgd2hhdCBgaXNWYWx1ZWAgYWNjZXB0cywgb3IgYG51bGxgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbGFibGVUeXBlR3VhcmQ8VD4oaXNWYWx1ZTogVHlwZUd1YXJkPFQ+KTogVHlwZUd1YXJkPG51bGwgfCBUPiB7XG4gIHJldHVybiB1bmlvblR5cGVHdWFyZChpc051bGwsIGlzVmFsdWUpO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbiBvYmplY3Qgd2hvc2UgZXZlcnkgbGlzdGVkIHByb3BlcnR5IGl0cyBndWFyZCBhY2NlcHRzLiBBIHByb3BlcnR5IGlzIHJlYWQgd2l0aFxuICogYFJlZmxlY3QuZ2V0YCwgc28gYW4gaW5oZXJpdGVkIG9uZSBjb3VudHMgYW5kIGFuIGFic2VudCBvbmUgcmVhZHMgYXMgYHVuZGVmaW5lZGAuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIG9iamVjdCB0eXBlLlxuICogQHBhcmFtIHByb3BlcnR5VHlwZUd1YXJkcyAtIE9uZSBndWFyZCBwZXIgcHJvcGVydHkgb2YgYFRgLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBmb3IgdGhlIGd1YXJkLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0VHlwZUd1YXJkPFQgZXh0ZW5kcyBvYmplY3Q+KHByb3BlcnR5VHlwZUd1YXJkczogUHJvcGVydHlUeXBlR3VhcmRzPFQ+LCBvcHRpb25zPzogT2JqZWN0VHlwZUd1YXJkT3B0aW9ucyk6IFR5cGVHdWFyZDxUPiB7XG4gIGNvbnN0IHNob3VsZFJlamVjdFVua25vd25LZXlzID0gb3B0aW9ucz8uc2hvdWxkUmVqZWN0VW5rbm93bktleXMgPz8gZmFsc2U7XG4gIHJldHVybiAodmFsdWUpOiB2YWx1ZSBpcyBUID0+IHtcbiAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRSZWplY3RVbmtub3duS2V5cyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkuc29tZSgoa2V5KSA9PiAhT2JqZWN0Lmhhc093bihwcm9wZXJ0eVR5cGVHdWFyZHMsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcGVydHlUeXBlR3VhcmRzKSB7XG4gICAgICBpZiAoIXByb3BlcnR5VHlwZUd1YXJkc1trZXldKFJlZmxlY3QuZ2V0KHZhbHVlLCBrZXkpKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbi8qKlxuICogV2lkZW5zIGEgZ3VhcmQgdG8gYWxzbyBhY2NlcHQgYHVuZGVmaW5lZGAsIHdoaWNoIGlzIHdoYXQgYW4gb3B0aW9uYWwgcHJvcGVydHkgb3IgcGFyYW1ldGVyIHJlYWRzIGFzIHdoZW4gaXQgaXNcbiAqIGxlZnQgb3V0LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIHRoZSBndWFyZCBuYXJyb3dzIHRvLlxuICogQHBhcmFtIGlzVmFsdWUgLSBUaGUgZ3VhcmQgdG8gd2lkZW4uXG4gKiBAcmV0dXJucyBBIGd1YXJkIGFjY2VwdGluZyB3aGF0IGBpc1ZhbHVlYCBhY2NlcHRzLCBvciBgdW5kZWZpbmVkYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGlvbmFsVHlwZUd1YXJkPFQ+KGlzVmFsdWU6IFR5cGVHdWFyZDxUPik6IFR5cGVHdWFyZDxUIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiB1bmlvblR5cGVHdWFyZChpc1VuZGVmaW5lZCwgaXNWYWx1ZSk7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgZ3VhcmQgYWNjZXB0aW5nIHdoYXQgYW55IG9mIHRoZSBnaXZlbiBndWFyZHMgYWNjZXB0cy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRUeXBlR3VhcmRzIC0gVGhlIGd1YXJkcy5cbiAqIEBwYXJhbSB0eXBlR3VhcmRzIC0gVGhlIGd1YXJkcywgdHJpZWQgaW4gb3JkZXIuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmlvblR5cGVHdWFyZDxjb25zdCBUVHlwZUd1YXJkcyBleHRlbmRzIHJlYWRvbmx5IFR5cGVHdWFyZDx1bmtub3duPltdPihcbiAgLi4udHlwZUd1YXJkczogVFR5cGVHdWFyZHNcbik6IFR5cGVHdWFyZDxHdWFyZGVkVHlwZTxUVHlwZUd1YXJkc1tudW1iZXJdPj4ge1xuICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgR3VhcmRlZFR5cGU8VFR5cGVHdWFyZHNbbnVtYmVyXT4gPT4gdHlwZUd1YXJkcy5zb21lKCh0eXBlR3VhcmQpID0+IHR5cGVHdWFyZCh2YWx1ZSkpO1xufVxuXG5mdW5jdGlvbiBpc1JlYWRvbmx5QXJyYXkodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyByZWFkb25seSB1bmtub3duW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFZQSxzQkFBcUI7QUE2RGQsU0FBUyxlQUFrQixRQUFzQztBQUN0RSxTQUFPLENBQUMsVUFBd0IsTUFBTSxRQUFRLEtBQUssS0FBSyxNQUFNLE1BQU0sQ0FBQyxTQUFTLE9BQU8sSUFBSSxDQUFDO0FBQzVGO0FBV08sU0FBUyxPQUFPLFFBQWlCLGdCQUFnRDtBQUN0RixNQUFJLENBQUMsUUFBUTtBQUNYLFVBQU0sT0FBTyxtQkFBbUIsV0FBVyxJQUFJLE1BQU0sY0FBYyxJQUFJO0FBQUEsRUFDekU7QUFDRjtBQVFPLFNBQVMsb0JBQXVCLFNBQWlEO0FBQ3RGLDRCQUFLO0FBQ1A7QUF1Qk8sU0FBUyxZQUFZLE9B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
179
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3R5cGUtZ3VhcmRzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHR5cGUgZ3VhcmRzLCBhbmQgY29tYmluYXRvcnMgdGhhdCBidWlsZCBhIHtAbGluayBUeXBlR3VhcmR9IG91dCBvZiBvdGhlcnMuXG4gKlxuICogVGhlIGNvbWJpbmF0b3JzIGhlcmUgd29yayBvbiBiYXJlIHR5cGUgZ3VhcmRzLiBUaGVpciBgYXBpLWNvbnRyYWN0YCBjb3VudGVycGFydHMgKGBhcnJheUd1YXJkYCwgYG9wdGlvbmFsR3VhcmRgLFxuICogLi4uKSB3b3JrIG9uIGFuIGBFeHBlY3RlZFR5cGVHdWFyZGAsIGEgdHlwZSBndWFyZCBwYWlyZWQgd2l0aCB0aGUgdGV4dCBhbiBpc3N1ZSBtZXNzYWdlIHJlcG9ydHMsIGFuZCB0aGVpciBuYW1lc1xuICogZHJvcCB0aGUgYFR5cGVgIHRoaXMgbGF5ZXIncyBuYW1lcyBjYXJyeS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEdlbmVyaWNGdW5jdGlvbiB9IGZyb20gJy4vZnVuY3Rpb24udHMnO1xuXG5pbXBvcnQgeyBub29wIH0gZnJvbSAnLi9mdW5jdGlvbi50cyc7XG5cbi8qKlxuICogQSB0eXBlIHRoYXQgcmVwcmVzZW50cyBhIGdlbmVyaWMgb2JqZWN0LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSBiYXNlIHR5cGUgdG8gaW50ZXJzZWN0IHdpdGguXG4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyaWNPYmplY3Q8VCA9IHVua25vd24+ID0gUmVjb3JkPHN0cmluZyB8IHN5bWJvbCwgdW5rbm93bj4gJiBUO1xuXG4vKipcbiAqIFRoZSB0eXBlIGEge0BsaW5rIFR5cGVHdWFyZH0gbmFycm93cyB0by4gRGlzdHJpYnV0ZXMgb3ZlciBhIHVuaW9uIG9mIGd1YXJkcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRUeXBlR3VhcmQgLSBUaGUgdHlwZSBndWFyZC5cbiAqL1xuZXhwb3J0IHR5cGUgR3VhcmRlZFR5cGU8VFR5cGVHdWFyZD4gPSBUVHlwZUd1YXJkIGV4dGVuZHMgKHZhbHVlOiB1bmtub3duKSA9PiB2YWx1ZSBpcyBpbmZlciBUID8gVCA6IG5ldmVyO1xuXG4vKipcbiAqIEEgdmFsdWUge0BsaW5rIGxpdGVyYWxUeXBlR3VhcmR9IGNhbiBjb21wYXJlIGFnYWluc3QuXG4gKi9cbmV4cG9ydCB0eXBlIExpdGVyYWwgPSBiaWdpbnQgfCBib29sZWFuIHwgbnVsbCB8IG51bWJlciB8IHN0cmluZyB8IHN5bWJvbCB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgb2JqZWN0VHlwZUd1YXJkfS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgb2JqZWN0IHR5cGUgdGhlIGd1YXJkIG5hcnJvd3MgdG8uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0VHlwZUd1YXJkT3B0aW9uczxUIGV4dGVuZHMgb2JqZWN0ID0gb2JqZWN0PiB7XG4gIC8qKlxuICAgKiBTd2l0Y2hlcyB0aGUgZ3VhcmQgdG8gRVhBQ1Qgb3B0aW9uYWwgcHJvcGVydGllcywgcmVhZGluZyBvbmx5IHRoZSB2YWx1ZSdzIE9XTiBrZXlzLiBMaXN0aW5nIGl0IGlzIHRoZSBzd2l0Y2gsXG4gICAqIHNvIHBhc3MgYHt9YCBmb3IgYSB0eXBlIHdpdGggbm8gb3B0aW9uYWwga2V5LlxuICAgKlxuICAgKiBFdmVyeSBvcHRpb25hbCBrZXkgb2YgYFRgIG11c3QgYmUgbGlzdGVkLCBzbyBhbiBvcHRpb25hbCBwcm9wZXJ0eSBsYXRlciBhZGRlZCB0byBgVGAgZmFpbHMgdG8gY29tcGlsZSB1bnRpbCBpdFxuICAgKiBpcy4gQSBsaXN0ZWQga2V5IG1heSB0aGVuIGJlIGFic2VudCwgYW5kIGl0cyBndWFyZCBpcyBub3QgcnVuOyBwcmVzZW50LCBldmVuIGFzIGB1bmRlZmluZWRgLCBpdCBtdXN0IHBhc3MgaXRzXG4gICAqIGd1YXJkLiBBbnkgb3RoZXIga2V5IG11c3QgYmUgcHJlc2VudC4gQW4gaW5oZXJpdGVkIGtleSBjb3VudHMgYXMgYWJzZW50LlxuICAgKlxuICAgKiBXaXRob3V0IGl0LCBhIHByb3BlcnR5IGlzIHJlYWQgd2l0aCBgUmVmbGVjdC5nZXRgLCBzbyBhbiBpbmhlcml0ZWQgb25lIGNvdW50cyBhbmQgYW4gYWJzZW50IG9uZSByZWFkcyBhc1xuICAgKiBgdW5kZWZpbmVkYCwgd2hpY2ggdGhlIGd1YXJkIG9mIGFuIG9wdGlvbmFsIHByb3BlcnR5IG11c3QgdGhlbiBhY2NlcHQuXG4gICAqL1xuICByZWFkb25seSBleGFjdE9wdGlvbmFsS2V5cz86IFJlYWRvbmx5PFJlY29yZDxPcHRpb25hbEtleXM8VD4sIHRydWU+PjtcblxuICAvKipcbiAgICogV2hldGhlciBhIHZhbHVlIGNhcnJ5aW5nIGFuIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXkgdGhhdCBubyBwcm9wZXJ0eSBndWFyZCBuYW1lcyBpcyByZWZ1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRSZWplY3RVbmtub3duS2V5cz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIGtleXMgb2YgYW4gb2JqZWN0IHR5cGUgdGhhdCBhcmUgb3B0aW9uYWwuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIG9iamVjdCB0eXBlLlxuICovXG5leHBvcnQgdHlwZSBPcHRpb25hbEtleXM8VCBleHRlbmRzIG9iamVjdD4gPSBPcHRpb25hbEtleU1hcDxUPltrZXlvZiBUXTtcblxuLyoqXG4gKiBPbmUgdHlwZSBndWFyZCBwZXIgcHJvcGVydHkgb2YgYW4gb2JqZWN0IHR5cGUsIGFzIHtAbGluayBvYmplY3RUeXBlR3VhcmR9IHRha2VzIHRoZW0uIEV2ZXJ5IGtleSBvZiBgVGAgbXVzdCBiZVxuICogbGlzdGVkLiBUaGUgZ3VhcmQgb2YgYW4gb3B0aW9uYWwgcHJvcGVydHkgaXMgdHlwZWQgdG8gbmFycm93IHRvIGB1bmRlZmluZWRgIGFzIHdlbGwsIGJ1dCBhIGd1YXJkIHRoYXQgcmVmdXNlc1xuICogYHVuZGVmaW5lZGAgc3RpbGwgY29tcGlsZXMgdGhlcmUsIHNvIHdpZGVuIGl0IHdpdGgge0BsaW5rIG9wdGlvbmFsVHlwZUd1YXJkfTogYW4gYWJzZW50IHByb3BlcnR5IHJlYWRzIGFzXG4gKiBgdW5kZWZpbmVkYCwgYW5kIGEgZ3VhcmQgcmVmdXNpbmcgaXQgcmVmdXNlcyB0aGUgb2JqZWN0LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSBvYmplY3QgdHlwZS5cbiAqL1xuZXhwb3J0IHR5cGUgUHJvcGVydHlUeXBlR3VhcmRzPFQgZXh0ZW5kcyBvYmplY3Q+ID0ge1xuICByZWFkb25seSBbVEtleSBpbiBrZXlvZiBUXS0/OiBUeXBlR3VhcmQ8UGFydGlhbDxQaWNrPFQsIFRLZXk+PiBleHRlbmRzIFBpY2s8VCwgVEtleT4gPyBUW1RLZXldIHwgdW5kZWZpbmVkIDogVFtUS2V5XT47XG59O1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gZGVjaWRpbmcgd2hldGhlciBhIHZhbHVlIGlzIGEgYFRgLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIHRoZSBndWFyZCBuYXJyb3dzIHRvLlxuICovXG5leHBvcnQgdHlwZSBUeXBlR3VhcmQ8VD4gPSAodmFsdWU6IHVua25vd24pID0+IHZhbHVlIGlzIFQ7XG5cbnR5cGUgTnVsbGFibGVDb25zdHJhaW50PFQ+ID0gbnVsbCBleHRlbmRzIFQgPyB1bmtub3duIDogdW5kZWZpbmVkIGV4dGVuZHMgVCA/IHVua25vd24gOiBuZXZlcjtcblxudHlwZSBPcHRpb25hbEtleU1hcDxUIGV4dGVuZHMgb2JqZWN0PiA9IHtcbiAgW1RLZXkgaW4ga2V5b2YgVF0tPzogUGFydGlhbDxQaWNrPFQsIFRLZXk+PiBleHRlbmRzIFBpY2s8VCwgVEtleT4gPyBUS2V5IDogbmV2ZXI7XG59O1xuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbiBhcnJheSB3aG9zZSBldmVyeSBpdGVtIHRoZSBpdGVtIGd1YXJkIGFjY2VwdHMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgYW4gaXRlbS5cbiAqIEBwYXJhbSBpc0l0ZW0gLSBUaGUgZ3VhcmQgZm9yIG9uZSBpdGVtLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlUeXBlR3VhcmQ8VD4oaXNJdGVtOiBUeXBlR3VhcmQ8VD4pOiBUeXBlR3VhcmQ8VFtdPiB7XG4gIHJldHVybiAodmFsdWUpOiB2YWx1ZSBpcyBUW10gPT4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkoKGl0ZW0pID0+IGlzSXRlbShpdGVtKSk7XG59XG5cbi8qKlxuICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGB0cnVlYC4gVGhyb3dzIGlmIGl0IGlzIG5vdC5cbiAqXG4gKiBVc2UgaW4gcGxhY2Ugb2YgYC8qIHY4IGlnbm9yZSAqXFwvYCBmb3IgZGVmZW5zaXZlIGd1YXJkcyB0aGF0IHNob3VsZFxuICogbmV2ZXIgdHJpZ2dlciBhdCBydW50aW1lIGJ1dCB3b3VsZCBvdGhlcndpc2UgY3JlYXRlIHVuY292ZXJlZCBicmFuY2hlcy5cbiAqXG4gKiBAcGFyYW0gaXNUcnVlIC0gVGhlIGNvbmRpdGlvbiB0byBhc3NlcnQuXG4gKiBAcGFyYW0gZXJyb3JPck1lc3NhZ2UgLSBUaGUgZXJyb3Igb3IgbWVzc2FnZSB0byB0aHJvdyBpZiB0aGUgY29uZGl0aW9uIGlzIGBmYWxzZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoaXNUcnVlOiBib29sZWFuLCBlcnJvck9yTWVzc2FnZTogRXJyb3IgfCBzdHJpbmcpOiBhc3NlcnRzIGlzVHJ1ZSB7XG4gIGlmICghaXNUcnVlKSB7XG4gICAgdGhyb3cgdHlwZW9mIGVycm9yT3JNZXNzYWdlID09PSAnc3RyaW5nJyA/IG5ldyBFcnJvcihlcnJvck9yTWVzc2FnZSkgOiBlcnJvck9yTWVzc2FnZTtcbiAgfVxufVxuXG4vKipcbiAqIEFzc2VydHMgdGhhdCBhIHZhbHVlIGlzIGEgZ2VuZXJpYyBvYmplY3QsIG5hcnJvd2luZyBpdHMgdHlwZSBpbiBwbGFjZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUuXG4gKiBAcGFyYW0gX29iamVjdCAtIFRoZSB2YWx1ZSB0byBhc3NlcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRHZW5lcmljT2JqZWN0PFQ+KF9vYmplY3Q6IFQpOiBhc3NlcnRzIF9vYmplY3QgaXMgR2VuZXJpY09iamVjdDxUPiB7XG4gIG5vb3AoKTtcbn1cblxuLyoqXG4gKiBBc3NlcnRzIGF0IGNvbXBpbGUgdGltZSB0aGF0IGV2ZXJ5IGNhc2Ugb2YgYSBkaXNjcmltaW5hdGVkIHVuaW9uIGhhcyBiZWVuXG4gKiBoYW5kbGVkLiBQbGFjZSBhdCB0aGUgYGRlZmF1bHRgIGJyYW5jaCBvZiBhIGBzd2l0Y2hgIG92ZXIgYSB1bmlvbiBvciBlbnVtLlxuICpcbiAqIElmIGEgbmV3IHZhcmlhbnQgaXMgYWRkZWQgdG8gdGhlIHVuaW9uIHdpdGhvdXQgYSBtYXRjaGluZyBgY2FzZWAsIHRoZSBjYWxsXG4gKiB0byB7QGxpbmsgYXNzZXJ0TmV2ZXJ9IGZhaWxzIHRvIGNvbXBpbGUgYmVjYXVzZSBgdmFsdWVgIGlzIG5vIGxvbmdlciBgbmV2ZXJgLlxuICogSWYgcmVhY2hlZCBhdCBydW50aW1lIChlLmcuIGJlY2F1c2UgdGhlIHZhbHVlIHdhcyBieXBhc3NlZCB2aWEgSlNPTiBvciBhXG4gKiB0eXBlIGFzc2VydGlvbiksIGl0IHRocm93cyBhIGRlc2NyaXB0aXZlIGBFcnJvcmAuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBzd2l0Y2ggKG1vZGUpIHtcbiAqICAgY2FzZSAnYSc6IHJldHVybiBkb0EoKTtcbiAqICAgY2FzZSAnYic6IHJldHVybiBkb0IoKTtcbiAqICAgZGVmYXVsdDogYXNzZXJ0TmV2ZXIobW9kZSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgZXhoYXVzdGl2ZWx5LWhhbmRsZWQgdmFsdWUsIG5hcnJvd2VkIHRvIGBuZXZlcmAgYnkgY29udHJvbCBmbG93LlxuICogQHRocm93cyBBbHdheXMsIGlmIHJlYWNoZWQgYXQgcnVudGltZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5ldmVyKHZhbHVlOiBuZXZlcik6IG5ldmVyIHtcbiAgdGhyb3cgbmV3IEVycm9yKGBVbmhhbmRsZWQgdmFsdWU6ICR7U3RyaW5nKHZhbHVlKX1gKTtcbn1cblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgYSB2YWx1ZSBpcyBub3QgYG51bGxgIG9yIGB1bmRlZmluZWRgLCBuYXJyb3dpbmcgaXRzIHR5cGUgaW4gcGxhY2UuXG4gKlxuICogT25seSBjYWxsYWJsZSB3aGVuIGBUYCBpbmNsdWRlcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuIFBhc3NpbmcgYW4gYWxyZWFkeSBub24tbnVsbGFibGUgdHlwZSBpcyBhIGNvbXBpbGUgZXJyb3IuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIGVycm9yT3JNZXNzYWdlIC0gT3B0aW9uYWwge0BsaW5rIEVycm9yfSBvciBlcnJvciBtZXNzYWdlIHN0cmluZy5cbiAqIEB0aHJvd3MgSWYgdGhlIHZhbHVlIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vbk51bGxhYmxlPFQgZXh0ZW5kcyBOdWxsYWJsZUNvbnN0cmFpbnQ8VD4+KHZhbHVlOiBULCBlcnJvck9yTWVzc2FnZT86IEVycm9yIHwgc3RyaW5nKTogYXNzZXJ0cyB2YWx1ZSBpcyBOb25OdWxsYWJsZTxUPiB7XG4gIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXJyb3JPck1lc3NhZ2UgPz89IHZhbHVlID09PSBudWxsID8gJ1ZhbHVlIGlzIG51bGwnIDogJ1ZhbHVlIGlzIHVuZGVmaW5lZCc7XG4gIGNvbnN0IGVycm9yID0gdHlwZW9mIGVycm9yT3JNZXNzYWdlID09PSAnc3RyaW5nJyA/IG5ldyBFcnJvcihlcnJvck9yTWVzc2FnZSkgOiBlcnJvck9yTWVzc2FnZTtcbiAgdGhyb3cgZXJyb3I7XG59XG5cbi8qKlxuICogRW5zdXJlcyB0aGF0IGEgdmFsdWUgaXMgYSBnZW5lcmljIG9iamVjdCwgcmV0dXJuaW5nIGl0IHdpdGggbmFycm93ZWQgdHlwZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUuXG4gKiBAcGFyYW0gJG9iamVjdCAtIFRoZSB2YWx1ZSB0byBlbnN1cmUuXG4gKiBAcmV0dXJucyBUaGUgdmFsdWUgYXMgYSBnZW5lcmljIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZUdlbmVyaWNPYmplY3Q8VD4oJG9iamVjdDogVCk6IEdlbmVyaWNPYmplY3Q8VD4ge1xuICByZXR1cm4gJG9iamVjdCBhcyBHZW5lcmljT2JqZWN0PFQ+O1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhIHZhbHVlIGlzIG5vdCBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgYW5kIHJldHVybnMgaXQgd2l0aCBuYXJyb3dlZCB0eXBlLlxuICpcbiAqIE9ubHkgY2FsbGFibGUgd2hlbiBgVGAgaW5jbHVkZXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLiBQYXNzaW5nIGFuIGFscmVhZHkgbm9uLW51bGxhYmxlIHR5cGUgaXMgYSBjb21waWxlIGVycm9yLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSBlcnJvck9yTWVzc2FnZSAtIE9wdGlvbmFsIHtAbGluayBFcnJvcn0gb3IgZXJyb3IgbWVzc2FnZSBzdHJpbmcuXG4gKiBAcmV0dXJucyBUaGUgdmFsdWUgd2l0aCBgbnVsbGAgYW5kIGB1bmRlZmluZWRgIGV4Y2x1ZGVkIGZyb20gaXRzIHR5cGUuXG4gKiBAdGhyb3dzIElmIHRoZSB2YWx1ZSBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVOb25OdWxsYWJsZTxUIGV4dGVuZHMgTnVsbGFibGVDb25zdHJhaW50PFQ+Pih2YWx1ZTogVCwgZXJyb3JPck1lc3NhZ2U/OiBFcnJvciB8IHN0cmluZyk6IE5vbk51bGxhYmxlPFQ+IHtcbiAgYXNzZXJ0Tm9uTnVsbGFibGUodmFsdWUsIGVycm9yT3JNZXNzYWdlKTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbnkgZnVuY3Rpb24sIG5hcnJvd2VkIHRvIHRoZSBzaWduYXR1cmUgYFRGdW5jdGlvbmAuIE9ubHkgdGhhdCB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvblxuICogaXMgY2hlY2tlZDogYSBzaWduYXR1cmUgY2Fubm90IGJlIGNoZWNrZWQgYXQgcnVudGltZSwgc28gdGhlIGd1YXJkIHRydXN0cyBpdC5cbiAqXG4gKiBAdHlwZVBhcmFtIFRGdW5jdGlvbiAtIFRoZSBzaWduYXR1cmUgdGhlIGd1YXJkIG5hcnJvd3MgdG8uXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdW5jdGlvblR5cGVHdWFyZDxURnVuY3Rpb24gZXh0ZW5kcyBHZW5lcmljRnVuY3Rpb24+KCk6IFR5cGVHdWFyZDxURnVuY3Rpb24+IHtcbiAgcmV0dXJuICh2YWx1ZSk6IHZhbHVlIGlzIFRGdW5jdGlvbiA9PiBpc0Z1bmN0aW9uKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBndWFyZCBhY2NlcHRpbmcgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzcywgb3Igb2YgYSBjbGFzcyBkZXJpdmVkIGZyb20gaXQuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgYW4gaW5zdGFuY2UuXG4gKiBAcGFyYW0gY29uc3RydWN0b3IgLSBUaGUgY2xhc3MuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YW5jZU9mVHlwZUd1YXJkPFQ+KGNvbnN0cnVjdG9yOiBhYnN0cmFjdCBuZXcgKC4uLmFyZ3VtZW50c186IG5ldmVyW10pID0+IFQpOiBUeXBlR3VhcmQ8VD4ge1xuICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgVCA9PiB2YWx1ZSBpbnN0YW5jZW9mIGNvbnN0cnVjdG9yO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYSBib29sZWFuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgR2VuZXJpY0Z1bmN0aW9uIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGBudWxsYC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBgbnVsbGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudWxsIHtcbiAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYSBudW1iZXIuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgYW4gb2JqZWN0OiBub3QgYG51bGxgLCBhbmQgbm90IGEgcHJpbWl0aXZlIG9yIGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3QodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBvYmplY3Qge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhbHVlIGlzIGFuIGFycmF5IG9mIHN0cmluZ3MuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgd2hvc2UgZXZlcnkgaXRlbSBpcyBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nQXJyYXkodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBzdHJpbmdbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5ldmVyeShpc1N0cmluZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBgdW5kZWZpbmVkYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgZ3VhcmQgYWNjZXB0aW5nIGV4YWN0bHkgdGhlIGtleXMgb2YgYSByZWNvcmQuIFR5cGluZyB0aGUgcmVjb3JkIG92ZXIgYSB1bmlvbiwgYXNcbiAqIGBsaXRlcmFsVHlwZUd1YXJkPE1vZGU+KHsgQTogdHJ1ZSwgQjogdHJ1ZSB9KWAsIG1ha2VzIGEgbWVtYmVyIGxhdGVyIGFkZGVkIHRvIHRoZSB1bmlvbiBmYWlsIHRvIGNvbXBpbGUgdW50aWxcbiAqIGl0IGlzIGxpc3RlZC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgYWNjZXB0ZWQgc3RyaW5ncy5cbiAqIEBwYXJhbSBsaXRlcmFscyAtIEEgcmVjb3JkIHdob3NlIGtleXMgYXJlIHRoZSBhY2NlcHRlZCBzdHJpbmdzLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGl0ZXJhbFR5cGVHdWFyZDxUIGV4dGVuZHMgc3RyaW5nPihsaXRlcmFsczogUmVhZG9ubHk8UmVjb3JkPFQsIHRydWU+Pik6IFR5cGVHdWFyZDxUPjtcbi8qKlxuICogQnVpbGRzIGEgZ3VhcmQgYWNjZXB0aW5nIGV4YWN0bHkgdGhlIGxpc3RlZCB2YWx1ZXMsIGNvbXBhcmVkIGFzIGBBcnJheS5wcm90b3R5cGUuaW5jbHVkZXNgIGNvbXBhcmVzIHRoZW0uXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIGFjY2VwdGVkIHZhbHVlcy5cbiAqIEBwYXJhbSBsaXRlcmFscyAtIFRoZSBhY2NlcHRlZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsVHlwZUd1YXJkPFQgZXh0ZW5kcyBMaXRlcmFsPihsaXRlcmFsczogcmVhZG9ubHkgVFtdKTogVHlwZUd1YXJkPFQ+O1xuLyoqXG4gKiBCdWlsZHMgYSBndWFyZCBhY2NlcHRpbmcgZXhhY3RseSB0aGUgbGlzdGVkIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gbGl0ZXJhbHMgLSBUaGUgYWNjZXB0ZWQgdmFsdWVzLCBhcyBhIGxpc3Qgb3IgYXMgdGhlIGtleXMgb2YgYSByZWNvcmQuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsVHlwZUd1YXJkKGxpdGVyYWxzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB0cnVlPj4gfCByZWFkb25seSBMaXRlcmFsW10pOiBUeXBlR3VhcmQ8TGl0ZXJhbD4ge1xuICBpZiAoaXNSZWFkb25seUFycmF5KGxpdGVyYWxzKSkge1xuICAgIGNvbnN0IGxpdGVyYWxMaXN0OiByZWFkb25seSB1bmtub3duW10gPSBsaXRlcmFscztcbiAgICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgTGl0ZXJhbCA9PiBsaXRlcmFsTGlzdC5pbmNsdWRlcyh2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gKHZhbHVlKTogdmFsdWUgaXMgTGl0ZXJhbCA9PiBpc1N0cmluZyh2YWx1ZSkgJiYgT2JqZWN0Lmhhc093bihsaXRlcmFscywgdmFsdWUpO1xufVxuXG4vKipcbiAqIFdpZGVucyBhIGd1YXJkIHRvIGFsc28gYWNjZXB0IGBudWxsYC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSB0aGUgZ3VhcmQgbmFycm93cyB0by5cbiAqIEBwYXJhbSBpc1ZhbHVlIC0gVGhlIGd1YXJkIHRvIHdpZGVuLlxuICogQHJldHVybnMgQSBndWFyZCBhY2NlcHRpbmcgd2hhdCBgaXNWYWx1ZWAgYWNjZXB0cywgb3IgYG51bGxgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbGFibGVUeXBlR3VhcmQ8VD4oaXNWYWx1ZTogVHlwZUd1YXJkPFQ+KTogVHlwZUd1YXJkPG51bGwgfCBUPiB7XG4gIHJldHVybiB1bmlvblR5cGVHdWFyZChpc051bGwsIGlzVmFsdWUpO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyBhbiBvYmplY3Qgd2hvc2UgZXZlcnkgbGlzdGVkIHByb3BlcnR5IGl0cyBndWFyZCBhY2NlcHRzLiBBIHByb3BlcnR5IGlzIHJlYWQgd2l0aFxuICogYFJlZmxlY3QuZ2V0YCwgc28gYW4gaW5oZXJpdGVkIG9uZSBjb3VudHMgYW5kIGFuIGFic2VudCBvbmUgcmVhZHMgYXMgYHVuZGVmaW5lZGAsIHVubGVzc1xuICoge0BsaW5rIE9iamVjdFR5cGVHdWFyZE9wdGlvbnMuZXhhY3RPcHRpb25hbEtleXN9IHN3aXRjaGVzIHRoZSBndWFyZCB0byBvd24ga2V5cyBhbmQgZXhhY3Qgb3B0aW9uYWwgcHJvcGVydGllcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgb2JqZWN0IHR5cGUuXG4gKiBAcGFyYW0gcHJvcGVydHlUeXBlR3VhcmRzIC0gT25lIGd1YXJkIHBlciBwcm9wZXJ0eSBvZiBgVGAuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgZ3VhcmQuXG4gKiBAcmV0dXJucyBUaGUgZ3VhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvYmplY3RUeXBlR3VhcmQ8VCBleHRlbmRzIG9iamVjdD4ocHJvcGVydHlUeXBlR3VhcmRzOiBQcm9wZXJ0eVR5cGVHdWFyZHM8VD4sIG9wdGlvbnM/OiBPYmplY3RUeXBlR3VhcmRPcHRpb25zPFQ+KTogVHlwZUd1YXJkPFQ+IHtcbiAgY29uc3Qgc2hvdWxkUmVqZWN0VW5rbm93bktleXMgPSBvcHRpb25zPy5zaG91bGRSZWplY3RVbmtub3duS2V5cyA/PyBmYWxzZTtcbiAgY29uc3QgZXhhY3RPcHRpb25hbEtleXMgPSBvcHRpb25zPy5leGFjdE9wdGlvbmFsS2V5cztcbiAgcmV0dXJuICh2YWx1ZSk6IHZhbHVlIGlzIFQgPT4ge1xuICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFJlamVjdFVua25vd25LZXlzICYmIE9iamVjdC5rZXlzKHZhbHVlKS5zb21lKChrZXkpID0+ICFPYmplY3QuaGFzT3duKHByb3BlcnR5VHlwZUd1YXJkcywga2V5KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlR3VhcmRzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBUeXBlR3VhcmQ8dW5rbm93bj4+PiA9IHByb3BlcnR5VHlwZUd1YXJkcztcbiAgICBmb3IgKGNvbnN0IFtrZXksIHR5cGVHdWFyZF0gb2YgT2JqZWN0LmVudHJpZXModHlwZUd1YXJkcykpIHtcbiAgICAgIGlmIChleGFjdE9wdGlvbmFsS2V5cyAmJiAhT2JqZWN0Lmhhc093bih2YWx1ZSwga2V5KSkge1xuICAgICAgICBpZiAoT2JqZWN0Lmhhc093bihleGFjdE9wdGlvbmFsS2V5cywga2V5KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXR5cGVHdWFyZChSZWZsZWN0LmdldCh2YWx1ZSwga2V5KSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG4vKipcbiAqIFdpZGVucyBhIGd1YXJkIHRvIGFsc28gYWNjZXB0IGB1bmRlZmluZWRgLCB3aGljaCBpcyB3aGF0IGFuIG9wdGlvbmFsIHByb3BlcnR5IG9yIHBhcmFtZXRlciByZWFkcyBhcyB3aGVuIGl0IGlzXG4gKiBsZWZ0IG91dC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSB0aGUgZ3VhcmQgbmFycm93cyB0by5cbiAqIEBwYXJhbSBpc1ZhbHVlIC0gVGhlIGd1YXJkIHRvIHdpZGVuLlxuICogQHJldHVybnMgQSBndWFyZCBhY2NlcHRpbmcgd2hhdCBgaXNWYWx1ZWAgYWNjZXB0cywgb3IgYHVuZGVmaW5lZGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25hbFR5cGVHdWFyZDxUPihpc1ZhbHVlOiBUeXBlR3VhcmQ8VD4pOiBUeXBlR3VhcmQ8VCB8IHVuZGVmaW5lZD4ge1xuICByZXR1cm4gdW5pb25UeXBlR3VhcmQoaXNVbmRlZmluZWQsIGlzVmFsdWUpO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGd1YXJkIGFjY2VwdGluZyB3aGF0IGFueSBvZiB0aGUgZ2l2ZW4gZ3VhcmRzIGFjY2VwdHMuXG4gKlxuICogQHR5cGVQYXJhbSBUVHlwZUd1YXJkcyAtIFRoZSBndWFyZHMuXG4gKiBAcGFyYW0gdHlwZUd1YXJkcyAtIFRoZSBndWFyZHMsIHRyaWVkIGluIG9yZGVyLlxuICogQHJldHVybnMgVGhlIGd1YXJkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5pb25UeXBlR3VhcmQ8Y29uc3QgVFR5cGVHdWFyZHMgZXh0ZW5kcyByZWFkb25seSBUeXBlR3VhcmQ8dW5rbm93bj5bXT4oXG4gIC4uLnR5cGVHdWFyZHM6IFRUeXBlR3VhcmRzXG4pOiBUeXBlR3VhcmQ8R3VhcmRlZFR5cGU8VFR5cGVHdWFyZHNbbnVtYmVyXT4+IHtcbiAgcmV0dXJuICh2YWx1ZSk6IHZhbHVlIGlzIEd1YXJkZWRUeXBlPFRUeXBlR3VhcmRzW251bWJlcl0+ID0+IHR5cGVHdWFyZHMuc29tZSgodHlwZUd1YXJkKSA9PiB0eXBlR3VhcmQodmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gaXNSZWFkb25seUFycmF5KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgcmVhZG9ubHkgdW5rbm93bltdIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBWUEsc0JBQXFCO0FBdUZkLFNBQVMsZUFBa0IsUUFBc0M7QUFDdEUsU0FBTyxDQUFDLFVBQXdCLE1BQU0sUUFBUSxLQUFLLEtBQUssTUFBTSxNQUFNLENBQUMsU0FBUyxPQUFPLElBQUksQ0FBQztBQUM1RjtBQVdPLFNBQVMsT0FBTyxRQUFpQixnQkFBZ0Q7QUFDdEYsTUFBSSxDQUFDLFFBQVE7QUFDWCxVQUFNLE9BQU8sbUJBQW1CLFdBQVcsSUFBSSxNQUFNLGNBQWMsSUFBSTtBQUFBLEVBQ3pFO0FBQ0Y7QUFRTyxTQUFTLG9CQUF1QixTQUFpRDtBQUN0Riw0QkFBSztBQUNQO0FBdUJPLFNBQVMsWUFBWSxPQUFxQjtBQUMvQyxRQUFNLElBQUksTUFBTSxvQkFBb0IsT0FBTyxLQUFLLENBQUMsRUFBRTtBQUNyRDtBQVlPLFNBQVMsa0JBQW1ELE9BQVUsZ0JBQWtFO0FBQzdJLE1BQUksVUFBVSxRQUFRLFVBQVUsUUFBVztBQUN6QztBQUFBLEVBQ0Y7QUFFQSxxQkFBbUIsVUFBVSxPQUFPLGtCQUFrQjtBQUN0RCxR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
@@ -27,8 +27,22 @@ export type GuardedType<TTypeGuard> = TTypeGuard extends (value: unknown) => val
27
27
  export type Literal = bigint | boolean | null | number | string | symbol | undefined;
28
28
  /**
29
29
  * Options for {@link objectTypeGuard}.
30
+ *
31
+ * @typeParam T - The object type the guard narrows to.
30
32
  */
31
- export interface ObjectTypeGuardOptions {
33
+ export interface ObjectTypeGuardOptions<T extends object = object> {
34
+ /**
35
+ * Switches the guard to EXACT optional properties, reading only the value's OWN keys. Listing it is the switch,
36
+ * so pass `{}` for a type with no optional key.
37
+ *
38
+ * Every optional key of `T` must be listed, so an optional property later added to `T` fails to compile until it
39
+ * is. A listed key may then be absent, and its guard is not run; present, even as `undefined`, it must pass its
40
+ * guard. Any other key must be present. An inherited key counts as absent.
41
+ *
42
+ * Without it, a property is read with `Reflect.get`, so an inherited one counts and an absent one reads as
43
+ * `undefined`, which the guard of an optional property must then accept.
44
+ */
45
+ readonly exactOptionalKeys?: Readonly<Record<OptionalKeys<T>, true>>;
32
46
  /**
33
47
  * Whether a value carrying an own enumerable string key that no property guard names is refused.
34
48
  *
@@ -36,6 +50,12 @@ export interface ObjectTypeGuardOptions {
36
50
  */
37
51
  readonly shouldRejectUnknownKeys?: boolean;
38
52
  }
53
+ /**
54
+ * The keys of an object type that are optional.
55
+ *
56
+ * @typeParam T - The object type.
57
+ */
58
+ export type OptionalKeys<T extends object> = OptionalKeyMap<T>[keyof T];
39
59
  /**
40
60
  * One type guard per property of an object type, as {@link objectTypeGuard} takes them. Every key of `T` must be
41
61
  * listed. The guard of an optional property is typed to narrow to `undefined` as well, but a guard that refuses
@@ -54,6 +74,9 @@ export type PropertyTypeGuards<T extends object> = {
54
74
  */
55
75
  export type TypeGuard<T> = (value: unknown) => value is T;
56
76
  type NullableConstraint<T> = null extends T ? unknown : undefined extends T ? unknown : never;
77
+ type OptionalKeyMap<T extends object> = {
78
+ [TKey in keyof T]-?: Partial<Pick<T, TKey>> extends Pick<T, TKey> ? TKey : never;
79
+ };
57
80
  /**
58
81
  * Builds a guard accepting an array whose every item the item guard accepts.
59
82
  *
@@ -232,14 +255,15 @@ export declare function literalTypeGuard<T extends Literal>(literals: readonly T
232
255
  export declare function nullableTypeGuard<T>(isValue: TypeGuard<T>): TypeGuard<null | T>;
233
256
  /**
234
257
  * Builds a guard accepting an object whose every listed property its guard accepts. A property is read with
235
- * `Reflect.get`, so an inherited one counts and an absent one reads as `undefined`.
258
+ * `Reflect.get`, so an inherited one counts and an absent one reads as `undefined`, unless
259
+ * {@link ObjectTypeGuardOptions.exactOptionalKeys} switches the guard to own keys and exact optional properties.
236
260
  *
237
261
  * @typeParam T - The object type.
238
262
  * @param propertyTypeGuards - One guard per property of `T`.
239
263
  * @param options - The options for the guard.
240
264
  * @returns The guard.
241
265
  */
242
- export declare function objectTypeGuard<T extends object>(propertyTypeGuards: PropertyTypeGuards<T>, options?: ObjectTypeGuardOptions): TypeGuard<T>;
266
+ export declare function objectTypeGuard<T extends object>(propertyTypeGuards: PropertyTypeGuards<T>, options?: ObjectTypeGuardOptions<T>): TypeGuard<T>;
243
267
  /**
244
268
  * Widens a guard to also accept `undefined`, which is what an optional property or parameter reads as when it is
245
269
  * left out.
@@ -0,0 +1,81 @@
1
+ /// <reference path="./library-references.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Checks an {@link ApiContract} against sample payloads, for a contract's own test: every method has both schemas,
6
+ * every schema reports the expected vendor, and each schema accepts every valid payload and refuses every invalid one.
7
+ *
8
+ * It returns what it found rather than asserting, so it runs under any test framework:
9
+ *
10
+ * ```ts
11
+ * expect(await verifyApiContract(MY_API_CONTRACT, { cases, vendor: 'my-plugin' })).toEqual([]);
12
+ * ```
13
+ *
14
+ * It lives apart from `api-contract.ts` because a contract a consumer copies imports that module into its plugin,
15
+ * and nothing here is needed at runtime.
16
+ */
17
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
18
+ import type { ApiContract } from './api-contract.mjs';
19
+ /**
20
+ * The sample payloads of one method, for each half of its contract.
21
+ */
22
+ export interface ApiMethodCases {
23
+ /**
24
+ * Sample argument lists.
25
+ */
26
+ readonly input: PayloadCases;
27
+ /**
28
+ * Sample return values.
29
+ */
30
+ readonly output: PayloadCases;
31
+ }
32
+ /**
33
+ * Sample payloads for one schema.
34
+ */
35
+ export interface PayloadCases {
36
+ /**
37
+ * Payloads the schema must refuse.
38
+ */
39
+ readonly invalid: readonly unknown[];
40
+ /**
41
+ * Payloads the schema must accept.
42
+ */
43
+ readonly valid: readonly unknown[];
44
+ }
45
+ /**
46
+ * Options for {@link verifyApiContract}.
47
+ *
48
+ * @typeParam TContract - The contract.
49
+ */
50
+ export interface VerifyApiContractOptions<TContract extends ApiContract> {
51
+ /**
52
+ * The sample payloads, one entry per method of the contract.
53
+ */
54
+ readonly cases: Readonly<Record<keyof TContract & string, ApiMethodCases>>;
55
+ /**
56
+ * The Standard Schema `vendor` every schema must report.
57
+ */
58
+ readonly vendor: string;
59
+ }
60
+ /**
61
+ * Runs a Standard Schema that must be synchronous. A schema guarding a call it cannot delay, as a contract's schemas
62
+ * do, has to answer before that call returns.
63
+ *
64
+ * @typeParam TOutput - The type the schema produces.
65
+ * @param schema - The schema.
66
+ * @param value - The value to validate.
67
+ * @returns The schema's result.
68
+ * @throws If the schema answers with a promise.
69
+ */
70
+ export declare function validateSync<TOutput>(schema: StandardSchemaV1<unknown, TOutput>, value: unknown): StandardSchemaV1.Result<TOutput>;
71
+ /**
72
+ * Checks a contract against sample payloads: the contract has exactly the methods the cases name, each with both
73
+ * schemas, every schema reports the given vendor and Standard Schema version 1, and each schema accepts every valid
74
+ * payload and refuses every invalid one.
75
+ *
76
+ * @typeParam TContract - The contract.
77
+ * @param contract - The contract.
78
+ * @param options - The sample payloads and the expected vendor.
79
+ * @returns One message per violation, empty when the contract passes.
80
+ */
81
+ export declare function verifyApiContract<TContract extends ApiContract>(contract: TContract, options: VerifyApiContractOptions<TContract>): Promise<string[]>;
@@ -0,0 +1,63 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ function validateSync(schema, value) {
7
+ const result = schema["~standard"].validate(value);
8
+ if (result instanceof Promise) {
9
+ throw new TypeError("Expected a synchronous schema, got one that answers with a promise.");
10
+ }
11
+ return result;
12
+ }
13
+ async function verifyApiContract(contract, options) {
14
+ const violations = [];
15
+ const looseContract = contract;
16
+ const cases = options.cases;
17
+ for (const methodName of Object.keys(looseContract)) {
18
+ if (!Object.hasOwn(cases, methodName)) {
19
+ violations.push(`${methodName}: the contract has the method, but no cases are given for it.`);
20
+ }
21
+ }
22
+ for (const [methodName, methodCases] of Object.entries(cases)) {
23
+ const methodContract = looseContract[methodName];
24
+ if (methodContract === void 0) {
25
+ violations.push(`${methodName}: cases are given, but the contract has no such method.`);
26
+ continue;
27
+ }
28
+ for (const half of ["input", "output"]) {
29
+ const schema = methodContract[half];
30
+ if (schema === void 0) {
31
+ violations.push(`${methodName} ${half}: the contract has no schema.`);
32
+ continue;
33
+ }
34
+ const { vendor } = schema["~standard"];
35
+ const version = schema["~standard"].version;
36
+ if (vendor !== options.vendor || version !== 1) {
37
+ violations.push(`${methodName} ${half}: the schema reports vendor '${vendor}' and version ${String(version)}, expected '${options.vendor}' and 1.`);
38
+ }
39
+ const { invalid, valid } = methodCases[half];
40
+ for (const [index, value] of valid.entries()) {
41
+ const result = await schema["~standard"].validate(value);
42
+ if (result.issues !== void 0) {
43
+ violations.push(`${methodName} ${half}: valid case ${String(index)} was refused: ${formatIssues(result.issues)}`);
44
+ }
45
+ }
46
+ for (const [index, value] of invalid.entries()) {
47
+ const result = await schema["~standard"].validate(value);
48
+ if (result.issues === void 0 || result.issues.length === 0) {
49
+ violations.push(`${methodName} ${half}: invalid case ${String(index)} was accepted.`);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ return violations;
55
+ }
56
+ function formatIssues(issues) {
57
+ return issues.map((issue) => issue.message).join(" ");
58
+ }
59
+ export {
60
+ validateSync,
61
+ verifyApiContract
62
+ };
63
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FwaS1jb250cmFjdC12ZXJpZmllci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIENoZWNrcyBhbiB7QGxpbmsgQXBpQ29udHJhY3R9IGFnYWluc3Qgc2FtcGxlIHBheWxvYWRzLCBmb3IgYSBjb250cmFjdCdzIG93biB0ZXN0OiBldmVyeSBtZXRob2QgaGFzIGJvdGggc2NoZW1hcyxcbiAqIGV2ZXJ5IHNjaGVtYSByZXBvcnRzIHRoZSBleHBlY3RlZCB2ZW5kb3IsIGFuZCBlYWNoIHNjaGVtYSBhY2NlcHRzIGV2ZXJ5IHZhbGlkIHBheWxvYWQgYW5kIHJlZnVzZXMgZXZlcnkgaW52YWxpZCBvbmUuXG4gKlxuICogSXQgcmV0dXJucyB3aGF0IGl0IGZvdW5kIHJhdGhlciB0aGFuIGFzc2VydGluZywgc28gaXQgcnVucyB1bmRlciBhbnkgdGVzdCBmcmFtZXdvcms6XG4gKlxuICogYGBgdHNcbiAqIGV4cGVjdChhd2FpdCB2ZXJpZnlBcGlDb250cmFjdChNWV9BUElfQ09OVFJBQ1QsIHsgY2FzZXMsIHZlbmRvcjogJ215LXBsdWdpbicgfSkpLnRvRXF1YWwoW10pO1xuICogYGBgXG4gKlxuICogSXQgbGl2ZXMgYXBhcnQgZnJvbSBgYXBpLWNvbnRyYWN0LnRzYCBiZWNhdXNlIGEgY29udHJhY3QgYSBjb25zdW1lciBjb3BpZXMgaW1wb3J0cyB0aGF0IG1vZHVsZSBpbnRvIGl0cyBwbHVnaW4sXG4gKiBhbmQgbm90aGluZyBoZXJlIGlzIG5lZWRlZCBhdCBydW50aW1lLlxuICovXG5cbmltcG9ydCB0eXBlIHsgU3RhbmRhcmRTY2hlbWFWMSB9IGZyb20gJ0BzdGFuZGFyZC1zY2hlbWEvc3BlYyc7XG5cbmltcG9ydCB0eXBlIHsgQXBpQ29udHJhY3QgfSBmcm9tICcuL2FwaS1jb250cmFjdC50cyc7XG5cbi8qKlxuICogVGhlIHNhbXBsZSBwYXlsb2FkcyBvZiBvbmUgbWV0aG9kLCBmb3IgZWFjaCBoYWxmIG9mIGl0cyBjb250cmFjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcGlNZXRob2RDYXNlcyB7XG4gIC8qKlxuICAgKiBTYW1wbGUgYXJndW1lbnQgbGlzdHMuXG4gICAqL1xuICByZWFkb25seSBpbnB1dDogUGF5bG9hZENhc2VzO1xuXG4gIC8qKlxuICAgKiBTYW1wbGUgcmV0dXJuIHZhbHVlcy5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dDogUGF5bG9hZENhc2VzO1xufVxuXG4vKipcbiAqIFNhbXBsZSBwYXlsb2FkcyBmb3Igb25lIHNjaGVtYS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXlsb2FkQ2FzZXMge1xuICAvKipcbiAgICogUGF5bG9hZHMgdGhlIHNjaGVtYSBtdXN0IHJlZnVzZS5cbiAgICovXG4gIHJlYWRvbmx5IGludmFsaWQ6IHJlYWRvbmx5IHVua25vd25bXTtcblxuICAvKipcbiAgICogUGF5bG9hZHMgdGhlIHNjaGVtYSBtdXN0IGFjY2VwdC5cbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkOiByZWFkb25seSB1bmtub3duW107XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIHZlcmlmeUFwaUNvbnRyYWN0fS5cbiAqXG4gKiBAdHlwZVBhcmFtIFRDb250cmFjdCAtIFRoZSBjb250cmFjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlBcGlDb250cmFjdE9wdGlvbnM8VENvbnRyYWN0IGV4dGVuZHMgQXBpQ29udHJhY3Q+IHtcbiAgLyoqXG4gICAqIFRoZSBzYW1wbGUgcGF5bG9hZHMsIG9uZSBlbnRyeSBwZXIgbWV0aG9kIG9mIHRoZSBjb250cmFjdC5cbiAgICovXG4gIHJlYWRvbmx5IGNhc2VzOiBSZWFkb25seTxSZWNvcmQ8a2V5b2YgVENvbnRyYWN0ICYgc3RyaW5nLCBBcGlNZXRob2RDYXNlcz4+O1xuXG4gIC8qKlxuICAgKiBUaGUgU3RhbmRhcmQgU2NoZW1hIGB2ZW5kb3JgIGV2ZXJ5IHNjaGVtYSBtdXN0IHJlcG9ydC5cbiAgICovXG4gIHJlYWRvbmx5IHZlbmRvcjogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJ1bnMgYSBTdGFuZGFyZCBTY2hlbWEgdGhhdCBtdXN0IGJlIHN5bmNocm9ub3VzLiBBIHNjaGVtYSBndWFyZGluZyBhIGNhbGwgaXQgY2Fubm90IGRlbGF5LCBhcyBhIGNvbnRyYWN0J3Mgc2NoZW1hc1xuICogZG8sIGhhcyB0byBhbnN3ZXIgYmVmb3JlIHRoYXQgY2FsbCByZXR1cm5zLlxuICpcbiAqIEB0eXBlUGFyYW0gVE91dHB1dCAtIFRoZSB0eXBlIHRoZSBzY2hlbWEgcHJvZHVjZXMuXG4gKiBAcGFyYW0gc2NoZW1hIC0gVGhlIHNjaGVtYS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZS5cbiAqIEByZXR1cm5zIFRoZSBzY2hlbWEncyByZXN1bHQuXG4gKiBAdGhyb3dzIElmIHRoZSBzY2hlbWEgYW5zd2VycyB3aXRoIGEgcHJvbWlzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU3luYzxUT3V0cHV0PihzY2hlbWE6IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgVE91dHB1dD4sIHZhbHVlOiB1bmtub3duKTogU3RhbmRhcmRTY2hlbWFWMS5SZXN1bHQ8VE91dHB1dD4ge1xuICBjb25zdCByZXN1bHQgPSBzY2hlbWFbJ35zdGFuZGFyZCddLnZhbGlkYXRlKHZhbHVlKTtcbiAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhIHN5bmNocm9ub3VzIHNjaGVtYSwgZ290IG9uZSB0aGF0IGFuc3dlcnMgd2l0aCBhIHByb21pc2UuJyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIENoZWNrcyBhIGNvbnRyYWN0IGFnYWluc3Qgc2FtcGxlIHBheWxvYWRzOiB0aGUgY29udHJhY3QgaGFzIGV4YWN0bHkgdGhlIG1ldGhvZHMgdGhlIGNhc2VzIG5hbWUsIGVhY2ggd2l0aCBib3RoXG4gKiBzY2hlbWFzLCBldmVyeSBzY2hlbWEgcmVwb3J0cyB0aGUgZ2l2ZW4gdmVuZG9yIGFuZCBTdGFuZGFyZCBTY2hlbWEgdmVyc2lvbiAxLCBhbmQgZWFjaCBzY2hlbWEgYWNjZXB0cyBldmVyeSB2YWxpZFxuICogcGF5bG9hZCBhbmQgcmVmdXNlcyBldmVyeSBpbnZhbGlkIG9uZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFRDb250cmFjdCAtIFRoZSBjb250cmFjdC5cbiAqIEBwYXJhbSBjb250cmFjdCAtIFRoZSBjb250cmFjdC5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIHNhbXBsZSBwYXlsb2FkcyBhbmQgdGhlIGV4cGVjdGVkIHZlbmRvci5cbiAqIEByZXR1cm5zIE9uZSBtZXNzYWdlIHBlciB2aW9sYXRpb24sIGVtcHR5IHdoZW4gdGhlIGNvbnRyYWN0IHBhc3Nlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeUFwaUNvbnRyYWN0PFRDb250cmFjdCBleHRlbmRzIEFwaUNvbnRyYWN0Pihjb250cmFjdDogVENvbnRyYWN0LCBvcHRpb25zOiBWZXJpZnlBcGlDb250cmFjdE9wdGlvbnM8VENvbnRyYWN0Pik6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgY29uc3QgdmlvbGF0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgbG9vc2VDb250cmFjdDogQXBpQ29udHJhY3QgPSBjb250cmFjdDtcbiAgY29uc3QgY2FzZXM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIEFwaU1ldGhvZENhc2VzPj4gPSBvcHRpb25zLmNhc2VzO1xuXG4gIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBPYmplY3Qua2V5cyhsb29zZUNvbnRyYWN0KSkge1xuICAgIGlmICghT2JqZWN0Lmhhc093bihjYXNlcywgbWV0aG9kTmFtZSkpIHtcbiAgICAgIHZpb2xhdGlvbnMucHVzaChgJHttZXRob2ROYW1lfTogdGhlIGNvbnRyYWN0IGhhcyB0aGUgbWV0aG9kLCBidXQgbm8gY2FzZXMgYXJlIGdpdmVuIGZvciBpdC5gKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IFttZXRob2ROYW1lLCBtZXRob2RDYXNlc10gb2YgT2JqZWN0LmVudHJpZXMoY2FzZXMpKSB7XG4gICAgY29uc3QgbWV0aG9kQ29udHJhY3QgPSBsb29zZUNvbnRyYWN0W21ldGhvZE5hbWVdO1xuICAgIGlmIChtZXRob2RDb250cmFjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB2aW9sYXRpb25zLnB1c2goYCR7bWV0aG9kTmFtZX06IGNhc2VzIGFyZSBnaXZlbiwgYnV0IHRoZSBjb250cmFjdCBoYXMgbm8gc3VjaCBtZXRob2QuYCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGhhbGYgb2YgWydpbnB1dCcsICdvdXRwdXQnXSBhcyBjb25zdCkge1xuICAgICAgY29uc3Qgc2NoZW1hID0gbWV0aG9kQ29udHJhY3RbaGFsZl07XG4gICAgICBpZiAoc2NoZW1hID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmlvbGF0aW9ucy5wdXNoKGAke21ldGhvZE5hbWV9ICR7aGFsZn06IHRoZSBjb250cmFjdCBoYXMgbm8gc2NoZW1hLmApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVhZCBhcyBhIG51bWJlcjogdGhlIHR5cGUgc2F5cyAxLCBidXQgYSBzY2hlbWEgZnJvbSBhbm90aGVyIGxpYnJhcnkgbWF5IHNwZWFrIGEgbGF0ZXIgdmVyc2lvbi5cbiAgICAgIGNvbnN0IHsgdmVuZG9yIH0gPSBzY2hlbWFbJ35zdGFuZGFyZCddO1xuICAgICAgY29uc3QgdmVyc2lvbjogbnVtYmVyID0gc2NoZW1hWyd+c3RhbmRhcmQnXS52ZXJzaW9uO1xuICAgICAgaWYgKHZlbmRvciAhPT0gb3B0aW9ucy52ZW5kb3IgfHwgdmVyc2lvbiAhPT0gMSkge1xuICAgICAgICB2aW9sYXRpb25zLnB1c2goYCR7bWV0aG9kTmFtZX0gJHtoYWxmfTogdGhlIHNjaGVtYSByZXBvcnRzIHZlbmRvciAnJHt2ZW5kb3J9JyBhbmQgdmVyc2lvbiAke1N0cmluZyh2ZXJzaW9uKX0sIGV4cGVjdGVkICcke29wdGlvbnMudmVuZG9yfScgYW5kIDEuYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgaW52YWxpZCwgdmFsaWQgfSA9IG1ldGhvZENhc2VzW2hhbGZdO1xuICAgICAgZm9yIChjb25zdCBbaW5kZXgsIHZhbHVlXSBvZiB2YWxpZC5lbnRyaWVzKCkpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2NoZW1hWyd+c3RhbmRhcmQnXS52YWxpZGF0ZSh2YWx1ZSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNzdWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB2aW9sYXRpb25zLnB1c2goYCR7bWV0aG9kTmFtZX0gJHtoYWxmfTogdmFsaWQgY2FzZSAke1N0cmluZyhpbmRleCl9IHdhcyByZWZ1c2VkOiAke2Zvcm1hdElzc3VlcyhyZXN1bHQuaXNzdWVzKX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IFtpbmRleCwgdmFsdWVdIG9mIGludmFsaWQuZW50cmllcygpKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNjaGVtYVsnfnN0YW5kYXJkJ10udmFsaWRhdGUodmFsdWUpO1xuICAgICAgICBpZiAocmVzdWx0Lmlzc3VlcyA9PT0gdW5kZWZpbmVkIHx8IHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKGAke21ldGhvZE5hbWV9ICR7aGFsZn06IGludmFsaWQgY2FzZSAke1N0cmluZyhpbmRleCl9IHdhcyBhY2NlcHRlZC5gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB2aW9sYXRpb25zO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRJc3N1ZXMoaXNzdWVzOiByZWFkb25seSBTdGFuZGFyZFNjaGVtYVYxLklzc3VlW10pOiBzdHJpbmcge1xuICByZXR1cm4gaXNzdWVzLm1hcCgoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpLmpvaW4oJyAnKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7O0FBNkVPLFNBQVMsYUFBc0IsUUFBNEMsT0FBa0Q7QUFDbEksUUFBTSxTQUFTLE9BQU8sV0FBVyxFQUFFLFNBQVMsS0FBSztBQUNqRCxNQUFJLGtCQUFrQixTQUFTO0FBQzdCLFVBQU0sSUFBSSxVQUFVLHFFQUFxRTtBQUFBLEVBQzNGO0FBRUEsU0FBTztBQUNUO0FBWUEsZUFBc0Isa0JBQWlELFVBQXFCLFNBQWlFO0FBQzNKLFFBQU0sYUFBdUIsQ0FBQztBQUM5QixRQUFNLGdCQUE2QjtBQUNuQyxRQUFNLFFBQWtELFFBQVE7QUFFaEUsYUFBVyxjQUFjLE9BQU8sS0FBSyxhQUFhLEdBQUc7QUFDbkQsUUFBSSxDQUFDLE9BQU8sT0FBTyxPQUFPLFVBQVUsR0FBRztBQUNyQyxpQkFBVyxLQUFLLEdBQUcsVUFBVSwrREFBK0Q7QUFBQSxJQUM5RjtBQUFBLEVBQ0Y7QUFFQSxhQUFXLENBQUMsWUFBWSxXQUFXLEtBQUssT0FBTyxRQUFRLEtBQUssR0FBRztBQUM3RCxVQUFNLGlCQUFpQixjQUFjLFVBQVU7QUFDL0MsUUFBSSxtQkFBbUIsUUFBVztBQUNoQyxpQkFBVyxLQUFLLEdBQUcsVUFBVSx5REFBeUQ7QUFDdEY7QUFBQSxJQUNGO0FBRUEsZUFBVyxRQUFRLENBQUMsU0FBUyxRQUFRLEdBQVk7QUFDL0MsWUFBTSxTQUFTLGVBQWUsSUFBSTtBQUNsQyxVQUFJLFdBQVcsUUFBVztBQUN4QixtQkFBVyxLQUFLLEdBQUcsVUFBVSxJQUFJLElBQUksK0JBQStCO0FBQ3BFO0FBQUEsTUFDRjtBQUdBLFlBQU0sRUFBRSxPQUFPLElBQUksT0FBTyxXQUFXO0FBQ3JDLFlBQU0sVUFBa0IsT0FBTyxXQUFXLEVBQUU7QUFDNUMsVUFBSSxXQUFXLFFBQVEsVUFBVSxZQUFZLEdBQUc7QUFDOUMsbUJBQVcsS0FBSyxHQUFHLFVBQVUsSUFBSSxJQUFJLGdDQUFnQyxNQUFNLGlCQUFpQixPQUFPLE9BQU8sQ0FBQyxlQUFlLFFBQVEsTUFBTSxVQUFVO0FBQUEsTUFDcEo7QUFFQSxZQUFNLEVBQUUsU0FBUyxNQUFNLElBQUksWUFBWSxJQUFJO0FBQzNDLGlCQUFXLENBQUMsT0FBTyxLQUFLLEtBQUssTUFBTSxRQUFRLEdBQUc7QUFDNUMsY0FBTSxTQUFTLE1BQU0sT0FBTyxXQUFXLEVBQUUsU0FBUyxLQUFLO0FBQ3ZELFlBQUksT0FBTyxXQUFXLFFBQVc7QUFDL0IscUJBQVcsS0FBSyxHQUFHLFVBQVUsSUFBSSxJQUFJLGdCQUFnQixPQUFPLEtBQUssQ0FBQyxpQkFBaUIsYUFBYSxPQUFPLE1BQU0sQ0FBQyxFQUFFO0FBQUEsUUFDbEg7QUFBQSxNQUNGO0FBRUEsaUJBQVcsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLFFBQVEsR0FBRztBQUM5QyxjQUFNLFNBQVMsTUFBTSxPQUFPLFdBQVcsRUFBRSxTQUFTLEtBQUs7QUFDdkQsWUFBSSxPQUFPLFdBQVcsVUFBYSxPQUFPLE9BQU8sV0FBVyxHQUFHO0FBQzdELHFCQUFXLEtBQUssR0FBRyxVQUFVLElBQUksSUFBSSxrQkFBa0IsT0FBTyxLQUFLLENBQUMsZ0JBQWdCO0FBQUEsUUFDdEY7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQ1Q7QUFFQSxTQUFTLGFBQWEsUUFBbUQ7QUFDdkUsU0FBTyxPQUFPLElBQUksQ0FBQyxVQUFVLE1BQU0sT0FBTyxFQUFFLEtBQUssR0FBRztBQUN0RDsiLAogICJuYW1lcyI6IFtdCn0K
@@ -14,7 +14,7 @@
14
14
  * Running the schemas is left to whoever owns the call path, since that is where an issue can be reported.
15
15
  */
16
16
  import type { StandardSchemaV1 } from '@standard-schema/spec';
17
- import type { GuardedType, Literal, TypeGuard } from './type-guards.mjs';
17
+ import type { GuardedType, Literal, ObjectTypeGuardOptions, TypeGuard } from './type-guards.mjs';
18
18
  /**
19
19
  * The contract an API declares: every key is a method the API promises to expose, and its value optionally
20
20
  * carries the payload schemas for that method.
@@ -126,6 +126,52 @@ export interface ExpectedTypeGuard<T> {
126
126
  */
127
127
  readonly typeGuard: (value: unknown) => value is T;
128
128
  }
129
+ /**
130
+ * Options for {@link objectGuard}.
131
+ *
132
+ * @typeParam T - The object type the guard narrows to.
133
+ */
134
+ export interface ObjectGuardOptions<T extends object> extends ObjectTypeGuardOptions<T> {
135
+ /**
136
+ * What the object is, put before its properties in `expected`, e.g. `'the options of the link'`.
137
+ */
138
+ readonly description?: string;
139
+ }
140
+ /**
141
+ * One guard per option of an all-optional object type, as {@link optionsGuard} takes them: each describes a
142
+ * PRESENT option, so it does not accept `undefined`. A required property of `T` takes `never`, so a type that is
143
+ * not all-optional does not compile.
144
+ *
145
+ * @typeParam T - The object type.
146
+ */
147
+ export type OptionGuards<T extends object> = {
148
+ readonly [TKey in keyof T]-?: Partial<Pick<T, TKey>> extends Pick<T, TKey> ? ExpectedTypeGuard<Exclude<T[TKey], undefined>> : never;
149
+ };
150
+ /**
151
+ * Options for {@link optionsGuard}.
152
+ */
153
+ export interface OptionsGuardOptions {
154
+ /**
155
+ * What the options are, put before them in `expected`, e.g. `'select options'`.
156
+ */
157
+ readonly description?: string;
158
+ /**
159
+ * Whether a value carrying an own enumerable string key that no option guard names is refused. Letting it through,
160
+ * the default, lets a consumer compiled against a later version of the options pass one this version does not know.
161
+ *
162
+ * @default `false`
163
+ */
164
+ readonly shouldRejectUnknownKeys?: boolean;
165
+ }
166
+ /**
167
+ * One guard per property of an object type, as {@link objectGuard} takes them, typed as {@link PropertyTypeGuards}
168
+ * types the bare guards.
169
+ *
170
+ * @typeParam T - The object type.
171
+ */
172
+ export type PropertyGuards<T extends object> = {
173
+ readonly [TKey in keyof T]-?: ExpectedTypeGuard<Partial<Pick<T, TKey>> extends Pick<T, TKey> ? T[TKey] | undefined : T[TKey]>;
174
+ };
129
175
  /**
130
176
  * The {@link ApiContract} of a named API: one entry per function member, each typed against that member. Both
131
177
  * schemas are REQUIRED here, so a typed contract is a full description of every signature and a `{}` entry does
@@ -251,6 +297,19 @@ export declare function literalGuard<T extends Literal>(literals: readonly T[]):
251
297
  * @returns A guard accepting what `guard` accepts, or `null`.
252
298
  */
253
299
  export declare function nullableGuard<T>(guard: ExpectedTypeGuard<T>): ExpectedTypeGuard<null | T>;
300
+ /**
301
+ * Builds a guard accepting an object whose every listed property its guard accepts, as {@link objectTypeGuard} does,
302
+ * expecting the properties and what each expects: `{ alias?: a string; path: a string }`, after the
303
+ * {@link ObjectGuardOptions.description} when one is given. A key is marked optional when it is listed in
304
+ * {@link ObjectTypeGuardOptions.exactOptionalKeys}; without that list, an optional property's guard says
305
+ * `or undefined` itself.
306
+ *
307
+ * @typeParam T - The object type.
308
+ * @param propertyGuards - One guard per property of `T`.
309
+ * @param options - The options for the guard.
310
+ * @returns The guard.
311
+ */
312
+ export declare function objectGuard<T extends object>(propertyGuards: PropertyGuards<T>, options?: ObjectGuardOptions<T>): ExpectedTypeGuard<T>;
254
313
  /**
255
314
  * Widens a guard to also accept `undefined`, which is what an optional parameter receives when it is left out.
256
315
  *
@@ -259,6 +318,18 @@ export declare function nullableGuard<T>(guard: ExpectedTypeGuard<T>): ExpectedT
259
318
  * @returns A guard accepting what `guard` accepts, or `undefined`.
260
319
  */
261
320
  export declare function optionalGuard<T>(guard: ExpectedTypeGuard<T>): ExpectedTypeGuard<T | undefined>;
321
+ /**
322
+ * Builds a guard accepting an options bag: an object whose every option may be absent, or `undefined`, and must
323
+ * otherwise pass its guard. A key no guard names is let through unless
324
+ * {@link OptionsGuardOptions.shouldRejectUnknownKeys} is set. It expects the options and what each expects:
325
+ * `{ prefix?: a string; isHidden?: a boolean }`, after the {@link OptionsGuardOptions.description} when one is given.
326
+ *
327
+ * @typeParam T - The options type, every property of which is optional.
328
+ * @param optionGuards - One guard per option of `T`, for a present value.
329
+ * @param options - The options for the guard.
330
+ * @returns The guard.
331
+ */
332
+ export declare function optionsGuard<T extends object>(optionGuards: OptionGuards<T>, options?: OptionsGuardOptions): ExpectedTypeGuard<T>;
262
333
  /**
263
334
  * Builds a guard accepting what any of the given guards accepts, expecting their `expected` texts joined by `or`.
264
335
  *