@everystack/cli 0.2.22 → 0.2.23

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 (3) hide show
  1. package/package.json +1 -1
  2. package/src/env.ts +2 -0
  3. package/src/sst.ts +75 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everystack/cli",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "CLI and OTA updates for Expo apps on everystack",
5
5
  "license": "AGPL-3.0-only",
6
6
  "publishConfig": {
package/src/env.ts CHANGED
@@ -37,6 +37,8 @@ export interface EnvConfig {
37
37
  mobile?: string[];
38
38
  /** Safe for all client bundles. Gets EXPO_PUBLIC_* for web delivery. */
39
39
  web?: string[];
40
+ /** SST secret declarations (infrastructure). Falls back to server tier if omitted. */
41
+ secrets?: string[];
40
42
  }
41
43
 
42
44
  /** Build surface — determines which tiers pass through the filter. */
package/src/sst.ts CHANGED
@@ -1,15 +1,85 @@
1
1
  /**
2
- * @everystack/cli/sst — Shared env config for SST infrastructure.
2
+ * @everystack/cli/sst — SST infrastructure helpers.
3
3
  *
4
4
  * Reads the same env.config.js that @everystack/cli/env uses,
5
5
  * ensuring sst.config.ts and app.config.js stay in sync.
6
6
  *
7
7
  * Usage in sst.config.ts:
8
- * import { loadEnvConfig } from '@everystack/cli/sst';
9
- * const env = loadEnvConfig();
10
- * // env.server = ['DATABASE_URL', 'JWT_SECRET']
8
+ * const { createSecrets } = await import('@everystack/cli/sst');
9
+ * const { secrets, link, environment } = createSecrets(sst.Secret);
11
10
  *
12
11
  * @module
13
12
  */
14
13
 
15
- export { loadEnvConfig, type EnvConfig } from './env.js';
14
+ import { loadEnvConfig, type EnvConfig } from './env.js';
15
+
16
+ export { loadEnvConfig, type EnvConfig };
17
+
18
+ /**
19
+ * Minimal interface matching the subset of sst.Secret we use.
20
+ *
21
+ * The real sst.Secret is a global available only inside sst.config.ts's
22
+ * run() function. We accept it as a constructor parameter to avoid
23
+ * coupling this package to SST internals.
24
+ */
25
+ interface SecretInstance {
26
+ value: unknown;
27
+ }
28
+
29
+ /** Return type of createSecrets. */
30
+ export interface CreateSecretsResult {
31
+ /** All secrets keyed by env var name for selective access. */
32
+ secrets: Record<string, SecretInstance>;
33
+ /** Flat array of all secret objects for Lambda `link`. */
34
+ link: SecretInstance[];
35
+ /** { KEY: secret.value } map for Lambda `environment`. */
36
+ environment: Record<string, unknown>;
37
+ }
38
+
39
+ /**
40
+ * Create SST Secret objects from env.config.js.
41
+ *
42
+ * Reads the `secrets` field from env.config.js (falls back to `server`
43
+ * tier if omitted). Creates one SST Secret per declared key name.
44
+ *
45
+ * @param SecretConstructor - The sst.Secret class, passed from run()
46
+ * @param configPath - Optional path to env.config.js (auto-discovers if omitted)
47
+ *
48
+ * @example
49
+ * const { createSecrets } = await import('@everystack/cli/sst');
50
+ * const { secrets, link, environment } = createSecrets(sst.Secret);
51
+ *
52
+ * // API Lambda — all secrets
53
+ * new sst.aws.Function('Api', {
54
+ * link: [...link, database, media],
55
+ * environment: { ENVIRONMENT: $app.stage, ...environment },
56
+ * });
57
+ *
58
+ * // Worker Lambda — selective
59
+ * new sst.aws.Function('Worker', {
60
+ * link: [secrets.DATABASE_URL, secrets.JWT_SECRET],
61
+ * });
62
+ *
63
+ * // CloudFront edge auth
64
+ * secrets.JWT_SECRET.value.apply((secret) => authFeature({ secret }));
65
+ */
66
+ export function createSecrets(
67
+ SecretConstructor: new (name: string) => SecretInstance,
68
+ configPath?: string,
69
+ ): CreateSecretsResult {
70
+ const config = loadEnvConfig(configPath);
71
+ const keys = [...new Set(config.secrets ?? config.server ?? [])];
72
+
73
+ const secrets: Record<string, SecretInstance> = {};
74
+ const link: SecretInstance[] = [];
75
+ const environment: Record<string, unknown> = {};
76
+
77
+ for (const key of keys) {
78
+ const secret = new SecretConstructor(key);
79
+ secrets[key] = secret;
80
+ link.push(secret);
81
+ environment[key] = secret.value;
82
+ }
83
+
84
+ return { secrets, link, environment };
85
+ }