honkit 6.1.7 → 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.
@@ -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 object_path_1 = __importDefault(require("object-path"));
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 = object_path_1.default.get(instance, newName);
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) => any;
9
- set: (key: any, value: any) => 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
@@ -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 object_path_1 = __importDefault(require("object-path"));
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 object_path_1.default.get(result.values, key, defaultValue);
15
+ return (0, safeObjectPath_1.getAtPath)(result.values, key, defaultValue);
16
16
  },
17
17
  set: function (key, value) {
18
- return object_path_1.default.set(result.values, key, value);
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) => any;
14
- set: (key: any, value: any) => 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;;AAGlC,wBAWG"}
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 moment_1 = __importDefault(require("moment"));
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, moment_1.default)(time).format(format);
16
+ return (0, dayjs_1.default)(time).format(format);
13
17
  },
14
18
  // Relative Time
15
19
  dateFromNow: function (time) {
16
- return (0, moment_1.default)(time).fromNow();
20
+ return (0, dayjs_1.default)(time).fromNow();
17
21
  }
18
22
  });
@@ -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?: string): Promise<string>;
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
 
@@ -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;AAC1B,OAAO,OAAO,MAAM,kBAAkB,CAAC;;AAIvC,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,MAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1E;;;;;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"}
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"}
@@ -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.safeDump(attrs.toJS(), { skipInvalid: true })}---\n\n`;
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=objectPath.contract.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=promise.contract.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=safeObjectPath.d.ts.map
@@ -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
+ });
@@ -3,7 +3,7 @@ declare namespace Git {
3
3
  var isUrl: (giturl: any) => boolean;
4
4
  var parseUrl: (giturl: any) => {
5
5
  host: any;
6
- ref: any;
6
+ ref: string;
7
7
  filepath: any;
8
8
  };
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAWA,iBAAS,GAAG,SAGX;kBAHQ,GAAG;;;;;;;;AA4HZ,eAAe,GAAG,CAAC"}
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 infos
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
- const uri = new urijs_1.default(giturl);
100
- const ref = uri.fragment() || null;
101
- uri.fragment(null);
102
- // Extract file inside the repo (after the .git)
103
- const fileParts = uri.path().split(".git");
104
- let filepath = fileParts.length > 1 ? fileParts.slice(1).join(".git") : "";
105
- if (filepath[0] == "/") {
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: uri.toString(),
112
- ref: ref,
113
- filepath: filepath
116
+ host,
117
+ ref,
118
+ filepath
114
119
  };
115
120
  };
116
121
  exports.default = Git;
@@ -1,52 +1,23 @@
1
- import Q from "q";
2
- /**
3
- * Reduce an array to a promise
4
- *
5
- * @param {Array|List} arr
6
- * @param {Function(value, element, index)} iter
7
- * @param {Array|List} base
8
- * @return {Promise<Mixed>}
9
- */
10
- declare function reduce(arr: any, iter: any, base: any): any;
11
- /**
12
- * Iterate over an array using an async iter
13
- *
14
- * @param {Array|List} arr
15
- * @param {Function(value, element, index)}
16
- * @return {Promise}
17
- */
18
- declare function forEach(arr: any, iter: any): any;
19
- /**
20
- * Transform an array
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,CAAC,MAAM,GAAG,CAAC;AAQlB;;;;;;;GAOG;AACH,iBAAS,MAAM,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,IAAI,KAAA,OAQ9B;AAED;;;;;;GAMG;AACH,iBAAS,OAAO,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,OAKzB;AAED;;;;;;GAMG;AACH,iBAAS,KAAK,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,IAAI,KAAA,OAW7B;AAED;;;;;;GAMG;AACH,iBAAS,IAAI,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,OAUtB;AAsBD;;;;;;GAMG;AACH,iBAAS,GAAG,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,OAmBrB;AAED;;;;;GAKG;AACH,iBAAS,IAAI,CAAC,IAAI,EAAE,QAAQ,aAQ3B;AAQD,eAAe,CAAC,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/utils/promise.ts"],"names":[],"mappings":"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"}
@@ -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
- // Debugging for long stack traces
15
- if (process.env.DEBUG || process.env.CI) {
16
- q_1.default.longStackSupport = true;
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
- arr = immutable_1.default.Iterable.isIterable(arr) ? arr : immutable_1.default.List(arr);
28
- return arr.reduce((prev, elem, key) => {
29
- return prev.then((val) => {
30
- return iter(val, elem, key);
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
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
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 (0, q_1.default)(iter(item, key)).then((r) => {
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
- arr = immutable_1.default.List(arr);
71
- return arr.reduce((prev, elem, i) => {
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
- }, (0, q_1.default)());
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 (0, q_1.default)(iter(entry, i)).then((out) => {
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
- return mapAsList(arr, (value, key) => {
108
- return (0, q_1.default)(iter(value, key)).then((result) => {
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
- const args = Array.prototype.slice.call(arguments, 0);
130
- return (0, q_1.default)().then(() => {
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
- q_1.default.forEach = forEach;
136
- q_1.default.reduce = reduce;
137
- q_1.default.map = map;
138
- q_1.default.serie = serie;
139
- q_1.default.some = some;
140
- q_1.default.wrap = wrap;
141
- exports.default = q_1.default;
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.7",
3
+ "version": "6.1.8",
4
4
  "description": "HonKit is building beautiful books using Markdown.",
5
5
  "keywords": [
6
6
  "git",
@@ -31,12 +31,13 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "bash-color": "^0.0.4",
34
- "cheerio": "~1.0.0",
34
+ "cheerio": "^1.0.0",
35
35
  "chokidar": "^3.6.0",
36
36
  "commander": "^5.1.0",
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",
@@ -54,32 +55,28 @@
54
55
  "ignore": "^5.3.2",
55
56
  "immutable": "^3.8.3",
56
57
  "is": "^3.3.0",
57
- "js-yaml": "^3.14.2",
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
71
  "send": "^0.19.2",
74
72
  "tiny-lr": "^1.1.1",
75
73
  "tmp": "0.2.4",
76
- "urijs": "^1.19.11",
77
- "@honkit/honkit-plugin-fontsettings": "6.1.7",
78
- "@honkit/asciidoc": "6.1.7",
79
- "@honkit/honkit-plugin-highlight": "6.1.7",
80
- "@honkit/honkit-plugin-theme-default": "6.1.7",
81
- "@honkit/html": "6.1.7",
82
- "@honkit/markdown-legacy": "6.1.7"
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.7"
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
  }