@64mb/freelens-power 1.2.0 → 1.2.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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/out/main/common/dashboard-picker.js +4 -4
  3. package/out/main/common/dashboard-picker.js.map +1 -1
  4. package/out/main/common/dashboard-readiness.js +17 -47
  5. package/out/main/common/dashboard-readiness.js.map +1 -1
  6. package/out/main/common/dashboard-selector.js +40 -6
  7. package/out/main/common/dashboard-selector.js.map +1 -1
  8. package/out/main/common/dashboard.js +1 -0
  9. package/out/main/common/dashboard.js.map +1 -1
  10. package/out/main/common/settings-export.js +1 -1
  11. package/out/main/common/settings-export.js.map +1 -1
  12. package/out/main/common/store/dashboard-preferences-store.js +2 -1
  13. package/out/main/common/store/dashboard-preferences-store.js.map +1 -1
  14. package/out/main/dashboard-picker.js +1 -4
  15. package/out/main/dashboard-picker.js.map +1 -1
  16. package/out/main/dashboard-preload.js +110 -0
  17. package/out/main/dashboard-preload.js.map +1 -0
  18. package/out/main/dashboard-views.js +216 -61
  19. package/out/main/dashboard-views.js.map +1 -1
  20. package/out/main/dock-icon.js +25 -10
  21. package/out/main/dock-icon.js.map +1 -1
  22. package/out/main/index.js +2 -0
  23. package/out/main/index.js.map +1 -1
  24. package/out/main/splash-accent.js +84 -0
  25. package/out/main/splash-accent.js.map +1 -0
  26. package/out/renderer/appearance.js +6 -2
  27. package/out/renderer/appearance.js.map +1 -1
  28. package/out/renderer/dashboard.js +69 -15
  29. package/out/renderer/dashboard.js.map +1 -1
  30. package/out/renderer/preferences/dashboard-preferences.js +16 -1
  31. package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
  32. package/out/renderer/preferences/settings-modal.js.map +1 -1
  33. package/out/renderer/src/common/dashboard-picker.js.map +1 -1
  34. package/out/renderer/src/common/dashboard-selector.js.map +1 -1
  35. package/out/renderer/src/common/dashboard.js +1 -0
  36. package/out/renderer/src/common/dashboard.js.map +1 -1
  37. package/out/renderer/src/common/settings-export.js.map +1 -1
  38. package/out/renderer/src/common/store/dashboard-preferences-store.js +2 -1
  39. package/out/renderer/src/common/store/dashboard-preferences-store.js.map +1 -1
  40. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"settings-export.js","names":[],"sources":["../../../../src/common/settings-export.ts"],"sourcesContent":["import { sanitizeAiShortcuts } from \"./ai-shortcuts\";\nimport { sanitizeDashboardCards } from \"./dashboard\";\nimport { normalizeDashboardSelector } from \"./dashboard-selector\";\n\nexport const SETTINGS_EXPORT = \"freelens-power:settings:export\";\nexport type SettingsExportResult = \"saved\" | \"canceled\" | \"error\";\nexport const SETTINGS_IMPORT = \"freelens-power:settings:import\";\nexport type SettingsImportResult = \"restored\" | \"canceled\" | \"error\";\nexport const SETTINGS_BACKUP_MAX_BYTES = 1024 * 1024;\n\nexport function parseSettingsImport(value: unknown) {\n const fail = () => {\n throw new Error(\"Invalid settings backup\");\n };\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return fail();\n const backup = value as {\n format?: unknown;\n version?: unknown;\n dashboard?: { cards?: unknown };\n ai?: { shortcuts?: unknown };\n };\n if (backup.format !== \"freelens-power-settings\" || backup.version !== 1) return fail();\n const cards = backup.dashboard?.cards;\n const shortcuts = backup.ai?.shortcuts;\n if (!Array.isArray(cards) || !Array.isArray(shortcuts)) return fail();\n const ids = new Set<string>();\n for (const card of cards) {\n if (\n !card ||\n typeof card !== \"object\" ||\n typeof card.id !== \"string\" ||\n !card.id.trim() ||\n ids.has(card.id) ||\n typeof card.title !== \"string\" ||\n !card.title.trim() ||\n typeof card.url !== \"string\" ||\n ![\"xs\", \"s\", \"m\", \"l\", \"xl\"].includes(card.size) ||\n (card.autoRefresh !== undefined && typeof card.autoRefresh !== \"boolean\") ||\n (card.selector !== undefined &&\n (typeof card.selector !== \"string\" || (card.selector.trim() && !normalizeDashboardSelector(card.selector))))\n )\n return fail();\n ids.add(card.id);\n }\n if (\n sanitizeDashboardCards(cards).length !== cards.length ||\n sanitizeAiShortcuts(shortcuts).length !== shortcuts.length\n )\n return fail();\n return createSettingsExport(cards, shortcuts);\n}\n\nfunction credentialKey(value: string): boolean {\n const key = value.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n return (\n /(?:token|password|passwd|secret|credential|authorization|signature|apikey|session)/.test(key) ||\n [\"auth\", \"key\", \"sig\", \"code\", \"jwt\", \"assertion\", \"ticket\", \"samlresponse\"].includes(key)\n );\n}\n\nfunction exportUrl(value: string): string {\n const url = new URL(value);\n url.username = \"\";\n url.password = \"\";\n for (const key of [...url.searchParams.keys()]) {\n if (credentialKey(key)) url.searchParams.delete(key);\n }\n // preserve SPA routes unless the fragment contains credential parameters\n const fragment = url.hash.slice(1);\n const parameters = new URLSearchParams(fragment.includes(\"?\") ? fragment.slice(fragment.indexOf(\"?\") + 1) : fragment);\n if ([...parameters.keys()].some(credentialKey)) url.hash = \"\";\n return url.href;\n}\n\nexport function createSettingsExport(cards: unknown, shortcuts: unknown) {\n const backup = {\n format: \"freelens-power-settings\",\n version: 1,\n dashboard: {\n cards: sanitizeDashboardCards(cards).map((card, index, all) => {\n const url = exportUrl(card.url);\n let id = card.id;\n if (/^card-https?%3a%2f%2f/i.test(id)) {\n id = `export-card-${index + 1}`;\n while (all.some((entry) => entry.id === id)) id += \"-\";\n }\n return { ...card, url, id };\n }),\n },\n ai: { shortcuts: sanitizeAiShortcuts(shortcuts) },\n };\n if (new TextEncoder().encode(`${JSON.stringify(backup, null, 2)}\\n`).byteLength > SETTINGS_BACKUP_MAX_BYTES)\n throw new Error(\"Settings backup is too large\");\n return backup;\n}\n"],"mappings":";AAIA,IAAa,kBAAkB;AAE/B,IAAa,kBAAkB"}
