@sanity/validation 2.33.4-performance-opts.16 → 2.33.4-shopify.8
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/dts/index.d.ts +0 -1
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/validateDocument.d.ts +1 -3
- package/dist/dts/validateDocument.d.ts.map +1 -1
- package/lib/index.js +1 -11
- package/lib/validateDocument.js +138 -149
- package/package.json +5 -6
- package/src/index.ts +0 -2
- package/src/validateDocument.test.ts +77 -0
- package/src/validateDocument.ts +60 -97
- package/dist/dts/util/requestIdleCallback.d.ts +0 -3
- package/dist/dts/util/requestIdleCallback.d.ts.map +0 -1
- package/lib/util/requestIdleCallback.js +0 -35
- package/src/util/requestIdleCallback.ts +0 -29
package/dist/dts/index.d.ts
CHANGED
package/dist/dts/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,QAAQ,CAAA;AAC9B,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AACjD,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAC/C,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;;;;;;;AAEvD,wBAAwF;AACxF,OAAO,EAAC,SAAS,IAAI,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAC,CAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,QAAQ,CAAA;AAC9B,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AACjD,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAC/C,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;;;;;;;AAEvD,wBAAwF;AACxF,OAAO,EAAC,SAAS,IAAI,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAC,CAAA"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { SanityDocument, Schema, SchemaType, ValidationContext, ValidationMarker } from '@sanity/types';
|
|
2
|
-
import { Observable } from 'rxjs';
|
|
3
2
|
/**
|
|
4
3
|
* @internal
|
|
5
4
|
*/
|
|
6
5
|
export declare function resolveTypeForArrayItem(item: unknown, candidates: SchemaType[]): SchemaType | undefined;
|
|
7
6
|
export default function validateDocument(doc: SanityDocument, schema: Schema, context?: Pick<ValidationContext, 'getDocumentExists'>): Promise<ValidationMarker[]>;
|
|
8
|
-
export declare function validateDocumentObservable(doc: SanityDocument, schema: Schema, context?: Pick<ValidationContext, 'getDocumentExists'>): Observable<ValidationMarker[]>;
|
|
9
7
|
/**
|
|
10
8
|
* this is used make optional properties required by replacing optionals with
|
|
11
9
|
* `T[P] | undefined`. this is used to prevent errors in `validateItem` where
|
|
@@ -19,6 +17,6 @@ declare type ExplicitUndefined<T> = {
|
|
|
19
17
|
declare type ValidateItemOptions = {
|
|
20
18
|
value: unknown;
|
|
21
19
|
} & ExplicitUndefined<ValidationContext>;
|
|
22
|
-
export declare function validateItem(
|
|
20
|
+
export declare function validateItem({ value, type, path, parent, ...restOfContext }: ValidateItemOptions): Promise<ValidationMarker[]>;
|
|
23
21
|
export {};
|
|
24
22
|
//# sourceMappingURL=validateDocument.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateDocument.d.ts","sourceRoot":"","sources":["../../src/validateDocument.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"validateDocument.d.ts","sourceRoot":"","sources":["../../src/validateDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,MAAM,EACN,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAMjB,MAAM,eAAe,CAAA;AAYtB;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,UAAU,EAAE,GACvB,UAAU,GAAG,SAAS,CAiBxB;AAED,wBAA8B,gBAAgB,CAC5C,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,GACrD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA2B7B;AAED;;;;;;GAMG;AACH,aAAK,iBAAiB,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAC5F,CAAA;AAED,aAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,OAAO,CAAA;CACf,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;AAExC,wBAAsB,YAAY,CAAC,EACjC,KAAK,EACL,IAAI,EACJ,IAAS,EACT,MAAM,EACN,GAAG,aAAa,EACjB,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA4HnD"}
|
package/lib/index.js
CHANGED
|
@@ -28,25 +28,15 @@ Object.defineProperty(exports, "validateDocument", {
|
|
|
28
28
|
return _validateDocument.default;
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
|
-
Object.defineProperty(exports, "validateDocumentObservable", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
get: function get() {
|
|
34
|
-
return _validateDocument.validateDocumentObservable;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
31
|
|
|
38
32
|
var _Rule = _interopRequireDefault(require("./Rule"));
|
|
39
33
|
|
|
40
|
-
var _validateDocument =
|
|
34
|
+
var _validateDocument = _interopRequireDefault(require("./validateDocument"));
|
|
41
35
|
|
|
42
36
|
var _inferFromSchema = _interopRequireDefault(require("./inferFromSchema"));
|
|
43
37
|
|
|
44
38
|
var _inferFromSchemaType = _interopRequireDefault(require("./inferFromSchemaType"));
|
|
45
39
|
|
|
46
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
47
|
-
|
|
48
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
49
|
-
|
|
50
40
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
51
41
|
|
|
52
42
|
var _default = {
|
package/lib/validateDocument.js
CHANGED
|
@@ -5,23 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = validateDocument;
|
|
7
7
|
exports.resolveTypeForArrayItem = resolveTypeForArrayItem;
|
|
8
|
-
exports.validateDocumentObservable = validateDocumentObservable;
|
|
9
8
|
exports.validateItem = validateItem;
|
|
10
9
|
|
|
11
10
|
var _uniqBy2 = _interopRequireDefault(require("lodash/uniqBy"));
|
|
12
11
|
|
|
13
|
-
var _flatten2 = _interopRequireDefault(require("lodash/flatten"));
|
|
14
|
-
|
|
15
12
|
var _types = require("@sanity/types");
|
|
16
13
|
|
|
17
|
-
var _rxjs = require("rxjs");
|
|
18
|
-
|
|
19
|
-
var _operators = require("rxjs/operators");
|
|
20
|
-
|
|
21
14
|
var _typeString = _interopRequireDefault(require("./util/typeString"));
|
|
22
15
|
|
|
23
|
-
var _requestIdleCallback = require("./util/requestIdleCallback");
|
|
24
|
-
|
|
25
16
|
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
|
|
26
17
|
|
|
27
18
|
var _normalizeValidationRules = _interopRequireDefault(require("./util/normalizeValidationRules"));
|
|
@@ -52,6 +43,10 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|
|
52
43
|
|
|
53
44
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
54
45
|
|
|
46
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
47
|
+
|
|
48
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
49
|
+
|
|
55
50
|
var isRecord = maybeRecord => typeof maybeRecord === 'object' && maybeRecord !== null && !Array.isArray(maybeRecord);
|
|
56
51
|
|
|
57
52
|
var isNonNullable = value => value !== null && value !== undefined;
|
|
@@ -79,36 +74,8 @@ function resolveTypeForArrayItem(item, candidates) {
|
|
|
79
74
|
}) || candidates.find(candidate => candidate.name === itemType) || candidates.find(candidate => candidate.name === 'object' && primitive === 'object');
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
function validateDocument(doc, schema, context) {
|
|
85
|
-
return validateDocumentObservable(doc, schema, context).toPromise();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function validateDocumentObservable(doc, schema, context) {
|
|
89
|
-
var documentType = schema.get(doc._type);
|
|
90
|
-
|
|
91
|
-
if (!documentType) {
|
|
92
|
-
console.warn('Schema type for object type "%s" not found, skipping validation', doc._type);
|
|
93
|
-
return (0, _rxjs.of)(EMPTY_MARKERS);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return validateItemObservable({
|
|
97
|
-
parent: undefined,
|
|
98
|
-
value: doc,
|
|
99
|
-
path: [],
|
|
100
|
-
document: doc,
|
|
101
|
-
type: documentType,
|
|
102
|
-
getDocumentExists: context === null || context === void 0 ? void 0 : context.getDocumentExists
|
|
103
|
-
}).pipe((0, _operators.catchError)(err => {
|
|
104
|
-
console.error(err);
|
|
105
|
-
return (0, _rxjs.of)([{
|
|
106
|
-
type: 'validation',
|
|
107
|
-
level: 'error',
|
|
108
|
-
path: [],
|
|
109
|
-
item: new _ValidationError.default(err === null || err === void 0 ? void 0 : err.message)
|
|
110
|
-
}]);
|
|
111
|
-
}));
|
|
77
|
+
function validateDocument(_x, _x2, _x3) {
|
|
78
|
+
return _validateDocument.apply(this, arguments);
|
|
112
79
|
}
|
|
113
80
|
/**
|
|
114
81
|
* this is used make optional properties required by replacing optionals with
|
|
@@ -119,124 +86,146 @@ function validateDocumentObservable(doc, schema, context) {
|
|
|
119
86
|
*/
|
|
120
87
|
|
|
121
88
|
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
89
|
+
function _validateDocument() {
|
|
90
|
+
_validateDocument = _asyncToGenerator(function* (doc, schema, context) {
|
|
91
|
+
var documentType = schema.get(doc._type);
|
|
125
92
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
type
|
|
140
|
-
})))); // run validation for nested values (conditionally)
|
|
141
|
-
|
|
142
|
-
var fieldChecks = [];
|
|
143
|
-
var selfIsRequired = rules.some(rule => rule.isRequired());
|
|
144
|
-
var shouldRunNestedObjectValidation = // run nested validation for objects
|
|
145
|
-
(type === null || type === void 0 ? void 0 : type.jsonType) === 'object' && ( // if the value is truthy
|
|
146
|
-
!!value || // or
|
|
147
|
-
// (the value is null or undefined) and the top-level value is required
|
|
148
|
-
(value === null || value === undefined) && selfIsRequired);
|
|
149
|
-
|
|
150
|
-
if (shouldRunNestedObjectValidation) {
|
|
151
|
-
var fieldTypes = type.fields.reduce((acc, field) => {
|
|
152
|
-
acc[field.name] = field.type;
|
|
153
|
-
return acc;
|
|
154
|
-
}, {}); // Validation for rules set at the object level with `Rule.fields({/* ... */})`
|
|
155
|
-
|
|
156
|
-
fieldChecks = fieldChecks.concat(rules.map(rule => rule._fieldRules).filter(isNonNullable).flatMap(fieldResults => Object.entries(fieldResults)).flatMap(_ref2 => {
|
|
157
|
-
var _ref3 = _slicedToArray(_ref2, 2),
|
|
158
|
-
name = _ref3[0],
|
|
159
|
-
validation = _ref3[1];
|
|
160
|
-
|
|
161
|
-
var fieldType = fieldTypes[name];
|
|
162
|
-
return (0, _normalizeValidationRules.default)(_objectSpread(_objectSpread({}, fieldType), {}, {
|
|
163
|
-
validation
|
|
164
|
-
})).map(subRule => {
|
|
165
|
-
var nestedValue = isRecord(value) ? value[name] : undefined;
|
|
166
|
-
return (0, _rxjs.defer)(() => subRule.validate(nestedValue, _objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
167
|
-
parent: value,
|
|
168
|
-
path: path.concat(name),
|
|
169
|
-
type: fieldType
|
|
170
|
-
})));
|
|
93
|
+
if (!documentType) {
|
|
94
|
+
console.warn('Schema type for object type "%s" not found, skipping validation', doc._type);
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
return yield validateItem({
|
|
100
|
+
parent: undefined,
|
|
101
|
+
value: doc,
|
|
102
|
+
path: [],
|
|
103
|
+
document: doc,
|
|
104
|
+
type: documentType,
|
|
105
|
+
getDocumentExists: context === null || context === void 0 ? void 0 : context.getDocumentExists
|
|
171
106
|
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
var shouldRunNestedValidationForArrays = (type === null || type === void 0 ? void 0 : type.jsonType) === 'array' && Array.isArray(value);
|
|
187
|
-
|
|
188
|
-
if (shouldRunNestedValidationForArrays) {
|
|
189
|
-
fieldChecks = fieldChecks.concat(value.map(item => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
190
|
-
parent: value,
|
|
191
|
-
value: item,
|
|
192
|
-
path: path.concat((0, _types.isKeyedObject)(item) ? {
|
|
193
|
-
_key: item._key
|
|
194
|
-
} : value.indexOf(item)),
|
|
195
|
-
type: resolveTypeForArrayItem(item, type.of)
|
|
196
|
-
}))));
|
|
197
|
-
} // markDefs also do no run nested validation if the parent object is undefined
|
|
198
|
-
// for a similar reason to arrays
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
var shouldRunNestedValidationForMarkDefs = (0, _types.isBlock)(value) && value.markDefs.length && (0, _types.isBlockSchemaType)(type);
|
|
202
|
-
|
|
203
|
-
if (shouldRunNestedValidationForMarkDefs) {
|
|
204
|
-
var _type$fields = _slicedToArray(type.fields, 1),
|
|
205
|
-
spanChildrenField = _type$fields[0];
|
|
206
|
-
|
|
207
|
-
var spanType = spanChildrenField.type.of.find(_types.isSpanSchemaType);
|
|
208
|
-
var annotations = ((spanType === null || spanType === void 0 ? void 0 : spanType.annotations) || []).reduce((acc, annotationType) => {
|
|
209
|
-
acc.set(annotationType.name, annotationType);
|
|
210
|
-
return acc;
|
|
211
|
-
}, new Map());
|
|
212
|
-
fieldChecks = fieldChecks.concat(value.markDefs.map(markDef => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
213
|
-
parent: value,
|
|
214
|
-
value: markDef,
|
|
215
|
-
path: path.concat(['markDefs', {
|
|
216
|
-
_key: markDef._key
|
|
217
|
-
}]),
|
|
218
|
-
type: annotations.get(markDef._type)
|
|
219
|
-
}))));
|
|
220
|
-
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error(err);
|
|
109
|
+
return [{
|
|
110
|
+
type: 'validation',
|
|
111
|
+
level: 'error',
|
|
112
|
+
path: [],
|
|
113
|
+
item: new _ValidationError.default(err === null || err === void 0 ? void 0 : err.message)
|
|
114
|
+
}];
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return _validateDocument.apply(this, arguments);
|
|
118
|
+
}
|
|
221
119
|
|
|
222
|
-
|
|
223
|
-
|
|
120
|
+
function validateItem(_x4) {
|
|
121
|
+
return _validateItem.apply(this, arguments);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function _validateItem() {
|
|
125
|
+
_validateItem = _asyncToGenerator(function* (_ref) {
|
|
126
|
+
var value = _ref.value,
|
|
127
|
+
type = _ref.type,
|
|
128
|
+
_ref$path = _ref.path,
|
|
129
|
+
path = _ref$path === void 0 ? [] : _ref$path,
|
|
130
|
+
parent = _ref.parent,
|
|
131
|
+
restOfContext = _objectWithoutProperties(_ref, _excluded);
|
|
132
|
+
|
|
133
|
+
var rules = (0, _normalizeValidationRules.default)(type); // run validation for the current value
|
|
134
|
+
|
|
135
|
+
var selfChecks = rules.map(rule => rule.validate(value, _objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
136
|
+
parent,
|
|
137
|
+
path,
|
|
138
|
+
type
|
|
139
|
+
}))); // run validation for nested values (conditionally)
|
|
140
|
+
|
|
141
|
+
var nestedChecks = [];
|
|
142
|
+
var selfIsRequired = rules.some(rule => rule.isRequired());
|
|
143
|
+
var shouldRunNestedObjectValidation = // run nested validation for objects
|
|
144
|
+
(type === null || type === void 0 ? void 0 : type.jsonType) === 'object' && ( // if the value is truthy
|
|
145
|
+
!!value || // or
|
|
146
|
+
// (the value is null or undefined) and the top-level value is required
|
|
147
|
+
(value === null || value === undefined) && selfIsRequired);
|
|
148
|
+
|
|
149
|
+
if (shouldRunNestedObjectValidation) {
|
|
150
|
+
var fieldTypes = type.fields.reduce((acc, field) => {
|
|
151
|
+
acc[field.name] = field.type;
|
|
152
|
+
return acc;
|
|
153
|
+
}, {}); // Validation for rules set at the object level with `Rule.fields({/* ... */})`
|
|
154
|
+
|
|
155
|
+
nestedChecks = nestedChecks.concat(rules.map(rule => rule._fieldRules).filter(isNonNullable).flatMap(fieldResults => Object.entries(fieldResults)).flatMap(_ref2 => {
|
|
156
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
157
|
+
name = _ref3[0],
|
|
158
|
+
validation = _ref3[1];
|
|
159
|
+
|
|
160
|
+
var fieldType = fieldTypes[name];
|
|
161
|
+
return (0, _normalizeValidationRules.default)(_objectSpread(_objectSpread({}, fieldType), {}, {
|
|
162
|
+
validation
|
|
163
|
+
})).map(subRule => {
|
|
164
|
+
var nestedValue = isRecord(value) ? value[name] : undefined;
|
|
165
|
+
return subRule.validate(nestedValue, _objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
166
|
+
parent: value,
|
|
167
|
+
path: path.concat(name),
|
|
168
|
+
type: fieldType
|
|
169
|
+
}));
|
|
170
|
+
});
|
|
171
|
+
})); // Validation from each field's schema `validation: Rule => {/* ... */}` function
|
|
172
|
+
|
|
173
|
+
nestedChecks = nestedChecks.concat(type.fields.map(field => validateItem(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
174
|
+
parent: value,
|
|
175
|
+
value: isRecord(value) ? value[field.name] : undefined,
|
|
176
|
+
path: path.concat(field.name),
|
|
177
|
+
type: field.type
|
|
178
|
+
}))));
|
|
179
|
+
} // note: unlike objects, arrays should not run nested validation for undefined
|
|
180
|
+
// values because we won't have a valid path to put a marker (i.e. missing the
|
|
181
|
+
// key or index in the path) and the downstream form builder won't have a
|
|
182
|
+
// valid target component
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
var shouldRunNestedValidationForArrays = (type === null || type === void 0 ? void 0 : type.jsonType) === 'array' && Array.isArray(value);
|
|
186
|
+
|
|
187
|
+
if (shouldRunNestedValidationForArrays) {
|
|
188
|
+
nestedChecks = nestedChecks.concat(value.map(item => validateItem(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
189
|
+
parent: value,
|
|
190
|
+
value: item,
|
|
191
|
+
path: path.concat((0, _types.isKeyedObject)(item) ? {
|
|
192
|
+
_key: item._key
|
|
193
|
+
} : value.indexOf(item)),
|
|
194
|
+
type: resolveTypeForArrayItem(item, type.of)
|
|
195
|
+
}))));
|
|
196
|
+
} // markDefs also do no run nested validation if the parent object is undefined
|
|
197
|
+
// for a similar reason to arrays
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
var shouldRunNestedValidationForMarkDefs = (0, _types.isBlock)(value) && value.markDefs.length && (0, _types.isBlockSchemaType)(type);
|
|
201
|
+
|
|
202
|
+
if (shouldRunNestedValidationForMarkDefs) {
|
|
203
|
+
var _type$fields = _slicedToArray(type.fields, 1),
|
|
204
|
+
spanChildrenField = _type$fields[0];
|
|
205
|
+
|
|
206
|
+
var spanType = spanChildrenField.type.of.find(_types.isSpanSchemaType);
|
|
207
|
+
var annotations = ((spanType === null || spanType === void 0 ? void 0 : spanType.annotations) || []).reduce((map, annotationType) => {
|
|
208
|
+
map.set(annotationType.name, annotationType);
|
|
209
|
+
return map;
|
|
210
|
+
}, new Map());
|
|
211
|
+
nestedChecks = nestedChecks.concat(value.markDefs.map(markDef => validateItem(_objectSpread(_objectSpread({}, restOfContext), {}, {
|
|
212
|
+
parent: value,
|
|
213
|
+
value: markDef,
|
|
214
|
+
path: path.concat(['markDefs', {
|
|
215
|
+
_key: markDef._key
|
|
216
|
+
}]),
|
|
217
|
+
type: annotations.get(markDef._type)
|
|
218
|
+
}))));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
var results = (yield Promise.all([...selfChecks, ...nestedChecks])).flat(); // run `uniqBy` if `_fieldRules` are present because they can
|
|
224
222
|
// cause repeat markers
|
|
223
|
+
|
|
225
224
|
if (rules.some(rule => rule._fieldRules)) {
|
|
226
225
|
return (0, _uniqBy2.default)(results, rule => JSON.stringify(rule));
|
|
227
226
|
}
|
|
228
227
|
|
|
229
228
|
return results;
|
|
230
|
-
}));
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
function idle(timeout) {
|
|
234
|
-
return new _rxjs.Observable(observer => {
|
|
235
|
-
var handle = (0, _requestIdleCallback.requestIdleCallback)(() => {
|
|
236
|
-
observer.complete();
|
|
237
|
-
}, timeout ? {
|
|
238
|
-
timeout
|
|
239
|
-
} : undefined);
|
|
240
|
-
return () => (0, _requestIdleCallback.cancelIdleCallback)(handle);
|
|
241
229
|
});
|
|
230
|
+
return _validateItem.apply(this, arguments);
|
|
242
231
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/validation",
|
|
3
|
-
"version": "2.33.4-
|
|
3
|
+
"version": "2.33.4-shopify.8+b3097f8c9",
|
|
4
4
|
"description": "Validation and warning infrastructure for Sanity projects",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./dist/dts",
|
|
@@ -33,13 +33,12 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@sanity/client": "^3.3.3",
|
|
36
|
-
"@sanity/schema": "2.33.4-
|
|
36
|
+
"@sanity/schema": "2.33.4-shopify.8+b3097f8c9"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@sanity/types": "2.33.4-
|
|
39
|
+
"@sanity/types": "2.33.4-shopify.8+b3097f8c9",
|
|
40
40
|
"date-fns": "^2.16.1",
|
|
41
|
-
"lodash": "^4.17.15"
|
|
42
|
-
"rxjs": "^6.5.3"
|
|
41
|
+
"lodash": "^4.17.15"
|
|
43
42
|
},
|
|
44
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "b3097f8c9ec8d874b3fd86005a17b0cb5eaf136c"
|
|
45
44
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,5 +5,3 @@ import inferFromSchemaType from './inferFromSchemaType'
|
|
|
5
5
|
|
|
6
6
|
export default {Rule: RuleClass, validateDocument, inferFromSchema, inferFromSchemaType}
|
|
7
7
|
export {RuleClass as Rule, validateDocument, inferFromSchema, inferFromSchemaType}
|
|
8
|
-
|
|
9
|
-
export {validateDocumentObservable} from './validateDocument'
|
|
@@ -687,4 +687,81 @@ describe('validateItem', () => {
|
|
|
687
687
|
},
|
|
688
688
|
])
|
|
689
689
|
})
|
|
690
|
+
|
|
691
|
+
it('runs all nested validation checks concurrently', async () => {
|
|
692
|
+
type Resolver = (value: true) => void
|
|
693
|
+
const resolvers = new Set<Resolver>()
|
|
694
|
+
const customValidationFn = () => new Promise<true>((resolve) => resolvers.add(resolve))
|
|
695
|
+
|
|
696
|
+
const schema: Schema = createSchema({
|
|
697
|
+
types: [
|
|
698
|
+
{
|
|
699
|
+
name: 'root',
|
|
700
|
+
type: 'object',
|
|
701
|
+
fields: [
|
|
702
|
+
{
|
|
703
|
+
name: 'level1Object',
|
|
704
|
+
type: 'object',
|
|
705
|
+
validation: (rule: Rule) => [
|
|
706
|
+
rule.custom(customValidationFn),
|
|
707
|
+
rule.fields({
|
|
708
|
+
level2String: (r) => r.custom(customValidationFn),
|
|
709
|
+
}),
|
|
710
|
+
],
|
|
711
|
+
fields: [
|
|
712
|
+
{
|
|
713
|
+
name: 'level2String',
|
|
714
|
+
type: 'string',
|
|
715
|
+
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
716
|
+
},
|
|
717
|
+
],
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
name: 'level1Array',
|
|
721
|
+
type: 'array',
|
|
722
|
+
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
723
|
+
of: [
|
|
724
|
+
{
|
|
725
|
+
type: 'object',
|
|
726
|
+
fields: [
|
|
727
|
+
{
|
|
728
|
+
name: 'level2Number',
|
|
729
|
+
type: 'number',
|
|
730
|
+
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
731
|
+
},
|
|
732
|
+
],
|
|
733
|
+
},
|
|
734
|
+
],
|
|
735
|
+
},
|
|
736
|
+
],
|
|
737
|
+
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
})
|
|
741
|
+
|
|
742
|
+
const value = {
|
|
743
|
+
level1Object: {level3String: 'a string'},
|
|
744
|
+
level1Array: [{level2Number: 5}],
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
const resultPromise = validateItem({
|
|
748
|
+
value,
|
|
749
|
+
document: undefined,
|
|
750
|
+
parent: undefined,
|
|
751
|
+
path: undefined,
|
|
752
|
+
type: schema.get('root'),
|
|
753
|
+
getDocumentExists: undefined,
|
|
754
|
+
})
|
|
755
|
+
|
|
756
|
+
// after `validateItem(...)` has been initiated, all of the custom
|
|
757
|
+
// validation calls should have fired so the resolver size should equal the
|
|
758
|
+
// amount of total fields
|
|
759
|
+
expect(resolvers.size).toBe(6)
|
|
760
|
+
|
|
761
|
+
for (const resolver of resolvers) {
|
|
762
|
+
resolver(true)
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
await resultPromise
|
|
766
|
+
})
|
|
690
767
|
})
|
package/src/validateDocument.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isBlock,
|
|
3
|
-
isBlockSchemaType,
|
|
4
|
-
isKeyedObject,
|
|
5
|
-
isSpanSchemaType,
|
|
6
|
-
isTypedObject,
|
|
7
2
|
SanityDocument,
|
|
8
3
|
Schema,
|
|
9
4
|
SchemaType,
|
|
10
5
|
ValidationContext,
|
|
11
6
|
ValidationMarker,
|
|
7
|
+
isKeyedObject,
|
|
8
|
+
isTypedObject,
|
|
9
|
+
isBlock,
|
|
10
|
+
isBlockSchemaType,
|
|
11
|
+
isSpanSchemaType,
|
|
12
12
|
} from '@sanity/types'
|
|
13
|
-
import {
|
|
14
|
-
import {catchError, map, mergeAll, mergeMap, toArray} from 'rxjs/operators'
|
|
15
|
-
import {flatten, uniqBy} from 'lodash'
|
|
13
|
+
import {uniqBy} from 'lodash'
|
|
16
14
|
import typeString from './util/typeString'
|
|
17
|
-
import {requestIdleCallback, cancelIdleCallback} from './util/requestIdleCallback'
|
|
18
15
|
import ValidationErrorClass from './ValidationError'
|
|
19
16
|
import normalizeValidationRules from './util/normalizeValidationRules'
|
|
20
17
|
|
|
@@ -48,47 +45,38 @@ export function resolveTypeForArrayItem(
|
|
|
48
45
|
candidates.find((candidate) => candidate.name === 'object' && primitive === 'object')
|
|
49
46
|
)
|
|
50
47
|
}
|
|
51
|
-
const EMPTY_MARKERS: ValidationMarker[] = []
|
|
52
48
|
|
|
53
|
-
export default function validateDocument(
|
|
49
|
+
export default async function validateDocument(
|
|
54
50
|
doc: SanityDocument,
|
|
55
51
|
schema: Schema,
|
|
56
52
|
context?: Pick<ValidationContext, 'getDocumentExists'>
|
|
57
53
|
): Promise<ValidationMarker[]> {
|
|
58
|
-
return validateDocumentObservable(doc, schema, context).toPromise()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function validateDocumentObservable(
|
|
62
|
-
doc: SanityDocument,
|
|
63
|
-
schema: Schema,
|
|
64
|
-
context?: Pick<ValidationContext, 'getDocumentExists'>
|
|
65
|
-
): Observable<ValidationMarker[]> {
|
|
66
54
|
const documentType = schema.get(doc._type)
|
|
67
55
|
if (!documentType) {
|
|
68
56
|
console.warn('Schema type for object type "%s" not found, skipping validation', doc._type)
|
|
69
|
-
return
|
|
57
|
+
return []
|
|
70
58
|
}
|
|
71
59
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
catchError((err) => {
|
|
81
|
-
console.error(err)
|
|
82
|
-
return of([
|
|
83
|
-
{
|
|
84
|
-
type: 'validation' as const,
|
|
85
|
-
level: 'error' as const,
|
|
86
|
-
path: [],
|
|
87
|
-
item: new ValidationErrorClass(err?.message),
|
|
88
|
-
},
|
|
89
|
-
])
|
|
60
|
+
try {
|
|
61
|
+
return await validateItem({
|
|
62
|
+
parent: undefined,
|
|
63
|
+
value: doc,
|
|
64
|
+
path: [],
|
|
65
|
+
document: doc,
|
|
66
|
+
type: documentType,
|
|
67
|
+
getDocumentExists: context?.getDocumentExists,
|
|
90
68
|
})
|
|
91
|
-
)
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error(err)
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
type: 'validation',
|
|
74
|
+
level: 'error',
|
|
75
|
+
path: [],
|
|
76
|
+
item: new ValidationErrorClass(err?.message),
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
}
|
|
92
80
|
}
|
|
93
81
|
|
|
94
82
|
/**
|
|
@@ -106,32 +94,27 @@ type ValidateItemOptions = {
|
|
|
106
94
|
value: unknown
|
|
107
95
|
} & ExplicitUndefined<ValidationContext>
|
|
108
96
|
|
|
109
|
-
export function validateItem(
|
|
110
|
-
return validateItemObservable(opts).toPromise()
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function validateItemObservable({
|
|
97
|
+
export async function validateItem({
|
|
114
98
|
value,
|
|
115
99
|
type,
|
|
116
100
|
path = [],
|
|
117
101
|
parent,
|
|
118
102
|
...restOfContext
|
|
119
|
-
}: ValidateItemOptions):
|
|
103
|
+
}: ValidateItemOptions): Promise<ValidationMarker[]> {
|
|
120
104
|
const rules = normalizeValidationRules(type)
|
|
105
|
+
|
|
121
106
|
// run validation for the current value
|
|
122
107
|
const selfChecks = rules.map((rule) =>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
})
|
|
130
|
-
)
|
|
108
|
+
rule.validate(value, {
|
|
109
|
+
...restOfContext,
|
|
110
|
+
parent,
|
|
111
|
+
path,
|
|
112
|
+
type,
|
|
113
|
+
})
|
|
131
114
|
)
|
|
132
115
|
|
|
133
116
|
// run validation for nested values (conditionally)
|
|
134
|
-
let
|
|
117
|
+
let nestedChecks: Array<Promise<ValidationMarker[]>> = []
|
|
135
118
|
|
|
136
119
|
const selfIsRequired = rules.some((rule) => rule.isRequired())
|
|
137
120
|
const shouldRunNestedObjectValidation =
|
|
@@ -149,7 +132,7 @@ function validateItemObservable({
|
|
|
149
132
|
}, {})
|
|
150
133
|
|
|
151
134
|
// Validation for rules set at the object level with `Rule.fields({/* ... */})`
|
|
152
|
-
|
|
135
|
+
nestedChecks = nestedChecks.concat(
|
|
153
136
|
rules
|
|
154
137
|
.map((rule) => rule._fieldRules)
|
|
155
138
|
.filter(isNonNullable)
|
|
@@ -158,22 +141,20 @@ function validateItemObservable({
|
|
|
158
141
|
const fieldType = fieldTypes[name]
|
|
159
142
|
return normalizeValidationRules({...fieldType, validation}).map((subRule) => {
|
|
160
143
|
const nestedValue = isRecord(value) ? value[name] : undefined
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
})
|
|
168
|
-
)
|
|
144
|
+
return subRule.validate(nestedValue, {
|
|
145
|
+
...restOfContext,
|
|
146
|
+
parent: value,
|
|
147
|
+
path: path.concat(name),
|
|
148
|
+
type: fieldType,
|
|
149
|
+
})
|
|
169
150
|
})
|
|
170
151
|
})
|
|
171
152
|
)
|
|
172
153
|
|
|
173
154
|
// Validation from each field's schema `validation: Rule => {/* ... */}` function
|
|
174
|
-
|
|
155
|
+
nestedChecks = nestedChecks.concat(
|
|
175
156
|
type.fields.map((field) =>
|
|
176
|
-
|
|
157
|
+
validateItem({
|
|
177
158
|
...restOfContext,
|
|
178
159
|
parent: value,
|
|
179
160
|
value: isRecord(value) ? value[field.name] : undefined,
|
|
@@ -191,9 +172,9 @@ function validateItemObservable({
|
|
|
191
172
|
const shouldRunNestedValidationForArrays = type?.jsonType === 'array' && Array.isArray(value)
|
|
192
173
|
|
|
193
174
|
if (shouldRunNestedValidationForArrays) {
|
|
194
|
-
|
|
175
|
+
nestedChecks = nestedChecks.concat(
|
|
195
176
|
value.map((item) =>
|
|
196
|
-
|
|
177
|
+
validateItem({
|
|
197
178
|
...restOfContext,
|
|
198
179
|
parent: value,
|
|
199
180
|
value: item,
|
|
@@ -214,16 +195,16 @@ function validateItemObservable({
|
|
|
214
195
|
const spanType = spanChildrenField.type.of.find(isSpanSchemaType)
|
|
215
196
|
|
|
216
197
|
const annotations = (spanType?.annotations || []).reduce<Map<string, SchemaType>>(
|
|
217
|
-
(
|
|
218
|
-
|
|
219
|
-
return
|
|
198
|
+
(map, annotationType) => {
|
|
199
|
+
map.set(annotationType.name, annotationType)
|
|
200
|
+
return map
|
|
220
201
|
},
|
|
221
202
|
new Map()
|
|
222
203
|
)
|
|
223
204
|
|
|
224
|
-
|
|
205
|
+
nestedChecks = nestedChecks.concat(
|
|
225
206
|
value.markDefs.map((markDef) =>
|
|
226
|
-
|
|
207
|
+
validateItem({
|
|
227
208
|
...restOfContext,
|
|
228
209
|
parent: value,
|
|
229
210
|
value: markDef,
|
|
@@ -234,31 +215,13 @@ function validateItemObservable({
|
|
|
234
215
|
)
|
|
235
216
|
}
|
|
236
217
|
|
|
237
|
-
|
|
238
|
-
mergeMap((validateNode) => concat(idle(), validateNode), 40),
|
|
239
|
-
mergeAll(),
|
|
240
|
-
toArray(),
|
|
241
|
-
map(flatten),
|
|
242
|
-
map((results) => {
|
|
243
|
-
// run `uniqBy` if `_fieldRules` are present because they can
|
|
244
|
-
// cause repeat markers
|
|
245
|
-
if (rules.some((rule) => rule._fieldRules)) {
|
|
246
|
-
return uniqBy(results, (rule) => JSON.stringify(rule))
|
|
247
|
-
}
|
|
248
|
-
return results
|
|
249
|
-
})
|
|
250
|
-
)
|
|
251
|
-
}
|
|
218
|
+
const results = (await Promise.all([...selfChecks, ...nestedChecks])).flat()
|
|
252
219
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
},
|
|
259
|
-
timeout ? {timeout} : undefined
|
|
260
|
-
)
|
|
220
|
+
// run `uniqBy` if `_fieldRules` are present because they can
|
|
221
|
+
// cause repeat markers
|
|
222
|
+
if (rules.some((rule) => rule._fieldRules)) {
|
|
223
|
+
return uniqBy(results, (rule) => JSON.stringify(rule))
|
|
224
|
+
}
|
|
261
225
|
|
|
262
|
-
|
|
263
|
-
})
|
|
226
|
+
return results
|
|
264
227
|
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare const requestIdleCallback: ((callback: IdleRequestCallback, options?: IdleRequestOptions | undefined) => number) & typeof globalThis.requestIdleCallback;
|
|
2
|
-
export declare const cancelIdleCallback: ((handle: number) => void) & typeof globalThis.cancelIdleCallback;
|
|
3
|
-
//# sourceMappingURL=requestIdleCallback.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"requestIdleCallback.d.ts","sourceRoot":"","sources":["../../../src/util/requestIdleCallback.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,mBAAmB,+HAAwD,CAAA;AACxF,eAAO,MAAM,kBAAkB,mEAAsD,CAAA"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.requestIdleCallback = exports.cancelIdleCallback = void 0;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Simple requestIdleCallback polyfill
|
|
10
|
-
* Can be removed when all browsers support requestIdleCallback: https://caniuse.com/requestidlecallback
|
|
11
|
-
* @param callback
|
|
12
|
-
* @param options
|
|
13
|
-
*/
|
|
14
|
-
var requestIdleCallbackShim = function requestIdleCallbackShim(callback, options) {
|
|
15
|
-
var start = Date.now();
|
|
16
|
-
return window.setTimeout(() => {
|
|
17
|
-
callback({
|
|
18
|
-
didTimeout: false,
|
|
19
|
-
|
|
20
|
-
timeRemaining() {
|
|
21
|
-
return Math.max(0, Date.now() - start);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
}, 0);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
var cancelIdleCallbackShim = function cancelIdleCallbackShim(handle) {
|
|
29
|
-
return window.clearTimeout(handle);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
var requestIdleCallback = window.requestIdleCallback || requestIdleCallbackShim;
|
|
33
|
-
exports.requestIdleCallback = requestIdleCallback;
|
|
34
|
-
var cancelIdleCallback = window.cancelIdleCallback || cancelIdleCallbackShim;
|
|
35
|
-
exports.cancelIdleCallback = cancelIdleCallback;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple requestIdleCallback polyfill
|
|
3
|
-
* Can be removed when all browsers support requestIdleCallback: https://caniuse.com/requestidlecallback
|
|
4
|
-
* @param callback
|
|
5
|
-
* @param options
|
|
6
|
-
*/
|
|
7
|
-
const requestIdleCallbackShim: typeof window.requestIdleCallback = function requestIdleCallbackShim(
|
|
8
|
-
callback,
|
|
9
|
-
options?
|
|
10
|
-
): number {
|
|
11
|
-
const start = Date.now()
|
|
12
|
-
return window.setTimeout(() => {
|
|
13
|
-
callback({
|
|
14
|
-
didTimeout: false,
|
|
15
|
-
timeRemaining() {
|
|
16
|
-
return Math.max(0, Date.now() - start)
|
|
17
|
-
},
|
|
18
|
-
})
|
|
19
|
-
}, 0)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const cancelIdleCallbackShim: typeof window.cancelIdleCallback = function cancelIdleCallbackShim(
|
|
23
|
-
handle: number
|
|
24
|
-
): void {
|
|
25
|
-
return window.clearTimeout(handle)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const requestIdleCallback = window.requestIdleCallback || requestIdleCallbackShim
|
|
29
|
-
export const cancelIdleCallback = window.cancelIdleCallback || cancelIdleCallbackShim
|