diff --git a/Makefile b/Makefile
index 86cdf24e95..068116b3ba 100644
--- a/Makefile
+++ b/Makefile
@@ -20,8 +20,10 @@ compile-dev:
yarn compile:renderer --cache
dev:
- test -f out/main.js || make init
- yarn dev # run electron and watch files
+ifeq ("$(wildcard static/build/main.js)","")
+ make init
+endif
+ yarn dev
lint:
yarn lint
@@ -53,6 +55,12 @@ else
endif
clean:
+ifeq "$(DETECTED_OS)" "Windows"
+ if exist binaries\client del /s /q binaries\client\*.*
+ if exist dist del /s /q dist\*.*
+ if exist static\build del /s /q static\build\*.*
+else
rm -rf binaries/client/*
rm -rf dist/*
- rm -rf out/*
+ rm -rf static/build/*
+endif
\ No newline at end of file
diff --git a/locales/en/messages.po b/locales/en/messages.po
index 46d7fdae36..8859dde6a8 100644
--- a/locales/en/messages.po
+++ b/locales/en/messages.po
@@ -79,7 +79,7 @@ msgid "Account Name"
msgstr "Account Name"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:51
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:46
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:50
msgid "Active"
msgstr "Active"
@@ -173,7 +173,7 @@ msgstr "Affinities"
#: src/renderer/components/+user-management-roles/roles.tsx:35
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:38
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:38
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:52
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:50
#: src/renderer/components/+workloads-deployments/deployments.tsx:63
#: src/renderer/components/+workloads-jobs/jobs.tsx:41
@@ -675,7 +675,7 @@ msgstr "Created at"
msgid "Credentials Ref"
msgstr "Credentials Ref"
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:40
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
msgid "Cron Jobs"
msgstr "Cron Jobs"
@@ -1154,6 +1154,10 @@ msgstr "Item list is empty"
msgid "JSON Path"
msgstr "JSON Path"
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:91
+msgid "Job name"
+msgstr "Job name"
+
#: src/renderer/components/+workloads/workloads.tsx:69
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:62
#: src/renderer/components/+workloads-jobs/jobs.tsx:36
@@ -1218,7 +1222,7 @@ msgid "Last Failure Time"
msgstr "Last Failure Time"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:57
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:51
msgid "Last schedule"
msgstr "Last schedule"
@@ -1448,7 +1452,7 @@ msgstr "Mounts"
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:35
#: src/renderer/components/+user-management-service-accounts/service-accounts-secret.tsx:29
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:36
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:41
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:45
#: src/renderer/components/+workloads-deployments/deployments.tsx:58
#: src/renderer/components/+workloads-jobs/jobs.tsx:37
@@ -1498,7 +1502,7 @@ msgstr "Names"
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:37
#: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:79
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:37
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:43
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:46
#: src/renderer/components/+workloads-deployments/deployments.tsx:59
#: src/renderer/components/+workloads-jobs/jobs.tsx:38
@@ -2155,7 +2159,7 @@ msgid "Scale Deployment <0>{deploymentName}0>"
msgstr "Scale Deployment <0>{deploymentName}0>"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:46
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
msgid "Schedule"
msgstr "Schedule"
@@ -2413,7 +2417,7 @@ msgid "Supplemental Groups"
msgstr "Supplemental Groups"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:54
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:49
msgid "Suspend"
msgstr "Suspend"
@@ -2482,6 +2486,16 @@ msgstr "Tolerations"
msgid "Transmit"
msgstr "Transmit"
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:107
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:79
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:80
+msgid "Trigger"
+msgstr "Trigger"
+
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:103
+msgid "Trigger CronJob <0>{cronjobName}0>"
+msgstr "Trigger CronJob <0>{cronjobName}0>"
+
#: src/renderer/components/+cluster/cluster-issues.tsx:102
#: src/renderer/components/+config-secrets/secret-details.tsx:74
#: src/renderer/components/+config-secrets/secrets.tsx:45
@@ -2717,7 +2731,7 @@ msgid "listKind"
msgstr "listKind"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:48
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:57
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:61
msgid "never"
msgstr "never"
diff --git a/locales/fi/messages.po b/locales/fi/messages.po
index 8e41f2b6a2..464a49bf9e 100644
--- a/locales/fi/messages.po
+++ b/locales/fi/messages.po
@@ -79,7 +79,7 @@ msgid "Account Name"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:51
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:46
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:50
msgid "Active"
msgstr ""
@@ -173,7 +173,7 @@ msgstr ""
#: src/renderer/components/+user-management-roles/roles.tsx:35
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:38
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:38
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:52
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:50
#: src/renderer/components/+workloads-deployments/deployments.tsx:63
#: src/renderer/components/+workloads-jobs/jobs.tsx:41
@@ -671,7 +671,7 @@ msgstr ""
msgid "Credentials Ref"
msgstr ""
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:40
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
msgid "Cron Jobs"
msgstr ""
@@ -1145,6 +1145,10 @@ msgstr ""
msgid "JSON Path"
msgstr ""
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:91
+msgid "Job name"
+msgstr ""
+
#: src/renderer/components/+workloads/workloads.tsx:69
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:62
#: src/renderer/components/+workloads-jobs/jobs.tsx:36
@@ -1209,7 +1213,7 @@ msgid "Last Failure Time"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:57
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:51
msgid "Last schedule"
msgstr ""
@@ -1439,7 +1443,7 @@ msgstr ""
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:35
#: src/renderer/components/+user-management-service-accounts/service-accounts-secret.tsx:29
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:36
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:41
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:45
#: src/renderer/components/+workloads-deployments/deployments.tsx:58
#: src/renderer/components/+workloads-jobs/jobs.tsx:37
@@ -1489,7 +1493,7 @@ msgstr ""
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:37
#: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:79
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:37
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:43
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:46
#: src/renderer/components/+workloads-deployments/deployments.tsx:59
#: src/renderer/components/+workloads-jobs/jobs.tsx:38
@@ -2138,7 +2142,7 @@ msgid "Scale Deployment <0>{deploymentName}0>"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:46
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
msgid "Schedule"
msgstr ""
@@ -2396,7 +2400,7 @@ msgid "Supplemental Groups"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:54
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:49
msgid "Suspend"
msgstr ""
@@ -2465,6 +2469,16 @@ msgstr ""
msgid "Transmit"
msgstr ""
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:107
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:79
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:80
+msgid "Trigger"
+msgstr ""
+
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:103
+msgid "Trigger CronJob <0>{cronjobName}0>"
+msgstr ""
+
#: src/renderer/components/+cluster/cluster-issues.tsx:102
#: src/renderer/components/+config-secrets/secret-details.tsx:74
#: src/renderer/components/+config-secrets/secrets.tsx:45
@@ -2700,7 +2714,7 @@ msgid "listKind"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:48
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:57
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:61
msgid "never"
msgstr ""
diff --git a/locales/ru/messages.po b/locales/ru/messages.po
index adcbd19aed..0200d47b72 100644
--- a/locales/ru/messages.po
+++ b/locales/ru/messages.po
@@ -80,7 +80,7 @@ msgid "Account Name"
msgstr "Название аккаунта"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:51
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:46
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:50
msgid "Active"
msgstr "Активный"
@@ -174,7 +174,7 @@ msgstr "Аффинитеты"
#: src/renderer/components/+user-management-roles/roles.tsx:35
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:38
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:38
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:52
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:50
#: src/renderer/components/+workloads-deployments/deployments.tsx:63
#: src/renderer/components/+workloads-jobs/jobs.tsx:41
@@ -676,7 +676,7 @@ msgstr "Создано"
msgid "Credentials Ref"
msgstr "Credentials Ref"
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:40
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
msgid "Cron Jobs"
msgstr ""
@@ -1155,6 +1155,10 @@ msgstr "Список пуст"
msgid "JSON Path"
msgstr ""
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:91
+msgid "Job name"
+msgstr ""
+
#: src/renderer/components/+workloads/workloads.tsx:69
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:62
#: src/renderer/components/+workloads-jobs/jobs.tsx:36
@@ -1219,7 +1223,7 @@ msgid "Last Failure Time"
msgstr "Время последнего сбоя"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:57
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:51
msgid "Last schedule"
msgstr "Последний запуск"
@@ -1449,7 +1453,7 @@ msgstr "Установки"
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:35
#: src/renderer/components/+user-management-service-accounts/service-accounts-secret.tsx:29
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:36
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:41
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:45
#: src/renderer/components/+workloads-deployments/deployments.tsx:58
#: src/renderer/components/+workloads-jobs/jobs.tsx:37
@@ -1499,7 +1503,7 @@ msgstr ""
#: src/renderer/components/+user-management-roles-bindings/role-bindings.tsx:37
#: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:79
#: src/renderer/components/+user-management-service-accounts/service-accounts.tsx:37
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:43
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:47
#: src/renderer/components/+workloads-daemonsets/daemonsets.tsx:46
#: src/renderer/components/+workloads-deployments/deployments.tsx:59
#: src/renderer/components/+workloads-jobs/jobs.tsx:38
@@ -2156,7 +2160,7 @@ msgid "Scale Deployment <0>{deploymentName}0>"
msgstr "Масштабировать Deployment <0>{deploymentName}0>"
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:46
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:44
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:48
msgid "Schedule"
msgstr "Расписание"
@@ -2414,7 +2418,7 @@ msgid "Supplemental Groups"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:54
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:45
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:49
msgid "Suspend"
msgstr "Заморозка"
@@ -2483,6 +2487,16 @@ msgstr "Толерантности"
msgid "Transmit"
msgstr "Транзит"
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:107
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:79
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:80
+msgid "Trigger"
+msgstr ""
+
+#: src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx:103
+msgid "Trigger CronJob <0>{cronjobName}0>"
+msgstr ""
+
#: src/renderer/components/+cluster/cluster-issues.tsx:102
#: src/renderer/components/+config-secrets/secret-details.tsx:74
#: src/renderer/components/+config-secrets/secrets.tsx:45
@@ -2718,7 +2732,7 @@ msgid "listKind"
msgstr ""
#: src/renderer/components/+workloads-cronjobs/cronjob-details.tsx:48
-#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:57
+#: src/renderer/components/+workloads-cronjobs/cronjobs.tsx:61
msgid "never"
msgstr ""
diff --git a/package.json b/package.json
index d4581123b0..54e4038c77 100644
--- a/package.json
+++ b/package.json
@@ -12,9 +12,9 @@
},
"scripts": {
"dev": "concurrently -k \"yarn dev-run -C\" \"yarn dev:main\" \"yarn dev:renderer\"",
- "dev-run": "nodemon --watch static/build/main.js --exec \"electron --inspect .\" $@",
- "dev:main": "env DEBUG=true yarn compile:main --watch $@",
- "dev:renderer": "env DEBUG=true yarn compile:renderer --watch $@",
+ "dev-run": "cross-env DEBUG=true nodemon --watch static/build/main.js --exec \"electron --inspect .\"",
+ "dev:main": "cross-env DEBUG=true yarn compile:main --watch",
+ "dev:renderer": "cross-env DEBUG=true yarn compile:renderer --watch",
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
"compile:main": "webpack --config webpack.main.ts",
"compile:renderer": "webpack --config webpack.renderer.ts",
@@ -175,6 +175,7 @@
"crypto-js": "^4.0.0",
"electron-updater": "^4.3.1",
"electron-window-state": "^5.0.3",
+ "file-type": "^14.7.1",
"filenamify": "^4.1.0",
"fs-extra": "^9.0.1",
"handlebars": "^4.7.6",
@@ -184,6 +185,7 @@
"jsonpath": "^1.0.2",
"lodash": "^4.17.15",
"mac-ca": "^1.0.4",
+ "make-synchronous": "^0.1.1",
"marked": "^1.1.0",
"md5-file": "^5.0.0",
"mobx": "^5.15.5",
@@ -264,6 +266,7 @@
"circular-dependency-plugin": "^5.2.0",
"color": "^3.1.2",
"concurrently": "^5.2.0",
+ "cross-env": "^7.0.2",
"css-element-queries": "^1.2.3",
"css-loader": "^3.5.3",
"dompurify": "^2.0.11",
diff --git a/src/common/cluster-store.ts b/src/common/cluster-store.ts
index ad25f43f26..6e9930f5ad 100644
--- a/src/common/cluster-store.ts
+++ b/src/common/cluster-store.ts
@@ -1,6 +1,5 @@
import type { WorkspaceId } from "./workspace-store";
-import path from "path";
-import { app, ipcRenderer, remote } from "electron";
+import { ipcRenderer } from "electron";
import { unlink } from "fs-extra";
import { action, computed, observable, toJS } from "mobx";
import { BaseStore } from "./base-store";
@@ -50,11 +49,6 @@ export interface ClusterPreferences {
}
export class ClusterStore extends BaseStore {
- static get iconsDir() {
- // TODO: remove remote cheat
- return path.join((app || remote.app).getPath("userData"), "icons");
- }
-
private constructor() {
super({
configName: "lens-cluster-store",
diff --git a/src/common/cluster-store_test.ts b/src/common/cluster-store_test.ts
index 3fc3e0b60e..6e5b99dbaf 100644
--- a/src/common/cluster-store_test.ts
+++ b/src/common/cluster-store_test.ts
@@ -6,6 +6,10 @@ import { ClusterStore } from "./cluster-store";
import { workspaceStore } from "./workspace-store";
import { saveConfigToAppFiles } from "./kube-helpers";
+const testDataIcon = fs.readFileSync("test-data/cluster-store-migration-icon.png")
+
+console.log("") // fix bug
+
let clusterStore: ClusterStore;
describe("empty config", () => {
@@ -236,12 +240,13 @@ describe("pre 2.6.0 config with a cluster icon", () => {
},
cluster1: {
kubeConfig: "foo",
- icon: "icon path",
+ icon: "icon_path",
preferences: {
terminalCWD: "/tmp"
}
},
- })
+ }),
+ "icon_path": testDataIcon,
}
}
mockFs(mockOpts);
@@ -257,7 +262,7 @@ describe("pre 2.6.0 config with a cluster icon", () => {
const storedClusterData = clusterStore.clustersList[0];
expect(storedClusterData.hasOwnProperty('icon')).toBe(false);
expect(storedClusterData.preferences.hasOwnProperty('icon')).toBe(true);
- expect(storedClusterData.preferences.icon).toBe("icon path");
+ expect(storedClusterData.preferences.icon.startsWith("data:image/jpeg;base64,")).toBe(true);
})
})
@@ -274,7 +279,6 @@ describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
},
cluster1: {
kubeConfig: "foo",
- icon: "icon path",
preferences: {
terminalCWD: "/tmp"
}
@@ -305,16 +309,20 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
- version: "2.7.0"
+ version: "3.5.0"
}
},
clusters: [
{
id: 'cluster1',
- kubeConfig: 'kubeconfig content'
+ kubeConfig: 'kubeconfig content',
+ preferences: {
+ icon: "store://icon_path",
+ }
}
]
- })
+ }),
+ "icon_path": testDataIcon,
}
};
mockFs(mockOpts);
@@ -330,4 +338,9 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
const config = clusterStore.clustersList[0].kubeConfigPath;
expect(fs.readFileSync(config, "utf8")).toBe("kubeconfig content");
})
+
+ it("migrates to modern format with icon not in file", async () => {
+ const { icon } = clusterStore.clustersList[0].preferences;
+ expect(icon.startsWith("data:image/jpeg;base64, ")).toBe(true);
+ })
})
\ No newline at end of file
diff --git a/src/migrations/cluster-store/2.7.0-beta.0.ts b/src/migrations/cluster-store/2.7.0-beta.0.ts
index 22c4e6bba9..3e0ae9337f 100644
--- a/src/migrations/cluster-store/2.7.0-beta.0.ts
+++ b/src/migrations/cluster-store/2.7.0-beta.0.ts
@@ -6,7 +6,7 @@ export default migration({
run(store, log) {
for (const value of store) {
const clusterKey = value[0];
- if(clusterKey === "__internal__") continue
+ if (clusterKey === "__internal__") continue
const cluster = value[1];
cluster.workspace = "default"
store.set(clusterKey, cluster)
diff --git a/src/migrations/cluster-store/3.6.0-beta.1.ts b/src/migrations/cluster-store/3.6.0-beta.1.ts
index adc354d9ef..db39cb741d 100644
--- a/src/migrations/cluster-store/3.6.0-beta.1.ts
+++ b/src/migrations/cluster-store/3.6.0-beta.1.ts
@@ -1,34 +1,71 @@
// Move embedded kubeconfig into separate file and add reference to it to cluster settings
+// convert file path cluster icons to their base64 encoded versions
import path from "path"
import { app, remote } from "electron"
import { migration } from "../migration-wrapper";
-import { ensureDirSync } from "fs-extra"
+import fse from "fs-extra"
import { ClusterModel } from "../../common/cluster-store";
import { loadConfig, saveConfigToAppFiles } from "../../common/kube-helpers";
+import makeSynchronous from "make-synchronous"
+
+const AsyncFunction = Object.getPrototypeOf(async function () { return }).constructor;
+const getFileTypeFnString = `return require("file-type").fromBuffer(fileData)`;
+const getFileType = new AsyncFunction("fileData", getFileTypeFnString);
export default migration({
version: "3.6.0-beta.1",
run(store, printLog) {
- const migratedClusters: ClusterModel[] = []
- const storedClusters: ClusterModel[] = store.get("clusters");
- const kubeConfigBase = path.join((app || remote.app).getPath("userData"), "kubeconfigs")
+ const userDataPath = (app || remote.app).getPath("userData")
+ const kubeConfigBase = path.join(userDataPath, "kubeconfigs")
+ const storedClusters: ClusterModel[] = store.get("clusters") || [];
- if (!storedClusters) return;
- ensureDirSync(kubeConfigBase);
+ if (!storedClusters.length) return;
+ fse.ensureDirSync(kubeConfigBase);
printLog("Number of clusters to migrate: ", storedClusters.length)
- for (const cluster of storedClusters) {
- try {
- // take the embedded kubeconfig and dump it into a file
- cluster.kubeConfigPath = saveConfigToAppFiles(cluster.id, cluster.kubeConfig)
- cluster.contextName = loadConfig(cluster.kubeConfigPath).getCurrentContext();
- delete cluster.kubeConfig;
- migratedClusters.push(cluster)
- } catch (error) {
- printLog(`Failed to migrate Kubeconfig for cluster "${cluster.id}"`, error)
- }
- }
+ const migratedClusters = storedClusters
+ .map(cluster => {
+ /**
+ * migrate kubeconfig
+ */
+ try {
+ // take the embedded kubeconfig and dump it into a file
+ cluster.kubeConfigPath = saveConfigToAppFiles(cluster.id, cluster.kubeConfig)
+ cluster.contextName = loadConfig(cluster.kubeConfigPath).getCurrentContext();
+ delete cluster.kubeConfig;
+
+ } catch (error) {
+ printLog(`Failed to migrate Kubeconfig for cluster "${cluster.id}", removing cluster...`, error)
+ return undefined;
+ }
+
+ /**
+ * migrate cluster icon
+ */
+ try {
+ if (cluster.preferences?.icon) {
+ printLog(`migrating ${cluster.preferences.icon} for ${cluster.preferences.clusterName}`)
+ const iconPath = cluster.preferences.icon.replace("store://", "")
+ const fileData = fse.readFileSync(path.join(userDataPath, iconPath));
+ const { mime = "" } = makeSynchronous(getFileType)(fileData);
+
+ if (!mime) {
+ printLog(`mime type not detected for ${cluster.preferences.clusterName}'s icon: ${iconPath}`)
+ }
+
+ cluster.preferences.icon = `data:${mime};base64, ${fileData.toString('base64')}`;
+ } else {
+ delete cluster.preferences?.icon;
+ }
+ } catch (error) {
+ printLog(`Failed to migrate cluster icon for cluster "${cluster.id}"`, error)
+ delete cluster.preferences.icon;
+ }
+
+ return cluster;
+ })
+ .filter(c => c);
// "overwrite" the cluster configs
if (migratedClusters.length > 0) {
diff --git a/src/renderer/api/endpoints/cron-job.api.ts b/src/renderer/api/endpoints/cron-job.api.ts
index e48a8636b8..887ec9833c 100644
--- a/src/renderer/api/endpoints/cron-job.api.ts
+++ b/src/renderer/api/endpoints/cron-job.api.ts
@@ -32,6 +32,12 @@ export class CronJob extends KubeObject {
jobTemplate: {
metadata: {
creationTimestamp?: string;
+ labels?: {
+ [key: string]: string;
+ };
+ annotations?: {
+ [key: string]: string;
+ };
};
spec: {
template: {
@@ -53,7 +59,7 @@ export class CronJob extends KubeObject {
failedJobsHistoryLimit: number;
}
status: {
- lastScheduleTime: string;
+ lastScheduleTime?: string;
}
getSuspendFlag() {
@@ -61,6 +67,7 @@ export class CronJob extends KubeObject {
}
getLastScheduleTime() {
+ if (!this.status.lastScheduleTime) return "-"
const diff = moment().diff(this.status.lastScheduleTime)
return formatDuration(diff, true)
}
diff --git a/src/renderer/api/endpoints/job.api.ts b/src/renderer/api/endpoints/job.api.ts
index d4657605f6..6c6c1967c1 100644
--- a/src/renderer/api/endpoints/job.api.ts
+++ b/src/renderer/api/endpoints/job.api.ts
@@ -13,7 +13,7 @@ export class Job extends WorkloadKubeObject {
parallelism?: number;
completions?: number;
backoffLimit?: number;
- selector: {
+ selector?: {
matchLabels: {
[name: string]: string;
};
@@ -21,8 +21,11 @@ export class Job extends WorkloadKubeObject {
template: {
metadata: {
creationTimestamp?: string;
- labels: {
- name: string;
+ labels?: {
+ [name: string]: string;
+ };
+ annotations?: {
+ [name: string]: string;
};
};
spec: {
@@ -35,7 +38,7 @@ export class Job extends WorkloadKubeObject {
nodeSelector?: {
[selector: string]: string;
};
- tolerations: {
+ tolerations?: {
key: string;
operator: string;
effect: string;
diff --git a/src/renderer/components/+cluster-settings/components/cluster-icon-setting.tsx b/src/renderer/components/+cluster-settings/components/cluster-icon-setting.tsx
index 20b4e6d6d5..04b7ef1fc6 100644
--- a/src/renderer/components/+cluster-settings/components/cluster-icon-setting.tsx
+++ b/src/renderer/components/+cluster-settings/components/cluster-icon-setting.tsx
@@ -28,7 +28,7 @@ export class ClusterIconSetting extends React.Component {
try {
if (file) {
const buf = Buffer.from(await file.arrayBuffer());
- cluster.preferences.icon = `data:image/jpeg;base64, ${buf.toString('base64')}`;
+ cluster.preferences.icon = `data:${file.type};base64, ${buf.toString('base64')}`;
} else {
// this has to be done as a seperate branch (and not always) because `cluster`
// is observable and triggers an update loop.
diff --git a/src/renderer/components/+landing-page/landing-page.scss b/src/renderer/components/+landing-page/landing-page.scss
index 6cc726f5d9..0d05c418d8 100644
--- a/src/renderer/components/+landing-page/landing-page.scss
+++ b/src/renderer/components/+landing-page/landing-page.scss
@@ -1,8 +1,24 @@
.LandingPage {
height: 100%;
- background: #282b2f url(../../components/icon/crane.svg) no-repeat;
- background-position: 0 35%;
- background-size: 85%;
- background-clip: content-box;
text-align: center;
+ z-index: 0;
+
+ &::after {
+ content: "";
+ background: url(../../components/icon/crane.svg) no-repeat;
+ background-position: 0 35%;
+ background-size: 85%;
+ background-clip: content-box;
+ opacity: 1;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ position: absolute;
+ z-index: -1;
+
+ .theme-light & {
+ opacity: 0.2;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.scss b/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.scss
new file mode 100644
index 0000000000..ef52eebb08
--- /dev/null
+++ b/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.scss
@@ -0,0 +1,18 @@
+.CronJobTriggerDialog {
+ .Wizard {
+ .header {
+ span {
+ color: #a0a0a0;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ }
+
+ .WizardStep {
+ .step-content {
+ min-height: 90px;
+ overflow: hidden;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx b/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx
new file mode 100644
index 0000000000..7f29c0478d
--- /dev/null
+++ b/src/renderer/components/+workloads-cronjobs/cronjob-trigger-dialog.tsx
@@ -0,0 +1,127 @@
+import "./cronjob-trigger-dialog.scss";
+
+import React, { Component } from "react";
+import { observable } from "mobx";
+import { observer } from "mobx-react";
+import { Trans } from "@lingui/macro";
+import { Dialog, DialogProps } from "../dialog";
+import { Wizard, WizardStep } from "../wizard";
+import { CronJob, cronJobApi, jobApi, Job } from "../../api/endpoints";
+import { Notifications } from "../notifications";
+import { cssNames } from "../../utils";
+import { Input } from "../input";
+import { systemName, maxLength } from "../input/input.validators";
+
+interface Props extends Partial {
+}
+
+@observer
+export class CronJobTriggerDialog extends Component {
+ @observable static isOpen = false;
+ @observable static data: CronJob = null;
+
+ @observable jobName = "";
+
+ @observable ready = false;
+
+ static open(cronjob: CronJob) {
+ CronJobTriggerDialog.isOpen = true;
+ CronJobTriggerDialog.data = cronjob;
+ }
+
+ static close() {
+ CronJobTriggerDialog.isOpen = false;
+ }
+
+ get cronjob() {
+ return CronJobTriggerDialog.data;
+ }
+
+ close = () => {
+ CronJobTriggerDialog.close();
+ }
+
+ onOpen = async () => {
+ const { cronjob } = this;
+ this.jobName = cronjob ? cronjob.getName() + "-manual-" + Math.random().toString(36).slice(2, 7) : "";
+ this.jobName = this.jobName.slice(0, 63);
+ this.ready = true;
+ }
+
+ onClose = () => {
+ this.ready = false;
+ }
+
+ trigger = async () => {
+ const { cronjob } = this;
+ const { close } = this;
+ try {
+ const cronjobDefinition = await cronJobApi.get({
+ name: cronjob.getName(),
+ namespace: cronjob.getNs()
+ });
+
+ await jobApi.create({
+ name: this.jobName,
+ namespace: cronjob.getNs()
+ }, {
+ spec: cronjobDefinition.spec.jobTemplate.spec
+ });
+
+ close();
+ } catch (err) {
+ Notifications.error(err);
+ }
+ }
+
+ renderContents() {
+ return (
+ <>
+
+ Job name:
+
+
+ this.jobName = v.toLowerCase()}
+ className="box grow"
+ />
+
+ >
+ )
+ }
+
+ render() {
+ const { className, ...dialogProps } = this.props;
+ const cronjobName = this.cronjob ? this.cronjob.getName() : "";
+ const header = (
+
+ Trigger CronJob {cronjobName}
+
+ );
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/renderer/components/+workloads-cronjobs/cronjob.store.ts b/src/renderer/components/+workloads-cronjobs/cronjob.store.ts
index 9e75c25121..e8fa3719ae 100644
--- a/src/renderer/components/+workloads-cronjobs/cronjob.store.ts
+++ b/src/renderer/components/+workloads-cronjobs/cronjob.store.ts
@@ -9,13 +9,13 @@ export class CronJobStore extends KubeObjectStore {
api = cronJobApi
getStatuses(cronJobs?: CronJob[]) {
- const status = { failed: 0, running: 0 }
+ const status = { suspended: 0, scheduled: 0 }
cronJobs.forEach(cronJob => {
if (cronJob.spec.suspend) {
- status.failed++
+ status.suspended++
}
else {
- status.running++
+ status.scheduled++
}
})
return status
diff --git a/src/renderer/components/+workloads-cronjobs/cronjobs.tsx b/src/renderer/components/+workloads-cronjobs/cronjobs.tsx
index 4221302116..32a2dc50dc 100644
--- a/src/renderer/components/+workloads-cronjobs/cronjobs.tsx
+++ b/src/renderer/components/+workloads-cronjobs/cronjobs.tsx
@@ -3,8 +3,10 @@ import "./cronjobs.scss";
import React from "react";
import { observer } from "mobx-react";
import { RouteComponentProps } from "react-router";
-import { Trans } from "@lingui/macro";
+import { t, Trans } from "@lingui/macro";
import { CronJob, cronJobApi } from "../../api/endpoints/cron-job.api";
+import { MenuItem } from "../menu";
+import { Icon } from "../icon";
import { cronJobStore } from "./cronjob.store";
import { jobStore } from "../+workloads-jobs/job.store";
import { eventStore } from "../+events/event.store";
@@ -12,7 +14,9 @@ import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-
import { ICronJobsRouteParams } from "../+workloads";
import { KubeObjectListLayout } from "../kube-object";
import { KubeEventIcon } from "../+events/kube-event-icon";
+import { _i18n } from "../../i18n";
import { apiManager } from "../../api/api-manager";
+import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
enum sortBy {
name = "name",
@@ -79,8 +83,14 @@ export class CronJobs extends React.Component {
}
export function CronJobMenu(props: KubeObjectMenuProps) {
+ const { object, toolbar } = props;
return (
-
+
+
+
)
}
diff --git a/src/renderer/components/+workloads-overview/overview-workload-status.scss b/src/renderer/components/+workloads-overview/overview-workload-status.scss
index c06ed5b4c8..4d47570973 100644
--- a/src/renderer/components/+workloads-overview/overview-workload-status.scss
+++ b/src/renderer/components/+workloads-overview/overview-workload-status.scss
@@ -3,6 +3,8 @@
--workload-status-pending: #{$pod-status-pending-color};
--workload-status-evicted: #{$pod-status-evicted-color};
--workload-status-succeeded: #{$pod-status-succeeded-color};
+ --workload-status-scheduled: #{$cronjob-scheduled};
+ --workload-status-suspended: #{$cronjob-suspended};
--workload-status-failed: #{$pod-status-failed-color};
--workload-status-terminated: #{$pod-status-terminated-color};
--workload-status-unknown: #{$pod-status-unknown-color};
diff --git a/src/renderer/components/+workloads/workloads-mixins.scss b/src/renderer/components/+workloads/workloads-mixins.scss
index 84bcca8219..8ba7f76665 100644
--- a/src/renderer/components/+workloads/workloads-mixins.scss
+++ b/src/renderer/components/+workloads/workloads-mixins.scss
@@ -26,6 +26,10 @@ $deployment-replicafailure: $colorError;
$job-complete: $colorSuccess;
$job-failed: $colorError;
+// Cronjob
+$cronjob-scheduled: $colorSuccess;
+$cronjob-suspended: $colorTerminated;
+
// Pod Statuses
$pod-status-color-list: (
running: $pod-status-running-color,
@@ -48,6 +52,12 @@ $job-condition-color-list: (
failed: $job-failed,
);
+// Cronjob Conditions
+$cronjob-condition-color-list: (
+ scheduled: $cronjob-scheduled,
+ suspended: $cronjob-suspended,
+);
+
@mixin pod-status-bgs {
@each $status, $color in $pod-status-color-list {
&.#{$status} {
diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx
index abdef9b7f4..23e71e2be9 100755
--- a/src/renderer/components/app.tsx
+++ b/src/renderer/components/app.tsx
@@ -25,6 +25,7 @@ import { KubeObjectDetails } from "./kube-object/kube-object-details";
import { AddRoleBindingDialog } from "./+user-management-roles-bindings";
import { PodLogsDialog } from "./+workloads-pods/pod-logs-dialog";
import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale-dialog";
+import { CronJobTriggerDialog } from "./+workloads-cronjobs/cronjob-trigger-dialog";
import { CustomResources } from "./+custom-resources/custom-resources";
import { crdRoute } from "./+custom-resources";
import { isAllowedResource } from "../../common/rbac";
@@ -80,6 +81,7 @@ export class App extends React.Component {
+
diff --git a/src/renderer/components/chart/chart.tsx b/src/renderer/components/chart/chart.tsx
index 92e3619031..a5fa4b9706 100644
--- a/src/renderer/components/chart/chart.tsx
+++ b/src/renderer/components/chart/chart.tsx
@@ -63,14 +63,14 @@ export class Chart extends React.Component {
this.renderChart()
}
- componentDidUpdate(prevProps: ChartProps) {
- const { data, showChart, redraw } = this.props
+ componentDidUpdate() {
+ const { showChart, redraw } = this.props
if (redraw) {
this.chart.destroy()
this.renderChart()
return
}
- if (!isEqual(prevProps.data, data) && showChart) {
+ if (showChart) {
if (!this.chart) this.renderChart()
else this.updateChart()
}
diff --git a/src/renderer/components/cluster-manager/clusters-menu.scss b/src/renderer/components/cluster-manager/clusters-menu.scss
index 0ee1f59d7e..9b412e5035 100644
--- a/src/renderer/components/cluster-manager/clusters-menu.scss
+++ b/src/renderer/components/cluster-manager/clusters-menu.scss
@@ -1,5 +1,4 @@
.ClustersMenu {
- @include hidden-scrollbar;
$spacing: $padding * 2;
position: relative;
@@ -23,8 +22,7 @@
padding: $spacing;
width: 320px;
background: $bgc;
- z-index: 100;
- color: white;
+ color: $textColorAccent;
filter: drop-shadow(0 0px 2px #ffffff33);
pointer-events: none;
@@ -38,6 +36,19 @@
border-right: $arrowSize solid $bgc;
right: 100%;
}
+
+ .theme-light & {
+ filter: drop-shadow(0 0px 2px #777);
+ background: white;
+
+ &:before {
+ border-right-color: white;
+ }
+ }
+ }
+
+ .clusters {
+ @include hidden-scrollbar;
}
> .add-cluster {
diff --git a/src/renderer/components/cluster-manager/clusters-menu.tsx b/src/renderer/components/cluster-manager/clusters-menu.tsx
index 23d85507c3..d4fb4cefb1 100644
--- a/src/renderer/components/cluster-manager/clusters-menu.tsx
+++ b/src/renderer/components/cluster-manager/clusters-menu.tsx
@@ -110,18 +110,20 @@ export class ClustersMenu extends React.Component {
)}
- {clusters.map(cluster => {
- return (
- this.showCluster(cluster.id)}
- onContextMenu={() => this.showContextMenu(cluster)}
- />
- )
- })}
+
+ {clusters.map(cluster => {
+ return (
+ this.showCluster(cluster.id)}
+ onContextMenu={() => this.showContextMenu(cluster)}
+ />
+ )
+ })}
+
Add Cluster
diff --git a/test-data/cluster-store-migration-icon.png b/test-data/cluster-store-migration-icon.png
new file mode 100644
index 0000000000..623a0fea77
Binary files /dev/null and b/test-data/cluster-store-migration-icon.png differ
diff --git a/yarn.lock b/yarn.lock
index d8881d0f1d..9e75e68c2d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1588,6 +1588,11 @@
dependencies:
defer-to-connect "^1.0.1"
+"@tokenizer/token@^0.1.0", "@tokenizer/token@^0.1.1":
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3"
+ integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==
+
"@types/anymatch@*":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
@@ -3997,6 +4002,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+cross-env@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9"
+ integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==
+ dependencies:
+ cross-spawn "^7.0.1"
+
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -4016,7 +4028,7 @@ cross-spawn@^3.0.0:
lru-cache "^4.0.1"
which "^1.2.9"
-cross-spawn@^7.0.0, cross-spawn@^7.0.2:
+cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -5189,6 +5201,16 @@ file-loader@^6.0.0:
loader-utils "^2.0.0"
schema-utils "^2.6.5"
+file-type@^14.7.1:
+ version "14.7.1"
+ resolved "https://registry.yarnpkg.com/file-type/-/file-type-14.7.1.tgz#f748732b3e70478bff530e1cf0ec2fe33608b1bb"
+ integrity sha512-sXAMgFk67fQLcetXustxfKX+PZgHIUFn96Xld9uH8aXPdX3xOp0/jg9OdouVTvQrf7mrn+wAa4jN/y9fUOOiRA==
+ dependencies:
+ readable-web-to-node-stream "^2.0.0"
+ strtok3 "^6.0.3"
+ token-types "^2.0.0"
+ typedarray-to-buffer "^3.1.5"
+
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@@ -6067,7 +6089,7 @@ identity-obj-proxy@^3.0.0:
dependencies:
harmony-reflect "^1.4.6"
-ieee754@^1.1.4:
+ieee754@^1.1.13, ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
@@ -7625,6 +7647,14 @@ make-plural@^6.2.1:
resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-6.2.1.tgz#2790af1d05fb2fc35a111ce759ffdb0aca1339a3"
integrity sha512-AmkruwJ9EjvyTv6AM8MBMK3TAeOJvhgTv5YQXzF0EP2qawhpvMjDpHvsdOIIT0Vn+BB0+IogmYZ1z+Ulm/m0Fg==
+make-synchronous@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/make-synchronous/-/make-synchronous-0.1.1.tgz#0169f6ec769c3cf8948d66790da262740c1209e7"
+ integrity sha512-Y4SxxqhaoyMDokJQ0AZz0E+bLhRkOSR7Z/IQoTKPdS6HYi3aobal2kMHoHHoqBadPWjf07P4K1FQLXOx3wf9Yw==
+ dependencies:
+ subsume "^3.0.0"
+ type-fest "^0.16.0"
+
makeerror@1.0.x:
version "1.0.11"
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
@@ -8936,6 +8966,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+peek-readable@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-3.1.0.tgz#250b08b7de09db8573d7fd8ea475215bbff14348"
+ integrity sha512-KGuODSTV6hcgdZvDrIDBUkN0utcAVj1LL7FfGbM0viKTtCHmtZcuEJ+lGqsp0fTFkGqesdtemV2yUSMeyy3ddA==
+
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -9529,6 +9564,11 @@ readable-stream@^3.1.1, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
+readable-web-to-node-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-2.0.0.tgz#751e632f466552ac0d5c440cc01470352f93c4b7"
+ integrity sha512-+oZJurc4hXpaaqsN68GoZGQAQIA3qr09Or4fqEsargABnbe5Aau8hFn6ISVleT3cpY/0n/8drn7huyyEvTbghA==
+
readdirp@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
@@ -10648,6 +10688,15 @@ strip-outer@^1.0.1:
dependencies:
escape-string-regexp "^1.0.2"
+strtok3@^6.0.3:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.0.4.tgz#ede0d20fde5aa9fda56417c3558eaafccc724694"
+ integrity sha512-rqWMKwsbN9APU47bQTMEYTPcwdpKDtmf1jVhHzNW2cL1WqAxaM9iBb9t5P2fj+RV2YsErUWgQzHD5JwV0uCTEQ==
+ dependencies:
+ "@tokenizer/token" "^0.1.1"
+ "@types/debug" "^4.1.5"
+ peek-readable "^3.1.0"
+
style-loader@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a"
@@ -10656,6 +10705,14 @@ style-loader@^1.2.1:
loader-utils "^2.0.0"
schema-utils "^2.6.6"
+subsume@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/subsume/-/subsume-3.0.0.tgz#22c92730f441ad72ee9af4bdad42dc4ff830cfaf"
+ integrity sha512-6n/UfV8UWKwJNO8OAOiKntwEMihuBeeoJfzpL542C+OuvT4iWG9SwjrXkOmsxjb4SteHUsos9SvrdqZ9+ICwTQ==
+ dependencies:
+ escape-string-regexp "^2.0.0"
+ unique-string "^2.0.0"
+
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
@@ -10977,6 +11034,14 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
+token-types@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/token-types/-/token-types-2.0.0.tgz#b23618af744818299c6fbf125e0fdad98bab7e85"
+ integrity sha512-WWvu8sGK8/ZmGusekZJJ5NM6rRVTTDO7/bahz4NGiSDb/XsmdYBn6a1N/bymUHuWYTWeuLUg98wUzvE4jPdCZw==
+ dependencies:
+ "@tokenizer/token" "^0.1.0"
+ ieee754 "^1.1.13"
+
touch@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
@@ -11150,6 +11215,11 @@ type-fest@^0.13.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
+type-fest@^0.16.0:
+ version "0.16.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860"
+ integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==
+
type-fest@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"