envhub-cli 0.1.2 → 0.3.0

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 (41) hide show
  1. package/README.md +5 -5
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +4 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +72 -2
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/pull.d.ts.map +1 -1
  9. package/dist/commands/pull.js +3 -1
  10. package/dist/commands/pull.js.map +1 -1
  11. package/dist/commands/push.d.ts.map +1 -1
  12. package/dist/commands/push.js +3 -2
  13. package/dist/commands/push.js.map +1 -1
  14. package/dist/commands/tui.d.ts +6 -0
  15. package/dist/commands/tui.d.ts.map +1 -0
  16. package/dist/commands/tui.js +30 -0
  17. package/dist/commands/tui.js.map +1 -0
  18. package/dist/config/config.schema.d.ts +2 -2
  19. package/dist/config/config.schema.d.ts.map +1 -1
  20. package/dist/config/config.schema.js +27 -0
  21. package/dist/config/config.schema.js.map +1 -1
  22. package/dist/providers/azure/azure-key-vault.provider.d.ts +27 -0
  23. package/dist/providers/azure/azure-key-vault.provider.d.ts.map +1 -0
  24. package/dist/providers/azure/azure-key-vault.provider.js +190 -0
  25. package/dist/providers/azure/azure-key-vault.provider.js.map +1 -0
  26. package/dist/providers/gcp/gcp-secret-manager.provider.d.ts +26 -0
  27. package/dist/providers/gcp/gcp-secret-manager.provider.d.ts.map +1 -0
  28. package/dist/providers/gcp/gcp-secret-manager.provider.js +199 -0
  29. package/dist/providers/gcp/gcp-secret-manager.provider.js.map +1 -0
  30. package/dist/providers/provider.factory.d.ts.map +1 -1
  31. package/dist/providers/provider.factory.js +12 -4
  32. package/dist/providers/provider.factory.js.map +1 -1
  33. package/dist/tui/app.d.ts +12 -0
  34. package/dist/tui/app.d.ts.map +1 -0
  35. package/dist/tui/app.js +220 -0
  36. package/dist/tui/app.js.map +1 -0
  37. package/dist/utils/envhub-header.d.ts +9 -0
  38. package/dist/utils/envhub-header.d.ts.map +1 -0
  39. package/dist/utils/envhub-header.js +35 -0
  40. package/dist/utils/envhub-header.js.map +1 -0
  41. package/package.json +23 -1
