git-stack-cli 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/AutoUpdate.js +4 -29
- package/dist/app/DependencyCheck.js +42 -27
- package/dist/app/MultiSelect.js +4 -0
- package/dist/app/SelectCommitRanges.js +1 -5
- package/dist/app/StatusTable.js +58 -60
- package/dist/app/Table.js +63 -0
- package/dist/app/Url.js +1 -1
- package/dist/core/fetch_json.js +24 -0
- package/dist/core/invariant copy.js +5 -0
- package/dist/core/isFiniteValue.js +3 -0
- package/dist/core/is_finite_value.js +3 -0
- package/dist/core/semver_compare.js +26 -0
- package/package.json +1 -1
package/dist/app/AutoUpdate.js
CHANGED
|
@@ -3,7 +3,9 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import * as Ink from "ink";
|
|
5
5
|
import { cli } from "../core/cli.js";
|
|
6
|
+
import { fetch_json } from "../core/fetch_json.js";
|
|
6
7
|
import { read_json } from "../core/read_json.js";
|
|
8
|
+
import { semver_compare } from "../core/semver_compare.js";
|
|
7
9
|
import { sleep } from "../core/sleep.js";
|
|
8
10
|
import { Brackets } from "./Brackets.js";
|
|
9
11
|
import { FormatText } from "./FormatText.js";
|
|
@@ -41,13 +43,12 @@ export function AutoUpdate(props) {
|
|
|
41
43
|
handle_output(React.createElement(Ink.Text, { key: "init", dimColor: true }, "Checking for latest version..."));
|
|
42
44
|
}
|
|
43
45
|
const timeout_ms = 2 * 1000;
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
+
const npm_json = await Promise.race([
|
|
47
|
+
fetch_json(`https://registry.npmjs.org/${props.name}`),
|
|
46
48
|
sleep(timeout_ms).then(() => {
|
|
47
49
|
throw new Error("timeout");
|
|
48
50
|
}),
|
|
49
51
|
]);
|
|
50
|
-
const npm_json = await npm_res.json();
|
|
51
52
|
latest_version = npm_json?.["dist-tags"]?.latest;
|
|
52
53
|
if (!latest_version) {
|
|
53
54
|
throw new Error("unable to retrieve latest version from npm");
|
|
@@ -119,29 +120,3 @@ export function AutoUpdate(props) {
|
|
|
119
120
|
output,
|
|
120
121
|
status));
|
|
121
122
|
}
|
|
122
|
-
// returns +1 if version_a is greater than version_b
|
|
123
|
-
// returns -1 if version_a is less than version_b
|
|
124
|
-
// returns +0 if version_a is exactly equal to version_b
|
|
125
|
-
//
|
|
126
|
-
// Examples
|
|
127
|
-
//
|
|
128
|
-
// semver_compare("0.1.1", "0.0.2"); // 1
|
|
129
|
-
// semver_compare("1.0.1", "0.0.2"); // 1
|
|
130
|
-
// semver_compare("0.0.1", "1.0.2"); // -1
|
|
131
|
-
// semver_compare("0.0.1", "0.1.2"); // -1
|
|
132
|
-
// semver_compare("1.0.1", "1.0.1"); // 0
|
|
133
|
-
//
|
|
134
|
-
function semver_compare(version_a, version_b) {
|
|
135
|
-
const split_a = version_a.split(".").map(Number);
|
|
136
|
-
const split_b = version_b.split(".").map(Number);
|
|
137
|
-
const max_split_parts = Math.max(split_a.length, split_b.length);
|
|
138
|
-
for (let i = 0; i < max_split_parts; i++) {
|
|
139
|
-
const num_a = split_a[i] || 0;
|
|
140
|
-
const num_b = split_b[i] || 0;
|
|
141
|
-
if (num_a > num_b)
|
|
142
|
-
return 1;
|
|
143
|
-
if (num_a < num_b)
|
|
144
|
-
return -1;
|
|
145
|
-
}
|
|
146
|
-
return 0;
|
|
147
|
-
}
|
|
@@ -3,6 +3,7 @@ import * as Ink from "ink";
|
|
|
3
3
|
import { cli } from "../core/cli.js";
|
|
4
4
|
import { is_command_available } from "../core/is_command_available.js";
|
|
5
5
|
import { match_group } from "../core/match_group.js";
|
|
6
|
+
import { semver_compare } from "../core/semver_compare.js";
|
|
6
7
|
import { Await } from "./Await.js";
|
|
7
8
|
import { Command } from "./Command.js";
|
|
8
9
|
import { Parens } from "./Parens.js";
|
|
@@ -23,45 +24,59 @@ export function DependencyCheck(props) {
|
|
|
23
24
|
actions.exit(2);
|
|
24
25
|
} },
|
|
25
26
|
React.createElement(Await, { fallback: React.createElement(Ink.Text, { color: "yellow" },
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
"Checking ",
|
|
28
|
+
React.createElement(Command, null, "node"),
|
|
29
|
+
" install..."), function: async () => {
|
|
30
|
+
const process_version = process.version.substring(1);
|
|
31
|
+
const semver_result = semver_compare(process_version, "14.0.0");
|
|
32
|
+
if (semver_result >= 0) {
|
|
31
33
|
return;
|
|
32
34
|
}
|
|
33
35
|
actions.output(React.createElement(Ink.Text, { color: "yellow" },
|
|
34
|
-
React.createElement(Command, null, "
|
|
36
|
+
React.createElement(Command, null, "node"),
|
|
35
37
|
" must be installed."));
|
|
36
|
-
actions.
|
|
37
|
-
React.createElement(Ink.Text, null, "Visit "),
|
|
38
|
-
React.createElement(Url, null, "https://cli.github.com"),
|
|
39
|
-
React.createElement(Ink.Text, null, " to install the github cli "),
|
|
40
|
-
React.createElement(Parens, null,
|
|
41
|
-
React.createElement(Command, null, "gh"))));
|
|
42
|
-
actions.exit(3);
|
|
38
|
+
actions.exit(2);
|
|
43
39
|
} },
|
|
44
40
|
React.createElement(Await, { fallback: React.createElement(Ink.Text, { color: "yellow" },
|
|
45
41
|
React.createElement(Ink.Text, null,
|
|
46
42
|
"Checking ",
|
|
47
|
-
React.createElement(Command, null, "gh
|
|
48
|
-
"...")), function: async () => {
|
|
49
|
-
|
|
50
|
-
ignoreExitCode: true,
|
|
51
|
-
});
|
|
52
|
-
if (auth_output.code === 0) {
|
|
53
|
-
const username = match_group(auth_output.stdout, RE.auth_username, "username");
|
|
54
|
-
actions.set((state) => {
|
|
55
|
-
state.username = username;
|
|
56
|
-
});
|
|
43
|
+
React.createElement(Command, null, "gh"),
|
|
44
|
+
" install...")), function: async () => {
|
|
45
|
+
if (is_command_available("gh")) {
|
|
57
46
|
return;
|
|
58
47
|
}
|
|
59
48
|
actions.output(React.createElement(Ink.Text, { color: "yellow" },
|
|
60
49
|
React.createElement(Command, null, "gh"),
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
" must be installed."));
|
|
51
|
+
actions.output(React.createElement(Ink.Text, { color: "yellow" },
|
|
52
|
+
React.createElement(Ink.Text, null, "Visit "),
|
|
53
|
+
React.createElement(Url, null, "https://cli.github.com"),
|
|
54
|
+
React.createElement(Ink.Text, null, " to install the github cli "),
|
|
55
|
+
React.createElement(Parens, null,
|
|
56
|
+
React.createElement(Command, null, "gh"))));
|
|
57
|
+
actions.exit(3);
|
|
58
|
+
} },
|
|
59
|
+
React.createElement(Await, { fallback: React.createElement(Ink.Text, { color: "yellow" },
|
|
60
|
+
React.createElement(Ink.Text, null,
|
|
61
|
+
"Checking ",
|
|
62
|
+
React.createElement(Command, null, "gh auth status"),
|
|
63
|
+
"...")), function: async () => {
|
|
64
|
+
const auth_status = await cli(`gh auth status`, {
|
|
65
|
+
ignoreExitCode: true,
|
|
66
|
+
});
|
|
67
|
+
if (auth_status.code === 0) {
|
|
68
|
+
const username = match_group(auth_status.stdout, RE.auth_username, "username");
|
|
69
|
+
actions.set((state) => {
|
|
70
|
+
state.username = username;
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
actions.output(React.createElement(Ink.Text, { color: "yellow" },
|
|
75
|
+
React.createElement(Command, null, "gh"),
|
|
76
|
+
React.createElement(Ink.Text, null, " requires login, please run "),
|
|
77
|
+
React.createElement(Command, null, "gh auth login")));
|
|
78
|
+
actions.exit(4);
|
|
79
|
+
} }, props.children)))));
|
|
65
80
|
}
|
|
66
81
|
const RE = {
|
|
67
82
|
// Logged in to github.com as magus
|
package/dist/app/MultiSelect.js
CHANGED
|
@@ -53,6 +53,10 @@ export function MultiSelect(props) {
|
|
|
53
53
|
props.onSelect({ item, selected, state });
|
|
54
54
|
}, [selected_set]);
|
|
55
55
|
Ink.useInput((_input, key) => {
|
|
56
|
+
if (props.disabled) {
|
|
57
|
+
// console.debug("[MultiSelect] disabled, ignoring input");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
56
60
|
if (key.return) {
|
|
57
61
|
selectRef.current = true;
|
|
58
62
|
const item = props.items[index];
|
|
@@ -135,12 +135,8 @@ function SelectCommitRangesInternal(props) {
|
|
|
135
135
|
max_item_width -= left_arrow.length + right_arrow.length;
|
|
136
136
|
return (React.createElement(Ink.Box, { flexDirection: "column" },
|
|
137
137
|
React.createElement(Ink.Box, { height: 1 }),
|
|
138
|
-
React.createElement(MultiSelect, { key: group.id, items: items, maxWidth: max_item_width, onSelect: (args) => {
|
|
138
|
+
React.createElement(MultiSelect, { key: group.id, items: items, maxWidth: max_item_width, disabled: group_input, onSelect: (args) => {
|
|
139
139
|
// console.debug("onSelect", args);
|
|
140
|
-
if (group_input) {
|
|
141
|
-
// console.debug("group_input is true, ignoring onSelect");
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
140
|
const key = args.item.sha;
|
|
145
141
|
let value;
|
|
146
142
|
if (args.selected) {
|
package/dist/app/StatusTable.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as Ink from "ink";
|
|
3
|
+
import { assertNever } from "../core/assertNever.js";
|
|
3
4
|
import { invariant } from "../core/invariant.js";
|
|
4
5
|
import { Store } from "./Store.js";
|
|
6
|
+
import { Table } from "./Table.js";
|
|
7
|
+
import { Url } from "./Url.js";
|
|
5
8
|
export function StatusTable() {
|
|
6
9
|
const commit_range = Store.useState((state) => state.commit_range);
|
|
7
10
|
invariant(commit_range, "commit_range must exist");
|
|
@@ -10,10 +13,9 @@ export function StatusTable() {
|
|
|
10
13
|
const row = {
|
|
11
14
|
icon: "",
|
|
12
15
|
count: "",
|
|
13
|
-
status: "",
|
|
16
|
+
status: "NEW",
|
|
14
17
|
title: "",
|
|
15
18
|
url: "",
|
|
16
|
-
id: group.id,
|
|
17
19
|
};
|
|
18
20
|
if (group.id === commit_range.UNASSIGNED) {
|
|
19
21
|
row.icon = "⭑";
|
|
@@ -41,69 +43,65 @@ export function StatusTable() {
|
|
|
41
43
|
row.url = group.pr.url;
|
|
42
44
|
}
|
|
43
45
|
else {
|
|
44
|
-
row.title = group.id;
|
|
46
|
+
row.title = group.title || group.id;
|
|
45
47
|
row.count = `0/${group.commits.length}`;
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
row_list.push(row);
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
return (React.createElement(Table, { data: row_list, fillColumn: "title",
|
|
53
|
+
// maxWidth={{
|
|
54
|
+
// title: 30,
|
|
55
|
+
// }}
|
|
56
|
+
columnGap: 3, columns: {
|
|
57
|
+
icon: IconColumn,
|
|
58
|
+
status: StatusColumn,
|
|
59
|
+
count: CountColumn,
|
|
60
|
+
title: TitleColumn,
|
|
61
|
+
url: UrlColumn,
|
|
62
|
+
} }));
|
|
63
|
+
}
|
|
64
|
+
function IconColumn(props) {
|
|
65
|
+
const value = props.row[props.column];
|
|
66
|
+
return (React.createElement(Ink.Text, { color: get_status_color(props.row), bold: get_status_bold(props.row) }, value));
|
|
67
|
+
}
|
|
68
|
+
function StatusColumn(props) {
|
|
69
|
+
const value = props.row[props.column];
|
|
70
|
+
return (React.createElement(Ink.Text, { color: get_status_color(props.row), bold: get_status_bold(props.row) }, value));
|
|
71
|
+
}
|
|
72
|
+
function CountColumn(props) {
|
|
73
|
+
const value = props.row[props.column];
|
|
74
|
+
return React.createElement(Ink.Text, { dimColor: true }, value);
|
|
75
|
+
}
|
|
76
|
+
function TitleColumn(props) {
|
|
77
|
+
const value = props.row[props.column];
|
|
78
|
+
return React.createElement(Ink.Text, { wrap: "truncate-end" }, value);
|
|
79
|
+
}
|
|
80
|
+
function UrlColumn(props) {
|
|
81
|
+
const value = props.row[props.column];
|
|
82
|
+
return React.createElement(Url, { dimColor: true }, value);
|
|
83
|
+
}
|
|
84
|
+
function get_status_color(row) {
|
|
85
|
+
switch (row.status) {
|
|
86
|
+
case "NEW":
|
|
87
|
+
return "yellow";
|
|
88
|
+
case "OUTDATED":
|
|
89
|
+
return "red";
|
|
90
|
+
case "MERGED":
|
|
91
|
+
return "purple";
|
|
92
|
+
case "SYNCED":
|
|
93
|
+
return "green";
|
|
94
|
+
default:
|
|
95
|
+
assertNever(row.status);
|
|
96
|
+
return "gray";
|
|
66
97
|
}
|
|
67
|
-
const { stdout } = Ink.useStdout();
|
|
68
|
-
const available_width = stdout.columns;
|
|
69
|
-
const columnGap = 2;
|
|
70
|
-
const breathing_room = 0;
|
|
71
|
-
const remaining_space = available_width -
|
|
72
|
-
// icon
|
|
73
|
-
max_col_width.icon -
|
|
74
|
-
// status
|
|
75
|
-
max_col_width.status -
|
|
76
|
-
// commits
|
|
77
|
-
max_col_width.count -
|
|
78
|
-
// url
|
|
79
|
-
max_col_width.url -
|
|
80
|
-
// gap * col count (minus one for row.id which is not shown but used at key)
|
|
81
|
-
columnGap * (col_list.length - 1) -
|
|
82
|
-
// remove some extra space
|
|
83
|
-
breathing_room;
|
|
84
|
-
// add one for ellipsis character
|
|
85
|
-
const title_width = Math.min(max_col_width.title, remaining_space + 1);
|
|
86
|
-
// prettier-ignore
|
|
87
|
-
// console.debug({ available_width, remaining_space, title_width, max_col_width });
|
|
88
|
-
return (React.createElement(Container, null, row_list.map((row) => {
|
|
89
|
-
return (React.createElement(Ink.Box, { key: row.id,
|
|
90
|
-
// borderStyle="round"
|
|
91
|
-
flexDirection: "row", columnGap: columnGap, width: available_width },
|
|
92
|
-
React.createElement(Ink.Box, { width: max_col_width.icon },
|
|
93
|
-
React.createElement(Ink.Text, null, row.icon)),
|
|
94
|
-
React.createElement(Ink.Box, { width: max_col_width.status },
|
|
95
|
-
React.createElement(Ink.Text, null, row.status)),
|
|
96
|
-
React.createElement(Ink.Box, { width: max_col_width.count },
|
|
97
|
-
React.createElement(Ink.Text, null, row.count)),
|
|
98
|
-
React.createElement(Ink.Box, { width: title_width },
|
|
99
|
-
React.createElement(Ink.Text, { wrap: "truncate-end" }, row.title)),
|
|
100
|
-
React.createElement(Ink.Box, { width: max_col_width.url },
|
|
101
|
-
React.createElement(Ink.Text, null, row.url))));
|
|
102
|
-
})));
|
|
103
98
|
}
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
function get_status_bold(row) {
|
|
100
|
+
switch (row.status) {
|
|
101
|
+
case "NEW":
|
|
102
|
+
case "OUTDATED":
|
|
103
|
+
return true;
|
|
104
|
+
default:
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
109
107
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as Ink from "ink";
|
|
3
|
+
import { is_finite_value } from "../core/is_finite_value.js";
|
|
4
|
+
export function Table(props) {
|
|
5
|
+
if (!props.data.length) {
|
|
6
|
+
return (React.createElement(Container, null,
|
|
7
|
+
React.createElement(Ink.Text, { dimColor: true }, "No data found.")));
|
|
8
|
+
}
|
|
9
|
+
const sample_row = props.data[0];
|
|
10
|
+
const RowColumnList = Object.keys(sample_row);
|
|
11
|
+
// walk data and discover max width for each column
|
|
12
|
+
const max_col_width = {};
|
|
13
|
+
for (const col of RowColumnList) {
|
|
14
|
+
max_col_width[col] = 0;
|
|
15
|
+
}
|
|
16
|
+
for (const row of props.data) {
|
|
17
|
+
for (const col of RowColumnList) {
|
|
18
|
+
const row_col = row[col];
|
|
19
|
+
max_col_width[col] = Math.max(String(row_col).length, max_col_width[col]);
|
|
20
|
+
const maxWidth = props.maxWidth?.[col];
|
|
21
|
+
if (is_finite_value(maxWidth)) {
|
|
22
|
+
max_col_width[col] = Math.min(maxWidth - 1, max_col_width[col]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const { stdout } = Ink.useStdout();
|
|
27
|
+
const available_width = stdout.columns;
|
|
28
|
+
const columnGap = is_finite_value(props.columnGap) ? props.columnGap : 2;
|
|
29
|
+
const breathing_room = 0;
|
|
30
|
+
if (props.fillColumn) {
|
|
31
|
+
let remaining_space = available_width;
|
|
32
|
+
for (const col of RowColumnList) {
|
|
33
|
+
// skip fill column from calculation
|
|
34
|
+
if (props.fillColumn === col) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
remaining_space -= max_col_width[col];
|
|
38
|
+
}
|
|
39
|
+
// gap * col count
|
|
40
|
+
remaining_space -= columnGap * (RowColumnList.length - 1);
|
|
41
|
+
// remove some extra space
|
|
42
|
+
remaining_space -= breathing_room;
|
|
43
|
+
if (props.fillColumn) {
|
|
44
|
+
max_col_width[props.fillColumn] = Math.min(max_col_width[props.fillColumn], remaining_space);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// console.debug({ available_width, remaining_space, max_col_width });
|
|
48
|
+
return (React.createElement(Container, null, props.data.map((row, i) => {
|
|
49
|
+
return (React.createElement(Ink.Box, { key: i,
|
|
50
|
+
// borderStyle="round"
|
|
51
|
+
flexDirection: "row", columnGap: columnGap, width: available_width }, RowColumnList.map((column) => {
|
|
52
|
+
const ColumnComponent = props.columns[column];
|
|
53
|
+
return (React.createElement(Ink.Box, { key: String(column), width: max_col_width[column] },
|
|
54
|
+
React.createElement(ColumnComponent, { row: row, column: column })));
|
|
55
|
+
})));
|
|
56
|
+
})));
|
|
57
|
+
}
|
|
58
|
+
function Container(props) {
|
|
59
|
+
return (React.createElement(Ink.Box, { flexDirection: "column" },
|
|
60
|
+
React.createElement(Ink.Box, { height: 1 }),
|
|
61
|
+
props.children,
|
|
62
|
+
React.createElement(Ink.Box, { height: 1 })));
|
|
63
|
+
}
|
package/dist/app/Url.js
CHANGED
|
@@ -2,5 +2,5 @@ import * as React from "react";
|
|
|
2
2
|
import * as Ink from "ink";
|
|
3
3
|
export function Url(props) {
|
|
4
4
|
const text_color = "#38bdf8";
|
|
5
|
-
return (React.createElement(Ink.Text, { bold: true, color: text_color }, props.children));
|
|
5
|
+
return (React.createElement(Ink.Text, { bold: true, color: text_color, ...props }, props.children));
|
|
6
6
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import https from "node:https";
|
|
2
|
+
export async function fetch_json(url) {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
https
|
|
5
|
+
.get(url, (res) => {
|
|
6
|
+
let data = "";
|
|
7
|
+
res.on("data", (chunk) => {
|
|
8
|
+
data += chunk;
|
|
9
|
+
});
|
|
10
|
+
res.on("end", () => {
|
|
11
|
+
try {
|
|
12
|
+
const json = JSON.parse(data);
|
|
13
|
+
resolve(json);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
reject(error);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
})
|
|
20
|
+
.on("error", (error) => {
|
|
21
|
+
reject(error);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// returns +1 if version_a is greater than version_b
|
|
2
|
+
// returns -1 if version_a is less than version_b
|
|
3
|
+
// returns +0 if version_a is exactly equal to version_b
|
|
4
|
+
//
|
|
5
|
+
// Examples
|
|
6
|
+
//
|
|
7
|
+
// semver_compare("0.1.1", "0.0.2"); // 1
|
|
8
|
+
// semver_compare("1.0.1", "0.0.2"); // 1
|
|
9
|
+
// semver_compare("0.0.1", "1.0.2"); // -1
|
|
10
|
+
// semver_compare("0.0.1", "0.1.2"); // -1
|
|
11
|
+
// semver_compare("1.0.1", "1.0.1"); // 0
|
|
12
|
+
//
|
|
13
|
+
export function semver_compare(version_a, version_b) {
|
|
14
|
+
const split_a = version_a.split(".").map(Number);
|
|
15
|
+
const split_b = version_b.split(".").map(Number);
|
|
16
|
+
const max_split_parts = Math.max(split_a.length, split_b.length);
|
|
17
|
+
for (let i = 0; i < max_split_parts; i++) {
|
|
18
|
+
const num_a = split_a[i] || 0;
|
|
19
|
+
const num_b = split_b[i] || 0;
|
|
20
|
+
if (num_a > num_b)
|
|
21
|
+
return 1;
|
|
22
|
+
if (num_a < num_b)
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
26
|
+
}
|