@rmartz/envctl 3.1.1

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 (190) hide show
  1. package/README.md +79 -0
  2. package/dist/envctl.d.ts +3 -0
  3. package/dist/envctl.d.ts.map +1 -0
  4. package/dist/envctl.js +36 -0
  5. package/dist/envctl.js.map +1 -0
  6. package/dist/lib/auth.d.ts +21 -0
  7. package/dist/lib/auth.d.ts.map +1 -0
  8. package/dist/lib/auth.js +148 -0
  9. package/dist/lib/auth.js.map +1 -0
  10. package/dist/lib/check-firebase.d.ts +6 -0
  11. package/dist/lib/check-firebase.d.ts.map +1 -0
  12. package/dist/lib/check-firebase.js +81 -0
  13. package/dist/lib/check-firebase.js.map +1 -0
  14. package/dist/lib/check-live.d.ts +3 -0
  15. package/dist/lib/check-live.d.ts.map +1 -0
  16. package/dist/lib/check-live.js +50 -0
  17. package/dist/lib/check-live.js.map +1 -0
  18. package/dist/lib/check.d.ts +9 -0
  19. package/dist/lib/check.d.ts.map +1 -0
  20. package/dist/lib/check.js +165 -0
  21. package/dist/lib/check.js.map +1 -0
  22. package/dist/lib/cli/help.d.ts +4 -0
  23. package/dist/lib/cli/help.d.ts.map +1 -0
  24. package/dist/lib/cli/help.js +52 -0
  25. package/dist/lib/cli/help.js.map +1 -0
  26. package/dist/lib/cli/registry.d.ts +19 -0
  27. package/dist/lib/cli/registry.d.ts.map +1 -0
  28. package/dist/lib/cli/registry.js +111 -0
  29. package/dist/lib/cli/registry.js.map +1 -0
  30. package/dist/lib/cli/router.d.ts +22 -0
  31. package/dist/lib/cli/router.d.ts.map +1 -0
  32. package/dist/lib/cli/router.js +98 -0
  33. package/dist/lib/cli/router.js.map +1 -0
  34. package/dist/lib/cli/version.d.ts +2 -0
  35. package/dist/lib/cli/version.d.ts.map +1 -0
  36. package/dist/lib/cli/version.js +58 -0
  37. package/dist/lib/cli/version.js.map +1 -0
  38. package/dist/lib/commands/auth.d.ts +2 -0
  39. package/dist/lib/commands/auth.d.ts.map +1 -0
  40. package/dist/lib/commands/auth.js +33 -0
  41. package/dist/lib/commands/auth.js.map +1 -0
  42. package/dist/lib/commands/bootstrap-args.d.ts +11 -0
  43. package/dist/lib/commands/bootstrap-args.d.ts.map +1 -0
  44. package/dist/lib/commands/bootstrap-args.js +111 -0
  45. package/dist/lib/commands/bootstrap-args.js.map +1 -0
  46. package/dist/lib/commands/bootstrap.d.ts +5 -0
  47. package/dist/lib/commands/bootstrap.d.ts.map +1 -0
  48. package/dist/lib/commands/bootstrap.js +166 -0
  49. package/dist/lib/commands/bootstrap.js.map +1 -0
  50. package/dist/lib/commands/check.d.ts +3 -0
  51. package/dist/lib/commands/check.d.ts.map +1 -0
  52. package/dist/lib/commands/check.js +47 -0
  53. package/dist/lib/commands/check.js.map +1 -0
  54. package/dist/lib/commands/config-pull.d.ts +12 -0
  55. package/dist/lib/commands/config-pull.d.ts.map +1 -0
  56. package/dist/lib/commands/config-pull.js +161 -0
  57. package/dist/lib/commands/config-pull.js.map +1 -0
  58. package/dist/lib/commands/config-push-args.d.ts +9 -0
  59. package/dist/lib/commands/config-push-args.d.ts.map +1 -0
  60. package/dist/lib/commands/config-push-args.js +108 -0
  61. package/dist/lib/commands/config-push-args.js.map +1 -0
  62. package/dist/lib/commands/config-push.d.ts +6 -0
  63. package/dist/lib/commands/config-push.d.ts.map +1 -0
  64. package/dist/lib/commands/config-push.js +166 -0
  65. package/dist/lib/commands/config-push.js.map +1 -0
  66. package/dist/lib/commands/deployment-config.d.ts +9 -0
  67. package/dist/lib/commands/deployment-config.d.ts.map +1 -0
  68. package/dist/lib/commands/deployment-config.js +73 -0
  69. package/dist/lib/commands/deployment-config.js.map +1 -0
  70. package/dist/lib/commands/env-plan.d.ts +4 -0
  71. package/dist/lib/commands/env-plan.d.ts.map +1 -0
  72. package/dist/lib/commands/env-plan.js +85 -0
  73. package/dist/lib/commands/env-plan.js.map +1 -0
  74. package/dist/lib/commands/env.d.ts +4 -0
  75. package/dist/lib/commands/env.d.ts.map +1 -0
  76. package/dist/lib/commands/env.js +122 -0
  77. package/dist/lib/commands/env.js.map +1 -0
  78. package/dist/lib/commands/init.d.ts +3 -0
  79. package/dist/lib/commands/init.d.ts.map +1 -0
  80. package/dist/lib/commands/init.js +59 -0
  81. package/dist/lib/commands/init.js.map +1 -0
  82. package/dist/lib/commands/secrets-args.d.ts +13 -0
  83. package/dist/lib/commands/secrets-args.d.ts.map +1 -0
  84. package/dist/lib/commands/secrets-args.js +136 -0
  85. package/dist/lib/commands/secrets-args.js.map +1 -0
  86. package/dist/lib/commands/secrets-plan.d.ts +9 -0
  87. package/dist/lib/commands/secrets-plan.d.ts.map +1 -0
  88. package/dist/lib/commands/secrets-plan.js +109 -0
  89. package/dist/lib/commands/secrets-plan.js.map +1 -0
  90. package/dist/lib/commands/secrets.d.ts +7 -0
  91. package/dist/lib/commands/secrets.d.ts.map +1 -0
  92. package/dist/lib/commands/secrets.js +191 -0
  93. package/dist/lib/commands/secrets.js.map +1 -0
  94. package/dist/lib/deployments.d.ts +4 -0
  95. package/dist/lib/deployments.d.ts.map +1 -0
  96. package/dist/lib/deployments.js +83 -0
  97. package/dist/lib/deployments.js.map +1 -0
  98. package/dist/lib/environments.d.ts +4 -0
  99. package/dist/lib/environments.d.ts.map +1 -0
  100. package/dist/lib/environments.js +97 -0
  101. package/dist/lib/environments.js.map +1 -0
  102. package/dist/lib/firebase-credential.d.ts +28 -0
  103. package/dist/lib/firebase-credential.d.ts.map +1 -0
  104. package/dist/lib/firebase-credential.js +50 -0
  105. package/dist/lib/firebase-credential.js.map +1 -0
  106. package/dist/lib/firebase-invalidate.d.ts +4 -0
  107. package/dist/lib/firebase-invalidate.d.ts.map +1 -0
  108. package/dist/lib/firebase-invalidate.js +61 -0
  109. package/dist/lib/firebase-invalidate.js.map +1 -0
  110. package/dist/lib/firebase-vars.d.ts +14 -0
  111. package/dist/lib/firebase-vars.d.ts.map +1 -0
  112. package/dist/lib/firebase-vars.js +40 -0
  113. package/dist/lib/firebase-vars.js.map +1 -0
  114. package/dist/lib/firebase.d.ts +20 -0
  115. package/dist/lib/firebase.d.ts.map +1 -0
  116. package/dist/lib/firebase.js +189 -0
  117. package/dist/lib/firebase.js.map +1 -0
  118. package/dist/lib/gcp.d.ts +4 -0
  119. package/dist/lib/gcp.d.ts.map +1 -0
  120. package/dist/lib/gcp.js +53 -0
  121. package/dist/lib/gcp.js.map +1 -0
  122. package/dist/lib/generated-secrets.d.ts +16 -0
  123. package/dist/lib/generated-secrets.d.ts.map +1 -0
  124. package/dist/lib/generated-secrets.js +68 -0
  125. package/dist/lib/generated-secrets.js.map +1 -0
  126. package/dist/lib/logger.d.ts +7 -0
  127. package/dist/lib/logger.d.ts.map +1 -0
  128. package/dist/lib/logger.js +60 -0
  129. package/dist/lib/logger.js.map +1 -0
  130. package/dist/lib/manifest/index.d.ts +6 -0
  131. package/dist/lib/manifest/index.d.ts.map +1 -0
  132. package/dist/lib/manifest/index.js +15 -0
  133. package/dist/lib/manifest/index.js.map +1 -0
  134. package/dist/lib/manifest/parse.d.ts +11 -0
  135. package/dist/lib/manifest/parse.d.ts.map +1 -0
  136. package/dist/lib/manifest/parse.js +214 -0
  137. package/dist/lib/manifest/parse.js.map +1 -0
  138. package/dist/lib/manifest/resolve.d.ts +9 -0
  139. package/dist/lib/manifest/resolve.d.ts.map +1 -0
  140. package/dist/lib/manifest/resolve.js +34 -0
  141. package/dist/lib/manifest/resolve.js.map +1 -0
  142. package/dist/lib/manifest/types.d.ts +57 -0
  143. package/dist/lib/manifest/types.d.ts.map +1 -0
  144. package/dist/lib/manifest/types.js +12 -0
  145. package/dist/lib/manifest/types.js.map +1 -0
  146. package/dist/lib/manifest/write.d.ts +3 -0
  147. package/dist/lib/manifest/write.d.ts.map +1 -0
  148. package/dist/lib/manifest/write.js +110 -0
  149. package/dist/lib/manifest/write.js.map +1 -0
  150. package/dist/lib/project.d.ts +6 -0
  151. package/dist/lib/project.d.ts.map +1 -0
  152. package/dist/lib/project.js +56 -0
  153. package/dist/lib/project.js.map +1 -0
  154. package/dist/lib/providers/deployment.d.ts +19 -0
  155. package/dist/lib/providers/deployment.d.ts.map +1 -0
  156. package/dist/lib/providers/deployment.js +62 -0
  157. package/dist/lib/providers/deployment.js.map +1 -0
  158. package/dist/lib/providers/registry.d.ts +5 -0
  159. package/dist/lib/providers/registry.d.ts.map +1 -0
  160. package/dist/lib/providers/registry.js +31 -0
  161. package/dist/lib/providers/registry.js.map +1 -0
  162. package/dist/lib/providers/service.d.ts +35 -0
  163. package/dist/lib/providers/service.d.ts.map +1 -0
  164. package/dist/lib/providers/service.js +81 -0
  165. package/dist/lib/providers/service.js.map +1 -0
  166. package/dist/lib/rotation-preflight.d.ts +11 -0
  167. package/dist/lib/rotation-preflight.d.ts.map +1 -0
  168. package/dist/lib/rotation-preflight.js +47 -0
  169. package/dist/lib/rotation-preflight.js.map +1 -0
  170. package/dist/lib/rotation.d.ts +33 -0
  171. package/dist/lib/rotation.d.ts.map +1 -0
  172. package/dist/lib/rotation.js +168 -0
  173. package/dist/lib/rotation.js.map +1 -0
  174. package/dist/lib/sentry.d.ts +5 -0
  175. package/dist/lib/sentry.d.ts.map +1 -0
  176. package/dist/lib/sentry.js +132 -0
  177. package/dist/lib/sentry.js.map +1 -0
  178. package/dist/lib/subprocess.d.ts +8 -0
  179. package/dist/lib/subprocess.d.ts.map +1 -0
  180. package/dist/lib/subprocess.js +30 -0
  181. package/dist/lib/subprocess.js.map +1 -0
  182. package/dist/lib/targets.d.ts +3 -0
  183. package/dist/lib/targets.d.ts.map +1 -0
  184. package/dist/lib/targets.js +25 -0
  185. package/dist/lib/targets.js.map +1 -0
  186. package/dist/lib/vercel-api.d.ts +50 -0
  187. package/dist/lib/vercel-api.d.ts.map +1 -0
  188. package/dist/lib/vercel-api.js +176 -0
  189. package/dist/lib/vercel-api.js.map +1 -0
  190. package/package.json +53 -0
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.triggerAndWaitRedeployments = triggerAndWaitRedeployments;
4
+ exports.refreshPreviewDeployments = refreshPreviewDeployments;
5
+ const logger_1 = require("./logger");
6
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
7
+ function targetEnvs(targetEnv) {
8
+ if (targetEnv === "all")
9
+ return ["production", "preview", "development"];
10
+ return [targetEnv];
11
+ }
12
+ // Poll one redeployment and report its outcome. A `canceled` result is benign
13
+ // (#125): Vercel auto-cancels a redeploy when a newer build supersedes it, so
14
+ // verification simply didn't complete on this deployment — the pushed variables
15
+ // are already saved on the target and take effect on its next successful build.
16
+ // It is a warning, not a failure; only a genuine ERROR/timeout throws (from
17
+ // pollDeploymentStatus).
18
+ async function pollAndReport(client, id) {
19
+ (0, logger_1.log)(` Polling ${id}...`);
20
+ const status = await client.pollDeploymentStatus(id, 60, 10_000);
21
+ if (status === "canceled") {
22
+ (0, logger_1.warn)(` ${id} → CANCELED (superseded by a newer build or auto-canceled). The pushed variables are saved on the target and apply on its next successful build; verification did not complete for this deployment.`);
23
+ }
24
+ else {
25
+ (0, logger_1.log)(` ${id} → READY`);
26
+ }
27
+ return status;
28
+ }
29
+ // ─── Redeployment ─────────────────────────────────────────────────────────────
30
+ async function triggerAndWaitRedeployments(targetEnv, client) {
31
+ (0, logger_1.log)("Triggering redeployments...");
32
+ const deploymentIds = [];
33
+ for (const vercelEnv of targetEnvs(targetEnv)) {
34
+ if (vercelEnv === "development") {
35
+ (0, logger_1.log)(` [${vercelEnv}] No remote deployment target — skipping`);
36
+ continue;
37
+ }
38
+ const deployTarget = vercelEnv === "production" ? "production" : "staging";
39
+ const latest = await client.getLatestDeployment(deployTarget);
40
+ if (!latest) {
41
+ (0, logger_1.warn)(`No READY deployment found for '${vercelEnv}' — skipping redeployment`);
42
+ continue;
43
+ }
44
+ (0, logger_1.log)(` Redeploying ${vercelEnv} (${latest.url})...`);
45
+ const newId = await client.triggerRedeployment(latest.uid, latest.name, deployTarget);
46
+ deploymentIds.push(newId);
47
+ (0, logger_1.log)(` Queued: ${newId}`);
48
+ }
49
+ if (deploymentIds.length === 0)
50
+ return;
51
+ (0, logger_1.log)(`Waiting for ${deploymentIds.length} deployment(s) to finish...`);
52
+ let allReady = true;
53
+ for (const id of deploymentIds) {
54
+ if ((await pollAndReport(client, id)) === "canceled")
55
+ allReady = false;
56
+ }
57
+ (0, logger_1.log)(allReady ? "All deployments ready." : "Redeployment polling complete.");
58
+ }
59
+ async function refreshPreviewDeployments(client) {
60
+ const previews = await client.listPreviewDeployments();
61
+ if (previews.length === 0) {
62
+ (0, logger_1.log)("No active preview deployments found — skipping preview refresh.");
63
+ return;
64
+ }
65
+ (0, logger_1.log)(`Refreshing ${previews.length} active preview deployment(s)...`);
66
+ const newIds = [];
67
+ for (const preview of previews) {
68
+ (0, logger_1.log)(` Redeploying ${preview.url}...`);
69
+ const newId = await client.triggerRedeployment(preview.uid, preview.name);
70
+ newIds.push(newId);
71
+ (0, logger_1.log)(` Queued: ${newId}`);
72
+ }
73
+ (0, logger_1.log)(`Waiting for ${newIds.length} preview deployment(s) to finish...`);
74
+ let allReady = true;
75
+ for (const id of newIds) {
76
+ if ((await pollAndReport(client, id)) === "canceled")
77
+ allReady = false;
78
+ }
79
+ (0, logger_1.log)(allReady
80
+ ? "Preview deployments refreshed."
81
+ : "Preview redeployment polling complete.");
82
+ }
83
+ //# sourceMappingURL=deployments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployments.js","sourceRoot":"","sources":["../../src/lib/deployments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function listActiveEnvs(deploymentDir: string): string[];
2
+ export declare function parseDeploymentEnv(deploymentDir: string, envName: string): Record<string, string>;
3
+ export declare function vercelTarget(envName: string): string;
4
+ //# sourceMappingURL=environments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/lib/environments.ts"],"names":[],"mappings":"AAiBA,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAI9D;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BxB;AAgBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.listActiveEnvs = listActiveEnvs;
37
+ exports.parseDeploymentEnv = parseDeploymentEnv;
38
+ exports.vercelTarget = vercelTarget;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const yaml = __importStar(require("js-yaml"));
42
+ // js-yaml 5 throws "expected a document, but the input is empty" on blank
43
+ // input, where v4 returned undefined. Treat a blank file as null so empty
44
+ // configs degrade to the empty result instead of raising.
45
+ function loadYamlFile(filePath) {
46
+ const content = fs.readFileSync(filePath, "utf-8");
47
+ return content.trim() === "" ? null : yaml.load(content);
48
+ }
49
+ function listActiveEnvs(deploymentDir) {
50
+ const envFile = path.join(deploymentDir, "environments.yml");
51
+ const data = loadYamlFile(envFile);
52
+ return data?.active ?? [];
53
+ }
54
+ function parseDeploymentEnv(deploymentDir, envName) {
55
+ const envFile = path.join(deploymentDir, `${envName}.yml`);
56
+ if (!fs.existsSync(envFile))
57
+ return {};
58
+ const data = loadYamlFile(envFile);
59
+ if (!data || typeof data !== "object" || Array.isArray(data))
60
+ return {};
61
+ // Support nested `variables:` format ({ environment: "staging", variables: { KEY: val } })
62
+ // as well as flat format ({ KEY: val }).
63
+ const vars = data.variables !== null &&
64
+ data.variables !== undefined &&
65
+ typeof data.variables === "object" &&
66
+ !Array.isArray(data.variables)
67
+ ? data.variables
68
+ : data;
69
+ const result = {};
70
+ for (const [key, value] of Object.entries(vars)) {
71
+ if (typeof value !== "string" &&
72
+ typeof value !== "number" &&
73
+ typeof value !== "boolean")
74
+ continue;
75
+ const strValue = typeof value === "boolean" ? String(value).toLowerCase() : String(value);
76
+ if (strValue)
77
+ result[key] = strValue;
78
+ }
79
+ return result;
80
+ }
81
+ // The name→target convention. As of #87 this is the **fallback** used only when
82
+ // the manifest's authoritative `deployments[].targets` map does not declare a
83
+ // target for an environment (a legacy config with no `targets:` block, or an env
84
+ // omitted from the map). Manifest-aware resolution lives in `targets.ts`
85
+ // (`resolveEnvTarget` / `envTargetResolver`); prefer it over calling this
86
+ // directly. It is also the basis parseManifest uses to derive targets for a
87
+ // legacy config, so back-compat resolution is unchanged.
88
+ const TARGET_MAP = {
89
+ production: "production",
90
+ staging: "preview",
91
+ preview: "preview",
92
+ development: "development",
93
+ };
94
+ function vercelTarget(envName) {
95
+ return TARGET_MAP[envName] ?? envName;
96
+ }
97
+ //# sourceMappingURL=environments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environments.js","sourceRoot":"","sources":["../../src/lib/environments.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,wCAIC;AAED,gDAiCC;AAgBD,oCAEC;AA1ED,uCAAyB;AACzB,2CAA6B;AAE7B,8CAAgC;AAMhC,0EAA0E;AAC1E,0EAA0E;AAC1E,0DAA0D;AAC1D,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,cAAc,CAAC,aAAqB;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAA8B,CAAC;IAChE,OAAO,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,SAAgB,kBAAkB,CAChC,aAAqB,EACrB,OAAe;IAEf,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,OAAO,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAmC,CAAC;IACrE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAExE,2FAA2F;IAC3F,yCAAyC;IACzC,MAAM,IAAI,GACR,IAAI,CAAC,SAAS,KAAK,IAAI;QACvB,IAAI,CAAC,SAAS,KAAK,SAAS;QAC5B,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;QAClC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAC5B,CAAC,CAAE,IAAI,CAAC,SAAqC;QAC7C,CAAC,CAAC,IAAI,CAAC;IAEX,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,SAAS;YAE1B,SAAS;QACX,MAAM,QAAQ,GACZ,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3E,IAAI,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IACvC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,8EAA8E;AAC9E,iFAAiF;AACjF,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,yDAAyD;AACzD,MAAM,UAAU,GAA2B;IACzC,UAAU,EAAE,YAAY;IACxB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;CAC3B,CAAC;AAEF,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;AACxC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { ServiceDecl } from "./manifest/types";
2
+ /** The provider's logical credential fields. */
3
+ export type FirebaseField = "projectId" | "clientEmail" | "privateKey" | "privateKeyId";
4
+ /** The default var name for each field — the back-compat naming envctl assumed. */
5
+ export declare const DEFAULT_FIREBASE_VAR_NAMES: Record<FirebaseField, string>;
6
+ export interface FirebaseCredentialSpec {
7
+ /** Resolved var name for every field (declared override ?? default). */
8
+ readonly names: Readonly<Record<FirebaseField, string>>;
9
+ }
10
+ /**
11
+ * Resolve a `firebase` service declaration into a concrete credential contract:
12
+ * the resolved var name for every field. A missing declaration (or missing
13
+ * fields) falls back to the default names.
14
+ *
15
+ * Throws if any override value is empty or if two fields resolve to the same
16
+ * var name — both produce unusable Vercel credentials.
17
+ */
18
+ export declare function resolveFirebaseCredential(service?: ServiceDecl): FirebaseCredentialSpec;
19
+ /**
20
+ * Keys whose presence in Vercel means Firebase is provisioned under the
21
+ * declared contract. Uses only the resolved names so the presence check is
22
+ * consistent with what the readers ({@link firebase-vars}) look for —
23
+ * advertising a legacy default name for a custom-named contract would cause
24
+ * `rotation.run` to detect Firebase as present but then fail inside
25
+ * `rotateFirebase` when the custom var can't be resolved.
26
+ */
27
+ export declare function firebasePresenceKeys(spec: FirebaseCredentialSpec): string[];
28
+ //# sourceMappingURL=firebase-credential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-credential.d.ts","sourceRoot":"","sources":["../../src/lib/firebase-credential.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQpD,gDAAgD;AAChD,MAAM,MAAM,aAAa,GACvB,WAAW,GAAG,aAAa,GAAG,YAAY,GAAG,cAAc,CAAC;AAE9D,mFAAmF;AACnF,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKpE,CAAC;AAIF,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,CAAC,EAAE,WAAW,GACpB,sBAAsB,CA2BxB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAE3E"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_FIREBASE_VAR_NAMES = void 0;
4
+ exports.resolveFirebaseCredential = resolveFirebaseCredential;
5
+ exports.firebasePresenceKeys = firebasePresenceKeys;
6
+ /** The default var name for each field — the back-compat naming envctl assumed. */
7
+ exports.DEFAULT_FIREBASE_VAR_NAMES = {
8
+ projectId: "FIREBASE_PROJECT_ID",
9
+ clientEmail: "FIREBASE_CLIENT_EMAIL",
10
+ privateKey: "FIREBASE_PRIVATE_KEY",
11
+ privateKeyId: "FIREBASE_PRIVATE_KEY_ID",
12
+ };
13
+ const ALL_FIELDS = Object.keys(exports.DEFAULT_FIREBASE_VAR_NAMES);
14
+ /**
15
+ * Resolve a `firebase` service declaration into a concrete credential contract:
16
+ * the resolved var name for every field. A missing declaration (or missing
17
+ * fields) falls back to the default names.
18
+ *
19
+ * Throws if any override value is empty or if two fields resolve to the same
20
+ * var name — both produce unusable Vercel credentials.
21
+ */
22
+ function resolveFirebaseCredential(service) {
23
+ const overrides = service?.variables ?? {};
24
+ for (const [field, name] of Object.entries(overrides)) {
25
+ if (!name || !name.trim())
26
+ throw new Error(`Firebase credential override for '${field}' must not be empty`);
27
+ }
28
+ const names = {};
29
+ for (const field of ALL_FIELDS)
30
+ names[field] = overrides[field] ?? exports.DEFAULT_FIREBASE_VAR_NAMES[field];
31
+ const seen = new Set();
32
+ for (const [field, name] of Object.entries(names)) {
33
+ if (seen.has(name))
34
+ throw new Error(`Firebase credential var names must be unique; '${name}' is mapped to multiple fields (including '${field}')`);
35
+ seen.add(name);
36
+ }
37
+ return { names };
38
+ }
39
+ /**
40
+ * Keys whose presence in Vercel means Firebase is provisioned under the
41
+ * declared contract. Uses only the resolved names so the presence check is
42
+ * consistent with what the readers ({@link firebase-vars}) look for —
43
+ * advertising a legacy default name for a custom-named contract would cause
44
+ * `rotation.run` to detect Firebase as present but then fail inside
45
+ * `rotateFirebase` when the custom var can't be resolved.
46
+ */
47
+ function firebasePresenceKeys(spec) {
48
+ return [spec.names.privateKey];
49
+ }
50
+ //# sourceMappingURL=firebase-credential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-credential.js","sourceRoot":"","sources":["../../src/lib/firebase-credential.ts"],"names":[],"mappings":";;;AAmCA,8DA6BC;AAUD,oDAEC;AAhED,mFAAmF;AACtE,QAAA,0BAA0B,GAAkC;IACvE,SAAS,EAAE,qBAAqB;IAChC,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE,sBAAsB;IAClC,YAAY,EAAE,yBAAyB;CACxC,CAAC;AAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,kCAA0B,CAAoB,CAAC;AAO9E;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CACvC,OAAqB;IAErB,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACvB,MAAM,IAAI,KAAK,CACb,qCAAqC,KAAK,qBAAqB,CAChE,CAAC;IACN,CAAC;IAED,MAAM,KAAK,GAAG,EAAmC,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,UAAU;QAC5B,KAAK,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,kCAA0B,CAAC,KAAK,CAAC,CAAC;IAEvE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAG7C,EAAE,CAAC;QACJ,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,kDAAkD,IAAI,8CAA8C,KAAK,IAAI,CAC9G,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAAC,IAA4B;IAC/D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { FirebaseIdentity } from "./firebase";
2
+ import type { DeploymentProvider } from "./providers/deployment";
3
+ export declare function invalidateFirebaseKeys(client: DeploymentProvider, fp: FirebaseIdentity): Promise<void>;
4
+ //# sourceMappingURL=firebase-invalidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-invalidate.d.ts","sourceRoot":"","sources":["../../src/lib/firebase-invalidate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAMjE,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE,gBAAgB,GACnB,OAAO,CAAC,IAAI,CAAC,CAiEf"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.invalidateFirebaseKeys = invalidateFirebaseKeys;
4
+ const firebase_vars_1 = require("./firebase-vars");
5
+ const gcp_1 = require("./gcp");
6
+ const logger_1 = require("./logger");
7
+ // Post-redeploy cleanup: once a rotation's new key is proven live, sweep every
8
+ // non-active user-managed key for each service account so old credentials can't
9
+ // be used. Kept separate from the mint/rotate/init flow (firebase.ts) as its own
10
+ // concern.
11
+ async function invalidateFirebaseKeys(client, fp) {
12
+ (0, logger_1.log)("Invalidating old Firebase keys (sweeping all non-active user-managed keys)...");
13
+ const allEnvs = await client.listEnvVars();
14
+ const activeKeys = new Set();
15
+ const saPairs = new Map(); // email → gcpProject
16
+ const unsweepable = new Set();
17
+ for (const checkEnv of ["production", "preview", "development"]) {
18
+ if (!(0, firebase_vars_1.hasFirebaseCredentialForEnv)(allEnvs.envs, fp.names, checkEnv))
19
+ continue;
20
+ const kid = await (0, firebase_vars_1.getFirebaseKeyIdForEnv)(checkEnv, allEnvs.envs, fp.names, client);
21
+ const saInfo = await (0, firebase_vars_1.getFirebaseSaForEnv)(checkEnv, allEnvs.envs, fp.names, client);
22
+ if (kid) {
23
+ activeKeys.add(kid);
24
+ (0, logger_1.log)(` Active key [${checkEnv}]: ${kid}`);
25
+ }
26
+ if (saInfo) {
27
+ saPairs.set(saInfo.email, saInfo.gcpProject);
28
+ if (!kid)
29
+ unsweepable.add(saInfo.email);
30
+ }
31
+ }
32
+ for (const [saEmail, gcpProject] of saPairs) {
33
+ if (unsweepable.has(saEmail)) {
34
+ (0, logger_1.warn)(`Skipping stray-key sweep for ${saEmail} — not all environments have the key id tracked.`);
35
+ (0, logger_1.warn)(" Rotate all environments first, then re-run to sweep old keys.");
36
+ continue;
37
+ }
38
+ (0, logger_1.log)(` Sweeping SA: ${saEmail}`);
39
+ const allKeys = (0, gcp_1.listUserManagedGcpKeys)(saEmail, gcpProject);
40
+ let deleted = 0;
41
+ for (const keyId of allKeys) {
42
+ if (activeKeys.has(keyId))
43
+ continue;
44
+ (0, logger_1.log)(` Deleting stray key: ${keyId}`);
45
+ try {
46
+ (0, gcp_1.deleteGcpKey)(keyId, saEmail, gcpProject);
47
+ (0, logger_1.log)(` Deleted: ${keyId}`);
48
+ deleted++;
49
+ }
50
+ catch {
51
+ (0, logger_1.warn)(`Failed to delete key ${keyId} — remove manually:`);
52
+ (0, logger_1.warn)(` gcloud iam service-accounts keys delete ${keyId} --iam-account=${saEmail}`);
53
+ }
54
+ }
55
+ if (deleted === 0)
56
+ (0, logger_1.log)(` No stray keys for ${saEmail}.`);
57
+ else
58
+ (0, logger_1.log)(` Deleted ${deleted} stray key(s) for ${saEmail}.`);
59
+ }
60
+ }
61
+ //# sourceMappingURL=firebase-invalidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-invalidate.js","sourceRoot":"","sources":["../../src/lib/firebase-invalidate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FirebaseCredentialSpec } from "./firebase-credential";
2
+ import type { DeploymentProvider } from "./providers/deployment";
3
+ import type { VercelEnvVar } from "./vercel-api";
4
+ type FieldNames = FirebaseCredentialSpec["names"];
5
+ export interface FirebaseSaInfo {
6
+ email: string;
7
+ gcpProject: string;
8
+ }
9
+ export declare function getFirebaseSaForEnv(vercelEnv: string, envs: VercelEnvVar[], names: FieldNames, client: DeploymentProvider): Promise<FirebaseSaInfo | null>;
10
+ export declare function getFirebaseKeyIdForEnv(vercelEnv: string, envs: VercelEnvVar[], names: FieldNames, client: DeploymentProvider): Promise<string>;
11
+ export declare function hasFirebaseCredential(envs: VercelEnvVar[], names: FieldNames): boolean;
12
+ export declare function hasFirebaseCredentialForEnv(envs: VercelEnvVar[], names: FieldNames, vercelEnv: string): boolean;
13
+ export {};
14
+ //# sourceMappingURL=firebase-vars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-vars.d.ts","sourceRoot":"","sources":["../../src/lib/firebase-vars.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD,KAAK,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,EAAE,EACpB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAehC;AAID,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,EAAE,EACpB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAGD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAAE,EACpB,KAAK,EAAE,UAAU,GAChB,OAAO,CAET;AAID,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,YAAY,EAAE,EACpB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAIT"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFirebaseSaForEnv = getFirebaseSaForEnv;
4
+ exports.getFirebaseKeyIdForEnv = getFirebaseKeyIdForEnv;
5
+ exports.hasFirebaseCredential = hasFirebaseCredential;
6
+ exports.hasFirebaseCredentialForEnv = hasFirebaseCredentialForEnv;
7
+ // The service-account identity (email + GCP project) for an environment, read
8
+ // from the discrete `clientEmail` / `projectId` vars. Returns null when the
9
+ // credential is absent for that environment.
10
+ async function getFirebaseSaForEnv(vercelEnv, envs, names, client) {
11
+ const ceRecord = envs.find((e) => e.key === names.clientEmail && e.target.includes(vercelEnv));
12
+ if (!ceRecord)
13
+ return null;
14
+ const email = await client.getEnvVarValue(ceRecord.id);
15
+ let gcpProject = "";
16
+ const pidRecord = envs.find((e) => e.key === names.projectId && e.target.includes(vercelEnv));
17
+ if (pidRecord)
18
+ gcpProject = await client.getEnvVarValue(pidRecord.id);
19
+ if (!gcpProject)
20
+ gcpProject = process.env.GCLOUD_PROJECT ?? "";
21
+ return { email, gcpProject };
22
+ }
23
+ // The active key id for an environment, from the tracked privateKeyId var.
24
+ // "" when untracked.
25
+ async function getFirebaseKeyIdForEnv(vercelEnv, envs, names, client) {
26
+ const record = envs.find((e) => e.key === names.privateKeyId && e.target.includes(vercelEnv));
27
+ if (!record)
28
+ return "";
29
+ return client.getEnvVarValue(record.id);
30
+ }
31
+ // Whether the credential is present anywhere in Vercel (by the resolved names).
32
+ function hasFirebaseCredential(envs, names) {
33
+ return envs.some((e) => e.key === names.privateKey);
34
+ }
35
+ // Whether the credential is present in one environment — so per-env reads and
36
+ // sweeps skip a target that has no credential.
37
+ function hasFirebaseCredentialForEnv(envs, names, vercelEnv) {
38
+ return envs.some((e) => e.key === names.privateKey && e.target.includes(vercelEnv));
39
+ }
40
+ //# sourceMappingURL=firebase-vars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-vars.js","sourceRoot":"","sources":["../../src/lib/firebase-vars.ts"],"names":[],"mappings":";;AAkBA,kDAoBC;AAID,wDAWC;AAGD,sDAKC;AAID,kEAQC;AA1DD,8EAA8E;AAC9E,4EAA4E;AAC5E,6CAA6C;AACtC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,IAAoB,EACpB,KAAiB,EACjB,MAA0B;IAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CACnE,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEvD,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CACjE,CAAC;IACF,IAAI,SAAS;QAAE,UAAU,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU;QAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;IAE/D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED,2EAA2E;AAC3E,qBAAqB;AACd,KAAK,UAAU,sBAAsB,CAC1C,SAAiB,EACjB,IAAoB,EACpB,KAAiB,EACjB,MAA0B;IAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CACpE,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,gFAAgF;AAChF,SAAgB,qBAAqB,CACnC,IAAoB,EACpB,KAAiB;IAEjB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,UAAU,CAAC,CAAC;AACtD,CAAC;AAED,8EAA8E;AAC9E,+CAA+C;AAC/C,SAAgB,2BAA2B,CACzC,IAAoB,EACpB,KAAiB,EACjB,SAAiB;IAEjB,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAClE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type FirebaseCredentialSpec } from "./firebase-credential";
2
+ import type { DeploymentProvider } from "./providers/deployment";
3
+ export interface FirebaseIdentity {
4
+ saEmail: string;
5
+ gcpProject: string;
6
+ /** Resolved credential var names for this project (#98). */
7
+ names: FirebaseCredentialSpec["names"];
8
+ }
9
+ export interface OldFirebaseKey {
10
+ vercelEnv: string;
11
+ keyId: string;
12
+ saEmail: string;
13
+ gcpProject: string;
14
+ }
15
+ export declare function rotateFirebase(targetEnv: string, client: DeploymentProvider, tempDir: string, spec?: FirebaseCredentialSpec, allowedTargets?: string[]): Promise<{
16
+ oldKeys: OldFirebaseKey[];
17
+ fp: FirebaseIdentity;
18
+ }>;
19
+ export declare function initFirebase(targetEnv: string, client: DeploymentProvider, tempDir: string, saEmailOverride?: string, gcpProjectOverride?: string, spec?: FirebaseCredentialSpec, allowedTargets?: string[]): Promise<void>;
20
+ //# sourceMappingURL=firebase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase.d.ts","sourceRoot":"","sources":["../../src/lib/firebase.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAKjE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmFD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,sBAAoD,EAC1D,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IAAC,EAAE,EAAE,gBAAgB,CAAA;CAAE,CAAC,CA2G9D;AAID,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,EACxB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,IAAI,GAAE,sBAAoD,EAC1D,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,IAAI,CAAC,CA4Df"}