@@ -0,0 +1,190 @@
1
+ import { DefaultAzureCredential } from "@azure/identity";
2
+ import { SecretClient, } from "@azure/keyvault-secrets";
3
+ import { parseEnvContent } from "../../utils/env-parser.js";
4
+ const AZURE_SECRET_NAME_REGEX = /^[0-9a-zA-Z-]+$/;
5
+ const MAX_AZURE_SECRET_NAME_LENGTH = 127;
6
+ /**
7
+ * Azure Key Vault implementation of the SecretProvider interface.
8
+ */
9
+ export class AzureKeyVaultProvider {
10
+ name = "azure";
11
+ client;
12
+ prefix;
13
+ constructor(config, prefix = "envhub-") {
14
+ this.client = new SecretClient(config.vaultUrl, new DefaultAzureCredential());
15
+ this.prefix = prefix;
16
+ }
17
+ fullName(secretName) {
18
+ const fullName = `${this.prefix}${secretName}`;
19
+ if (fullName.length > MAX_AZURE_SECRET_NAME_LENGTH) {
20
+ throw new Error(`Azure Key Vault secret name is too long (${fullName.length}). ` +
21
+ `Maximum length is ${MAX_AZURE_SECRET_NAME_LENGTH}.`);
22
+ }
23
+ if (!AZURE_SECRET_NAME_REGEX.test(fullName)) {
24
+ throw new Error(`Invalid secret name '${fullName}'. Azure Key Vault allows only letters, numbers, and dashes.`);
25
+ }
26
+ return fullName;
27
+ }
28
+ stripPrefix(fullName) {
29
+ if (fullName.startsWith(this.prefix)) {
30
+ return fullName.substring(this.prefix.length);
31
+ }
32
+ return fullName;
33
+ }
34
+ isNotFoundError(error) {
35
+ if (!error || typeof error !== "object") {
36
+ return false;
37
+ }
38
+ const maybeError = error;
39
+ return (maybeError.statusCode === 404 ||
40
+ maybeError.code === "SecretNotFound" ||
41
+ maybeError.code === "NotFound");
42
+ }
43
+ parsePayload(secretName, value) {
44
+ let payload;
45
+ try {
46
+ payload = JSON.parse(value);
47
+ }
48
+ catch {
49
+ throw new Error(`Secret '${secretName}' is not in envhub format. It may have been created outside envhub.`);
50
+ }
51
+ if (!payload ||
52
+ typeof payload !== "object" ||
53
+ !("content" in payload) ||
54
+ !("metadata" in payload)) {
55
+ throw new Error(`Secret '${secretName}' is missing envhub metadata. It may have been created outside envhub.`);
56
+ }
57
+ const parsed = payload;
58
+ if (typeof parsed.content !== "string" ||
59
+ typeof parsed.metadata?.version !== "number") {
60
+ throw new Error(`Secret '${secretName}' has an invalid envhub payload format.`);
61
+ }
62
+ return parsed;
63
+ }
64
+ async getPayload(secretName) {
65
+ const result = await this.client.getSecret(this.fullName(secretName));
66
+ if (!result.value) {
67
+ throw new Error(`Secret '${secretName}' has no string content.`);
68
+ }
69
+ return this.parsePayload(secretName, result.value);
70
+ }
71
+ async secretExists(secretName) {
72
+ try {
73
+ await this.client.getSecret(this.fullName(secretName));
74
+ return true;
75
+ }
76
+ catch (error) {
77
+ if (this.isNotFoundError(error)) {
78
+ return false;
79
+ }
80
+ throw error;
81
+ }
82
+ }
83
+ async push(secretName, content, options) {
84
+ const exists = await this.secretExists(secretName);
85
+ let newVersion = 1;
86
+ if (exists) {
87
+ const currentPayload = await this.getPayload(secretName);
88
+ newVersion = currentPayload.metadata.version + 1;
89
+ }
90
+ const payload = {
91
+ content,
92
+ metadata: {
93
+ version: newVersion,
94
+ message: options?.message,
95
+ updatedAt: new Date().toISOString(),
96
+ managedBy: "envhub-cli",
97
+ },
98
+ };
99
+ const tags = {
100
+ managedBy: "envhub-cli",
101
+ envhubVersion: String(newVersion),
102
+ };
103
+ if (options?.message) {
104
+ tags.envhubMessage = options.message.slice(0, 256);
105
+ }
106
+ await this.client.setSecret(this.fullName(secretName), JSON.stringify(payload), {
107
+ tags,
108
+ });
109
+ return { version: newVersion, name: secretName };
110
+ }
111
+ async pull(secretName) {
112
+ const payload = await this.getPayload(secretName);
113
+ return {
114
+ content: payload.content,
115
+ version: payload.metadata.version,
116
+ name: secretName,
117
+ };
118
+ }
119
+ async cat(secretName) {
120
+ const payload = await this.getPayload(secretName);
121
+ return payload.content;
122
+ }
123
+ async list() {
124
+ const items = [];
125
+ for await (const secret of this.client.listPropertiesOfSecrets()) {
126
+ if (!secret.name.startsWith(this.prefix)) {
127
+ continue;
128
+ }
129
+ items.push(await this.mapListItem(secret));
130
+ }
131
+ return items.sort((a, b) => a.name.localeCompare(b.name));
132
+ }
133
+ async mapListItem(secret) {
134
+ const secretName = this.stripPrefix(secret.name);
135
+ let secretsCount = 0;
136
+ let lastMessage = null;
137
+ try {
138
+ const payload = await this.getPayload(secretName);
139
+ const entries = parseEnvContent(payload.content);
140
+ secretsCount = entries.size;
141
+ lastMessage = payload.metadata.message ?? null;
142
+ }
143
+ catch {
144
+ // If we cannot parse the payload, still show the secret in list output.
145
+ }
146
+ return {
147
+ name: secretName,
148
+ secretsCount,
149
+ updatedAt: secret.updatedOn ?? null,
150
+ lastMessage,
151
+ };
152
+ }
153
+ async delete(secretName, options) {
154
+ const fullName = this.fullName(secretName);
155
+ const poller = await this.client.beginDeleteSecret(fullName);
156
+ await poller.pollUntilDone();
157
+ if (options?.force) {
158
+ try {
159
+ await this.client.purgeDeletedSecret(fullName);
160
+ }
161
+ catch (error) {
162
+ const reason = error instanceof Error ? error.message : "Unknown error.";
163
+ throw new Error(`Failed to force-delete '${secretName}'. Azure Key Vault may block purge (for example due to purge protection). ${reason}`);
164
+ }
165
+ }
166
+ }
167
+ async grant(secretName, userIdentifier) {
168
+ void secretName;
169
+ void userIdentifier;
170
+ throw new Error("Grant is not implemented for Azure Key Vault yet. Use Azure RBAC or access policies in Azure.");
171
+ }
172
+ async revoke(secretName, userIdentifier) {
173
+ void secretName;
174
+ void userIdentifier;
175
+ throw new Error("Revoke is not implemented for Azure Key Vault yet. Use Azure RBAC or access policies in Azure.");
176
+ }
177
+ async getVersion(secretName) {
178
+ try {
179
+ const payload = await this.getPayload(secretName);
180
+ return payload.metadata.version;
181
+ }
182
+ catch (error) {
183
+ if (this.isNotFoundError(error)) {
184
+ return 0;
185
+ }
186
+ throw error;
187
+ }
188
+ }
189
+ }
190
+ //# sourceMappingURL=azure-key-vault.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-key-vault.provider.js","sourceRoot":"","sources":["../../../src/providers/azure/azure-key-vault.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { GCPConfig } from "../../config/config.schema.js";
2
+ import type { DeleteOptions, PullResult, PushOptions, PushResult, SecretListItem, SecretProvider } from "../provider.interface.js";
3
+ export declare class GCPSecretManagerProvider implements SecretProvider {
4
+ readonly name = "gcp";
5
+ private client;
6
+ private prefix;
7
+ private projectId;
8
+ constructor(config: GCPConfig, prefix?: string);
9
+ private get projectPath();
10
+ private fullName;
11
+ private stripPrefix;
12
+ private secretResource;
13
+ private isNotFoundError;
14
+ private parsePayload;
15
+ private secretExists;
16
+ private getPayload;
17
+ push(secretName: string, content: string, options?: PushOptions): Promise<PushResult>;
18
+ pull(secretName: string): Promise<PullResult>;
19
+ cat(secretName: string): Promise<string>;
20
+ list(): Promise<SecretListItem[]>;
21
+ delete(secretName: string, _options?: DeleteOptions): Promise<void>;
22
+ grant(_secretName: string, _userIdentifier: string): Promise<void>;
23
+ revoke(_secretName: string, _userIdentifier: string): Promise<void>;
24
+ getVersion(secretName: string): Promise<number>;
25
+ }
26
+ //# sourceMappingURL=gcp-secret-manager.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcp-secret-manager.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/gcp/gcp-secret-manager.provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACf,MAAM,0BAA0B,CAAC;AAkBlC,qBAAa,wBAAyB,YAAW,cAAc;IAC7D,QAAQ,CAAC,IAAI,SAAS;IACtB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,SAAS,EAAE,MAAM,GAAE,MAAkB;IAMzD,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,YAAY;YAgCN,YAAY;YAYZ,UAAU;IAalB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCrF,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAS7C,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxC,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAyCjC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnE,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAWtD"}
@@ -0,0 +1,199 @@
1
+ import { SecretManagerServiceClient } from "@google-cloud/secret-manager";
2
+ import { parseEnvContent } from "../../utils/env-parser.js";
3
+ const GCP_SECRET_ID_REGEX = /^[A-Za-z0-9_-]+$/;
4
+ const MAX_GCP_SECRET_ID_LENGTH = 255;
5
+ export class GCPSecretManagerProvider {
6
+ name = "gcp";
7
+ client;
8
+ prefix;
9
+ projectId;
10
+ constructor(config, prefix = "envhub-") {
11
+ this.client = new SecretManagerServiceClient();
12
+ this.projectId = config.projectId;
13
+ this.prefix = prefix;
14
+ }
15
+ get projectPath() {
16
+ return `projects/${this.projectId}`;
17
+ }
18
+ fullName(secretName) {
19
+ const fullName = `${this.prefix}${secretName}`;
20
+ if (fullName.length > MAX_GCP_SECRET_ID_LENGTH) {
21
+ throw new Error(`GCP Secret Manager secret id is too long (${fullName.length}). ` +
22
+ `Maximum length is ${MAX_GCP_SECRET_ID_LENGTH}.`);
23
+ }
24
+ if (!GCP_SECRET_ID_REGEX.test(fullName)) {
25
+ throw new Error(`Invalid secret name '${fullName}'. GCP Secret Manager allows only letters, numbers, dashes, and underscores.`);
26
+ }
27
+ return fullName;
28
+ }
29
+ stripPrefix(fullName) {
30
+ if (fullName.startsWith(this.prefix)) {
31
+ return fullName.substring(this.prefix.length);
32
+ }
33
+ return fullName;
34
+ }
35
+ secretResource(secretName) {
36
+ return `${this.projectPath}/secrets/${this.fullName(secretName)}`;
37
+ }
38
+ isNotFoundError(error) {
39
+ if (!error || typeof error !== "object") {
40
+ return false;
41
+ }
42
+ const maybeError = error;
43
+ return maybeError.code === 5 || maybeError.details?.includes("not found") === true;
44
+ }
45
+ parsePayload(secretName, value) {
46
+ let payload;
47
+ try {
48
+ payload = JSON.parse(value);
49
+ }
50
+ catch {
51
+ throw new Error(`Secret '${secretName}' is not in envhub format. It may have been created outside envhub.`);
52
+ }
53
+ if (!payload ||
54
+ typeof payload !== "object" ||
55
+ !("content" in payload) ||
56
+ !("metadata" in payload)) {
57
+ throw new Error(`Secret '${secretName}' is missing envhub metadata. It may have been created outside envhub.`);
58
+ }
59
+ const parsed = payload;
60
+ if (typeof parsed.content !== "string" ||
61
+ typeof parsed.metadata?.version !== "number") {
62
+ throw new Error(`Secret '${secretName}' has an invalid envhub payload format.`);
63
+ }
64
+ return parsed;
65
+ }
66
+ async secretExists(secretName) {
67
+ try {
68
+ await this.client.getSecret({ name: this.secretResource(secretName) });
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ if (this.isNotFoundError(error)) {
73
+ return false;
74
+ }
75
+ throw error;
76
+ }
77
+ }
78
+ async getPayload(secretName) {
79
+ const [result] = await this.client.accessSecretVersion({
80
+ name: `${this.secretResource(secretName)}/versions/latest`,
81
+ });
82
+ const data = result.payload?.data;
83
+ if (!data) {
84
+ throw new Error(`Secret '${secretName}' has no string content.`);
85
+ }
86
+ return this.parsePayload(secretName, data.toString("utf-8"));
87
+ }
88
+ async push(secretName, content, options) {
89
+ const exists = await this.secretExists(secretName);
90
+ let newVersion = 1;
91
+ // NOTE: GCP Secret Manager does not support conditional writes.
92
+ // The version in the payload is a metadata counter, not atomically guaranteed.
93
+ if (!exists) {
94
+ await this.client.createSecret({
95
+ parent: this.projectPath,
96
+ secretId: this.fullName(secretName),
97
+ secret: {
98
+ replication: { automatic: {} },
99
+ },
100
+ });
101
+ }
102
+ else {
103
+ const currentPayload = await this.getPayload(secretName);
104
+ newVersion = currentPayload.metadata.version + 1;
105
+ }
106
+ const payload = {
107
+ content,
108
+ metadata: {
109
+ version: newVersion,
110
+ message: options?.message,
111
+ updatedAt: new Date().toISOString(),
112
+ managedBy: "envhub-cli",
113
+ },
114
+ };
115
+ await this.client.addSecretVersion({
116
+ parent: this.secretResource(secretName),
117
+ payload: {
118
+ data: Buffer.from(JSON.stringify(payload), "utf-8"),
119
+ },
120
+ });
121
+ return { version: newVersion, name: secretName };
122
+ }
123
+ async pull(secretName) {
124
+ const payload = await this.getPayload(secretName);
125
+ return {
126
+ content: payload.content,
127
+ version: payload.metadata.version,
128
+ name: secretName,
129
+ };
130
+ }
131
+ async cat(secretName) {
132
+ const payload = await this.getPayload(secretName);
133
+ return payload.content;
134
+ }
135
+ async list() {
136
+ const secrets = [];
137
+ let pageToken;
138
+ do {
139
+ const [page, , response] = await this.client.listSecrets({ parent: this.projectPath, pageToken });
140
+ secrets.push(...page);
141
+ pageToken = response?.nextPageToken ?? undefined;
142
+ } while (pageToken);
143
+ const relevant = secrets
144
+ .map((s) => s.name?.split("/").pop())
145
+ .filter((fullName) => !!fullName && fullName.startsWith(this.prefix))
146
+ .map((fullName) => this.stripPrefix(fullName));
147
+ const items = await Promise.all(relevant.map(async (secretName) => {
148
+ let secretsCount = 0;
149
+ let lastMessage = null;
150
+ let updatedAt = null;
151
+ try {
152
+ const payload = await this.getPayload(secretName);
153
+ const entries = parseEnvContent(payload.content);
154
+ secretsCount = entries.size;
155
+ lastMessage = payload.metadata.message ?? null;
156
+ updatedAt = new Date(payload.metadata.updatedAt);
157
+ }
158
+ catch (error) {
159
+ const grpcCode = error.code;
160
+ if (typeof grpcCode === "number" && !this.isNotFoundError(error)) {
161
+ throw error;
162
+ }
163
+ // Parse errors and not-found: still show secret in list output.
164
+ }
165
+ return { name: secretName, secretsCount, updatedAt, lastMessage };
166
+ }));
167
+ return items.sort((a, b) => a.name.localeCompare(b.name));
168
+ }
169
+ async delete(secretName, _options) {
170
+ try {
171
+ await this.client.deleteSecret({ name: this.secretResource(secretName) });
172
+ }
173
+ catch (error) {
174
+ if (this.isNotFoundError(error)) {
175
+ throw new Error(`Secret '${secretName}' not found.`);
176
+ }
177
+ throw error;
178
+ }
179
+ }
180
+ async grant(_secretName, _userIdentifier) {
181
+ throw new Error("Grant is not implemented for GCP Secret Manager yet. Use IAM bindings in Google Cloud.");
182
+ }
183
+ async revoke(_secretName, _userIdentifier) {
184
+ throw new Error("Revoke is not implemented for GCP Secret Manager yet. Use IAM bindings in Google Cloud.");
185
+ }
186
+ async getVersion(secretName) {
187
+ try {
188
+ const payload = await this.getPayload(secretName);
189
+ return payload.metadata.version;
190
+ }
191
+ catch (error) {
192
+ if (this.isNotFoundError(error)) {
193
+ return 0;
194
+ }
195
+ throw error;
196
+ }
197
+ }
198
+ }
199
+ //# sourceMappingURL=gcp-secret-manager.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcp-secret-manager.provider.js","sourceRoot":"","sources":["../../../src/providers/gcp/gcp-secret-manager.provider.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.factory.d.ts","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAGxE;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc;IA2B3D;;OAEG;IACH,MAAM,CAAC,qBAAqB,IAAI;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,EAAE;CAO5F"}
1
+ {"version":3,"file":"provider.factory.d.ts","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAKxE;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc;IA6B3D;;OAEG;IACH,MAAM,CAAC,qBAAqB,IAAI;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,EAAE;CAO5F"}
@@ -1,4 +1,6 @@
1
1
  import { AWSSecretsProvider } from "./aws/aws-secrets.provider.js";
