@checkstack/secrets-backend 0.2.11 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @checkstack/secrets-backend
2
2
 
3
+ ## 0.2.12
4
+
5
+ ### Patch Changes
6
+
7
+ - 8cad340: Widen Cmd+K command-palette coverage to every top-level sidebar destination.
8
+
9
+ The command palette previously only surfaced commands from a handful of plugins,
10
+ so large feature areas were silently unreachable from search. Each of these
11
+ plugins now registers a "navigate to <feature>" command per top-level route via
12
+ `registerSearchProvider`, so every sidebar destination they own is reachable
13
+ from Cmd+K (entity search can come later):
14
+
15
+ - dependency: "Dependency Map"
16
+ - status-page: "Status pages"
17
+ - satellite: "Satellites"
18
+ - gitops: "GitOps", "Kind Registry"
19
+ - secrets: "Secrets"
20
+ - notification: "Notification Settings"
21
+ - script-packages: "Script Packages", "Script Sandbox"
22
+
23
+ Each command reuses the plugin's own route helper (`resolveRoute`) for its href
24
+ and carries the same access rule that gates its sidebar nav entry, so palette
25
+ visibility matches sidebar visibility. The notification command carries no
26
+ access rule, matching its authenticated-only nav entry.
27
+
28
+ - 8cad340: refactor: replace `env as unknown as EnvStash` double casts with module-scoped holders
29
+
30
+ The `init()` -> `afterPluginsReady()` bridging that stashed setup closures and
31
+ service handles as ad-hoc mutable properties on the framework `env` object via a
32
+ double cast (`env as unknown as EnvStash`) is replaced with typed module- or
33
+ register-scoped `let` holders, mirroring the existing pattern in
34
+ `healthcheck-backend` (`storedEmitHook`). No behavior or DB change; the holders
35
+ are pod-local setup state (never queryable current state), so they remain
36
+ scale-correct. This removes an unsafe, copy-paste-prone idiom from five core
37
+ plugins.
38
+
39
+ - Updated dependencies [8cad340]
40
+ - Updated dependencies [8cad340]
41
+ - Updated dependencies [8cad340]
42
+ - Updated dependencies [8cad340]
43
+ - Updated dependencies [8cad340]
44
+ - Updated dependencies [8cad340]
45
+ - Updated dependencies [8cad340]
46
+ - Updated dependencies [8cad340]
47
+ - @checkstack/backend-api@0.25.0
48
+ - @checkstack/common@0.17.0
49
+ - @checkstack/command-backend@0.2.12
50
+ - @checkstack/secrets-common@0.2.5
51
+
3
52
  ## 0.2.11
4
53
 
5
54
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/secrets-backend",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Secrets platform backend: resolver service, masking, backend extension point, RPC router",
5
5
  "author": "Checkstack contributors",
6
6
  "license": "Elastic-2.0",
@@ -25,21 +25,22 @@
25
25
  "test": "bun test"
26
26
  },
27
27
  "dependencies": {
28
- "@checkstack/backend-api": "0.24.1",
29
- "@checkstack/common": "0.16.0",
30
- "@checkstack/secrets-common": "0.2.4",
28
+ "@checkstack/backend-api": "0.25.0",
29
+ "@checkstack/command-backend": "0.2.12",
30
+ "@checkstack/common": "0.17.0",
31
+ "@checkstack/secrets-common": "0.2.5",
31
32
  "@orpc/server": "^1.14.4",
32
33
  "drizzle-orm": "^0.45.0",
33
34
  "uuid": "^14.0.0",
34
35
  "zod": "^4.2.1"
35
36
  },
