@fluidframework/core-utils 2.102.0 → 2.103.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.
- package/CHANGELOG.md +4 -0
- package/dist/allOrNone.d.ts +39 -0
- package/dist/allOrNone.d.ts.map +1 -0
- package/dist/allOrNone.js +42 -0
- package/dist/allOrNone.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/lib/allOrNone.d.ts +39 -0
- package/lib/allOrNone.d.ts.map +1 -0
- package/lib/allOrNone.js +38 -0
- package/lib/allOrNone.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/allOrNone.ts +57 -0
- package/src/index.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Classification returned by {@link validateAllOrNone}.
|
|
7
|
+
*
|
|
8
|
+
* - `"all"`: every named key has a defined value.
|
|
9
|
+
*
|
|
10
|
+
* - `"none"`: every named key is `undefined`.
|
|
11
|
+
*
|
|
12
|
+
* - `"mixed"`: some keys are defined and others are not — the case that
|
|
13
|
+
* `AllOrNone<T>` from `@fluidframework/core-interfaces` forbids at compile
|
|
14
|
+
* time but that can still arise when the input is constructed via cast or
|
|
15
|
+
* crosses an API boundary that erases the discriminated union.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export type AllOrNoneResult = "all" | "none" | "mixed";
|
|
20
|
+
/**
|
|
21
|
+
* Runtime validator for the `AllOrNone<T>` type modifier from
|
|
22
|
+
* `@fluidframework/core-interfaces`.
|
|
23
|
+
*
|
|
24
|
+
* Given an object and the set of keys to inspect, classifies the object as
|
|
25
|
+
* `"all"`, `"none"`, or `"mixed"` based on which of the named keys carry a
|
|
26
|
+
* defined value. Useful at API entry points that accept a discriminated union
|
|
27
|
+
* of "supply the whole group, or supply none of it": a `"mixed"` result is
|
|
28
|
+
* the misuse case and is typically translated by the caller into a single
|
|
29
|
+
* named `UsageError` instead of letting a partial supply propagate to an
|
|
30
|
+
* inner layer where the failure surfaces as a less helpful error.
|
|
31
|
+
*
|
|
32
|
+
* Only the presence of `obj[key] !== undefined` is consulted — values that
|
|
33
|
+
* are `null`, `0`, `""`, or `false` count as "defined". Keys not present on
|
|
34
|
+
* the object at all are treated the same as `undefined`.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateAllOrNone<T extends object>(obj: Partial<T>, keys: readonly (keyof T)[]): AllOrNoneResult;
|
|
39
|
+
//# sourceMappingURL=allOrNone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOrNone.d.ts","sourceRoot":"","sources":["../src/allOrNone.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjD,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACxB,eAAe,CAcjB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateAllOrNone = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Runtime validator for the `AllOrNone<T>` type modifier from
|
|
10
|
+
* `@fluidframework/core-interfaces`.
|
|
11
|
+
*
|
|
12
|
+
* Given an object and the set of keys to inspect, classifies the object as
|
|
13
|
+
* `"all"`, `"none"`, or `"mixed"` based on which of the named keys carry a
|
|
14
|
+
* defined value. Useful at API entry points that accept a discriminated union
|
|
15
|
+
* of "supply the whole group, or supply none of it": a `"mixed"` result is
|
|
16
|
+
* the misuse case and is typically translated by the caller into a single
|
|
17
|
+
* named `UsageError` instead of letting a partial supply propagate to an
|
|
18
|
+
* inner layer where the failure surfaces as a less helpful error.
|
|
19
|
+
*
|
|
20
|
+
* Only the presence of `obj[key] !== undefined` is consulted — values that
|
|
21
|
+
* are `null`, `0`, `""`, or `false` count as "defined". Keys not present on
|
|
22
|
+
* the object at all are treated the same as `undefined`.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
function validateAllOrNone(obj, keys) {
|
|
27
|
+
let definedCount = 0;
|
|
28
|
+
for (const key of keys) {
|
|
29
|
+
if (obj[key] !== undefined) {
|
|
30
|
+
definedCount++;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (definedCount === 0) {
|
|
34
|
+
return "none";
|
|
35
|
+
}
|
|
36
|
+
if (definedCount === keys.length) {
|
|
37
|
+
return "all";
|
|
38
|
+
}
|
|
39
|
+
return "mixed";
|
|
40
|
+
}
|
|
41
|
+
exports.validateAllOrNone = validateAllOrNone;
|
|
42
|
+
//# sourceMappingURL=allOrNone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOrNone.js","sourceRoot":"","sources":["../src/allOrNone.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkBH;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,iBAAiB,CAChC,GAAe,EACf,IAA0B;IAE1B,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5B,YAAY,EAAE,CAAC;QAChB,CAAC;IACF,CAAC;IACD,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC;IACf,CAAC;IACD,IAAI,YAAY,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAjBD,8CAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Classification returned by {@link validateAllOrNone}.\n *\n * - `\"all\"`: every named key has a defined value.\n *\n * - `\"none\"`: every named key is `undefined`.\n *\n * - `\"mixed\"`: some keys are defined and others are not — the case that\n * `AllOrNone<T>` from `@fluidframework/core-interfaces` forbids at compile\n * time but that can still arise when the input is constructed via cast or\n * crosses an API boundary that erases the discriminated union.\n *\n * @internal\n */\nexport type AllOrNoneResult = \"all\" | \"none\" | \"mixed\";\n\n/**\n * Runtime validator for the `AllOrNone<T>` type modifier from\n * `@fluidframework/core-interfaces`.\n *\n * Given an object and the set of keys to inspect, classifies the object as\n * `\"all\"`, `\"none\"`, or `\"mixed\"` based on which of the named keys carry a\n * defined value. Useful at API entry points that accept a discriminated union\n * of \"supply the whole group, or supply none of it\": a `\"mixed\"` result is\n * the misuse case and is typically translated by the caller into a single\n * named `UsageError` instead of letting a partial supply propagate to an\n * inner layer where the failure surfaces as a less helpful error.\n *\n * Only the presence of `obj[key] !== undefined` is consulted — values that\n * are `null`, `0`, `\"\"`, or `false` count as \"defined\". Keys not present on\n * the object at all are treated the same as `undefined`.\n *\n * @internal\n */\nexport function validateAllOrNone<T extends object>(\n\tobj: Partial<T>,\n\tkeys: readonly (keyof T)[],\n): AllOrNoneResult {\n\tlet definedCount = 0;\n\tfor (const key of keys) {\n\t\tif (obj[key] !== undefined) {\n\t\t\tdefinedCount++;\n\t\t}\n\t}\n\tif (definedCount === 0) {\n\t\treturn \"none\";\n\t}\n\tif (definedCount === keys.length) {\n\t\treturn \"all\";\n\t}\n\treturn \"mixed\";\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export { unreachableCase } from "./unreachable.js";
|
|
|
19
19
|
export { isObject, isPromiseLike } from "./typesGuards.js";
|
|
20
20
|
export { oob } from "./oob.js";
|
|
21
21
|
export { transformMapValues } from "./map.js";
|
|
22
|
+
export { validateAllOrNone, type AllOrNoneResult } from "./allOrNone.js";
|
|
22
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.transformMapValues = exports.oob = exports.isPromiseLike = exports.isObject = exports.unreachableCase = exports.Timer = exports.setLongTimeout = exports.PromiseTimer = exports.shallowCloneObject = exports.Deferred = exports.PromiseCache = exports.walkList = exports.iterateListValuesWhile = exports.DoublyLinkedList = exports.LazyPromise = exports.Lazy = exports.NumberComparer = exports.Heap = exports.delay = exports.compareArrays = exports.onAssertionFailure = exports.emulateProductionBuild = exports.nonProductionConditionalsIncluded = exports.configureDebugAsserts = exports.debugAssert = exports.fail = exports.assert = void 0;
|
|
7
|
+
exports.validateAllOrNone = exports.transformMapValues = exports.oob = exports.isPromiseLike = exports.isObject = exports.unreachableCase = exports.Timer = exports.setLongTimeout = exports.PromiseTimer = exports.shallowCloneObject = exports.Deferred = exports.PromiseCache = exports.walkList = exports.iterateListValuesWhile = exports.DoublyLinkedList = exports.LazyPromise = exports.Lazy = exports.NumberComparer = exports.Heap = exports.delay = exports.compareArrays = exports.onAssertionFailure = exports.emulateProductionBuild = exports.nonProductionConditionalsIncluded = exports.configureDebugAsserts = exports.debugAssert = exports.fail = exports.assert = void 0;
|
|
8
8
|
var assert_js_1 = require("./assert.js");
|
|
9
9
|
Object.defineProperty(exports, "assert", { enumerable: true, get: function () { return assert_js_1.assert; } });
|
|
10
10
|
Object.defineProperty(exports, "fail", { enumerable: true, get: function () { return assert_js_1.fail; } });
|
|
@@ -46,4 +46,6 @@ var oob_js_1 = require("./oob.js");
|
|
|
46
46
|
Object.defineProperty(exports, "oob", { enumerable: true, get: function () { return oob_js_1.oob; } });
|
|
47
47
|
var map_js_1 = require("./map.js");
|
|
48
48
|
Object.defineProperty(exports, "transformMapValues", { enumerable: true, get: function () { return map_js_1.transformMapValues; } });
|
|
49
|
+
var allOrNone_js_1 = require("./allOrNone.js");
|
|
50
|
+
Object.defineProperty(exports, "validateAllOrNone", { enumerable: true, get: function () { return allOrNone_js_1.validateAllOrNone; } });
|
|
49
51
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAQqB;AAPpB,mGAAA,MAAM,OAAA;AACN,iGAAA,IAAI,OAAA;AACJ,wGAAA,WAAW,OAAA;AACX,kHAAA,qBAAqB,OAAA;AACrB,8HAAA,iCAAiC,OAAA;AACjC,mHAAA,sBAAsB,OAAA;AACtB,+GAAA,kBAAkB,OAAA;AAEnB,2CAA6C;AAApC,2GAAA,aAAa,OAAA;AACtB,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AAEd,qCAAiD;AAAxC,+FAAA,IAAI,OAAA;AAAE,yGAAA,cAAc,OAAA;AAC7B,qCAA8C;AAArC,+FAAA,IAAI,OAAA;AAAE,sGAAA,WAAW,OAAA;AAC1B,qCAMmB;AALlB,2GAAA,gBAAgB,OAAA;AAGhB,iHAAA,sBAAsB,OAAA;AACtB,mGAAA,QAAQ,OAAA;AAGT,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AACrB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,qDAAuD;AAA9C,qHAAA,kBAAkB,OAAA;AAE3B,uCAAiE;AAAxD,wGAAA,YAAY,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,iGAAA,KAAK,OAAA;AAC5C,mDAAmD;AAA1C,iHAAA,eAAe,OAAA;AACxB,mDAA2D;AAAlD,0GAAA,QAAQ,OAAA;AAAE,+GAAA,aAAa,OAAA;AAChC,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AACZ,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tconfigureDebugAsserts,\n\tnonProductionConditionalsIncluded,\n\temulateProductionBuild,\n\tonAssertionFailure,\n} from \"./assert.js\";\nexport { compareArrays } from \"./compare.js\";\nexport { delay } from \"./delay.js\";\nexport type { IComparer, IHeapNode } from \"./heap.js\";\nexport { Heap, NumberComparer } from \"./heap.js\";\nexport { Lazy, LazyPromise } from \"./lazy.js\";\nexport {\n\tDoublyLinkedList,\n\ttype ListNode,\n\ttype ListNodeRange,\n\titerateListValuesWhile,\n\twalkList,\n} from \"./list.js\";\nexport type { PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache.js\";\nexport { PromiseCache } from \"./promiseCache.js\";\nexport { Deferred } from \"./promises.js\";\nexport { shallowCloneObject } from \"./shallowClone.js\";\nexport type { IPromiseTimer, IPromiseTimerResult, ITimer } from \"./timer.js\";\nexport { PromiseTimer, setLongTimeout, Timer } from \"./timer.js\";\nexport { unreachableCase } from \"./unreachable.js\";\nexport { isObject, isPromiseLike } from \"./typesGuards.js\";\nexport { oob } from \"./oob.js\";\nexport { transformMapValues } from \"./map.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAQqB;AAPpB,mGAAA,MAAM,OAAA;AACN,iGAAA,IAAI,OAAA;AACJ,wGAAA,WAAW,OAAA;AACX,kHAAA,qBAAqB,OAAA;AACrB,8HAAA,iCAAiC,OAAA;AACjC,mHAAA,sBAAsB,OAAA;AACtB,+GAAA,kBAAkB,OAAA;AAEnB,2CAA6C;AAApC,2GAAA,aAAa,OAAA;AACtB,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AAEd,qCAAiD;AAAxC,+FAAA,IAAI,OAAA;AAAE,yGAAA,cAAc,OAAA;AAC7B,qCAA8C;AAArC,+FAAA,IAAI,OAAA;AAAE,sGAAA,WAAW,OAAA;AAC1B,qCAMmB;AALlB,2GAAA,gBAAgB,OAAA;AAGhB,iHAAA,sBAAsB,OAAA;AACtB,mGAAA,QAAQ,OAAA;AAGT,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AACrB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,qDAAuD;AAA9C,qHAAA,kBAAkB,OAAA;AAE3B,uCAAiE;AAAxD,wGAAA,YAAY,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,iGAAA,KAAK,OAAA;AAC5C,mDAAmD;AAA1C,iHAAA,eAAe,OAAA;AACxB,mDAA2D;AAAlD,0GAAA,QAAQ,OAAA;AAAE,+GAAA,aAAa,OAAA;AAChC,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AACZ,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAC3B,+CAAyE;AAAhE,iHAAA,iBAAiB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tconfigureDebugAsserts,\n\tnonProductionConditionalsIncluded,\n\temulateProductionBuild,\n\tonAssertionFailure,\n} from \"./assert.js\";\nexport { compareArrays } from \"./compare.js\";\nexport { delay } from \"./delay.js\";\nexport type { IComparer, IHeapNode } from \"./heap.js\";\nexport { Heap, NumberComparer } from \"./heap.js\";\nexport { Lazy, LazyPromise } from \"./lazy.js\";\nexport {\n\tDoublyLinkedList,\n\ttype ListNode,\n\ttype ListNodeRange,\n\titerateListValuesWhile,\n\twalkList,\n} from \"./list.js\";\nexport type { PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache.js\";\nexport { PromiseCache } from \"./promiseCache.js\";\nexport { Deferred } from \"./promises.js\";\nexport { shallowCloneObject } from \"./shallowClone.js\";\nexport type { IPromiseTimer, IPromiseTimerResult, ITimer } from \"./timer.js\";\nexport { PromiseTimer, setLongTimeout, Timer } from \"./timer.js\";\nexport { unreachableCase } from \"./unreachable.js\";\nexport { isObject, isPromiseLike } from \"./typesGuards.js\";\nexport { oob } from \"./oob.js\";\nexport { transformMapValues } from \"./map.js\";\nexport { validateAllOrNone, type AllOrNoneResult } from \"./allOrNone.js\";\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Classification returned by {@link validateAllOrNone}.
|
|
7
|
+
*
|
|
8
|
+
* - `"all"`: every named key has a defined value.
|
|
9
|
+
*
|
|
10
|
+
* - `"none"`: every named key is `undefined`.
|
|
11
|
+
*
|
|
12
|
+
* - `"mixed"`: some keys are defined and others are not — the case that
|
|
13
|
+
* `AllOrNone<T>` from `@fluidframework/core-interfaces` forbids at compile
|
|
14
|
+
* time but that can still arise when the input is constructed via cast or
|
|
15
|
+
* crosses an API boundary that erases the discriminated union.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export type AllOrNoneResult = "all" | "none" | "mixed";
|
|
20
|
+
/**
|
|
21
|
+
* Runtime validator for the `AllOrNone<T>` type modifier from
|
|
22
|
+
* `@fluidframework/core-interfaces`.
|
|
23
|
+
*
|
|
24
|
+
* Given an object and the set of keys to inspect, classifies the object as
|
|
25
|
+
* `"all"`, `"none"`, or `"mixed"` based on which of the named keys carry a
|
|
26
|
+
* defined value. Useful at API entry points that accept a discriminated union
|
|
27
|
+
* of "supply the whole group, or supply none of it": a `"mixed"` result is
|
|
28
|
+
* the misuse case and is typically translated by the caller into a single
|
|
29
|
+
* named `UsageError` instead of letting a partial supply propagate to an
|
|
30
|
+
* inner layer where the failure surfaces as a less helpful error.
|
|
31
|
+
*
|
|
32
|
+
* Only the presence of `obj[key] !== undefined` is consulted — values that
|
|
33
|
+
* are `null`, `0`, `""`, or `false` count as "defined". Keys not present on
|
|
34
|
+
* the object at all are treated the same as `undefined`.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateAllOrNone<T extends object>(obj: Partial<T>, keys: readonly (keyof T)[]): AllOrNoneResult;
|
|
39
|
+
//# sourceMappingURL=allOrNone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOrNone.d.ts","sourceRoot":"","sources":["../src/allOrNone.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjD,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACxB,eAAe,CAcjB"}
|
package/lib/allOrNone.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Runtime validator for the `AllOrNone<T>` type modifier from
|
|
7
|
+
* `@fluidframework/core-interfaces`.
|
|
8
|
+
*
|
|
9
|
+
* Given an object and the set of keys to inspect, classifies the object as
|
|
10
|
+
* `"all"`, `"none"`, or `"mixed"` based on which of the named keys carry a
|
|
11
|
+
* defined value. Useful at API entry points that accept a discriminated union
|
|
12
|
+
* of "supply the whole group, or supply none of it": a `"mixed"` result is
|
|
13
|
+
* the misuse case and is typically translated by the caller into a single
|
|
14
|
+
* named `UsageError` instead of letting a partial supply propagate to an
|
|
15
|
+
* inner layer where the failure surfaces as a less helpful error.
|
|
16
|
+
*
|
|
17
|
+
* Only the presence of `obj[key] !== undefined` is consulted — values that
|
|
18
|
+
* are `null`, `0`, `""`, or `false` count as "defined". Keys not present on
|
|
19
|
+
* the object at all are treated the same as `undefined`.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export function validateAllOrNone(obj, keys) {
|
|
24
|
+
let definedCount = 0;
|
|
25
|
+
for (const key of keys) {
|
|
26
|
+
if (obj[key] !== undefined) {
|
|
27
|
+
definedCount++;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (definedCount === 0) {
|
|
31
|
+
return "none";
|
|
32
|
+
}
|
|
33
|
+
if (definedCount === keys.length) {
|
|
34
|
+
return "all";
|
|
35
|
+
}
|
|
36
|
+
return "mixed";
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=allOrNone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOrNone.js","sourceRoot":"","sources":["../src/allOrNone.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB,CAChC,GAAe,EACf,IAA0B;IAE1B,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5B,YAAY,EAAE,CAAC;QAChB,CAAC;IACF,CAAC;IACD,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC;IACf,CAAC;IACD,IAAI,YAAY,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Classification returned by {@link validateAllOrNone}.\n *\n * - `\"all\"`: every named key has a defined value.\n *\n * - `\"none\"`: every named key is `undefined`.\n *\n * - `\"mixed\"`: some keys are defined and others are not — the case that\n * `AllOrNone<T>` from `@fluidframework/core-interfaces` forbids at compile\n * time but that can still arise when the input is constructed via cast or\n * crosses an API boundary that erases the discriminated union.\n *\n * @internal\n */\nexport type AllOrNoneResult = \"all\" | \"none\" | \"mixed\";\n\n/**\n * Runtime validator for the `AllOrNone<T>` type modifier from\n * `@fluidframework/core-interfaces`.\n *\n * Given an object and the set of keys to inspect, classifies the object as\n * `\"all\"`, `\"none\"`, or `\"mixed\"` based on which of the named keys carry a\n * defined value. Useful at API entry points that accept a discriminated union\n * of \"supply the whole group, or supply none of it\": a `\"mixed\"` result is\n * the misuse case and is typically translated by the caller into a single\n * named `UsageError` instead of letting a partial supply propagate to an\n * inner layer where the failure surfaces as a less helpful error.\n *\n * Only the presence of `obj[key] !== undefined` is consulted — values that\n * are `null`, `0`, `\"\"`, or `false` count as \"defined\". Keys not present on\n * the object at all are treated the same as `undefined`.\n *\n * @internal\n */\nexport function validateAllOrNone<T extends object>(\n\tobj: Partial<T>,\n\tkeys: readonly (keyof T)[],\n): AllOrNoneResult {\n\tlet definedCount = 0;\n\tfor (const key of keys) {\n\t\tif (obj[key] !== undefined) {\n\t\t\tdefinedCount++;\n\t\t}\n\t}\n\tif (definedCount === 0) {\n\t\treturn \"none\";\n\t}\n\tif (definedCount === keys.length) {\n\t\treturn \"all\";\n\t}\n\treturn \"mixed\";\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export { unreachableCase } from "./unreachable.js";
|
|
|
19
19
|
export { isObject, isPromiseLike } from "./typesGuards.js";
|
|
20
20
|
export { oob } from "./oob.js";
|
|
21
21
|
export { transformMapValues } from "./map.js";
|
|
22
|
+
export { validateAllOrNone, type AllOrNoneResult } from "./allOrNone.js";
|
|
22
23
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -16,4 +16,5 @@ export { unreachableCase } from "./unreachable.js";
|
|
|
16
16
|
export { isObject, isPromiseLike } from "./typesGuards.js";
|
|
17
17
|
export { oob } from "./oob.js";
|
|
18
18
|
export { transformMapValues } from "./map.js";
|
|
19
|
+
export { validateAllOrNone } from "./allOrNone.js";
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAGhB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tconfigureDebugAsserts,\n\tnonProductionConditionalsIncluded,\n\temulateProductionBuild,\n\tonAssertionFailure,\n} from \"./assert.js\";\nexport { compareArrays } from \"./compare.js\";\nexport { delay } from \"./delay.js\";\nexport type { IComparer, IHeapNode } from \"./heap.js\";\nexport { Heap, NumberComparer } from \"./heap.js\";\nexport { Lazy, LazyPromise } from \"./lazy.js\";\nexport {\n\tDoublyLinkedList,\n\ttype ListNode,\n\ttype ListNodeRange,\n\titerateListValuesWhile,\n\twalkList,\n} from \"./list.js\";\nexport type { PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache.js\";\nexport { PromiseCache } from \"./promiseCache.js\";\nexport { Deferred } from \"./promises.js\";\nexport { shallowCloneObject } from \"./shallowClone.js\";\nexport type { IPromiseTimer, IPromiseTimerResult, ITimer } from \"./timer.js\";\nexport { PromiseTimer, setLongTimeout, Timer } from \"./timer.js\";\nexport { unreachableCase } from \"./unreachable.js\";\nexport { isObject, isPromiseLike } from \"./typesGuards.js\";\nexport { oob } from \"./oob.js\";\nexport { transformMapValues } from \"./map.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,gBAAgB,EAGhB,sBAAsB,EACtB,QAAQ,GACR,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAwB,MAAM,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tconfigureDebugAsserts,\n\tnonProductionConditionalsIncluded,\n\temulateProductionBuild,\n\tonAssertionFailure,\n} from \"./assert.js\";\nexport { compareArrays } from \"./compare.js\";\nexport { delay } from \"./delay.js\";\nexport type { IComparer, IHeapNode } from \"./heap.js\";\nexport { Heap, NumberComparer } from \"./heap.js\";\nexport { Lazy, LazyPromise } from \"./lazy.js\";\nexport {\n\tDoublyLinkedList,\n\ttype ListNode,\n\ttype ListNodeRange,\n\titerateListValuesWhile,\n\twalkList,\n} from \"./list.js\";\nexport type { PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache.js\";\nexport { PromiseCache } from \"./promiseCache.js\";\nexport { Deferred } from \"./promises.js\";\nexport { shallowCloneObject } from \"./shallowClone.js\";\nexport type { IPromiseTimer, IPromiseTimerResult, ITimer } from \"./timer.js\";\nexport { PromiseTimer, setLongTimeout, Timer } from \"./timer.js\";\nexport { unreachableCase } from \"./unreachable.js\";\nexport { isObject, isPromiseLike } from \"./typesGuards.js\";\nexport { oob } from \"./oob.js\";\nexport { transformMapValues } from \"./map.js\";\nexport { validateAllOrNone, type AllOrNoneResult } from \"./allOrNone.js\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/core-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.103.0",
|
|
4
4
|
"description": "Not intended for use outside the Fluid client repo.",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
91
91
|
"@biomejs/biome": "~2.4.5",
|
|
92
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
92
|
+
"@fluid-internal/mocha-test-setup": "~2.103.0",
|
|
93
93
|
"@fluid-tools/benchmark": "^0.59.0",
|
|
94
94
|
"@fluid-tools/build-cli": "^0.65.0",
|
|
95
95
|
"@fluidframework/build-common": "^2.0.3",
|
package/src/allOrNone.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Classification returned by {@link validateAllOrNone}.
|
|
8
|
+
*
|
|
9
|
+
* - `"all"`: every named key has a defined value.
|
|
10
|
+
*
|
|
11
|
+
* - `"none"`: every named key is `undefined`.
|
|
12
|
+
*
|
|
13
|
+
* - `"mixed"`: some keys are defined and others are not — the case that
|
|
14
|
+
* `AllOrNone<T>` from `@fluidframework/core-interfaces` forbids at compile
|
|
15
|
+
* time but that can still arise when the input is constructed via cast or
|
|
16
|
+
* crosses an API boundary that erases the discriminated union.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export type AllOrNoneResult = "all" | "none" | "mixed";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Runtime validator for the `AllOrNone<T>` type modifier from
|
|
24
|
+
* `@fluidframework/core-interfaces`.
|
|
25
|
+
*
|
|
26
|
+
* Given an object and the set of keys to inspect, classifies the object as
|
|
27
|
+
* `"all"`, `"none"`, or `"mixed"` based on which of the named keys carry a
|
|
28
|
+
* defined value. Useful at API entry points that accept a discriminated union
|
|
29
|
+
* of "supply the whole group, or supply none of it": a `"mixed"` result is
|
|
30
|
+
* the misuse case and is typically translated by the caller into a single
|
|
31
|
+
* named `UsageError` instead of letting a partial supply propagate to an
|
|
32
|
+
* inner layer where the failure surfaces as a less helpful error.
|
|
33
|
+
*
|
|
34
|
+
* Only the presence of `obj[key] !== undefined` is consulted — values that
|
|
35
|
+
* are `null`, `0`, `""`, or `false` count as "defined". Keys not present on
|
|
36
|
+
* the object at all are treated the same as `undefined`.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export function validateAllOrNone<T extends object>(
|
|
41
|
+
obj: Partial<T>,
|
|
42
|
+
keys: readonly (keyof T)[],
|
|
43
|
+
): AllOrNoneResult {
|
|
44
|
+
let definedCount = 0;
|
|
45
|
+
for (const key of keys) {
|
|
46
|
+
if (obj[key] !== undefined) {
|
|
47
|
+
definedCount++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (definedCount === 0) {
|
|
51
|
+
return "none";
|
|
52
|
+
}
|
|
53
|
+
if (definedCount === keys.length) {
|
|
54
|
+
return "all";
|
|
55
|
+
}
|
|
56
|
+
return "mixed";
|
|
57
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -34,3 +34,4 @@ export { unreachableCase } from "./unreachable.js";
|
|
|
34
34
|
export { isObject, isPromiseLike } from "./typesGuards.js";
|
|
35
35
|
export { oob } from "./oob.js";
|
|
36
36
|
export { transformMapValues } from "./map.js";
|
|
37
|
+
export { validateAllOrNone, type AllOrNoneResult } from "./allOrNone.js";
|