Skip to content

Commit d1c9277

Browse files
Merge pull request #28 from rhamilto/upgrade-to-pf6
CONSOLE-4444: Upgrade console-crontab-plugin to PatternFly 6
2 parents 78615fb + 278720f commit d1c9277

6 files changed

Lines changed: 111 additions & 106 deletions

File tree

.vscode/settings.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,29 @@
33
"[javascript]": {
44
"editor.formatOnSave": true,
55
"editor.codeActionsOnSave": {
6-
"source.organizeImports": false,
7-
"source.sortImports": false
6+
"source.organizeImports": "never",
7+
"source.sortImports": "never"
88
}
99
},
1010
"[javascriptreact]": {
1111
"editor.formatOnSave": true,
1212
"editor.codeActionsOnSave": {
13-
"source.organizeImports": false,
14-
"source.sortImports": false
13+
"source.organizeImports": "never",
14+
"source.sortImports": "never"
1515
}
1616
},
1717
"[typescript]": {
1818
"editor.formatOnSave": true,
1919
"editor.codeActionsOnSave": {
20-
"source.organizeImports": false,
21-
"source.sortImports": false
20+
"source.organizeImports": "never",
21+
"source.sortImports": "never"
2222
}
2323
},
2424
"[typescriptreact]": {
2525
"editor.formatOnSave": true,
2626
"editor.codeActionsOnSave": {
27-
"source.organizeImports": false,
28-
"source.sortImports": false
27+
"source.organizeImports": "never",
28+
"source.sortImports": "never"
2929
}
3030
},
3131
"[json]": {

integration-tests/support/login.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ declare global {
1010
}
1111

1212
const KUBEADMIN_USERNAME = "kubeadmin";
13-
const loginUsername = Cypress.env("BRIDGE_KUBEADMIN_PASSWORD")
14-
? "user-dropdown"
15-
: "username";
1613

1714
// This will add 'cy.login(...)'
1815
// ex: cy.login('my-user', 'my-password')
@@ -33,7 +30,7 @@ Cypress.Commands.add("login", (username: string, password: string) => {
3330
);
3431
cy.get("button[type=submit]").click();
3532

36-
cy.get(`[data-test="${loginUsername}"]`).should("be.visible");
33+
cy.get("[data-test='username']").should("be.visible");
3734
});
3835
});
3936

@@ -43,7 +40,7 @@ Cypress.Commands.add("logout", () => {
4340
if (win.SERVER_FLAGS?.authDisabled) {
4441
return;
4542
}
46-
cy.get('[data-test="user-dropdown"]').click();
43+
cy.get('[data-test="user-dropdown-toggle"]').click();
4744
cy.get('[data-test="log-out"]').should("be.visible");
4845
cy.get('[data-test="log-out"]').click({ force: true });
4946
});

locales/en/plugin__console-crontab-plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"Actions": "Actions",
23
"Create CronTab": "Create CronTab",
34
"Created": "Created",
45
"CronSpec": "CronSpec",
@@ -11,4 +12,4 @@
1112
"Name": "Name",
1213
"Namespace": "Namespace",
1314
"Replicas": "Replicas"
14-
}
15+
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
"@cypress/webpack-preprocessor": "^6.0.0",
2222
"@openshift-console/dynamic-plugin-sdk": "^1.0.0",
2323
"@openshift-console/dynamic-plugin-sdk-webpack": "^1.0.0",
24-
"@patternfly/react-core": "^5.1.1",
25-
"@patternfly/react-table": "^5.1.1",
24+
"@patternfly/react-core": "^6.2.0-prerelease.15",
25+
"@patternfly/react-icons": "^6.2.0-prerelease.2",
26+
"@patternfly/react-table": "^6.2.0-prerelease.16",
2627
"@types/node": "^16.11.6",
2728
"@types/react": "^17.0.34",
2829
"@types/react-helmet": "^6.1.4",

src/views/CronTabList/CronTabList.tsx

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ import {
2424
} from "@openshift-console/dynamic-plugin-sdk";
2525
import { sortable } from "@patternfly/react-table";
2626
import {
27-
Dropdown as DropdownDeprecated,
28-
DropdownPosition as DropdownPositionDeprecated,
29-
KebabToggle as KebabToggleDeprecated,
30-
DropdownItem as DropdownItemDeprecated,
31-
} from "@patternfly/react-core/deprecated";
27+
Dropdown,
28+
DropdownItem,
29+
DropdownList,
30+
MenuToggle,
31+
MenuToggleElement,
32+
} from "@patternfly/react-core";
33+
import { EllipsisVIcon } from "@patternfly/react-icons";
3234
import { useHistory } from "react-router-dom";
3335
import { cronTabGroupVersionKind } from "src/utils/utils";
3436
import { CRONTAB_KIND_PLURAL } from "src/const";
@@ -115,10 +117,6 @@ const CronTabKebab: React.FC<CronTabKebabProps> = ({ obj }) => {
115117
});
116118
const history = useHistory();
117119

