keep-a-changelog 0.10.3 → 2.0.1

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +13 -185
  2. package/LICENSE +1 -1
  3. package/README.md +93 -63
  4. package/esm/_dnt.shims.js +62 -0
  5. package/esm/bin.js +114 -0
  6. package/esm/deps/deno_land/std_0.120.0/_util/assert.js +13 -0
  7. package/esm/deps/deno_land/std_0.120.0/_util/os.js +15 -0
  8. package/esm/deps/deno_land/std_0.120.0/flags/mod.js +255 -0
  9. package/esm/deps/deno_land/std_0.120.0/path/_constants.js +45 -0
  10. package/esm/deps/deno_land/std_0.120.0/path/_interface.js +3 -0
  11. package/esm/deps/deno_land/std_0.120.0/path/_util.js +114 -0
  12. package/esm/deps/deno_land/std_0.120.0/path/common.js +36 -0
  13. package/esm/deps/deno_land/std_0.120.0/path/glob.js +361 -0
  14. package/esm/deps/deno_land/std_0.120.0/path/mod.js +14 -0
  15. package/esm/deps/deno_land/std_0.120.0/path/posix.js +493 -0
  16. package/esm/deps/deno_land/std_0.120.0/path/separator.js +5 -0
  17. package/esm/deps/deno_land/std_0.120.0/path/win32.js +963 -0
  18. package/esm/deps/deno_land/std_0.51.0/fs/eol.js +29 -0
  19. package/esm/deps/deno_land/x/ini_v2.1.0/ini.js +226 -0
  20. package/esm/deps/deno_land/x/ini_v2.1.0/mod.js +1 -0
  21. package/esm/deps/deno_land/x/semver_v1.4.0/mod.js +1527 -0
  22. package/esm/mod.js +5 -0
  23. package/esm/package.json +3 -0
  24. package/esm/src/Change.js +48 -0
  25. package/esm/src/Changelog.js +137 -0
  26. package/esm/src/Release.js +204 -0
  27. package/esm/src/deps.js +1 -0
  28. package/esm/src/parser.js +159 -0
  29. package/esm/test/changelog.custom.type.md +24 -0
  30. package/esm/test/changelog.expected.md +169 -0
  31. package/esm/test/changelog.md +200 -0
  32. package/esm/test/empty.expected.md +6 -0
  33. package/package.json +26 -24
  34. package/types/_dnt.shims.d.ts +9 -0
  35. package/types/bin.d.ts +2 -0
  36. package/types/deps/deno_land/std_0.120.0/_util/assert.d.ts +5 -0
  37. package/types/deps/deno_land/std_0.120.0/_util/os.d.ts +3 -0
  38. package/types/deps/deno_land/std_0.120.0/flags/mod.d.ts +50 -0
  39. package/types/deps/deno_land/std_0.120.0/path/_constants.d.ts +39 -0
  40. package/types/deps/deno_land/std_0.120.0/path/_interface.d.ts +26 -0
  41. package/types/deps/deno_land/std_0.120.0/path/_util.d.ts +8 -0
  42. package/types/deps/deno_land/std_0.120.0/path/common.d.ts +13 -0
  43. package/types/deps/deno_land/std_0.120.0/path/glob.d.ts +78 -0
  44. package/types/deps/deno_land/std_0.120.0/path/mod.d.ts +9 -0
  45. package/types/deps/deno_land/std_0.120.0/path/posix.d.ts +80 -0
  46. package/types/deps/deno_land/std_0.120.0/path/separator.d.ts +2 -0
  47. package/types/deps/deno_land/std_0.120.0/path/win32.d.ts +87 -0
  48. package/types/deps/deno_land/std_0.51.0/fs/eol.d.ts +12 -0
  49. package/types/deps/deno_land/x/ini_v2.1.0/ini.d.ts +53 -0
  50. package/types/deps/deno_land/x/ini_v2.1.0/mod.d.ts +1 -0
  51. package/types/deps/deno_land/x/semver_v1.4.0/mod.d.ts +116 -0
  52. package/types/mod.d.ts +5 -0
  53. package/types/src/Change.d.ts +8 -0
  54. package/types/src/Changelog.d.ts +18 -0
  55. package/types/src/Release.d.ts +25 -0
  56. package/types/src/deps.d.ts +1 -0
  57. package/types/src/parser.d.ts +11 -0
  58. package/umd/_dnt.shims.js +76 -0
  59. package/umd/bin.js +145 -0
  60. package/umd/deps/deno_land/std_0.120.0/_util/assert.js +28 -0
  61. package/umd/deps/deno_land/std_0.120.0/_util/os.js +47 -0
  62. package/umd/deps/deno_land/std_0.120.0/flags/mod.js +269 -0
  63. package/umd/deps/deno_land/std_0.120.0/path/_constants.js +58 -0
  64. package/umd/deps/deno_land/std_0.120.0/path/_interface.js +14 -0
  65. package/umd/deps/deno_land/std_0.120.0/path/_util.js +134 -0
  66. package/umd/deps/deno_land/std_0.120.0/path/common.js +50 -0
  67. package/umd/deps/deno_land/std_0.120.0/path/glob.js +397 -0
  68. package/umd/deps/deno_land/std_0.120.0/path/mod.js +51 -0
  69. package/umd/deps/deno_land/std_0.120.0/path/posix.js +538 -0
  70. package/umd/deps/deno_land/std_0.120.0/path/separator.js +18 -0
  71. package/umd/deps/deno_land/std_0.120.0/path/win32.js +1008 -0
  72. package/umd/deps/deno_land/std_0.51.0/fs/eol.js +44 -0
  73. package/umd/deps/deno_land/x/ini_v2.1.0/ini.js +262 -0
  74. package/umd/deps/deno_land/x/ini_v2.1.0/mod.js +23 -0
  75. package/umd/deps/deno_land/x/semver_v1.4.0/mod.js +1578 -0
  76. package/umd/mod.js +24 -0
  77. package/umd/package.json +3 -0
  78. package/umd/src/Change.js +61 -0
  79. package/umd/src/Changelog.js +150 -0
  80. package/umd/src/Release.js +220 -0
  81. package/umd/src/deps.js +19 -0
  82. package/umd/src/parser.js +175 -0
  83. package/umd/test/changelog.custom.type.md +24 -0
  84. package/umd/test/changelog.expected.md +169 -0
  85. package/umd/test/changelog.md +200 -0
  86. package/umd/test/empty.expected.md +6 -0
  87. package/bin.js +0 -114
  88. package/src/Change.js +0 -40
  89. package/src/Changelog.js +0 -121
  90. package/src/Release.js +0 -220
  91. package/src/index.js +0 -6
  92. package/src/parser.js +0 -182
