honkit 6.1.6 → 6.1.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/lib/api/deprecate.js +2 -2
- package/lib/api/encodeConfig.d.ts +2 -2
- package/lib/api/encodeConfig.js +3 -3
- package/lib/api/encodeGlobal.d.ts +2 -2
- package/lib/constants/defaultFilters.d.ts.map +1 -1
- package/lib/constants/defaultFilters.js +7 -3
- package/lib/models/fs.d.ts +2 -3
- package/lib/models/fs.d.ts.map +1 -1
- package/lib/models/page.js +1 -1
- package/lib/utils/__tests__/objectPath.contract.test.d.ts +2 -0
- package/lib/utils/__tests__/objectPath.contract.test.d.ts.map +1 -0
- package/lib/utils/__tests__/objectPath.contract.test.js +97 -0
- package/lib/utils/__tests__/promise.contract.test.d.ts +2 -0
- package/lib/utils/__tests__/promise.contract.test.d.ts.map +1 -0
- package/lib/utils/__tests__/promise.contract.test.js +195 -0
- package/lib/utils/__tests__/safeObjectPath.d.ts +2 -0
- package/lib/utils/__tests__/safeObjectPath.d.ts.map +1 -0
- package/lib/utils/__tests__/safeObjectPath.js +129 -0
- package/lib/utils/git.d.ts +1 -1
- package/lib/utils/git.d.ts.map +1 -1
- package/lib/utils/git.js +19 -14
- package/lib/utils/promise.d.ts +21 -50
- package/lib/utils/promise.d.ts.map +1 -1
- package/lib/utils/promise.js +152 -83
- package/lib/utils/safeObjectPath.d.ts +17 -0
- package/lib/utils/safeObjectPath.d.ts.map +1 -0
- package/lib/utils/safeObjectPath.js +93 -0
- package/package.json +15 -16
package/lib/api/deprecate.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const is_1 = __importDefault(require("is"));
|
|
7
|
-
const
|
|
7
|
+
const safeObjectPath_1 = require("../utils/safeObjectPath");
|
|
8
8
|
const logged = {};
|
|
9
9
|
const disabled = {};
|
|
10
10
|
/**
|
|
@@ -101,7 +101,7 @@ function disableDeprecation(key) {
|
|
|
101
101
|
*/
|
|
102
102
|
function deprecateRenamedMethod(book, key, instance, oldName, newName, msg) {
|
|
103
103
|
msg = msg || `"${oldName}" is deprecated, use "${newName}()" instead`;
|
|
104
|
-
const fn =
|
|
104
|
+
const fn = (0, safeObjectPath_1.getAtPath)(instance, newName);
|
|
105
105
|
instance[oldName] = deprecateMethod(book, key, fn, msg);
|
|
106
106
|
}
|
|
107
107
|
exports.default = {
|
|
@@ -5,8 +5,8 @@ import Config from "../models/config";
|
|
|
5
5
|
*/
|
|
6
6
|
declare function encodeConfig(output: Output, config: Config): {
|
|
7
7
|
values: any;
|
|
8
|
-
get: (key: any, defaultValue: any) =>
|
|
9
|
-
set: (key: any, value: any) =>
|
|
8
|
+
get: (key: any, defaultValue: any) => unknown;
|
|
9
|
+
set: (key: any, value: any) => void;
|
|
10
10
|
};
|
|
11
11
|
export default encodeConfig;
|
|
12
12
|
//# sourceMappingURL=encodeConfig.d.ts.map
|
package/lib/api/encodeConfig.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
6
|
+
const safeObjectPath_1 = require("../utils/safeObjectPath");
|
|
7
7
|
const deprecate_1 = __importDefault(require("./deprecate"));
|
|
8
8
|
/**
|
|
9
9
|
Encode a config object into a JS config api
|
|
@@ -12,10 +12,10 @@ function encodeConfig(output, config) {
|
|
|
12
12
|
const result = {
|
|
13
13
|
values: config.getValues().toJS(),
|
|
14
14
|
get: function (key, defaultValue) {
|
|
15
|
-
return
|
|
15
|
+
return (0, safeObjectPath_1.getAtPath)(result.values, key, defaultValue);
|
|
16
16
|
},
|
|
17
17
|
set: function (key, value) {
|
|
18
|
-
|
|
18
|
+
(0, safeObjectPath_1.setAtPath)(result.values, key, value);
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
deprecate_1.default.field(output, "config.options", result, "options", result.values, '"config.options" property is deprecated, use "config.get(key)" instead');
|
|
@@ -10,8 +10,8 @@ declare function encodeGlobal(output: any): {
|
|
|
10
10
|
log: any;
|
|
11
11
|
config: {
|
|
12
12
|
values: any;
|
|
13
|
-
get: (key: any, defaultValue: any) =>
|
|
14
|
-
set: (key: any, value: any) =>
|
|
13
|
+
get: (key: any, defaultValue: any) => unknown;
|
|
14
|
+
set: (key: any, value: any) => void;
|
|
15
15
|
};
|
|
16
16
|
summary: {
|
|
17
17
|
walk: (iter: any) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultFilters.d.ts","sourceRoot":"","sources":["../../src/constants/defaultFilters.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;;
|
|
1
|
+
{"version":3,"file":"defaultFilters.d.ts","sourceRoot":"","sources":["../../src/constants/defaultFilters.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;;AAQlC,wBAWG"}
|
|
@@ -4,15 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const immutable_1 = __importDefault(require("immutable"));
|
|
7
|
-
const
|
|
7
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
|
+
const relativeTime_1 = __importDefault(require("dayjs/plugin/relativeTime"));
|
|
9
|
+
const advancedFormat_1 = __importDefault(require("dayjs/plugin/advancedFormat"));
|
|
10
|
+
dayjs_1.default.extend(relativeTime_1.default);
|
|
11
|
+
dayjs_1.default.extend(advancedFormat_1.default);
|
|
8
12
|
exports.default = immutable_1.default.Map({
|
|
9
13
|
// Format a date
|
|
10
14
|
// ex: 'MMMM Do YYYY, h:mm:ss a
|
|
11
15
|
date: function (time, format) {
|
|
12
|
-
return (0,
|
|
16
|
+
return (0, dayjs_1.default)(time).format(format);
|
|
13
17
|
},
|
|
14
18
|
// Relative Time
|
|
15
19
|
dateFromNow: function (time) {
|
|
16
|
-
return (0,
|
|
20
|
+
return (0, dayjs_1.default)(time).fromNow();
|
|
17
21
|
}
|
|
18
22
|
});
|
package/lib/models/fs.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Immutable from "immutable";
|
|
2
2
|
import File from "./file";
|
|
3
|
-
import Promise from "../utils/promise";
|
|
4
3
|
declare const FS_base: Immutable.Record.Class;
|
|
5
4
|
declare class FS extends FS_base {
|
|
6
5
|
/**
|
|
@@ -39,7 +38,7 @@ declare class FS extends FS_base {
|
|
|
39
38
|
Read a file as a string (utf-8)
|
|
40
39
|
@return {Promise<String>}
|
|
41
40
|
*/
|
|
42
|
-
readAsString(filename: string, encoding?:
|
|
41
|
+
readAsString(filename: string, encoding?: BufferEncoding): Promise<string>;
|
|
43
42
|
/**
|
|
44
43
|
Read file as a stream
|
|
45
44
|
|
|
@@ -94,7 +93,7 @@ declare class FS extends FS_base {
|
|
|
94
93
|
@param {string} filename
|
|
95
94
|
@return {Promise<Object>}
|
|
96
95
|
*/
|
|
97
|
-
loadAsObject(filename: string): any
|
|
96
|
+
loadAsObject(filename: string): Promise<any>;
|
|
98
97
|
/**
|
|
99
98
|
Create a FS instance
|
|
100
99
|
|
package/lib/models/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/models/fs.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,IAAI,MAAM,QAAQ,CAAC
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/models/fs.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,IAAI,MAAM,QAAQ,CAAC;;AAK1B,cAAM,EAAG,SAAQ,OAUf;IACE;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOpC;;;OAGG;IACH,OAAO,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM;IAelC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW1C;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvC;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAMlF;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM;IAiB7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAezC;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM;IAevB;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM;IAMzB;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO;IA4BjE;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAQ1C;;;;;;OAMG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM;IAwB7B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,GAAG,KAAA;IAIjB;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE;CAGhD;AAQD,eAAe,EAAE,CAAC"}
|
package/lib/models/page.js
CHANGED
|
@@ -38,7 +38,7 @@ class Page extends immutable_1.default.Record({
|
|
|
38
38
|
if (attrs.size === 0) {
|
|
39
39
|
return content;
|
|
40
40
|
}
|
|
41
|
-
const frontMatter = `---\n${js_yaml_1.default.
|
|
41
|
+
const frontMatter = `---\n${js_yaml_1.default.dump(attrs.toJS(), { skipInvalid: true })}---\n\n`;
|
|
42
42
|
return frontMatter + (content || "");
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objectPath.contract.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/objectPath.contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/**
|
|
7
|
+
* Same scenarios as `safeObjectPath` contract tests on the refactored branch, run here against
|
|
8
|
+
* the real `object-path` dependency (pre-#508). Expectations match object-path@0.11.8, not
|
|
9
|
+
* `safeObjectPath` (see PR review discussion).
|
|
10
|
+
*/
|
|
11
|
+
const object_path_1 = __importDefault(require("object-path"));
|
|
12
|
+
describe("object-path baseline (pre safeObjectPath)", () => {
|
|
13
|
+
describe("get", () => {
|
|
14
|
+
test("returns nested value by dot path", () => {
|
|
15
|
+
const obj = { structure: { readme: "README.md" } };
|
|
16
|
+
expect(object_path_1.default.get(obj, "structure.readme")).toBe("README.md");
|
|
17
|
+
});
|
|
18
|
+
test("accepts array path", () => {
|
|
19
|
+
const obj = { structure: { readme: "README.md" } };
|
|
20
|
+
expect(object_path_1.default.get(obj, ["structure", "readme"])).toBe("README.md");
|
|
21
|
+
});
|
|
22
|
+
test("returns default when path missing", () => {
|
|
23
|
+
const obj = { a: 1 };
|
|
24
|
+
expect(object_path_1.default.get(obj, "b", "fallback")).toBe("fallback");
|
|
25
|
+
expect(object_path_1.default.get(obj, "a.c", "fallback")).toBe("fallback");
|
|
26
|
+
});
|
|
27
|
+
test("returns default for null / undefined root", () => {
|
|
28
|
+
expect(object_path_1.default.get(null, "a", "d")).toBe("d");
|
|
29
|
+
expect(object_path_1.default.get(undefined, "a", "d")).toBe("d");
|
|
30
|
+
});
|
|
31
|
+
test("empty path returns the object (object-path semantics)", () => {
|
|
32
|
+
expect(object_path_1.default.get({ a: 1 }, "", "d")).toEqual({ a: 1 });
|
|
33
|
+
});
|
|
34
|
+
test("returns null when key exists with null value", () => {
|
|
35
|
+
expect(object_path_1.default.get({ x: null }, "x", "d")).toBeNull();
|
|
36
|
+
});
|
|
37
|
+
test("returns default when traversing into null intermediate", () => {
|
|
38
|
+
expect(object_path_1.default.get({ x: null }, "x.y", "d")).toBe("d");
|
|
39
|
+
});
|
|
40
|
+
test("returns default when traversing into non-object", () => {
|
|
41
|
+
expect(object_path_1.default.get({ x: "str" }, "x.y", "d")).toBe("d");
|
|
42
|
+
});
|
|
43
|
+
test("undefined leaf with default returns default", () => {
|
|
44
|
+
expect(object_path_1.default.get({ a: {} }, "a.missing", "d")).toBe("d");
|
|
45
|
+
});
|
|
46
|
+
test("prototype-ish keys with default", () => {
|
|
47
|
+
const obj = { safe: 1 };
|
|
48
|
+
expect(object_path_1.default.get(obj, "__proto__.polluted", "d")).toBe("d");
|
|
49
|
+
expect(object_path_1.default.get(obj, "constructor.prototype.polluted", "d")).toBe("d");
|
|
50
|
+
expect(obj.polluted).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
test("does not trim segment whitespace (object-path)", () => {
|
|
53
|
+
expect(object_path_1.default.get({ a: { b: 2 } }, " a . b ", "d")).toBe("d");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe("set", () => {
|
|
57
|
+
test("sets nested value by dot path", () => {
|
|
58
|
+
const obj = {};
|
|
59
|
+
object_path_1.default.set(obj, "structure.readme", "INTRO.md");
|
|
60
|
+
expect(obj).toEqual({ structure: { readme: "INTRO.md" } });
|
|
61
|
+
});
|
|
62
|
+
test("accepts array path", () => {
|
|
63
|
+
const obj = {};
|
|
64
|
+
object_path_1.default.set(obj, ["structure", "readme"], "INTRO.md");
|
|
65
|
+
expect(obj).toEqual({ structure: { readme: "INTRO.md" } });
|
|
66
|
+
});
|
|
67
|
+
test("overwrites existing nested value", () => {
|
|
68
|
+
const obj = { structure: { readme: "A.md" } };
|
|
69
|
+
object_path_1.default.set(obj, "structure.readme", "B.md");
|
|
70
|
+
expect(obj.structure.readme).toBe("B.md");
|
|
71
|
+
});
|
|
72
|
+
test("throws when intermediate is a non-object (object-path)", () => {
|
|
73
|
+
const obj = { a: "was-string" };
|
|
74
|
+
expect(() => object_path_1.default.set(obj, "a.b", 1)).toThrow();
|
|
75
|
+
});
|
|
76
|
+
test("throws when intermediate is null (object-path / native JS)", () => {
|
|
77
|
+
const obj = { a: null };
|
|
78
|
+
expect(() => object_path_1.default.set(obj, "a.b", 1)).toThrow();
|
|
79
|
+
expect(obj.a).toBeNull();
|
|
80
|
+
});
|
|
81
|
+
test("uses array index segments like object-path", () => {
|
|
82
|
+
const obj = {};
|
|
83
|
+
object_path_1.default.set(obj, "items.0.name", "first");
|
|
84
|
+
expect(obj.items).toEqual([{ name: "first" }]);
|
|
85
|
+
});
|
|
86
|
+
test("set on __proto__ path is a no-op for own keys (object-path)", () => {
|
|
87
|
+
const obj = { ok: true };
|
|
88
|
+
expect(object_path_1.default.set(obj, "__proto__", "ignored")).toBeUndefined();
|
|
89
|
+
expect(obj).toEqual({ ok: true });
|
|
90
|
+
});
|
|
91
|
+
test("set returns undefined (object-path)", () => {
|
|
92
|
+
const obj = {};
|
|
93
|
+
expect(object_path_1.default.set(obj, "x", 42)).toBeUndefined();
|
|
94
|
+
expect(obj.x).toBe(42);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promise.contract.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/promise.contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/**
|
|
7
|
+
* Contract tests for {@link ../promise} — encodes the Q-style API from `q` before the native
|
|
8
|
+
* shim (see PR review: https://github.com/honkit/honkit/pull/508#pullrequestreview-4268311613).
|
|
9
|
+
*/
|
|
10
|
+
const immutable_1 = __importDefault(require("immutable"));
|
|
11
|
+
const promise_1 = __importDefault(require("../promise"));
|
|
12
|
+
describe("promise contract (Q implementation)", () => {
|
|
13
|
+
test("factory resolves value", async () => {
|
|
14
|
+
await expect((0, promise_1.default)(7)).resolves.toBe(7);
|
|
15
|
+
});
|
|
16
|
+
test("thenResolve replaces result", async () => {
|
|
17
|
+
const p = (0, promise_1.default)("a").thenResolve("b");
|
|
18
|
+
await expect(p).resolves.toBe("b");
|
|
19
|
+
});
|
|
20
|
+
test("spread unpacks array fulfillment", async () => {
|
|
21
|
+
const p = (0, promise_1.default)([1, 2, 3]).spread((a, b, c) => a + b + c);
|
|
22
|
+
await expect(p).resolves.toBe(6);
|
|
23
|
+
});
|
|
24
|
+
test.skip("spread with non-array fulfillment (Q never settles)", async () => {
|
|
25
|
+
const p = (0, promise_1.default)("solo").spread((x) => x + "!");
|
|
26
|
+
await expect(p).resolves.toBe("solo!");
|
|
27
|
+
});
|
|
28
|
+
test("fail is catch alias", async () => {
|
|
29
|
+
const p = promise_1.default.reject(new Error("x")).fail(() => "recovered");
|
|
30
|
+
await expect(p).resolves.toBe("recovered");
|
|
31
|
+
});
|
|
32
|
+
test("tap runs side effect and preserves value", async () => {
|
|
33
|
+
let tapped;
|
|
34
|
+
const p = (0, promise_1.default)(5).tap((v) => {
|
|
35
|
+
tapped = v;
|
|
36
|
+
});
|
|
37
|
+
await expect(p).resolves.toBe(5);
|
|
38
|
+
expect(tapped).toBe(5);
|
|
39
|
+
});
|
|
40
|
+
test("tap awaits async side effect", async () => {
|
|
41
|
+
const order = [];
|
|
42
|
+
const p = (0, promise_1.default)("x").tap(async () => {
|
|
43
|
+
order.push("tap");
|
|
44
|
+
});
|
|
45
|
+
await p;
|
|
46
|
+
order.push("after");
|
|
47
|
+
expect(order).toEqual(["tap", "after"]);
|
|
48
|
+
});
|
|
49
|
+
test("fin runs on success and preserves value", async () => {
|
|
50
|
+
let ran = false;
|
|
51
|
+
const p = (0, promise_1.default)(9).fin(() => {
|
|
52
|
+
ran = true;
|
|
53
|
+
});
|
|
54
|
+
await expect(p).resolves.toBe(9);
|
|
55
|
+
expect(ran).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
test("fin runs on failure and preserves rejection", async () => {
|
|
58
|
+
let ran = false;
|
|
59
|
+
const err = new Error("boom");
|
|
60
|
+
const p = promise_1.default.reject(err).fin(() => {
|
|
61
|
+
ran = true;
|
|
62
|
+
});
|
|
63
|
+
await expect(p).rejects.toThrow("boom");
|
|
64
|
+
expect(ran).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
test("defer resolve / reject", async () => {
|
|
67
|
+
const d = promise_1.default.defer();
|
|
68
|
+
d.resolve(123);
|
|
69
|
+
await expect(d.promise).resolves.toBe(123);
|
|
70
|
+
const d2 = promise_1.default.defer();
|
|
71
|
+
d2.reject(new Error("no"));
|
|
72
|
+
await expect(d2.promise).rejects.toThrow("no");
|
|
73
|
+
});
|
|
74
|
+
test("defer makeNodeResolver (single result)", async () => {
|
|
75
|
+
const d = promise_1.default.defer();
|
|
76
|
+
d.makeNodeResolver()(null, "ok");
|
|
77
|
+
await expect(d.promise).resolves.toBe("ok");
|
|
78
|
+
});
|
|
79
|
+
test("defer makeNodeResolver (multiple results become array)", async () => {
|
|
80
|
+
const d = promise_1.default.defer();
|
|
81
|
+
d.makeNodeResolver()(null, "a", "b");
|
|
82
|
+
await expect(d.promise).resolves.toEqual(["a", "b"]);
|
|
83
|
+
});
|
|
84
|
+
test("defer notify invokes progress handlers", async () => {
|
|
85
|
+
const d = promise_1.default.defer();
|
|
86
|
+
const seen = [];
|
|
87
|
+
d.promise.progress((x) => seen.push(x));
|
|
88
|
+
d.notify("chunk");
|
|
89
|
+
d.resolve("done");
|
|
90
|
+
await d.promise;
|
|
91
|
+
expect(seen).toEqual(["chunk"]);
|
|
92
|
+
});
|
|
93
|
+
test("nfcall and get(index)", async () => {
|
|
94
|
+
function read(cb) {
|
|
95
|
+
cb(null, "x", "y");
|
|
96
|
+
}
|
|
97
|
+
const p = promise_1.default.nfcall(read).get(1);
|
|
98
|
+
await expect(p).resolves.toBe("y");
|
|
99
|
+
});
|
|
100
|
+
test("nfbind binds this", async () => {
|
|
101
|
+
const ctx = {
|
|
102
|
+
val: 3,
|
|
103
|
+
run(cb) {
|
|
104
|
+
cb(null, this.val);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const bound = promise_1.default.nfbind(ctx.run.bind(ctx));
|
|
108
|
+
await expect(bound()).resolves.toBe(3);
|
|
109
|
+
});
|
|
110
|
+
test("reduce over array", async () => {
|
|
111
|
+
const p = promise_1.default.reduce([1, 2, 3], (acc, n) => acc + n, 0);
|
|
112
|
+
await expect(p).resolves.toBe(6);
|
|
113
|
+
});
|
|
114
|
+
test("reduce over Immutable.List", async () => {
|
|
115
|
+
const p = promise_1.default.reduce(immutable_1.default.List([2, 3]), (acc, n) => acc * n, 2);
|
|
116
|
+
await expect(p).resolves.toBe(12);
|
|
117
|
+
});
|
|
118
|
+
test("forEach", async () => {
|
|
119
|
+
const acc = [];
|
|
120
|
+
await promise_1.default.forEach([10, 20], (n) => {
|
|
121
|
+
acc.push(n);
|
|
122
|
+
});
|
|
123
|
+
expect(acc).toEqual([10, 20]);
|
|
124
|
+
});
|
|
125
|
+
test("serie collects mapped results in order", async () => {
|
|
126
|
+
const p = promise_1.default.serie(["a", "b"], (s) => s.toUpperCase());
|
|
127
|
+
await expect(p).resolves.toEqual(["A", "B"]);
|
|
128
|
+
});
|
|
129
|
+
test("some returns first truthy iter result", async () => {
|
|
130
|
+
const p = promise_1.default.some([0, "", 42, 99], (x) => x);
|
|
131
|
+
await expect(p).resolves.toBe(42);
|
|
132
|
+
});
|
|
133
|
+
test("some yields last iter result when no value is truthy", async () => {
|
|
134
|
+
const p = promise_1.default.some([0, "", null], (x) => x);
|
|
135
|
+
await expect(p).resolves.toBeNull();
|
|
136
|
+
});
|
|
137
|
+
test("map over array returns Immutable.List", async () => {
|
|
138
|
+
const p = promise_1.default.map([1, 2], (n) => n * 2);
|
|
139
|
+
const list = await p;
|
|
140
|
+
expect(immutable_1.default.List.isList(list)).toBe(true);
|
|
141
|
+
expect(list.toJS()).toEqual([2, 4]);
|
|
142
|
+
});
|
|
143
|
+
test("map over Immutable.Map preserves Map", async () => {
|
|
144
|
+
const m = immutable_1.default.Map({ a: 1, b: 2 });
|
|
145
|
+
const p = promise_1.default.map(m, (v) => v + 10);
|
|
146
|
+
const out = await p;
|
|
147
|
+
expect(immutable_1.default.Map.isMap(out)).toBe(true);
|
|
148
|
+
expect(out.toJS()).toEqual({ a: 11, b: 12 });
|
|
149
|
+
});
|
|
150
|
+
test("map over Immutable.OrderedMap preserves OrderedMap", async () => {
|
|
151
|
+
const m = immutable_1.default.OrderedMap({ z: 1, a: 2 });
|
|
152
|
+
const p = promise_1.default.map(m, (v) => v + 10);
|
|
153
|
+
const out = await p;
|
|
154
|
+
expect(immutable_1.default.OrderedMap.isOrderedMap(out)).toBe(true);
|
|
155
|
+
expect(out.toJS()).toEqual({ z: 11, a: 12 });
|
|
156
|
+
});
|
|
157
|
+
test("wrap defers sync function", async () => {
|
|
158
|
+
const fn = promise_1.default.wrap((a, b) => a + b);
|
|
159
|
+
await expect(fn(2, 3)).resolves.toBe(5);
|
|
160
|
+
});
|
|
161
|
+
test("reject", async () => {
|
|
162
|
+
await expect(promise_1.default.reject(new Error("r"))).rejects.toThrow("r");
|
|
163
|
+
});
|
|
164
|
+
test("all", async () => {
|
|
165
|
+
await expect(promise_1.default.all([1, Promise.resolve(2)])).resolves.toEqual([1, 2]);
|
|
166
|
+
});
|
|
167
|
+
test("isPromiseAlike", () => {
|
|
168
|
+
expect(promise_1.default.isPromiseAlike(null)).toBe(false);
|
|
169
|
+
expect(promise_1.default.isPromiseAlike({})).toBe(false);
|
|
170
|
+
expect(promise_1.default.isPromiseAlike(Promise.resolve())).toBe(true);
|
|
171
|
+
expect(promise_1.default.isPromiseAlike({ then() { } })).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
test("nodeify with callback", async () => {
|
|
174
|
+
await new Promise((resolve, reject) => {
|
|
175
|
+
(0, promise_1.default)(88).nodeify((err, val) => {
|
|
176
|
+
if (err)
|
|
177
|
+
reject(err);
|
|
178
|
+
else {
|
|
179
|
+
expect(val).toBe(88);
|
|
180
|
+
resolve();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
test("nodeify without callback returns promise", async () => {
|
|
186
|
+
const p = (0, promise_1.default)(1).nodeify();
|
|
187
|
+
await expect(p).resolves.toBe(1);
|
|
188
|
+
});
|
|
189
|
+
test("top-level progress is no-op chain passthrough", async () => {
|
|
190
|
+
const p = (0, promise_1.default)(5).progress(() => {
|
|
191
|
+
/* unused for non-deferred promises */
|
|
192
|
+
});
|
|
193
|
+
await expect(p).resolves.toBe(5);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeObjectPath.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/safeObjectPath.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Direct unit tests for {@link ../safeObjectPath} — mirrors {@link ./objectPath.contract.test.ts}
|
|
5
|
+
* to keep object-path compatibility. Documents intentional differences (empty path, trimmed
|
|
6
|
+
* segments, unsafe segment handling).
|
|
7
|
+
*/
|
|
8
|
+
const safeObjectPath_1 = require("../safeObjectPath");
|
|
9
|
+
describe("safeObjectPath", () => {
|
|
10
|
+
describe("getAtPath", () => {
|
|
11
|
+
test("returns nested value by dot path", () => {
|
|
12
|
+
const obj = { structure: { readme: "README.md" } };
|
|
13
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "structure.readme")).toBe("README.md");
|
|
14
|
+
});
|
|
15
|
+
test("accepts array path", () => {
|
|
16
|
+
const obj = { structure: { readme: "README.md" } };
|
|
17
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, ["structure", "readme"])).toBe("README.md");
|
|
18
|
+
});
|
|
19
|
+
test("array path preserves empty-string segments as literal keys", () => {
|
|
20
|
+
const obj = { "": { key: 1 }, a: { "": 2 } };
|
|
21
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, ["", "key"], "d")).toBe(1);
|
|
22
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, ["a", ""], "d")).toBe(2);
|
|
23
|
+
});
|
|
24
|
+
test("returns default when path missing", () => {
|
|
25
|
+
const obj = { a: 1 };
|
|
26
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "b", "fallback")).toBe("fallback");
|
|
27
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "a.c", "fallback")).toBe("fallback");
|
|
28
|
+
});
|
|
29
|
+
test("returns default for null / undefined root", () => {
|
|
30
|
+
expect((0, safeObjectPath_1.getAtPath)(null, "a", "d")).toBe("d");
|
|
31
|
+
expect((0, safeObjectPath_1.getAtPath)(undefined, "a", "d")).toBe("d");
|
|
32
|
+
});
|
|
33
|
+
test("empty path returns default (unlike object-path empty-path root)", () => {
|
|
34
|
+
expect((0, safeObjectPath_1.getAtPath)({ a: 1 }, "", "d")).toBe("d");
|
|
35
|
+
expect((0, safeObjectPath_1.getAtPath)({ a: 1 }, [], "d")).toBe("d");
|
|
36
|
+
});
|
|
37
|
+
test("returns null when key exists with null value", () => {
|
|
38
|
+
expect((0, safeObjectPath_1.getAtPath)({ x: null }, "x", "d")).toBeNull();
|
|
39
|
+
});
|
|
40
|
+
test("returns default when traversing into null intermediate", () => {
|
|
41
|
+
expect((0, safeObjectPath_1.getAtPath)({ x: null }, "x.y", "d")).toBe("d");
|
|
42
|
+
});
|
|
43
|
+
test("returns default when traversing into non-object", () => {
|
|
44
|
+
expect((0, safeObjectPath_1.getAtPath)({ x: "str" }, "x.y", "d")).toBe("d");
|
|
45
|
+
});
|
|
46
|
+
test("undefined leaf with default returns default", () => {
|
|
47
|
+
expect((0, safeObjectPath_1.getAtPath)({ a: {} }, "a.missing", "d")).toBe("d");
|
|
48
|
+
});
|
|
49
|
+
test("does not read inherited prototype properties (matches object-path)", () => {
|
|
50
|
+
const obj = Object.create({ inherited: 1 });
|
|
51
|
+
obj.own = 2;
|
|
52
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "inherited", "d")).toBe("d");
|
|
53
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "own", "d")).toBe(2);
|
|
54
|
+
});
|
|
55
|
+
test("rejects whole path containing unsafe segments", () => {
|
|
56
|
+
const obj = { safe: 1, polluted: "real-value" };
|
|
57
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "__proto__.polluted", "d")).toBe("d");
|
|
58
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "constructor.prototype.polluted", "d")).toBe("d");
|
|
59
|
+
// path is not rewritten to "polluted" by stripping __proto__
|
|
60
|
+
expect((0, safeObjectPath_1.getAtPath)(obj, "__proto__", "d")).toBe("d");
|
|
61
|
+
});
|
|
62
|
+
test("trims segment whitespace for string paths (differs from object-path)", () => {
|
|
63
|
+
expect((0, safeObjectPath_1.getAtPath)({ a: { b: 2 } }, " a . b ", "d")).toBe(2);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe("setAtPath", () => {
|
|
67
|
+
test("sets nested value by dot path", () => {
|
|
68
|
+
const obj = {};
|
|
69
|
+
(0, safeObjectPath_1.setAtPath)(obj, "structure.readme", "INTRO.md");
|
|
70
|
+
expect(obj).toEqual({ structure: { readme: "INTRO.md" } });
|
|
71
|
+
});
|
|
72
|
+
test("accepts array path", () => {
|
|
73
|
+
const obj = {};
|
|
74
|
+
(0, safeObjectPath_1.setAtPath)(obj, ["structure", "readme"], "INTRO.md");
|
|
75
|
+
expect(obj).toEqual({ structure: { readme: "INTRO.md" } });
|
|
76
|
+
});
|
|
77
|
+
test("array path preserves empty-string segments when writing", () => {
|
|
78
|
+
const obj = {};
|
|
79
|
+
(0, safeObjectPath_1.setAtPath)(obj, ["", "key"], "v");
|
|
80
|
+
expect(obj).toEqual({ "": { key: "v" } });
|
|
81
|
+
});
|
|
82
|
+
test("overwrites existing nested value", () => {
|
|
83
|
+
const obj = { structure: { readme: "A.md" } };
|
|
84
|
+
(0, safeObjectPath_1.setAtPath)(obj, "structure.readme", "B.md");
|
|
85
|
+
expect(obj.structure.readme).toBe("B.md");
|
|
86
|
+
});
|
|
87
|
+
test("uses array index segments for numeric keys", () => {
|
|
88
|
+
const obj = {};
|
|
89
|
+
(0, safeObjectPath_1.setAtPath)(obj, "items.0.name", "first");
|
|
90
|
+
expect(obj.items).toEqual([{ name: "first" }]);
|
|
91
|
+
});
|
|
92
|
+
test("throws when intermediate is a non-object scalar (matches object-path)", () => {
|
|
93
|
+
const obj = { a: "was-string" };
|
|
94
|
+
expect(() => (0, safeObjectPath_1.setAtPath)(obj, "a.b", 1)).toThrow();
|
|
95
|
+
});
|
|
96
|
+
test("throws when intermediate is null (matches object-path / native JS)", () => {
|
|
97
|
+
const obj = { a: null };
|
|
98
|
+
expect(() => (0, safeObjectPath_1.setAtPath)(obj, "a.b", 1)).toThrow();
|
|
99
|
+
// original null is left untouched
|
|
100
|
+
expect(obj.a).toBeNull();
|
|
101
|
+
});
|
|
102
|
+
test("creates missing intermediate when the existing key is undefined", () => {
|
|
103
|
+
const obj = {};
|
|
104
|
+
(0, safeObjectPath_1.setAtPath)(obj, "a.b", 1);
|
|
105
|
+
expect(obj).toEqual({ a: { b: 1 } });
|
|
106
|
+
});
|
|
107
|
+
test("set on path containing __proto__ is a no-op (does not write top-level)", () => {
|
|
108
|
+
const obj = { ok: true };
|
|
109
|
+
expect((0, safeObjectPath_1.setAtPath)(obj, "__proto__", "ignored")).toBeUndefined();
|
|
110
|
+
expect((0, safeObjectPath_1.setAtPath)(obj, "__proto__.polluted", "ignored")).toBeUndefined();
|
|
111
|
+
expect(obj).toEqual({ ok: true });
|
|
112
|
+
expect(obj.polluted).toBeUndefined();
|
|
113
|
+
});
|
|
114
|
+
test("does not descend into inherited objects when setting", () => {
|
|
115
|
+
const proto = { nested: { shared: 1 } };
|
|
116
|
+
const obj = Object.create(proto);
|
|
117
|
+
(0, safeObjectPath_1.setAtPath)(obj, "nested.shared", 2);
|
|
118
|
+
// own "nested" was created on obj, not mutated on proto
|
|
119
|
+
expect(Object.prototype.hasOwnProperty.call(obj, "nested")).toBe(true);
|
|
120
|
+
expect(proto.nested).toEqual({ shared: 1 });
|
|
121
|
+
expect(obj.nested.shared).toBe(2);
|
|
122
|
+
});
|
|
123
|
+
test("returns undefined (matches object-path)", () => {
|
|
124
|
+
const obj = {};
|
|
125
|
+
expect((0, safeObjectPath_1.setAtPath)(obj, "x", 42)).toBeUndefined();
|
|
126
|
+
expect(obj.x).toBe(42);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
package/lib/utils/git.d.ts
CHANGED
package/lib/utils/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAUA,iBAAS,GAAG,SAGX;kBAHQ,GAAG;;;;;;;;AAkIZ,eAAe,GAAG,CAAC"}
|
package/lib/utils/git.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const is_1 = __importDefault(require("is"));
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const crc_1 = __importDefault(require("crc"));
|
|
9
|
-
const urijs_1 = __importDefault(require("urijs"));
|
|
10
9
|
const path_2 = __importDefault(require("./path"));
|
|
11
10
|
const promise_1 = __importDefault(require("./promise"));
|
|
12
11
|
const command_1 = __importDefault(require("./command"));
|
|
@@ -91,26 +90,32 @@ Git.prototype.resolveRoot = function (filepath) {
|
|
|
91
90
|
Git.isUrl = function (giturl) {
|
|
92
91
|
return giturl.indexOf(GIT_PREFIX) === 0;
|
|
93
92
|
};
|
|
94
|
-
// Parse and extract
|
|
93
|
+
// Parse and extract information (git+https://... and git+git@host:path/repo.git/... — no URI.js)
|
|
95
94
|
Git.parseUrl = function (giturl) {
|
|
96
95
|
if (!Git.isUrl(giturl))
|
|
97
96
|
return null;
|
|
98
97
|
giturl = giturl.slice(GIT_PREFIX.length);
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
let ref = null;
|
|
99
|
+
const hashIdx = giturl.indexOf("#");
|
|
100
|
+
if (hashIdx >= 0) {
|
|
101
|
+
ref = giturl.slice(hashIdx + 1) || null;
|
|
102
|
+
giturl = giturl.slice(0, hashIdx);
|
|
103
|
+
}
|
|
104
|
+
// Match a real repository ".git" suffix (not e.g. "gist.github.com" where ".git" appears inside the hostname)
|
|
105
|
+
const gitSuffix = /\.git(\/|$)/;
|
|
106
|
+
const m = gitSuffix.exec(giturl);
|
|
107
|
+
if (!m) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const host = giturl.slice(0, m.index + 4);
|
|
111
|
+
let filepath = giturl.slice(m.index + 4);
|
|
112
|
+
if (filepath.startsWith("/")) {
|
|
106
113
|
filepath = filepath.slice(1);
|
|
107
114
|
}
|
|
108
|
-
// Recreate pathname without the real filename
|
|
109
|
-
uri.path(`${fileParts[0]}.git`);
|
|
110
115
|
return {
|
|
111
|
-
host
|
|
112
|
-
ref
|
|
113
|
-
filepath
|
|
116
|
+
host,
|
|
117
|
+
ref,
|
|
118
|
+
filepath
|
|
114
119
|
};
|
|
115
120
|
};
|
|
116
121
|
exports.default = Git;
|
package/lib/utils/promise.d.ts
CHANGED
|
@@ -1,52 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
declare function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @param {Array|List} arr
|
|
23
|
-
* @param {Function(value, element, index)}
|
|
24
|
-
* @return {Promise}
|
|
25
|
-
*/
|
|
26
|
-
declare function serie(arr: any, iter: any, base: any): any;
|
|
27
|
-
/**
|
|
28
|
-
* Iter over an array and return first result (not null)
|
|
29
|
-
*
|
|
30
|
-
* @param {Array|List} arr
|
|
31
|
-
* @param {Function(element, index)}
|
|
32
|
-
* @return {Promise<Mixed>}
|
|
33
|
-
*/
|
|
34
|
-
declare function some(arr: any, iter: any): any;
|
|
35
|
-
/**
|
|
36
|
-
* Map an array or map
|
|
37
|
-
*
|
|
38
|
-
* @param {Array|List|Map|OrderedMap} arr
|
|
39
|
-
* @param {Function(element, key)}
|
|
40
|
-
* @return {Promise<List|Map|OrderedMap>}
|
|
41
|
-
*/
|
|
42
|
-
declare function map(arr: any, iter: any): any;
|
|
43
|
-
/**
|
|
44
|
-
* Wrap a function in a promise
|
|
45
|
-
*
|
|
46
|
-
* @param {Function} func
|
|
47
|
-
* @return {Funciton}
|
|
48
|
-
*/
|
|
49
|
-
declare function wrap(func: Function): () => any;
|
|
50
|
-
export default Q;
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
/** HonKit historically used `q`; this module keeps the same surface on top of native Promises. */
|
|
3
|
+
export type ExtendedPromise<T> = Promise<T> & {
|
|
4
|
+
thenResolve<U>(value: U): ExtendedPromise<U>;
|
|
5
|
+
spread(fn: (...args: any[]) => any): ExtendedPromise<any>;
|
|
6
|
+
fail(onRejected: (reason: unknown) => unknown): ExtendedPromise<unknown>;
|
|
7
|
+
get?(index: number): ExtendedPromise<unknown>;
|
|
8
|
+
tap(onFulfilled: (value: T) => unknown): ExtendedPromise<T>;
|
|
9
|
+
progress(onProgress: (data: unknown) => void): ExtendedPromise<T>;
|
|
10
|
+
nodeify(callback?: (err: unknown, result?: T) => void): ExtendedPromise<T> | void;
|
|
11
|
+
/** Q `fin` — like `finally`; preserves fulfillment value or rejection reason. */
|
|
12
|
+
fin(onFinally: () => unknown): ExtendedPromise<T>;
|
|
13
|
+
};
|
|
14
|
+
declare function reduce<TAcc, TElem>(arr: Immutable.List<TElem> | unknown[] | Immutable.Iterable<TElem, unknown>, iter: (acc: TAcc, elem: TElem, key: unknown) => unknown, base?: TAcc): ExtendedPromise<TAcc>;
|
|
15
|
+
declare function forEach<T>(arr: Immutable.List<T> | unknown[] | Immutable.Iterable<T, unknown>, iter: (el: T, key: unknown) => unknown): ExtendedPromise<any>;
|
|
16
|
+
declare function serie<T, R>(arr: Immutable.List<T> | unknown[] | Immutable.Iterable<T, unknown>, iter: (item: T, key: unknown) => unknown): ExtendedPromise<R[]>;
|
|
17
|
+
declare function some<T>(arr: Immutable.List<T> | unknown[] | Immutable.Iterable<T, unknown>, iter: (el: T, i: unknown) => unknown): Promise<unknown>;
|
|
18
|
+
declare function map<T, R>(arr: Immutable.Map<string, T> | Immutable.OrderedMap<string, T> | Immutable.List<T> | unknown[] | Immutable.Iterable<T, unknown>, iter: (el: T, key: unknown) => unknown): Promise<Immutable.Map<unknown, unknown>> | Promise<Immutable.List<R>>;
|
|
19
|
+
declare function wrap(func: (...args: unknown[]) => unknown): (this: unknown, ...args: unknown[]) => Promise<any>;
|
|
20
|
+
declare const _default: any;
|
|
21
|
+
export default _default;
|
|
51
22
|
export { forEach, reduce, map, serie, some, wrap };
|
|
52
23
|
//# sourceMappingURL=promise.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/utils/promise.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/utils/promise.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,kGAAkG;AAGlG,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG;IAC1C,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9C,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5D,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClF,iFAAiF;IACjF,GAAG,CAAC,SAAS,EAAE,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AA8IF,iBAAS,MAAM,CAAC,IAAI,EAAE,KAAK,EACvB,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,EAC3E,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,EACvD,IAAI,CAAC,EAAE,IAAI,GACZ,eAAe,CAAC,IAAI,CAAC,CASvB;AAED,iBAAS,OAAO,CAAC,CAAC,EACd,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,EACnE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,wBASzC;AAED,iBAAS,KAAK,CAAC,CAAC,EAAE,CAAC,EACf,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,EACnE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,wBAY3C;AAED,iBAAS,IAAI,CAAC,CAAC,EACX,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,EACnE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,oBAevC;AAkBD,iBAAS,GAAG,CAAC,CAAC,EAAE,CAAC,EACb,GAAG,EACG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GACxB,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,GAC/B,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GACjB,OAAO,EAAE,GACT,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,EACpC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,yEAwBzC;AAED,iBAAS,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,UACxB,OAAO,WAAW,OAAO,EAAE,kBAKrD;wBA2BmC,GAAG;AAAvC,wBAAwC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC"}
|
package/lib/utils/promise.js
CHANGED
|
@@ -9,106 +9,168 @@ exports.map = map;
|
|
|
9
9
|
exports.serie = serie;
|
|
10
10
|
exports.some = some;
|
|
11
11
|
exports.wrap = wrap;
|
|
12
|
-
const q_1 = __importDefault(require("q"));
|
|
13
12
|
const immutable_1 = __importDefault(require("immutable"));
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const HONKIT = Symbol("honkitPromise");
|
|
14
|
+
function extendPromise(p) {
|
|
15
|
+
const ep = p;
|
|
16
|
+
if (ep[HONKIT]) {
|
|
17
|
+
return ep;
|
|
18
|
+
}
|
|
19
|
+
ep[HONKIT] = true;
|
|
20
|
+
const origThen = p.then.bind(p);
|
|
21
|
+
const origCatch = p.catch.bind(p);
|
|
22
|
+
ep.then = function (onFulfilled, onRejected) {
|
|
23
|
+
return extendPromise(origThen(onFulfilled, onRejected));
|
|
24
|
+
};
|
|
25
|
+
ep.catch = function (onRejected) {
|
|
26
|
+
return extendPromise(origCatch(onRejected));
|
|
27
|
+
};
|
|
28
|
+
ep.thenResolve = function (value) {
|
|
29
|
+
return extendPromise(this.then(() => value));
|
|
30
|
+
};
|
|
31
|
+
ep.spread = function (fn) {
|
|
32
|
+
return extendPromise(this.then((arr) => {
|
|
33
|
+
if (Array.isArray(arr)) {
|
|
34
|
+
return fn(...arr);
|
|
35
|
+
}
|
|
36
|
+
return fn(arr);
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
ep.fail = function (onRejected) {
|
|
40
|
+
return extendPromise(this.catch(onRejected));
|
|
41
|
+
};
|
|
42
|
+
ep.tap = function (onFulfilled) {
|
|
43
|
+
return extendPromise(this.then((value) => Promise.resolve(onFulfilled(value)).then(() => value)));
|
|
44
|
+
};
|
|
45
|
+
ep.progress = function (_onProgress) {
|
|
46
|
+
return ep;
|
|
47
|
+
};
|
|
48
|
+
ep.nodeify = function (callback) {
|
|
49
|
+
if (!callback) {
|
|
50
|
+
return ep;
|
|
51
|
+
}
|
|
52
|
+
this.then((result) => {
|
|
53
|
+
callback(null, result);
|
|
54
|
+
}, (err) => {
|
|
55
|
+
callback(err);
|
|
56
|
+
});
|
|
57
|
+
return undefined;
|
|
58
|
+
};
|
|
59
|
+
ep.fin = function (onFinally) {
|
|
60
|
+
return extendPromise(this.finally(() => {
|
|
61
|
+
return onFinally();
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
return ep;
|
|
65
|
+
}
|
|
66
|
+
function defer() {
|
|
67
|
+
const progressHandlers = new Set();
|
|
68
|
+
let resolve;
|
|
69
|
+
let reject;
|
|
70
|
+
const promise = new Promise((res, rej) => {
|
|
71
|
+
resolve = res;
|
|
72
|
+
reject = rej;
|
|
73
|
+
});
|
|
74
|
+
const ext = extendPromise(promise);
|
|
75
|
+
ext.progress = function (_onProgress) {
|
|
76
|
+
progressHandlers.add(_onProgress);
|
|
77
|
+
return ext;
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
promise: ext,
|
|
81
|
+
resolve,
|
|
82
|
+
reject,
|
|
83
|
+
notify(data) {
|
|
84
|
+
progressHandlers.forEach((f) => f(data));
|
|
85
|
+
},
|
|
86
|
+
makeNodeResolver() {
|
|
87
|
+
return (err, ...args) => {
|
|
88
|
+
if (err) {
|
|
89
|
+
reject(err);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
resolve(args.length <= 1 ? args[0] : args);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function nfcall(fn, ...args) {
|
|
99
|
+
const inner = new Promise((resolve, reject) => {
|
|
100
|
+
const callback = (err, ...cbArgs) => {
|
|
101
|
+
if (err) {
|
|
102
|
+
reject(err);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
resolve(cbArgs.length <= 1 ? cbArgs[0] : cbArgs);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
fn(...args, callback);
|
|
109
|
+
});
|
|
110
|
+
const ext = extendPromise(inner);
|
|
111
|
+
ext.get = (index) => extendPromise(inner.then((val) => {
|
|
112
|
+
if (Array.isArray(val)) {
|
|
113
|
+
return val[index];
|
|
114
|
+
}
|
|
115
|
+
return index === 0 ? val : undefined;
|
|
116
|
+
}));
|
|
117
|
+
return ext;
|
|
118
|
+
}
|
|
119
|
+
function nfbind(fn) {
|
|
120
|
+
return function (...args) {
|
|
121
|
+
return nfcall(fn.bind(this), ...args);
|
|
122
|
+
};
|
|
17
123
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Reduce an array to a promise
|
|
20
|
-
*
|
|
21
|
-
* @param {Array|List} arr
|
|
22
|
-
* @param {Function(value, element, index)} iter
|
|
23
|
-
* @param {Array|List} base
|
|
24
|
-
* @return {Promise<Mixed>}
|
|
25
|
-
*/
|
|
26
124
|
function reduce(arr, iter, base) {
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
return prev.then((val) =>
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
}, (0, q_1.default)(base));
|
|
125
|
+
const list = immutable_1.default.Iterable.isIterable(arr) ? arr : immutable_1.default.List(arr);
|
|
126
|
+
return list.reduce((prev, elem, key) => {
|
|
127
|
+
return prev.then((val) => iter(val, elem, key));
|
|
128
|
+
}, extendPromise(Promise.resolve(base)));
|
|
33
129
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Iterate over an array using an async iter
|
|
36
|
-
*
|
|
37
|
-
* @param {Array|List} arr
|
|
38
|
-
* @param {Function(value, element, index)}
|
|
39
|
-
* @return {Promise}
|
|
40
|
-
*/
|
|
41
130
|
function forEach(arr, iter) {
|
|
42
|
-
|
|
43
|
-
return reduce(arr, (val, el, key) => {
|
|
131
|
+
return reduce(arr, (_val, el, key) => {
|
|
44
132
|
return iter(el, key);
|
|
45
|
-
});
|
|
133
|
+
}, undefined);
|
|
46
134
|
}
|
|
47
|
-
|
|
48
|
-
* Transform an array
|
|
49
|
-
*
|
|
50
|
-
* @param {Array|List} arr
|
|
51
|
-
* @param {Function(value, element, index)}
|
|
52
|
-
* @return {Promise}
|
|
53
|
-
*/
|
|
54
|
-
function serie(arr, iter, base) {
|
|
135
|
+
function serie(arr, iter) {
|
|
55
136
|
return reduce(arr, (before, item, key) => {
|
|
56
|
-
return (
|
|
137
|
+
return extendPromise(Promise.resolve(iter(item, key))).then((r) => {
|
|
57
138
|
before.push(r);
|
|
58
139
|
return before;
|
|
59
140
|
});
|
|
60
141
|
}, []);
|
|
61
142
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Iter over an array and return first result (not null)
|
|
64
|
-
*
|
|
65
|
-
* @param {Array|List} arr
|
|
66
|
-
* @param {Function(element, index)}
|
|
67
|
-
* @return {Promise<Mixed>}
|
|
68
|
-
*/
|
|
69
143
|
function some(arr, iter) {
|
|
70
|
-
|
|
71
|
-
return
|
|
144
|
+
const list = immutable_1.default.List.isList(arr) ? arr : immutable_1.default.List(arr);
|
|
145
|
+
return list.reduce((prev, elem, i) => {
|
|
72
146
|
return prev.then((val) => {
|
|
73
|
-
if (val)
|
|
147
|
+
if (val) {
|
|
74
148
|
return val;
|
|
149
|
+
}
|
|
75
150
|
return iter(elem, i);
|
|
76
151
|
});
|
|
77
|
-
}, (
|
|
152
|
+
}, extendPromise(Promise.resolve(undefined)));
|
|
78
153
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Map an array using an async (promised) iterator
|
|
81
|
-
*
|
|
82
|
-
* @param {Array|List} arr
|
|
83
|
-
* @param {Function(element, index)}
|
|
84
|
-
* @return {Promise<List>}
|
|
85
|
-
*/
|
|
86
154
|
function mapAsList(arr, iter) {
|
|
87
155
|
return reduce(arr, (prev, entry, i) => {
|
|
88
|
-
return (
|
|
156
|
+
return extendPromise(Promise.resolve(iter(entry, i))).then((out) => {
|
|
89
157
|
prev.push(out);
|
|
90
158
|
return prev;
|
|
91
159
|
});
|
|
92
160
|
}, []);
|
|
93
161
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Map an array or map
|
|
96
|
-
*
|
|
97
|
-
* @param {Array|List|Map|OrderedMap} arr
|
|
98
|
-
* @param {Function(element, key)}
|
|
99
|
-
* @return {Promise<List|Map|OrderedMap>}
|
|
100
|
-
*/
|
|
101
162
|
function map(arr, iter) {
|
|
102
163
|
if (immutable_1.default.Map.isMap(arr)) {
|
|
103
164
|
let type = "Map";
|
|
104
165
|
if (immutable_1.default.OrderedMap.isOrderedMap(arr)) {
|
|
105
166
|
type = "OrderedMap";
|
|
106
167
|
}
|
|
107
|
-
|
|
108
|
-
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
|
+
return mapAsList(arr, ((value, key) => {
|
|
170
|
+
return extendPromise(Promise.resolve(iter(value, key))).then((result) => {
|
|
109
171
|
return [key, result];
|
|
110
172
|
});
|
|
111
|
-
}).then((result) => {
|
|
173
|
+
})).then((result) => {
|
|
112
174
|
return immutable_1.default[type](result);
|
|
113
175
|
});
|
|
114
176
|
}
|
|
@@ -118,24 +180,31 @@ function map(arr, iter) {
|
|
|
118
180
|
});
|
|
119
181
|
}
|
|
120
182
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Wrap a function in a promise
|
|
123
|
-
*
|
|
124
|
-
* @param {Function} func
|
|
125
|
-
* @return {Funciton}
|
|
126
|
-
*/
|
|
127
183
|
function wrap(func) {
|
|
128
|
-
return function () {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return func.apply(null, args);
|
|
184
|
+
return function (...args) {
|
|
185
|
+
return extendPromise(Promise.resolve()).then(() => {
|
|
186
|
+
return func.apply(this, args);
|
|
132
187
|
});
|
|
133
188
|
};
|
|
134
189
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
190
|
+
function isPromiseAlike(x) {
|
|
191
|
+
return x != null && typeof x.then === "function";
|
|
192
|
+
}
|
|
193
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- Q-compatible surface is intentionally loose for chaining */
|
|
194
|
+
const HonkitPromiseRoot = Object.assign(function HonkitPromise(value) {
|
|
195
|
+
return extendPromise(Promise.resolve(value));
|
|
196
|
+
}, {
|
|
197
|
+
defer,
|
|
198
|
+
nfcall,
|
|
199
|
+
nfbind,
|
|
200
|
+
reject: (reason) => extendPromise(Promise.reject(reason)),
|
|
201
|
+
all: (values) => extendPromise(Promise.all(Array.from(values))),
|
|
202
|
+
reduce,
|
|
203
|
+
forEach,
|
|
204
|
+
map,
|
|
205
|
+
serie,
|
|
206
|
+
some,
|
|
207
|
+
wrap,
|
|
208
|
+
isPromiseAlike
|
|
209
|
+
});
|
|
210
|
+
exports.default = HonkitPromiseRoot;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal dot-path get/set with prototype-pollution guards.
|
|
3
|
+
* Replaces object-path for config key access (e.g. "plugins", "structure.readme").
|
|
4
|
+
*
|
|
5
|
+
* Behavior is kept compatible with the previous object-path wrapper:
|
|
6
|
+
* - get / set accept `string | string[]`
|
|
7
|
+
* - lookups only descend through own properties (matches object-path)
|
|
8
|
+
* - set throws when an intermediate value is a non-object scalar (string,
|
|
9
|
+
* number, boolean, null) — null follows from native JS, the others match
|
|
10
|
+
* object-path's check
|
|
11
|
+
* - set returns undefined
|
|
12
|
+
* - paths containing __proto__ / constructor / prototype are rejected as a
|
|
13
|
+
* whole, so e.g. "__proto__.polluted" does not collapse to "polluted"
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAtPath(obj: Record<string, unknown> | null | undefined, path: string | string[], defaultValue?: unknown): unknown;
|
|
16
|
+
export declare function setAtPath(obj: Record<string, unknown> | null | undefined, path: string | string[], value: unknown): void;
|
|
17
|
+
//# sourceMappingURL=safeObjectPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeObjectPath.d.ts","sourceRoot":"","sources":["../../src/utils/safeObjectPath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+BH,wBAAgB,SAAS,CACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,YAAY,CAAC,EAAE,OAAO,GACvB,OAAO,CAmBT;AAED,wBAAgB,SAAS,CACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,KAAK,EAAE,OAAO,GACf,IAAI,CA6BN"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal dot-path get/set with prototype-pollution guards.
|
|
4
|
+
* Replaces object-path for config key access (e.g. "plugins", "structure.readme").
|
|
5
|
+
*
|
|
6
|
+
* Behavior is kept compatible with the previous object-path wrapper:
|
|
7
|
+
* - get / set accept `string | string[]`
|
|
8
|
+
* - lookups only descend through own properties (matches object-path)
|
|
9
|
+
* - set throws when an intermediate value is a non-object scalar (string,
|
|
10
|
+
* number, boolean, null) — null follows from native JS, the others match
|
|
11
|
+
* object-path's check
|
|
12
|
+
* - set returns undefined
|
|
13
|
+
* - paths containing __proto__ / constructor / prototype are rejected as a
|
|
14
|
+
* whole, so e.g. "__proto__.polluted" does not collapse to "polluted"
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.getAtPath = getAtPath;
|
|
18
|
+
exports.setAtPath = setAtPath;
|
|
19
|
+
const UNSAFE = new Set(["__proto__", "constructor", "prototype"]);
|
|
20
|
+
function toSegments(path) {
|
|
21
|
+
let parts;
|
|
22
|
+
if (Array.isArray(path)) {
|
|
23
|
+
// Array paths are caller-supplied keys — empty string is a valid property name
|
|
24
|
+
parts = path.map((s) => String(s));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// String paths are dot-delimited; trim whitespace and drop empty split artifacts
|
|
28
|
+
parts = String(path)
|
|
29
|
+
.split(".")
|
|
30
|
+
.map((s) => s.trim())
|
|
31
|
+
.filter((s) => s.length > 0);
|
|
32
|
+
}
|
|
33
|
+
if (parts.length === 0) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
for (const part of parts) {
|
|
37
|
+
if (UNSAFE.has(part)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return parts;
|
|
42
|
+
}
|
|
43
|
+
function hasOwn(obj, key) {
|
|
44
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
45
|
+
}
|
|
46
|
+
function getAtPath(obj, path, defaultValue) {
|
|
47
|
+
if (obj == null || path == null) {
|
|
48
|
+
return defaultValue;
|
|
49
|
+
}
|
|
50
|
+
const parts = toSegments(path);
|
|
51
|
+
if (parts === null) {
|
|
52
|
+
return defaultValue;
|
|
53
|
+
}
|
|
54
|
+
let cur = obj;
|
|
55
|
+
for (const key of parts) {
|
|
56
|
+
if (cur == null || typeof cur !== "object") {
|
|
57
|
+
return defaultValue;
|
|
58
|
+
}
|
|
59
|
+
if (!hasOwn(cur, key)) {
|
|
60
|
+
return defaultValue;
|
|
61
|
+
}
|
|
62
|
+
cur = cur[key];
|
|
63
|
+
}
|
|
64
|
+
return cur === undefined ? defaultValue : cur;
|
|
65
|
+
}
|
|
66
|
+
function setAtPath(obj, path, value) {
|
|
67
|
+
if (obj == null || path == null) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const parts = toSegments(path);
|
|
71
|
+
if (parts === null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let cur = obj;
|
|
75
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
76
|
+
const key = parts[i];
|
|
77
|
+
if (!hasOwn(cur, key) || cur[key] === undefined) {
|
|
78
|
+
const nextKey = parts[i + 1];
|
|
79
|
+
const created = /^\d+$/.test(nextKey) ? [] : {};
|
|
80
|
+
cur[key] = created;
|
|
81
|
+
cur = created;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const ownNext = cur[key];
|
|
85
|
+
if (ownNext === null || typeof ownNext !== "object") {
|
|
86
|
+
throw new Error(`safeObjectPath.setAtPath: cannot set "${parts.join(".")}" because intermediate "${parts
|
|
87
|
+
.slice(0, i + 1)
|
|
88
|
+
.join(".")}" is not an object`);
|
|
89
|
+
}
|
|
90
|
+
cur = ownNext;
|
|
91
|
+
}
|
|
92
|
+
cur[parts[parts.length - 1]] = value;
|
|
93
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "honkit",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.8",
|
|
4
4
|
"description": "HonKit is building beautiful books using Markdown.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"git",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"cp": "^0.2.0",
|
|
38
38
|
"cpr": "^3.0.1",
|
|
39
39
|
"crc": "^3.8.0",
|
|
40
|
+
"dayjs": "^1.11.13",
|
|
40
41
|
"destroy": "^1.2.0",
|
|
41
42
|
"direction": "^0.1.5",
|
|
42
43
|
"dom-serializer": "^0.1.1",
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
"escape-html": "^1.0.3",
|
|
45
46
|
"escape-string-regexp": "^4.0.0",
|
|
46
47
|
"extend": "^3.0.2",
|
|
47
|
-
"flat-cache": "^
|
|
48
|
+
"flat-cache": "^4.0.1",
|
|
48
49
|
"front-matter": "^2.3.0",
|
|
49
50
|
"gitbook-plugin-livereload": "^0.0.1",
|
|
50
51
|
"gitbook-plugin-lunr": "^1.2.0",
|
|
@@ -52,34 +53,30 @@
|
|
|
52
53
|
"github-slugid": "^1.0.1",
|
|
53
54
|
"i18n-t": "^1.0.1",
|
|
54
55
|
"ignore": "^5.3.2",
|
|
55
|
-
"immutable": "^3.8.
|
|
56
|
+
"immutable": "^3.8.3",
|
|
56
57
|
"is": "^3.3.0",
|
|
57
|
-
"js-yaml": "^
|
|
58
|
+
"js-yaml": "^4.1.0",
|
|
58
59
|
"json-schema-defaults": "^0.1.1",
|
|
59
60
|
"jsonschema": "1.1.0",
|
|
60
61
|
"juice": "^8.1.0",
|
|
61
62
|
"lru_map": "^0.4.1",
|
|
62
63
|
"memoize-one": "^5.2.1",
|
|
63
64
|
"mkdirp": "^1.0.4",
|
|
64
|
-
"moment": "^2.30.1",
|
|
65
65
|
"nunjucks": "^3.2.4",
|
|
66
66
|
"nunjucks-do": "^1.0.0",
|
|
67
|
-
"object-path": "^0.11.8",
|
|
68
67
|
"omit-keys": "^0.1.0",
|
|
69
68
|
"open": "^7.4.2",
|
|
70
|
-
"q": "^1.5.1",
|
|
71
69
|
"resolve": "^1.22.8",
|
|
72
70
|
"semver": "^7.6.3",
|
|
73
|
-
"send": "^0.
|
|
71
|
+
"send": "^0.19.2",
|
|
74
72
|
"tiny-lr": "^1.1.1",
|
|
75
73
|
"tmp": "0.2.4",
|
|
76
|
-
"
|
|
77
|
-
"@honkit/honkit-plugin-
|
|
78
|
-
"@honkit/honkit-plugin-fontsettings": "6.1.
|
|
79
|
-
"@honkit/html": "6.1.
|
|
80
|
-
"@honkit/markdown-legacy": "6.1.
|
|
81
|
-
"@honkit/
|
|
82
|
-
"@honkit/honkit-plugin-theme-default": "6.1.6"
|
|
74
|
+
"@honkit/asciidoc": "6.1.8",
|
|
75
|
+
"@honkit/honkit-plugin-theme-default": "6.1.8",
|
|
76
|
+
"@honkit/honkit-plugin-fontsettings": "6.1.8",
|
|
77
|
+
"@honkit/html": "6.1.8",
|
|
78
|
+
"@honkit/markdown-legacy": "6.1.8",
|
|
79
|
+
"@honkit/honkit-plugin-highlight": "6.1.8"
|
|
83
80
|
},
|
|
84
81
|
"devDependencies": {
|
|
85
82
|
"@relmify/jest-serializer-strip-ansi": "^1.0.2",
|
|
@@ -88,14 +85,16 @@
|
|
|
88
85
|
"@types/nunjucks": "^3.2.6",
|
|
89
86
|
"jest": "^29.7.0",
|
|
90
87
|
"jest-mock-process": "^2.0.0",
|
|
88
|
+
"object-path": "^0.11.8",
|
|
91
89
|
"rimraf": "^6.0.1",
|
|
92
90
|
"typescript": "^5.6.2",
|
|
93
|
-
"@honkit/internal-test-utils": "6.1.
|
|
91
|
+
"@honkit/internal-test-utils": "6.1.8"
|
|
94
92
|
},
|
|
95
93
|
"scripts": {
|
|
96
94
|
"build": "tsc -p .",
|
|
97
95
|
"clean": "rimraf lib/",
|
|
98
96
|
"test": "jest src",
|
|
97
|
+
"test:contract": "jest --config jest.contract.config.js --coverage src/utils/__tests__/promise.contract.test.ts src/utils/__tests__/objectPath.contract.test.ts",
|
|
99
98
|
"updateSnapshot": "jest src -u"
|
|
100
99
|
}
|
|
101
100
|
}
|