2
+ import { AzureKeyVaultProvider } from "./azure/azure-key-vault.provider.js";
3
+ import { GCPSecretManagerProvider } from "./gcp/gcp-secret-manager.provider.js";
2
4
  /**
3
5
  * Factory for creating provider instances based on configuration.
4
6
  *
@@ -19,9 +21,15 @@ export class ProviderFactory {
19
21
  }
20
22
  return new AWSSecretsProvider(config.aws, config.prefix);
21
23
  case "azure":
22
- throw new Error("Azure Key Vault provider is not yet implemented. Coming soon!");
24
+ if (!config.azure) {
25
+ throw new Error("Azure configuration is missing. Run 'envhub init' first.");
26
+ }
27
+ return new AzureKeyVaultProvider(config.azure, config.prefix);
23
28
  case "gcp":
24
- throw new Error("GCP Secret Manager provider is not yet implemented. Coming soon!");
29
+ if (!config.gcp) {
30
+ throw new Error("GCP configuration is missing. Run 'envhub init' first.");
31
+ }
32
+ return new GCPSecretManagerProvider(config.gcp, config.prefix);
25
33
  default:
26
34
  throw new Error(`Unknown provider '${providerType}'. Supported: aws, azure, gcp`);
27
35
  }
@@ -32,8 +40,8 @@ export class ProviderFactory {
32
40
  static getAvailableProviders() {
33
41
  return [
34
42
  { type: "aws", label: "AWS Secrets Manager", available: true },
35
- { type: "azure", label: "Azure Key Vault", available: false },
36
- { type: "gcp", label: "GCP Secret Manager", available: false },
43
+ { type: "azure", label: "Azure Key Vault", available: true },
44
+ { type: "gcp", label: "GCP Secret Manager", available: true },
37
45
  ];
38
46
  }
39
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"provider.factory.js","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAoB;QACxC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC;QAErC,QAAQ,YAAY,EAAE,CAAC;YACrB,KAAK,KAAK;gBACR,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;gBAC5E,CAAC;gBACD,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAE3D,KAAK,OAAO;gBACV,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;YAEJ,KAAK,KAAK;gBACR,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;YAEJ;gBACE,MAAM,IAAI,KAAK,CACb,qBAAqB,YAA4B,+BAA+B,CACjF,CAAC;QACN,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,qBAAqB;QAC1B,OAAO;YACL,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,EAAE;YAC9D,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE;YAC7D,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,KAAK,EAAE;SAC/D,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"provider.factory.js","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAoB;QACxC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC;QAErC,QAAQ,YAAY,EAAE,CAAC;YACrB,KAAK,KAAK;gBACR,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;gBAC5E,CAAC;gBACD,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAE3D,KAAK,OAAO;gBACV,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC9E,CAAC;gBACD,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAEhE,KAAK,KAAK;gBACR,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;gBAC5E,CAAC;gBACD,OAAO,IAAI,wBAAwB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAEjE;gBACE,MAAM,IAAI,KAAK,CACb,qBAAqB,YAA4B,+BAA+B,CACjF,CAAC;QACN,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,qBAAqB;QAC1B,OAAO;YACL,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,EAAE;YAC9D,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE;YAC5D,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,IAAI,EAAE;SAC9D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { EnvhubConfig } from "../config/config.schema.js";
3
+ import type { SecretProvider } from "../providers/provider.interface.js";
4
+ import type { VersionControl } from "../versioning/version-control.js";
5
+ interface EnvhubTuiAppProps {
6
+ config: EnvhubConfig;
7
+ provider: SecretProvider;
8
+ versionControl: VersionControl;
9
+ }
10
+ export declare function EnvhubTuiApp({ config, provider, versionControl, }: EnvhubTuiAppProps): React.JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEvE,UAAU,iBAAiB;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC;AAaD,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,QAAQ,EACR,cAAc,GACf,EAAE,iBAAiB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsSvC"}