1
+ {"version":3,"file":"settings-export.js","names":[],"sources":["../../../../src/common/settings-export.ts"],"sourcesContent":["import { sanitizeAiShortcuts } from \"./ai-shortcuts\";\nimport { sanitizeDashboardCards } from \"./dashboard\";\nimport { normalizeDashboardSelector } from \"./dashboard-selector\";\n\nexport const SETTINGS_EXPORT = \"freelens-power:settings:export\";\nexport type SettingsExportResult = \"saved\" | \"canceled\" | \"error\";\nexport const SETTINGS_IMPORT = \"freelens-power:settings:import\";\nexport type SettingsImportResult = \"restored\" | \"canceled\" | \"error\";\nexport const SETTINGS_BACKUP_MAX_BYTES = 1024 * 1024;\n\nexport function parseSettingsImport(value: unknown) {\n const fail = () => {\n throw new Error(\"Invalid settings backup\");\n };\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return fail();\n const backup = value as {\n format?: unknown;\n version?: unknown;\n dashboard?: { cards?: unknown };\n ai?: { shortcuts?: unknown };\n };\n if (backup.format !== \"freelens-power-settings\" || backup.version !== 1) return fail();\n const cards = backup.dashboard?.cards;\n const shortcuts = backup.ai?.shortcuts;\n if (!Array.isArray(cards) || !Array.isArray(shortcuts)) return fail();\n const ids = new Set<string>();\n for (const card of cards) {\n if (\n !card ||\n typeof card !== \"object\" ||\n typeof card.id !== \"string\" ||\n !card.id.trim() ||\n ids.has(card.id) ||\n typeof card.title !== \"string\" ||\n !card.title.trim() ||\n typeof card.url !== \"string\" ||\n ![\"xs\", \"s\", \"m\", \"l\", \"xl\"].includes(card.size) ||\n (card.autoRefresh !== undefined && typeof card.autoRefresh !== \"boolean\") ||\n (card.refreshEvery10Seconds !== undefined && typeof card.refreshEvery10Seconds !== \"boolean\") ||\n (card.selector !== undefined &&\n (typeof card.selector !== \"string\" || (card.selector.trim() && !normalizeDashboardSelector(card.selector))))\n )\n return fail();\n ids.add(card.id);\n }\n if (\n sanitizeDashboardCards(cards).length !== cards.length ||\n sanitizeAiShortcuts(shortcuts).length !== shortcuts.length\n )\n return fail();\n return createSettingsExport(cards, shortcuts);\n}\n\nfunction credentialKey(value: string): boolean {\n const key = value.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n return (\n /(?:token|password|passwd|secret|credential|authorization|signature|apikey|session)/.test(key) ||\n [\"auth\", \"key\", \"sig\", \"code\", \"jwt\", \"assertion\", \"ticket\", \"samlresponse\"].includes(key)\n );\n}\n\nfunction exportUrl(value: string): string {\n const url = new URL(value);\n url.username = \"\";\n url.password = \"\";\n for (const key of [...url.searchParams.keys()]) {\n if (credentialKey(key)) url.searchParams.delete(key);\n }\n // preserve SPA routes unless the fragment contains credential parameters\n const fragment = url.hash.slice(1);\n const parameters = new URLSearchParams(fragment.includes(\"?\") ? fragment.slice(fragment.indexOf(\"?\") + 1) : fragment);\n if ([...parameters.keys()].some(credentialKey)) url.hash = \"\";\n return url.href;\n}\n\nexport function createSettingsExport(cards: unknown, shortcuts: unknown) {\n const backup = {\n format: \"freelens-power-settings\",\n version: 1,\n dashboard: {\n cards: sanitizeDashboardCards(cards).map((card, index, all) => {\n const url = exportUrl(card.url);\n let id = card.id;\n if (/^card-https?%3a%2f%2f/i.test(id)) {\n id = `export-card-${index + 1}`;\n while (all.some((entry) => entry.id === id)) id += \"-\";\n }\n return { ...card, url, id };\n }),\n },\n ai: { shortcuts: sanitizeAiShortcuts(shortcuts) },\n };\n if (new TextEncoder().encode(`${JSON.stringify(backup, null, 2)}\\n`).byteLength > SETTINGS_BACKUP_MAX_BYTES)\n throw new Error(\"Settings backup is too large\");\n return backup;\n}\n"],"mappings":";AAIA,IAAa,kBAAkB;AAE/B,IAAa,kBAAkB"}
@@ -39,12 +39,13 @@ var DashboardPreferencesStore = class extends require_extensions.Common.Store.Ex
39
39
  this.cards.splice(destination, 0, card);
