freelens-eso-extension 1.0.2 → 1.0.3

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 (2) hide show
  1. package/README.md +130 -139
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,177 +1,168 @@
1
1
  # freelens-eso-extension
2
2
 
3
- Extensão Freelens para o **External Secrets Operator (ESO)**. Portado da extension API v2
4
- para a **API v1 (Freelens 1.x, `engines.freelens: ^1.8.0`)**, seguindo o layout de build da
5
- extensão oficial [`freelensapp/freelens-fluxcd-extension`](https://github.com/freelensapp/freelens-fluxcd-extension)
6
- v5.3.1 (electron-vite, `out/`, bundles CommonJS).
3
+ A Freelens extension for the [External Secrets Operator](https://external-secrets.io/) (ESO):
4
+ browse ExternalSecrets, SecretStores and ClusterSecretStores, see their sync status at a
5
+ glance, and trigger a manual sync from the UI.
7
6
 
8
- Repositório: <https://github.com/nidiodolfini/freelens-eso-extension> · Pacote npm:
9
- [`freelens-eso-extension`](https://www.npmjs.com/package/freelens-eso-extension)
7
+ Built for the Freelens **extension API v1** (Freelens 1.x, `engines.freelens: ^1.8.0`), with
8
+ the build layout of the official
9
+ [`freelensapp/freelens-fluxcd-extension`](https://github.com/freelensapp/freelens-fluxcd-extension)
10
+ v5.3.1 (electron-vite, CommonJS bundles in `out/`).
10
11
 
11
- ## O que a extensão faz
12
+ Repository: <https://github.com/nidiodolfini/freelens-eso-extension> ·
13
+ npm package: [`freelens-eso-extension`](https://www.npmjs.com/package/freelens-eso-extension) ·
14
+ Proposed in [freelensapp/freelens discussion #2840](https://github.com/freelensapp/freelens/discussions/2840).
12
15
 
13
- Três páginas de cluster, uma por recurso do ESO:
16
+ ## What the extension does
14
17
 
15
- - **External Secrets** (`es`) — colunas espelhando `kubectl get es`: Name, Namespace, Store
16
- Type, Store, Refresh Interval, Status, Ready, Last Sync e Age.
17
- - **Secret Stores** (`ss`) — colunas espelhando `kubectl get ss`: Name, Namespace, Provider,
18
- Status, Capabilities, Ready e Age.
19
- - **Cluster Secret Stores** (`css`) — o mesmo, sem Namespace.
18
+ Three cluster pages, one per ESO resource, grouped under a single sidebar entry:
20
19
 
21
- O status vem da condition `Ready` de cada recurso: `success`/`error`/`warning`, com o reason do
22
- controller (`SecretSynced`, `SecretSyncedError`, `Valid`, `ValidationFailed`, ...). Quando a CRD
23
- não está instalada no cluster, a página mostra "Not Available".
20
+ - **External Secrets** (`es`) — columns mirroring `kubectl get es`: Name, Namespace, Store
21
+ Type, Store, Refresh Interval, Status, Ready, Last Sync and Age.
22
+ - **Secret Stores** (`ss`) — columns mirroring `kubectl get ss`: Name, Namespace, Provider,
23
+ Status, Capabilities, Ready and Age.
24
+ - **Cluster Secret Stores** (`css`) — the same, without Namespace.
24
25
 
25
- Cada recurso tem um painel de detalhes no drawer: target Secret, store, refresh policy/interval,
26
- última sincronização, resource version sincronizada e as conditions com tooltip da message.
26
+ Sync status comes from each resource's `Ready` condition and is rendered as a colored badge
27
+ (`success` / `error` / `warning`) with the controller's reason (`SecretSynced`,
28
+ `SecretSyncedError`, `Valid`, `ValidationFailed`, ...). When the CRD is not installed in the
29
+ cluster, the page shows a friendly "Not Available" message.
27
30
 
28
- **Force Sync**: o menu do `ExternalSecret` ganha a ação "Force Sync", que grava um timestamp novo
29
- na annotation `external-secrets.io/force-sync` — o mesmo que
30
- `kubectl annotate es <name> force-sync=$(date +%s) --overwrite`. O controller reconcilia quando a
31
- annotation muda. SecretStore e ClusterSecretStore não têm essa ação.
31
+ Each resource also gets a details panel in the drawer: target Secret, store, refresh
32
+ policy/interval, last sync time, synced resource version and the full conditions with their
33
+ messages as tooltips.
32
34
 
33
- ## Requisitos
35
+ **Force Sync**: the `ExternalSecret` menu gains a "Force Sync" action, which writes a fresh
36
+ timestamp to the `external-secrets.io/force-sync` annotation — the same as
37
+ `kubectl annotate es <name> force-sync=$(date +%s) --overwrite`. The controller reconciles
38
+ whenever the annotation changes, so the secret is refreshed immediately. `SecretStore` and
39
+ `ClusterSecretStore` do not support this action, so they have no menu item.
34
40
 
35
- - Freelens 1.10.x (extension API v1; `engines.freelens` exige `^1.8.0`).
36
- - Um cluster com o External Secrets Operator instalado (`external-secrets.io/v1`).
41
+ ## Requirements
37
42
 
38
- ## Pré-requisitos deste ambiente
43
+ - Freelens 1.8 or newer (extension API v1; tested on 1.10.x).
44
+ - A cluster with the External Secrets Operator installed (`external-secrets.io/v1`).
39
45
 
40
- - **Node**: `C:\Users\nidio\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe`
41
- - **pnpm 11.28.6** (vendored em `.tools/pnpm11/`; o pnpm 12 do harness usa um lock de
42
- store em `%LOCALAPPDATA%`, que o sandbox bloqueia). Um shim está em
43
- [`.tools/bin/pnpm.cmd`](.tools/bin/pnpm.cmd) — adicione `.tools\bin` ao `PATH`:
46
+ ## Installation
44
47
 
45
- ```powershell
46
- $env:PATH = "C:\Users\nidio\GitHub\freelens-extension\.tools\bin;" + $env:PATH
47
- ```
48
+ In Freelens, open **Extensions**, choose **Install** and type `freelens-eso-extension`
49
+ (no path). Freelens resolves the package from the npm registry, exactly like the official
50
+ extensions. Enable it, and the "External Secrets" sidebar group appears on every cluster.
48
51
 
49
- ## Setup
52
+ To install from a local checkout instead (for development), see
53
+ [Development](#development) below.
50
54
 
51
- ```powershell
52
- $env:ELECTRON_SKIP_BINARY_DOWNLOAD = "1" # pular binário do electron (types apenas)
53
- $env:NPM_CONFIG_CACHE = "C:\Users\nidio\GitHub\freelens-extension\.npm-cache"
54
- pnpm install
55
- node .tools\patch-vite.mjs # patch idempotente do vite p/ o sandbox
56
- ```
55
+ ## Usage
56
+
57
+ 1. Apply the example objects to a cluster with ESO installed:
57
58
 
58
- Caches ficam dentro do workspace: `.pnpm-store`, `.pnpm-cache`, `.pnpm-state`,
59
- `.npm-cache` (ver `.npmrc` e `pnpm-workspace.yaml`).
59
+ ```powershell
60
+ kubectl apply -f examples/eso/secretstore.yaml
61
+ kubectl apply -f examples/eso/clustersecretstore.yaml
62
+ kubectl apply -f examples/eso/externalsecret.yaml
63
+ ```
60
64
 
61
- > O patch aplica três correções de ambiente (o sandbox DSH bloqueia spawn com
62
- > stdio em pipe): o `net use` do realpath (try/catch), o uso do compilador Sass
63
- > JS puro (`sass`) em vez do `sass-embedded` (que spawna o binário Dart Sass) e,
64
- > no electron-vite, a transpilação do config por TypeScript in-process em vez do
65
- > serviço esbuild (que spawna um binário). Rode o script novamente após qualquer
66
- > `pnpm install` que recrie as dependências.
65
+ These use ESO's `fake` provider, which serves the pair `/hello -> world` without touching
66
+ any real secret backend; the ExternalSecret creates a Secret named `hello-world` with the
67
+ key `hello`.
67
68
 
68
- ## Comandos de desenvolvimento
69
+ 2. Open the cluster in Freelens. The pages list `fake-store`, `fake-cluster-store` and
70
+ `hello-world`; the ExternalSecret details panel shows `Ready=SecretSynced` after the first
71
+ sync.
72
+
73
+ 3. Open the `hello-world` menu and click **Force Sync**; the "Last Sync" column updates
74
+ within seconds as the controller reconciles.
75
+
76
+ ## Development
77
+
78
+ Node 22+ and pnpm are required.
69
79
 
70
80
  ```powershell
71
- pnpm type:check # tsc -p tsconfig.json (um programa único, como no fluxcd)
81
+ pnpm install
82
+ pnpm type:check # tsc -p tsconfig.json (single program, as in the fluxcd extension)
72
83
  pnpm test:unit # vitest
73
- pnpm build # electron-vite build → out/main e out/renderer (CommonJS)
74
- pnpm biome:fix # formatação/lint (TypeScript, TSX, JSON, CSS, HTML)
84
+ pnpm build # electron-vite build -> out/main and out/renderer (CommonJS)
85
+ pnpm biome:fix # formatting/lint (TypeScript, TSX, JSON, CSS, HTML)
75
86
  pnpm biome:check
76
- pnpm knip:check # arquivos e dependências não usados (requer download via pnpm dlx)
77
- pnpm pack:dev # bump prerelease + build + .tgz para instalar no Freelens
87
+ pnpm knip:check # unused files and dependencies (downloads knip via pnpm dlx)
88
+ pnpm pack:dev # bump prerelease + build + .tgz to install in Freelens
78
89
  pnpm clean # remove out/
79
90
  ```
80
91
 
81
- > `biome:*` e `knip:*` rodam via `pnpm dlx`, cujo cache padrão fica em
82
- > `%LOCALAPPDATA%` (bloqueado no sandbox). Redirecione para dentro do workspace antes de
83
- > rodá-los: `$env:LOCALAPPDATA = "C:\Users\nidio\GitHub\freelens-extension\.localappdata"`.
84
- > O `test:unit` usa `--pool=threads` porque o pool forks do vitest spawna processos filhos,
85
- > bloqueados no sandbox.
86
-
87
- ## Instalar pelo nome (npm)
88
-
89
- Depois de publicado, o Freelens instala a extensão pelo nome, como as extensões oficiais:
92
+ To load the checkout in Freelens, run `pnpm install && pnpm build`, then in **Extensions**
93
+ choose **Install from directory** and point at this directory; confirm loading the
94
+ extension "in place" so rebuilds reload it automatically.
95
+
96
+ ### Development environment notes (this workspace)
97
+
98
+ The development machine runs inside a sandbox that blocks some standard tooling, so this
99
+ checkout carries a few workarounds; they are documented here because they differ from the
100
+ upstream template:
101
+
102
+ - `packageManager` is `pnpm@11.28.6`, vendored under `.tools/` with a shim at
103
+ `.tools/bin/pnpm.cmd` (add `.tools\bin` to `PATH`). pnpm 12 keeps its store lock in
104
+ `%LOCALAPPDATA%`, which the sandbox blocks.
105
+ - `nodeLinker: hoisted` is set in `pnpm-workspace.yaml`.
106
+ - The sandbox blocks spawning child processes with piped stdio, so `.tools/patch-vite.mjs`
107
+ applies three environment fixes after `pnpm install`: the `net use` realpath call of Vite
108
+ (try/catch), the pure-JS `sass` compiler instead of `sass-embedded` (which spawns the Dart
109
+ Sass binary), and in-process TypeScript transpilation of the electron-vite config instead
110
+ of the esbuild service (which spawns a binary).
111
+ - The electron-vite config therefore does not use `@vitejs/plugin-react` (the config's
112
+ CommonJS loader cannot `require()` the plugin's ESM graph with top-level `await`); JSX uses
113
+ Vite's native automatic transform (`react/jsx-runtime` mapped to the host global). The
114
+ plugin stays as a devDependency to mirror the fluxcd extension, and knip ignores it.
115
+ - `test:unit` uses `--pool=threads` and `knip:check` uses `&&` instead of the parallel
116
+ regex script, both because of the same spawn restriction.
117
+ - `biome:*` and `knip:*` download via `pnpm dlx`, whose default cache lives in
118
+ `%LOCALAPPDATA%`; set `$env:LOCALAPPDATA` to a workspace-local directory before running
119
+ them on this machine.
120
+
121
+ ## Project structure
90
122
 
91
- 1. No Freelens, em **Extensions**, escolha **Install** e digite `freelens-eso-extension`
92
- (sem caminho de diretório). O Freelens resolve o pacote no registry do npm.
93
- 2. Confirme e habilite a extensão; as três páginas aparecem na sidebar de cada cluster.
94
-
95
- Para publicar uma nova versão:
96
-
97
- ```powershell
98
- pnpm bump-version patch # ou minor/major/prerelease
99
- pnpm build
100
- pnpm publish --no-git-checks # requer NODE_AUTH_TOKEN do npmjs.com
123
+ ```text
124
+ electron.vite.config.js # electron-vite config (main + renderer in preload)
125
+ build/global-externals.js # plugin: react/mobx/... -> host globals (v1)
126
+ src/
127
+ main/index.ts # main entry (stateless)
128
+ renderer/index.tsx # v1 registrations: apiManager, 3 pages, details, menu
129
+ renderer/api/types.ts # ESO spec/status types
130
+ renderer/api/store-helpers.ts # pure status helpers shared by the stores
131
+ renderer/api/externalsecret/externalsecret-v1.ts # ExternalSecret model (+ Api/Store, test)
132
+ renderer/api/secretstore/secretstore-v1.ts # SecretStore model (+ Api/Store, test)
133
+ renderer/api/clustersecretstore/clustersecretstore-v1.ts # ClusterSecretStore model (+ Api/Store, test)
134
+ renderer/pages/ # 3 pages + CSS module
135
+ renderer/details/ # 3 details panels
136
+ renderer/menus/ # Force Sync (ExternalSecret)
137
+ renderer/icons/ # External Secrets Operator logo (currentColor)
138
+ renderer/components/ # createAvailableVersionPage, error boundaries
139
+ examples/eso/ # test objects (kubectl apply -f)
101
140
  ```
102
141
 
103
- O workflow `.github/workflows/release.yaml` também publica automaticamente no push de uma tag
104
- `v*` (requer o secret `NPM_TOKEN` do registry npm no repositório GitHub).
142
+ Build output goes to `out/main/index.js` and `out/renderer/index.js` (CommonJS bundles, like
143
+ the other Freelens 1.x extensions); `package.json` points `main`/`renderer` at them.
105
144
 
106
- ## Instalar no Freelens (a partir do diretório, para desenvolvimento)
145
+ ## Supported API versions
107
146
 
108
- 1. `pnpm install && pnpm build` (ou deixe `pnpm dev` rodando para o watch).
109
- 2. No Freelens, em **Extensions**, escolha **Install from directory** e aponte para este
110
- diretório. Confirme carregar a extensão "in place" para que os rebuilds recarreguem sozinhos.
147
+ The extension supports **`external-secrets.io/v1` only** (one version per kind, with the
148
+ "Not Available" page when the CRD is missing). `v1beta1` has been unserved since ESO 0.9
149
+ (2023); to add it later, follow the same per-version model/page/details pattern and list
150
+ both versions in `createAvailableVersionPage`, newest first.
111
151
 
112
- ## Testar com os exemplos
113
-
114
- Aplique os objetos de exemplo em um cluster com o ESO instalado:
152
+ ## Publishing a release
115
153
 
116
154
  ```powershell
117
- kubectl apply -f examples/eso/secretstore.yaml
118
- kubectl apply -f examples/eso/clustersecretstore.yaml
119
- kubectl apply -f examples/eso/externalsecret.yaml
155
+ pnpm bump-version patch # or minor/major/prerelease
156
+ pnpm build
157
+ pnpm publish # requires npmjs.com authentication (NODE_AUTH_TOKEN)
120
158
  ```
121
159
 
122
- As páginas "Secret Stores", "Cluster Secret Stores" e "External Secrets" devem listar
123
- `fake-store`, `fake-cluster-store` e `hello-world`, e o details do ExternalSecret mostra a
124
- condition `Ready=SecretSynced` depois do primeiro sync (o provider `fake` serve o par
125
- `/hello → world`, usado para criar o Secret `hello-world` com a chave `hello`).
126
-
127
- ## Estrutura
160
+ The `.github/workflows/release.yaml` workflow also publishes automatically when a `v*` tag
161
+ is pushed (it needs the npm registry `NPM_TOKEN` secret in the GitHub repository, or npm
162
+ Trusted Publishing / provenance).
128
163
 
129
- ```text
130
- electron.vite.config.js # config do electron-vite (main + renderer em preload)
131
- build/global-externals.js # plugin: react/mobx/... → globals do host (v1)
132
- src/
133
- main/index.ts # entry main (sem estado)
134
- renderer/index.tsx # registros v1: apiManager, 3 páginas, details, menu
135
- renderer/api/types.ts # tipos do spec/status do ESO
136
- renderer/api/store-helpers.ts # helpers puros de status dos stores
137
- renderer/api/externalsecret/externalsecret-v1.ts # modelo ExternalSecret (+ Api/Store consts, teste)
138
- renderer/api/secretstore/secretstore-v1.ts # modelo SecretStore (+ Api/Store consts, teste)
139
- renderer/api/clustersecretstore/clustersecretstore-v1.ts # modelo ClusterSecretStore (+ Api/Store consts, teste)
140
- renderer/pages/ # 3 páginas + CSS module
141
- renderer/details/ # 3 painéis de detalhes
142
- renderer/menus/ # Force Sync (ExternalSecret)
143
- renderer/icons/ # ícone cadeado + seta de refresh
144
- renderer/components/ # createAvailableVersionPage, error boundaries
145
- examples/eso/ # objetos de teste (kubectl apply -f)
146
- ```
164
+ ## License
147
165
 
148
- Build em `out/main/index.js` e `out/renderer/index.js` (bundles CommonJS, como as extensões
149
- Freelens 1.x); `package.json` aponta `main`/`renderer` para esses arquivos.
150
-
151
- ## Versões da API
152
-
153
- A extensão suporta **somente `external-secrets.io/v1`** (uma versão por kind, com a página
154
- "Not Available" quando a CRD não está instalada). O `v1beta1` está unserved desde o ESO 0.9
155
- (2023); para adicioná-lo depois, siga o mesmo padrão de modelo/página/details por versão e
156
- liste as duas em `createAvailableVersionPage`, da mais nova para a mais antiga.
157
-
158
- ## Desvios do template
159
-
160
- - `packageManager` = `pnpm@11.28.6` (pnpm 12 exige lock em `%LOCALAPPDATA%`, negado no sandbox).
161
- - `nodeLinker: hoisted` em `pnpm-workspace.yaml`.
162
- - O build usa electron-vite (`electron.vite.config.js` + `build/global-externals.js`, espelhando
163
- o fluxcd v5.3.1): `react`/`react-dom`/`mobx`/`mobx-react`/`@freelensapp/extensions` são
164
- fornecidos pelo host v1 via `global.*` e ficam externos; main e renderer saem como CommonJS.
165
- - A seção `preload` do electron-vite compila o renderer (sem HTML de entrada) para `out/renderer`.
166
- - CSS dos módulos entra nas páginas via `?inline` + `<style>` (padrão do fluxcd v1), porque o
167
- build com `preserveModules` não garante um único `renderer.css` carregado pelo host.
168
- - O config do electron-vite **não** usa `@vitejs/plugin-react` (ao contrário do fluxcd): o
169
- carregador CommonJS do config não consegue `require()` o grafo ESM do plugin (tem
170
- top-level `await`) e o sandbox não executa o bundler esbuild do electron-vite; o JSX do
171
- renderer usa o transform automático nativo do Vite (`react/jsx-runtime` → global do host).
172
- O plugin permanece como devDependency (espelho do fluxcd) e o knip o ignora.
173
- - `test:unit` usa `--pool=threads` porque o pool forks do vitest spawna processos filhos,
174
- bloqueados no sandbox.
175
- - `knip:check` usa `&&` em vez do padrão regex `pnpm "/^...$/"` (sintaxe de aspas quebra no
176
- `cmd.exe` do Windows).
177
- - Sem preferências/ExtensionStore e sem testes de integração (o main é uma classe mínima).
166
+ MIT. The sidebar icon is the External Secrets Operator logo
167
+ ([external-secrets.io](https://external-secrets.io/), Apache-2.0), recolored with
168
+ `currentColor` so it follows the Freelens theme.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freelens-eso-extension",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Freelens extension for External Secrets Operator",
5
5
  "repository": {
6
6
  "type": "git",