36
37
  "devDependencies": {
37
- "@checkstack/scripts": "0.6.2",
38
- "@checkstack/dev-server": "2.2.2",
39
- "@checkstack/backend": "0.20.1",
38
+ "@checkstack/scripts": "0.6.3",
39
+ "@checkstack/dev-server": "2.2.3",
40
+ "@checkstack/backend": "0.21.0",
40
41
  "@checkstack/tsconfig": "0.0.7",
41
- "@checkstack/drizzle-helper": "0.0.5",
42
- "@checkstack/test-utils-backend": "0.1.45",
42
+ "@checkstack/drizzle-helper": "0.0.6",
43
+ "@checkstack/test-utils-backend": "0.1.46",
43
44
  "@types/bun": "^1.3.5",
44
45
  "@types/node": "^20.0.0",
45
46
  "drizzle-kit": "^0.31.10",
package/src/index.ts CHANGED
@@ -6,17 +6,18 @@ import {
6
6
  import {
7
7
  pluginMetadata,
8
8
  secretsAccessRules,
9
+ secretsAccess,
10
+ secretsRoutes,
9
11
  secretsContract,
10
12
  } from "@checkstack/secrets-common";
11
13
  import type { PluginMetadata } from "@checkstack/common";
14
+ import { resolveRoute } from "@checkstack/common";
15
+ import { registerSearchProvider } from "@checkstack/command-backend";
12
16
  import {
13
17
  secretBackendExtensionPoint,
14
18
  type SecretBackend,
15
19
  } from "./secret-backend";
16
- import {
17
- createSecretBackendRegistry,
18
- type SecretBackendRegistry,
19
- } from "./secret-backend-registry";
20
+ import { createSecretBackendRegistry } from "./secret-backend-registry";
20
21
  import {
21
22
  createSecretResolverService,
22
23
  type SecretResolverService,
@@ -70,21 +71,23 @@ export const internalSecretsRef = createServiceRef<InternalSecretsService>(
70
71
  "secrets.internal",
71
72
  );
72
73
 
73
- interface EnvStash {
74
- backends: SecretBackendRegistry;
75
- configStore?: BackendConfigStore;
76
- emitChanged?: (input: {
77
- name: string;
78
- change: "created" | "rotated" | "deleted";
79
- }) => Promise<void>;
80
- }
81
-
82
74
  export default createBackendPlugin({
83
75
  metadata: pluginMetadata,
84
76
 
85
77
  register(env) {
86
78
  const backends = createSecretBackendRegistry();
87
- (env as unknown as EnvStash).backends = backends;
79
+
80
+ // Bridge holders set in init()/afterPluginsReady() and read by the router
81
+ // and admin-service closures wired below. Pod-local setup handles, never
82
+ // queryable current state, so they are scale-safe (mirrors
83
+ // healthcheck-backend's `storedEmitHook`).
84
+ let configStore: BackendConfigStore | undefined;
85
+ let emitChangedSink:
86
+ | ((input: {
87
+ name: string;
88
+ change: "created" | "rotated" | "deleted";
89
+ }) => Promise<void>)
90
+ | undefined;
88
91
 
89
92
  env.registerAccessRules(secretsAccessRules);
90
93
 
@@ -112,7 +115,7 @@ export default createBackendPlugin({
112
115
  };
113
116
 
114
117
  const getActiveBackendId = async (): Promise<string> => {
115
- const store = (env as unknown as EnvStash).configStore;
118
+ const store = configStore;
116
119
  const redacted = await store?.loadRedacted();
117
120
  const persisted = redacted?.activeBackend;
118
121
  if (persisted && backends.has(persisted)) return persisted;
@@ -120,7 +123,7 @@ export default createBackendPlugin({
120
123
  };
121
124
 
122
125
  const setActiveBackendId = async (id: string): Promise<void> => {
123
- const store = (env as unknown as EnvStash).configStore;
126
+ const store = configStore;
124
127
  if (!store) {
125
128
  throw new Error("Backend config store is not initialized yet.");
126
129
  }
@@ -143,7 +146,7 @@ export default createBackendPlugin({
143
146
  name: string;
144
147
  change: "created" | "rotated" | "deleted";
145
148
  }): Promise<void> => {
146
- await (env as unknown as EnvStash).emitChanged?.(input);
149
+ await emitChangedSink?.(input);
147
150
  };
148
151
 
149
152
  const getActiveBackend = async (): Promise<SecretBackend> =>
@@ -173,7 +176,7 @@ export default createBackendPlugin({
173
176
  init: async ({ logger, rpc, config }) => {
174
177
  logger.debug("🔐 Initializing Secrets Backend...");
175
178
 
176
- (env as unknown as EnvStash).configStore = createBackendConfigStore({
179
+ configStore = createBackendConfigStore({
177
180
  config,
178
181
  });
179
182
 
@@ -186,11 +189,28 @@ export default createBackendPlugin({
186
189
  });
187
190
  rpc.registerRouter(router, secretsContract);
188
191
 
192
+ // Register the "Secrets" navigation command in the command palette so
193
+ // the sidebar destination is reachable from Cmd+K. Gated on manage,
194
+ // mirroring the nav entry (the page is the admin settings view).
195
+ registerSearchProvider({
196
+ pluginMetadata,
197
+ commands: [
198
+ {
199
+ id: "home",
200
+ title: "Secrets",
201
+ subtitle: "Create, rotate, and delete secrets",
202
+ iconName: "KeyRound",
203
+ route: resolveRoute(secretsRoutes.routes.home),
204
+ requiredAccessRules: [secretsAccess.secret.manage],
205
+ },
206
+ ],
207
+ });
208
+
189
209
  logger.debug("✅ Secrets Backend initialized.");
190
210
  },
191
211
 
192
212
  afterPluginsReady: async ({ logger, emitHook }) => {
193
- (env as unknown as EnvStash).emitChanged = async (input) => {
213
+ emitChangedSink = async (input) => {
194
214
  await emitHook(secretsChangedHook, input);
195
215
  };
196
216
  logger.debug("✅ Secrets Backend afterPluginsReady complete.");
package/tsconfig.json CHANGED
@@ -10,6 +10,9 @@
10
10
  {
11
11
  "path": "../backend-api"
12
12
  },
13
+ {
14
+ "path": "../command-backend"
15
+ },
13
16
  {
14
17
  "path": "../common"
15
18
  },