118-
const onToggle = (isOpen: boolean) => {
119-
setIsOpen(isOpen);
120-
};
121-
122120
const onFocus = () => {
123121
const element = document.getElementById("kebab-button");
124122
element.focus();
@@ -134,59 +132,62 @@ const CronTabKebab: React.FC<CronTabKebabProps> = ({ obj }) => {
134132
}~${cronTabGroupVersionKind.kind}/${encodeURIComponent(name)}/yaml`;
135133

136134
const dropdownItems = [
137-
<DropdownItemDeprecated
135+
<DropdownItem
138136
key={KEBAB_ACTION_EDIT_LABELS_ID}
139-
component="button"
140137
onClick={launchLabelsModal}
141138
isDisabled={!canEditCronTab}
142139
data-test-action={KEBAB_ACTION_EDIT_LABELS_ID}
143140
>
144141
{t("Edit labels")}
145-
</DropdownItemDeprecated>,
146-
<DropdownItemDeprecated
142+
</DropdownItem>,
143+
<DropdownItem
147144
key={KEBAB_ACTION_EDIT_ANNOTATIONS_ID}
148-
component="button"
149145
onClick={() => launchAnnotationsModal()}
150146
isDisabled={!canEditCronTab[0]}
151147
data-test-action={KEBAB_ACTION_EDIT_ANNOTATIONS_ID}
152148
>
153149
{t("Edit annotations")}
154-
</DropdownItemDeprecated>,
155-
<DropdownItemDeprecated
150+
</DropdownItem>,
151+
<DropdownItem
156152
key={KEBAB_ACTION_EDIT_ID}
157-
component="button"
158153
onClick={() => history.push(editURL)}
159154
isDisabled={!canEditCronTab[0]}
160155
data-test-action={KEBAB_ACTION_EDIT_ID}
161156
>
162157
{t("Edit CronTab")}
163-
</DropdownItemDeprecated>,
164-
<DropdownItemDeprecated
158+
</DropdownItem>,
159+
<DropdownItem
165160
key={KEBAB_ACTION_DELETE_ID}
166-
component="button"
167161
onClick={launchDeleteModal}
168162
isDisabled={!canDeleteCronTab[0]}
169163
data-test-action={KEBAB_ACTION_DELETE_ID}
170164
>
171165
{t("Delete CronTab")}
172-
</DropdownItemDeprecated>,
166+
</DropdownItem>,
173167
];
174168

175169
return (
176-
<DropdownDeprecated
170+
<Dropdown
171+
isOpen={isOpen}
177172
onSelect={onSelect}
178-
toggle={
179-
<KebabToggleDeprecated
173+
onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)}
174+
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
175+
<MenuToggle
176+
ref={toggleRef}
177+
aria-label={t("Actions")}
178+
variant="plain"
179+
onClick={() => setIsOpen(!isOpen)}
180+
isExpanded={isOpen}
181+
icon={<EllipsisVIcon />}
180182
id={KEBAB_BUTTON_ID}
181183
data-test={KEBAB_BUTTON_ID}
182-
onToggle={(e, isOpen) => onToggle(isOpen)}
183184
/>
184-
}
185-
isOpen={isOpen}
186-
isPlain
187-
dropdownItems={dropdownItems}
188-
position={DropdownPositionDeprecated.right}
189-
/>
185+
)}
186+
popperProps={{ position: "right" }}
187+
shouldFocusToggleOnSelect
188+
>
189+
<DropdownList>{dropdownItems}</DropdownList>
190+
</Dropdown>
190191
);
191192
};
192193

@@ -197,7 +198,7 @@ const tableColumnInfo = [
197198
{ id: "image" },
198199
{ id: "replicas" },
199200
{ id: "created" },
200-
{ className: "pf-v5-c-table__action", id: "" },
201+
{ className: "pf-v6-c-table__action", id: "" },
201202
];
202203

203204
const cronTabListRow: React.FC<RowProps<CronTabKind>> = ({

yarn.lock

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -313,44 +313,44 @@
313313
semver "^7.3.7"
314314
yup "^0.32.11"
315315

316-
"@patternfly/react-core@^5.1.1", "@patternfly/react-core@^5.2.0":
317-
version "5.2.0"
318-
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-5.2.0.tgz#85abcce50e5e6aa08c5f4a377422374b987faf40"
319-
integrity sha512-AUd7jccCgE2ZRwVtpEbJNF2Sq1A//ZhRaEQ/QHZiiq8mQRQM0Bkpnx0HdefToZT+TgUIjmPW4AXO3ooRJmt26w==
320-
dependencies:
321-
"@patternfly/react-icons" "^5.2.0"
322-
"@patternfly/react-styles" "^5.2.0"
323-
"@patternfly/react-tokens" "^5.2.0"
324-
focus-trap "7.5.2"
325-
react-dropzone "^14.2.3"
326-
tslib "^2.5.0"
327-
328-
"@patternfly/react-icons@^5.2.0":
329-
version "5.2.0"
330-
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-5.2.0.tgz#65080fdbf5b4ea375f59f5ff64dc981372db006c"
331-
integrity sha512-vklAF2unvtK0trwx9Kk8nf4Xa2+nie4zxaIaQdnjIL7kX6a5SdsewDjlavOC3cRxnibZLQ5HQtpDZ4EmuXm8DQ==
332-
333-
"@patternfly/react-styles@^5.2.0":
334-
version "5.2.0"
335-
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-5.2.0.tgz#5e2ffd1270f252844acddb1b45b4e70fefbc72c6"
336-
integrity sha512-u8in9RSU8YzcT0npgVeiIHi1Bdp7UdER9azWGi7vlJWooRI1hgQjIDpm22wopGFg0h8VOqhfIFWIyvqxuzhW6A==
337-
338-
"@patternfly/react-table@^5.1.1":
339-
version "5.2.0"
340-
resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-5.2.0.tgz#b2fdaa5ca4ed647503e4eae71165a16823f802de"
341-
integrity sha512-Pd+llSuAU9i1dvteQL1keEXmsQv6d8x4+F2arqGQS1umeOR3lvvycyFac1OboJ4oV2rAX97GVmtZdoJjaqxdhg==
342-
dependencies:
343-
"@patternfly/react-core" "^5.2.0"
344-
"@patternfly/react-icons" "^5.2.0"
345-
"@patternfly/react-styles" "^5.2.0"
346-
"@patternfly/react-tokens" "^5.2.0"
347-
lodash "^4.17.19"
348-
tslib "^2.5.0"
316+
"@patternfly/react-core@^6.2.0-prerelease.15", "@patternfly/react-core@^6.2.0-prerelease.17":
317+
version "6.2.0-prerelease.17"
318+
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-6.2.0-prerelease.17.tgz#d01657e2754306f0e76b718941ca757f9d0fbdfe"
319+
integrity sha512-NWiif+SMXOYTDVwcVv1OAOKEN95PFRqeDgEcA580M0KxNqEo1oFaNKQ/xUuhpYxGuvEj0oVjcOjN9lglyOQZZA==
320+
dependencies:
321+
"@patternfly/react-icons" "^6.2.0-prerelease.2"
322+
"@patternfly/react-styles" "^6.2.0-prerelease.2"
323+
"@patternfly/react-tokens" "^6.2.0-prerelease.2"
324+
focus-trap "7.6.4"
325+
react-dropzone "^14.3.5"
326+
tslib "^2.8.1"
327+
328+
"@patternfly/react-icons@^6.2.0-prerelease.2":
329+
version "6.2.0-prerelease.2"
330+
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-6.2.0-prerelease.2.tgz#b695a12733d90004d243b37458bfe52947317d8e"
331+
integrity sha512-3ymG24ICMAvMqrDPzU8ycPcsHht4RfHjQil3ox43wwHI+nLrpywAgE9z6GtAzwtdm+DVZHBT1CWLWuAgdofX8w==
332+
333+
"@patternfly/react-styles@^6.2.0-prerelease.2":
334+
version "6.2.0-prerelease.2"
335+
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-6.2.0-prerelease.2.tgz#32935b2e8d3bfb8aa4287e06a9aa3d4fbd550eea"
336+
integrity sha512-1YJH8Ozu05AHCBNGRZyNA5X1HxNGXuYTQvcR8FbVaNGuuWtvZxzb2EovN9xYVBu2joh+/LCLhiTAXI4eNKw3Ag==
337+
338+
"@patternfly/react-table@^6.2.0-prerelease.16":
339+
version "6.2.0-prerelease.18"
340+
resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-6.2.0-prerelease.18.tgz#1bb01e3a85fbb3ac972f6476c47cf57a47c37791"
341+
integrity sha512-W0NtprppJ8yMH5i+K8lfwdmmTHW5X96Ax4savrsSJ9b8AfI6xcsgUXjUOLqVa+Umv9A5m4S5GJOh/llvevGdhg==
342+
dependencies:
343+
"@patternfly/react-core" "^6.2.0-prerelease.17"
344+
"@patternfly/react-icons" "^6.2.0-prerelease.2"
345+
"@patternfly/react-styles" "^6.2.0-prerelease.2"
346+
"@patternfly/react-tokens" "^6.2.0-prerelease.2"
347+
lodash "^4.17.21"
348+
tslib "^2.8.1"
349349

350-
"@patternfly/react-tokens@^5.2.0":
351-
version "5.2.0"
352-
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-5.2.0.tgz#525aa82c9b280eca32cc48987fd70e3da1e08422"
353-
integrity sha512-ZsrLpStHJQfvUJLIXT+cObJbA3jM4r9iWwULLva0s7DzznXJ6iIACQQfgwDtcSVyM95z5S1a/LHPj/wYgaqUIg==
350+
"@patternfly/react-tokens@^6.2.0-prerelease.2":
351+
version "6.2.0-prerelease.2"
352+
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.2.0-prerelease.2.tgz#d1db6f455f581daa84d728c0a248802096cd797a"
353+
integrity sha512-3snWPqFBOcv0P0UZk5SfG3ZrhBaMb5P1griaMydA/cXdWe9XRX5oP4QuE3uGtQfBVuAaEqRDokQfo2xhWP2Gyw==
354354

355355
"@remix-run/router@1.8.0":
356356
version "1.8.0"
@@ -1125,10 +1125,10 @@ at-least-node@^1.0.0:
11251125
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
11261126
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
11271127

1128-
attr-accept@^2.2.2:
1129-
version "2.2.2"
1130-
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
1131-
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
1128+
attr-accept@^2.2.4:
1129+
version "2.2.5"
1130+
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
1131+
integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
11321132

11331133
available-typed-arrays@^1.0.5:
11341134
version "1.0.5"
@@ -2648,12 +2648,12 @@ file-entry-cache@^6.0.1:
26482648
dependencies:
26492649
flat-cache "^3.0.4"
26502650

2651-
file-selector@^0.6.0:
2652-
version "0.6.0"
2653-
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
2654-
integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
2651+
file-selector@^2.1.0:
2652+
version "2.1.2"
2653+
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.2.tgz#fe7c7ee9e550952dfbc863d73b14dc740d7de8b4"
2654+
integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
26552655
dependencies:
2656-
tslib "^2.4.0"
2656+
tslib "^2.7.0"
26572657

26582658
fill-range@^7.0.1:
26592659
version "7.0.1"
@@ -2721,10 +2721,10 @@ flush-write-stream@^1.0.2:
27212721
inherits "^2.0.3"
27222722
readable-stream "^2.3.6"
27232723

2724-
focus-trap@7.5.2:
2725-
version "7.5.2"
2726-
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.2.tgz#e5ee678d10a18651f2591ffb66c949fb098d57cf"
2727-
integrity sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==
2724+
focus-trap@7.6.4:
2725+
version "7.6.4"
2726+
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.6.4.tgz#455ec5c51fee5ae99604ca15142409ffbbf84db9"
2727+
integrity sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==
27282728
dependencies:
27292729
tabbable "^6.2.0"
27302730

@@ -4035,7 +4035,7 @@ lodash.truncate@^4.4.2:
40354035
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
40364036
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
40374037

4038-
lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21:
4038+
lodash@^4.17.20, lodash@^4.17.21:
40394039
version "4.17.21"
40404040
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
40414041
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -5014,13 +5014,13 @@ react-dom@^17.0.1:
50145014
object-assign "^4.1.1"
50155015
scheduler "^0.20.2"
50165016

5017-
react-dropzone@^14.2.3:
5018-
version "14.2.3"
5019-
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.2.3.tgz#0acab68308fda2d54d1273a1e626264e13d4e84b"
5020-
integrity sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==
5017+
react-dropzone@^14.3.5:
5018+
version "14.3.5"
5019+
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.5.tgz#1a8bd312c8a353ec78ef402842ccb3589c225add"
5020+
integrity sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==
50215021
dependencies:
5022-
attr-accept "^2.2.2"
5023-
file-selector "^0.6.0"
5022+
attr-accept "^2.2.4"
5023+
file-selector "^2.1.0"
50245024
prop-types "^15.8.1"
50255025

50265026
react-fast-compare@^3.1.1:
@@ -6226,11 +6226,16 @@ tslib@^1.8.1:
62266226
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
62276227
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
62286228

6229-
tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0:
6229+
tslib@^2.1.0:
62306230
version "2.6.2"
62316231
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
62326232
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
62336233

6234+
tslib@^2.7.0, tslib@^2.8.1:
6235+
version "2.8.1"
6236+
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
6237+
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
6238+
62346239
tsutils@^3.21.0:
62356240
version "3.21.0"
62366241
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"

0 commit comments

Comments
 (0)