40
40
  }
41
41
  toJSON() {
42
- return { cards: this.cards.map(({ id, title, url, size, autoRefresh, selector }) => ({
42
+ return { cards: this.cards.map(({ id, title, url, size, autoRefresh, refreshEvery10Seconds, selector }) => ({
43
43
  id,
44
44
  title,
45
45
  url,
46
46
  size,
47
47
  autoRefresh: autoRefresh === true,
48
+ ...refreshEvery10Seconds === true ? { refreshEvery10Seconds: true } : {},
48
49
  ...selector ? { selector } : {}
49
50
  })) };
50
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-preferences-store.js","names":[],"sources":["../../../../../src/common/store/dashboard-preferences-store.ts"],"sourcesContent":["import { Common } from \"@freelensapp/extensions\";\nimport { action, makeObservable, observable } from \"mobx\";\nimport { type DashboardCard, sanitizeDashboardCards } from \"../dashboard\";\n\nexport interface DashboardPreferencesModel {\n cards: DashboardCard[];\n}\n\nexport class DashboardPreferencesStore extends Common.Store.ExtensionStore<DashboardPreferencesModel> {\n cards: DashboardCard[] = [];\n\n constructor() {\n super({ configName: \"dashboard-preferences\", defaults: { cards: [] } });\n makeObservable(this, {\n cards: observable,\n fromStore: action,\n upsertCard: action,\n removeCard: action,\n moveCard: action,\n });\n }\n\n fromStore(data: Partial<DashboardPreferencesModel>): void {\n this.cards = sanitizeDashboardCards(data?.cards);\n }\n\n upsertCard(card: DashboardCard): void {\n const normalized = sanitizeDashboardCards([card])[0];\n if (!normalized) return;\n const index = this.cards.findIndex((entry) => entry.id === normalized.id);\n if (index < 0) this.cards.push(normalized);\n else this.cards[index] = normalized;\n }\n\n removeCard(id: string): void {\n this.cards = this.cards.filter((card) => card.id !== id);\n }\n\n moveCard(id: string, targetIndex: number): void {\n const index = this.cards.findIndex((card) => card.id === id);\n if (index < 0 || !Number.isFinite(targetIndex)) return;\n const destination = Math.max(0, Math.min(this.cards.length - 1, Math.trunc(targetIndex)));\n if (index === destination) return;\n const [card] = this.cards.splice(index, 1);\n this.cards.splice(destination, 0, card);\n }\n\n toJSON(): DashboardPreferencesModel {\n return {\n cards: this.cards.map(({ id, title, url, size, autoRefresh, selector }) => ({\n id,\n title,\n url,\n size,\n autoRefresh: autoRefresh === true,\n ...(selector ? { selector } : {}),\n })),\n };\n }\n}\n"],"mappings":";;;;AAQA,IAAa,4BAAb,cAA+C,mBAAA,OAAO,MAAM,eAA0C;CACpG,QAAyB,CAAC;CAE1B,cAAc;EACZ,MAAM;GAAE,YAAY;GAAyB,UAAU,EAAE,OAAO,CAAC,EAAE;EAAE,CAAC;EACtE,8BAAA,eAAe,MAAM;GACnB,OAAO,8BAAA;GACP,WAAW,8BAAA;GACX,YAAY,8BAAA;GACZ,YAAY,8BAAA;GACZ,UAAU,8BAAA;EACZ,CAAC;CACH;CAEA,UAAU,MAAgD;EACxD,KAAK,QAAQ,kBAAA,uBAAuB,MAAM,KAAK;CACjD;CAEA,WAAW,MAA2B;EACpC,MAAM,aAAa,kBAAA,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;EAClD,IAAI,CAAC,YAAY;EACjB,MAAM,QAAQ,KAAK,MAAM,WAAW,UAAU,MAAM,OAAO,WAAW,EAAE;EACxE,IAAI,QAAQ,GAAG,KAAK,MAAM,KAAK,UAAU;OACpC,KAAK,MAAM,SAAS;CAC3B;CAEA,WAAW,IAAkB;EAC3B,KAAK,QAAQ,KAAK,MAAM,QAAQ,SAAS,KAAK,OAAO,EAAE;CACzD;CAEA,SAAS,IAAY,aAA2B;EAC9C,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,QAAQ,KAAK,CAAC,OAAO,SAAS,WAAW,GAAG;EAChD,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,WAAW,CAAC,CAAC;EACxF,IAAI,UAAU,aAAa;EAC3B,MAAM,CAAC,QAAQ,KAAK,MAAM,OAAO,OAAO,CAAC;EACzC,KAAK,MAAM,OAAO,aAAa,GAAG,IAAI;CACxC;CAEA,SAAoC;EAClC,OAAO,EACL,OAAO,KAAK,MAAM,KAAK,EAAE,IAAI,OAAO,KAAK,MAAM,aAAa,gBAAgB;GAC1E;GACA;GACA;GACA;GACA,aAAa,gBAAgB;GAC7B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EACjC,EAAE,EACJ;CACF;AACF"}
1
+ {"version":3,"file":"dashboard-preferences-store.js","names":[],"sources":["../../../../../src/common/store/dashboard-preferences-store.ts"],"sourcesContent":["import { Common } from \"@freelensapp/extensions\";\nimport { action, makeObservable, observable } from \"mobx\";\nimport { type DashboardCard, sanitizeDashboardCards } from \"../dashboard\";\n\nexport interface DashboardPreferencesModel {\n cards: DashboardCard[];\n}\n\nexport class DashboardPreferencesStore extends Common.Store.ExtensionStore<DashboardPreferencesModel> {\n cards: DashboardCard[] = [];\n\n constructor() {\n super({ configName: \"dashboard-preferences\", defaults: { cards: [] } });\n makeObservable(this, {\n cards: observable,\n fromStore: action,\n upsertCard: action,\n removeCard: action,\n moveCard: action,\n });\n }\n\n fromStore(data: Partial<DashboardPreferencesModel>): void {\n this.cards = sanitizeDashboardCards(data?.cards);\n }\n\n upsertCard(card: DashboardCard): void {\n const normalized = sanitizeDashboardCards([card])[0];\n if (!normalized) return;\n const index = this.cards.findIndex((entry) => entry.id === normalized.id);\n if (index < 0) this.cards.push(normalized);\n else this.cards[index] = normalized;\n }\n\n removeCard(id: string): void {\n this.cards = this.cards.filter((card) => card.id !== id);\n }\n\n moveCard(id: string, targetIndex: number): void {\n const index = this.cards.findIndex((card) => card.id === id);\n if (index < 0 || !Number.isFinite(targetIndex)) return;\n const destination = Math.max(0, Math.min(this.cards.length - 1, Math.trunc(targetIndex)));\n if (index === destination) return;\n const [card] = this.cards.splice(index, 1);\n this.cards.splice(destination, 0, card);\n }\n\n toJSON(): DashboardPreferencesModel {\n return {\n cards: this.cards.map(({ id, title, url, size, autoRefresh, refreshEvery10Seconds, selector }) => ({\n id,\n title,\n url,\n size,\n autoRefresh: autoRefresh === true,\n ...(refreshEvery10Seconds === true ? { refreshEvery10Seconds: true } : {}),\n ...(selector ? { selector } : {}),\n })),\n };\n }\n}\n"],"mappings":";;;;AAQA,IAAa,4BAAb,cAA+C,mBAAA,OAAO,MAAM,eAA0C;CACpG,QAAyB,CAAC;CAE1B,cAAc;EACZ,MAAM;GAAE,YAAY;GAAyB,UAAU,EAAE,OAAO,CAAC,EAAE;EAAE,CAAC;EACtE,8BAAA,eAAe,MAAM;GACnB,OAAO,8BAAA;GACP,WAAW,8BAAA;GACX,YAAY,8BAAA;GACZ,YAAY,8BAAA;GACZ,UAAU,8BAAA;EACZ,CAAC;CACH;CAEA,UAAU,MAAgD;EACxD,KAAK,QAAQ,kBAAA,uBAAuB,MAAM,KAAK;CACjD;CAEA,WAAW,MAA2B;EACpC,MAAM,aAAa,kBAAA,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;EAClD,IAAI,CAAC,YAAY;EACjB,MAAM,QAAQ,KAAK,MAAM,WAAW,UAAU,MAAM,OAAO,WAAW,EAAE;EACxE,IAAI,QAAQ,GAAG,KAAK,MAAM,KAAK,UAAU;OACpC,KAAK,MAAM,SAAS;CAC3B;CAEA,WAAW,IAAkB;EAC3B,KAAK,QAAQ,KAAK,MAAM,QAAQ,SAAS,KAAK,OAAO,EAAE;CACzD;CAEA,SAAS,IAAY,aAA2B;EAC9C,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,QAAQ,KAAK,CAAC,OAAO,SAAS,WAAW,GAAG;EAChD,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,WAAW,CAAC,CAAC;EACxF,IAAI,UAAU,aAAa;EAC3B,MAAM,CAAC,QAAQ,KAAK,MAAM,OAAO,OAAO,CAAC;EACzC,KAAK,MAAM,OAAO,aAAa,GAAG,IAAI;CACxC;CAEA,SAAoC;EAClC,OAAO,EACL,OAAO,KAAK,MAAM,KAAK,EAAE,IAAI,OAAO,KAAK,MAAM,aAAa,uBAAuB,gBAAgB;GACjG;GACA;GACA;GACA;GACA,aAAa,gBAAgB;GAC7B,GAAI,0BAA0B,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;GACxE,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EACjC,EAAE,EACJ;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@64mb/freelens-power",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Power tools for Freelens Kubernetes IDE",
5
5
  "main": "out/main/index.js",
6
6
  "renderer": "out/renderer/index.js",