@@ -0,0 +1,255 @@
1
+ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
2
+ import { assert } from "../_util/assert.js";
3
+ const { hasOwn } = Object;
4
+ function get(obj, key) {
5
+ if (hasOwn(obj, key)) {
6
+ return obj[key];
7
+ }
8
+ }
9
+ function getForce(obj, key) {
10
+ const v = get(obj, key);
11
+ assert(v != null);
12
+ return v;
13
+ }
14
+ function isNumber(x) {
15
+ if (typeof x === "number")
16
+ return true;
17
+ if (/^0x[0-9a-f]+$/i.test(String(x)))
18
+ return true;
19
+ return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
20
+ }
21
+ function hasKey(obj, keys) {
22
+ let o = obj;
23
+ keys.slice(0, -1).forEach((key) => {
24
+ o = (get(o, key) ?? {});
25
+ });
26
+ const key = keys[keys.length - 1];
27
+ return key in o;
28
+ }
29
+ /** Take a set of command line arguments, with an optional set of options, and
30
+ * return an object representation of those argument.
31
+ *
32
+ * ```ts
33
+ * import { parse } from "./mod.ts";
34
+ * const parsedArgs = parse(Deno.args);
35
+ * ```
36
+ */
37
+ export function parse(args, { "--": doubleDash = false, alias = {}, boolean = false, default: defaults = {}, stopEarly = false, string = [], unknown = (i) => i, } = {}) {
38
+ const flags = {
39
+ bools: {},
40
+ strings: {},
41
+ unknownFn: unknown,
42
+ allBools: false,
43
+ };
44
+ if (boolean !== undefined) {
45
+ if (typeof boolean === "boolean") {
46
+ flags.allBools = !!boolean;
47
+ }
48
+ else {
49
+ const booleanArgs = typeof boolean === "string" ? [boolean] : boolean;
50
+ for (const key of booleanArgs.filter(Boolean)) {
51
+ flags.bools[key] = true;
52
+ }
53
+ }
54
+ }
55
+ const aliases = {};
56
+ if (alias !== undefined) {
57
+ for (const key in alias) {
58
+ const val = getForce(alias, key);
59
+ if (typeof val === "string") {
60
+ aliases[key] = [val];
61
+ }
62
+ else {
63
+ aliases[key] = val;
64
+ }
65
+ for (const alias of getForce(aliases, key)) {
66
+ aliases[alias] = [key].concat(aliases[key].filter((y) => alias !== y));
67
+ }
68
+ }
69
+ }
70
+ if (string !== undefined) {
71
+ const stringArgs = typeof string === "string" ? [string] : string;
72
+ for (const key of stringArgs.filter(Boolean)) {
73
+ flags.strings[key] = true;
74
+ const alias = get(aliases, key);
75
+ if (alias) {
76
+ for (const al of alias) {
77
+ flags.strings[al] = true;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ const argv = { _: [] };
83
+ function argDefined(key, arg) {
84
+ return ((flags.allBools && /^--[^=]+$/.test(arg)) ||
85
+ get(flags.bools, key) ||
86
+ !!get(flags.strings, key) ||
87
+ !!get(aliases, key));
88
+ }
89
+ function setKey(obj, keys, value) {
90
+ let o = obj;
91
+ keys.slice(0, -1).forEach(function (key) {
92
+ if (get(o, key) === undefined) {
93
+ o[key] = {};
94
+ }
95
+ o = get(o, key);
96
+ });
97
+ const key = keys[keys.length - 1];
98
+ if (get(o, key) === undefined ||
99
+ get(flags.bools, key) ||
100
+ typeof get(o, key) === "boolean") {
101
+ o[key] = value;
102
+ }
103
+ else if (Array.isArray(get(o, key))) {
104
+ o[key].push(value);
105
+ }
106
+ else {
107
+ o[key] = [get(o, key), value];
108
+ }
109
+ }
110
+ function setArg(key, val, arg = undefined) {
111
+ if (arg && flags.unknownFn && !argDefined(key, arg)) {
112
+ if (flags.unknownFn(arg, key, val) === false)
113
+ return;
114
+ }
115
+ const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
116
+ setKey(argv, key.split("."), value);
117
+ const alias = get(aliases, key);
118
+ if (alias) {
119
+ for (const x of alias) {
120
+ setKey(argv, x.split("."), value);
121
+ }
122
+ }
123
+ }
124
+ function aliasIsBoolean(key) {
125
+ return getForce(aliases, key).some((x) => typeof get(flags.bools, x) === "boolean");
126
+ }
127
+ for (const key of Object.keys(flags.bools)) {
128
+ setArg(key, defaults[key] === undefined ? false : defaults[key]);
129
+ }
130
+ let notFlags = [];
131
+ // all args after "--" are not parsed
132
+ if (args.includes("--")) {
133
+ notFlags = args.slice(args.indexOf("--") + 1);
134
+ args = args.slice(0, args.indexOf("--"));
135
+ }
136
+ for (let i = 0; i < args.length; i++) {
137
+ const arg = args[i];
138
+ if (/^--.+=/.test(arg)) {
139
+ const m = arg.match(/^--([^=]+)=(.*)$/s);
140
+ assert(m != null);
141
+ const [, key, value] = m;
142
+ if (flags.bools[key]) {
143
+ const booleanValue = value !== "false";
144
+ setArg(key, booleanValue, arg);
145
+ }
146
+ else {
147
+ setArg(key, value, arg);
148
+ }
149
+ }
150
+ else if (/^--no-.+/.test(arg)) {
151
+ const m = arg.match(/^--no-(.+)/);
152
+ assert(m != null);
153
+ setArg(m[1], false, arg);
154
+ }
155
+ else if (/^--.+/.test(arg)) {
156
+ const m = arg.match(/^--(.+)/);
157
+ assert(m != null);
158
+ const [, key] = m;
159
+ const next = args[i + 1];
160
+ if (next !== undefined &&
161
+ !/^-/.test(next) &&
162
+ !get(flags.bools, key) &&
163
+ !flags.allBools &&
164
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
165
+ setArg(key, next, arg);
166
+ i++;
167
+ }
168
+ else if (/^(true|false)$/.test(next)) {
169
+ setArg(key, next === "true", arg);
170
+ i++;
171
+ }
172
+ else {
173
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
174
+ }
175
+ }
176
+ else if (/^-[^-]+/.test(arg)) {
177
+ const letters = arg.slice(1, -1).split("");
178
+ let broken = false;
179
+ for (let j = 0; j < letters.length; j++) {
180
+ const next = arg.slice(j + 2);
181
+ if (next === "-") {
182
+ setArg(letters[j], next, arg);
183
+ continue;
184
+ }
185
+ if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
186
+ setArg(letters[j], next.split(/=(.+)/)[1], arg);
187
+ broken = true;
188
+ break;
189
+ }
190
+ if (/[A-Za-z]/.test(letters[j]) &&
191
+ /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
192
+ setArg(letters[j], next, arg);
193
+ broken = true;
194
+ break;
195
+ }
196
+ if (letters[j + 1] && letters[j + 1].match(/\W/)) {
197
+ setArg(letters[j], arg.slice(j + 2), arg);
198
+ broken = true;
199
+ break;
200
+ }
201
+ else {
202
+ setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
203
+ }
204
+ }
205
+ const [key] = arg.slice(-1);
206
+ if (!broken && key !== "-") {
207
+ if (args[i + 1] &&
208
+ !/^(-|--)[^-]/.test(args[i + 1]) &&
209
+ !get(flags.bools, key) &&
210
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
211
+ setArg(key, args[i + 1], arg);
212
+ i++;
213
+ }
214
+ else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
215
+ setArg(key, args[i + 1] === "true", arg);
216
+ i++;
217
+ }
218
+ else {
219
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
220
+ }
221
+ }
222
+ }
223
+ else {
224
+ if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
225
+ argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
226
+ }
227
+ if (stopEarly) {
228
+ argv._.push(...args.slice(i + 1));
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ for (const key of Object.keys(defaults)) {
234
+ if (!hasKey(argv, key.split("."))) {
235
+ setKey(argv, key.split("."), defaults[key]);
236
+ if (aliases[key]) {
237
+ for (const x of aliases[key]) {
238
+ setKey(argv, x.split("."), defaults[key]);
239
+ }
240
+ }
241
+ }
242
+ }
243
+ if (doubleDash) {
244
+ argv["--"] = [];
245
+ for (const key of notFlags) {
246
+ argv["--"].push(key);
247
+ }
248
+ }
249
+ else {
250
+ for (const key of notFlags) {
251
+ argv._.push(key);
252
+ }
253
+ }
254
+ return argv;
255
+ }
@@ -0,0 +1,45 @@
1
+ // Copyright the Browserify authors. MIT License.
2
+ // Ported from https://github.com/browserify/path-browserify/
3
+ // This module is browser compatible.
4
+ // Alphabet chars.
5
+ export const CHAR_UPPERCASE_A = 65; /* A */
6
+ export const CHAR_LOWERCASE_A = 97; /* a */
7
+ export const CHAR_UPPERCASE_Z = 90; /* Z */
8
+ export const CHAR_LOWERCASE_Z = 122; /* z */
9
+ // Non-alphabetic chars.
10
+ export const CHAR_DOT = 46; /* . */
11
+ export const CHAR_FORWARD_SLASH = 47; /* / */
12
+ export const CHAR_BACKWARD_SLASH = 92; /* \ */
13
+ export const CHAR_VERTICAL_LINE = 124; /* | */
14
+ export const CHAR_COLON = 58; /* : */
15
+ export const CHAR_QUESTION_MARK = 63; /* ? */
16
+ export const CHAR_UNDERSCORE = 95; /* _ */
17
+ export const CHAR_LINE_FEED = 10; /* \n */
18
+ export const CHAR_CARRIAGE_RETURN = 13; /* \r */
19
+ export const CHAR_TAB = 9; /* \t */
20
+ export const CHAR_FORM_FEED = 12; /* \f */
21
+ export const CHAR_EXCLAMATION_MARK = 33; /* ! */
22
+ export const CHAR_HASH = 35; /* # */
23
+ export const CHAR_SPACE = 32; /* */
24
+ export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */
25
+ export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */
26
+ export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */
27
+ export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */
28
+ export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */
29
+ export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */
30
+ export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */
31
+ export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */
32
+ export const CHAR_HYPHEN_MINUS = 45; /* - */
33
+ export const CHAR_PLUS = 43; /* + */
34
+ export const CHAR_DOUBLE_QUOTE = 34; /* " */
35
+ export const CHAR_SINGLE_QUOTE = 39; /* ' */
36
+ export const CHAR_PERCENT = 37; /* % */
37
+ export const CHAR_SEMICOLON = 59; /* ; */
38
+ export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */
39
+ export const CHAR_GRAVE_ACCENT = 96; /* ` */
40
+ export const CHAR_AT = 64; /* @ */
41
+ export const CHAR_AMPERSAND = 38; /* & */
42
+ export const CHAR_EQUAL = 61; /* = */
43
+ // Digits
44
+ export const CHAR_0 = 48; /* 0 */
45
+ export const CHAR_9 = 57; /* 9 */
@@ -0,0 +1,3 @@
1
+ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+ export {};
@@ -0,0 +1,114 @@
1
+ // Copyright the Browserify authors. MIT License.
2
+ // Ported from https://github.com/browserify/path-browserify/
3
+ // This module is browser compatible.
4
+ import { CHAR_BACKWARD_SLASH, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, CHAR_UPPERCASE_A, CHAR_UPPERCASE_Z, } from "./_constants.js";
5
+ export function assertPath(path) {
6
+ if (typeof path !== "string") {
7
+ throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`);
8
+ }
9
+ }
10
+ export function isPosixPathSeparator(code) {
11
+ return code === CHAR_FORWARD_SLASH;
12
+ }
13
+ export function isPathSeparator(code) {
14
+ return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH;
15
+ }
16
+ export function isWindowsDeviceRoot(code) {
17
+ return ((code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) ||
18
+ (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z));
19
+ }
20
+ // Resolves . and .. elements in a path with directory names
21
+ export function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
22
+ let res = "";
23
+ let lastSegmentLength = 0;
24
+ let lastSlash = -1;
25
+ let dots = 0;
26
+ let code;
27
+ for (let i = 0, len = path.length; i <= len; ++i) {
28
+ if (i < len)
29
+ code = path.charCodeAt(i);
30
+ else if (isPathSeparator(code))
31
+ break;
32
+ else
33
+ code = CHAR_FORWARD_SLASH;
34
+ if (isPathSeparator(code)) {
35
+ if (lastSlash === i - 1 || dots === 1) {
36
+ // NOOP
37
+ }
38
+ else if (lastSlash !== i - 1 && dots === 2) {
39
+ if (res.length < 2 ||
40
+ lastSegmentLength !== 2 ||
41
+ res.charCodeAt(res.length - 1) !== CHAR_DOT ||
42
+ res.charCodeAt(res.length - 2) !== CHAR_DOT) {
43
+ if (res.length > 2) {
44
+ const lastSlashIndex = res.lastIndexOf(separator);
45
+ if (lastSlashIndex === -1) {
46
+ res = "";
47
+ lastSegmentLength = 0;
48
+ }
49
+ else {
50
+ res = res.slice(0, lastSlashIndex);
51
+ lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
52
+ }
53
+ lastSlash = i;
54
+ dots = 0;
55
+ continue;
56
+ }
57
+ else if (res.length === 2 || res.length === 1) {
58
+ res = "";
59
+ lastSegmentLength = 0;
60
+ lastSlash = i;
61
+ dots = 0;
62
+ continue;
63
+ }
64
+ }
65
+ if (allowAboveRoot) {
66
+ if (res.length > 0)
67
+ res += `${separator}..`;
68
+ else
69
+ res = "..";
70
+ lastSegmentLength = 2;
71
+ }
72
+ }
73
+ else {
74
+ if (res.length > 0)
75
+ res += separator + path.slice(lastSlash + 1, i);
76
+ else
77
+ res = path.slice(lastSlash + 1, i);
78
+ lastSegmentLength = i - lastSlash - 1;
79
+ }
80
+ lastSlash = i;
81
+ dots = 0;
82
+ }
83
+ else if (code === CHAR_DOT && dots !== -1) {
84
+ ++dots;
85
+ }
86
+ else {
87
+ dots = -1;
88
+ }
89
+ }
90
+ return res;
91
+ }
92
+ export function _format(sep, pathObject) {
93
+ const dir = pathObject.dir || pathObject.root;
94
+ const base = pathObject.base ||
95
+ (pathObject.name || "") + (pathObject.ext || "");
96
+ if (!dir)
97
+ return base;
98
+ if (dir === pathObject.root)
99
+ return dir + base;
100
+ return dir + sep + base;
101
+ }
102
+ const WHITESPACE_ENCODINGS = {
103
+ "\u0009": "%09",
104
+ "\u000A": "%0A",
105
+ "\u000B": "%0B",
106
+ "\u000C": "%0C",
107
+ "\u000D": "%0D",
108
+ "\u0020": "%20",
109
+ };
110
+ export function encodeWhitespace(string) {
111
+ return string.replaceAll(/[\s]/g, (c) => {
112
+ return WHITESPACE_ENCODINGS[c] ?? c;
113
+ });
114
+ }
@@ -0,0 +1,36 @@
1
+ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+ import { SEP } from "./separator.js";
4
+ /** Determines the common path from a set of paths, using an optional separator,
5
+ * which defaults to the OS default separator.
6
+ *
7
+ * ```ts
8
+ * import { common } from "https://deno.land/std@$STD_VERSION/path/mod.ts";
9
+ * const p = common([
10
+ * "./deno/std/path/mod.ts",
11
+ * "./deno/std/fs/mod.ts",
12
+ * ]);
13
+ * console.log(p); // "./deno/std/"
14
+ * ```
15
+ */
16
+ export function common(paths, sep = SEP) {
17
+ const [first = "", ...remaining] = paths;
18
+ if (first === "" || remaining.length === 0) {
19
+ return first.substring(0, first.lastIndexOf(sep) + 1);
20
+ }
21
+ const parts = first.split(sep);
22
+ let endOfPrefix = parts.length;
23
+ for (const path of remaining) {
24
+ const compare = path.split(sep);
25
+ for (let i = 0; i < endOfPrefix; i++) {
26
+ if (compare[i] !== parts[i]) {
27
+ endOfPrefix = i;
28
+ }
29
+ }
30
+ if (endOfPrefix === 0) {
31
+ return "";
32
+ }
33
+ }
34
+ const prefix = parts.slice(0, endOfPrefix).join(sep);
35
+ return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
36
+ }