@clicadigital/vault-sdk 0.1.0 → 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.
package/src/index.ts CHANGED
@@ -1,167 +1,177 @@
1
- import { writeFile } from "node:fs/promises";
2
- import { createClientFromEnv, VaultClient, type VaultClientOptions } from "./client.js";
3
- import { toDotEnv, varsToRecord } from "./dotenv.js";
4
- import type { EnvVar, ProjectTree } from "./types.js";
5
-
6
- export type { EnvVar, ProjectTree, ProjectTreeEnv } from "./types.js";
7
- export { VaultClient, createClientFromEnv, type VaultClientOptions };
8
- export { toDotEnv, varsToRecord };
9
-
10
- export type ResolveOptions = {
11
- project: string;
12
- env: string;
13
- client?: VaultClient;
14
- };
15
-
16
- export type EnsureOptions = ResolveOptions & {
17
- createProject?: boolean;
18
- };
19
-
20
- export type PullOptions = ResolveOptions & {
21
- out?: string;
22
- inject?: boolean;
23
- };
24
-
25
- export type CreateEnvOptions = {
26
- project: string;
27
- env: string;
28
- /** URL da API do vault na VPN (cluster-internal) */
29
- url?: string;
30
- vars?: Record<string, string>;
31
- client?: VaultClient;
32
- };
33
-
34
- async function findProject(
35
- client: VaultClient,
36
- name: string,
37
- ): Promise<ProjectTree | undefined> {
38
- const tree = await client.listProjects();
39
- return tree.find((p) => p.name === name);
40
- }
41
-
42
- function resolveClient(opts: { client?: VaultClient; url?: string }): VaultClient {
43
- if (opts.client) return opts.client;
44
- if (opts.url) return new VaultClient({ baseUrl: opts.url });
45
- return createClientFromEnv();
46
- }
47
-
48
- export async function resolveEnvironment(
49
- opts: ResolveOptions,
50
- ): Promise<{ projectId: string; environmentId: string }> {
51
- const client = opts.client ?? createClientFromEnv();
52
- const project = await findProject(client, opts.project);
53
- if (!project) throw new Error(`Project not found: ${opts.project}`);
54
- const environment = project.environments.find((e) => e.name === opts.env);
55
- if (!environment) {
56
- throw new Error(`Environment "${opts.env}" not found in project "${opts.project}"`);
57
- }
58
- return { projectId: project.id, environmentId: environment.id };
59
- }
60
-
61
- /** Garante projeto + environment na VPN (cria se não existir). */
62
- export async function ensureEnvironment(opts: EnsureOptions): Promise<{
63
- projectId: string;
64
- environmentId: string;
65
- createdProject: boolean;
66
- createdEnvironment: boolean;
67
- }> {
68
- const client = opts.client ?? createClientFromEnv();
69
- let createdProject = false;
70
- let createdEnvironment = false;
71
-
72
- let project = await findProject(client, opts.project);
73
- if (!project) {
74
- if (opts.createProject === false) {
75
- throw new Error(`Project not found: ${opts.project}`);
76
- }
77
- await client.createProject(opts.project);
78
- createdProject = true;
79
- project = await findProject(client, opts.project);
80
- if (!project) throw new Error(`Failed to create project: ${opts.project}`);
81
- }
82
-
83
- let environment = project.environments.find((e) => e.name === opts.env);
84
- if (!environment) {
85
- await client.createEnvironment(project.id, opts.env);
86
- createdEnvironment = true;
87
- const refreshed = await findProject(client, opts.project);
88
- if (!refreshed) throw new Error(`Failed to reload project: ${opts.project}`);
89
- project = refreshed;
90
- environment = project.environments.find((e) => e.name === opts.env);
91
- if (!environment) throw new Error(`Failed to create environment: ${opts.env}`);
92
- }
93
-
94
- return {
95
- projectId: project.id,
96
- environmentId: environment.id,
97
- createdProject,
98
- createdEnvironment,
99
- };
100
- }
101
-
102
- /**
103
- * Cria (ou garante) o environment no vault via URL da VPN
104
- * e opcionalmente faz upsert das variáveis.
105
- */
106
- export async function createEnv(opts: CreateEnvOptions): Promise<{
107
- projectId: string;
108
- environmentId: string;
109
- createdProject: boolean;
110
- createdEnvironment: boolean;
111
- upserted: string[];
112
- }> {
113
- const client = resolveClient(opts);
114
- const ensured = await ensureEnvironment({
115
- project: opts.project,
116
- env: opts.env,
117
- client,
118
- });
119
-
120
- const upserted: string[] = [];
121
- if (opts.vars) {
122
- for (const [key, value] of Object.entries(opts.vars)) {
123
- await client.upsertVar(ensured.environmentId, key, value);
124
- upserted.push(key);
125
- }
126
- }
127
-
128
- return { ...ensured, upserted };
129
- }
130
-
131
- export async function fetchVars(opts: ResolveOptions): Promise<EnvVar[]> {
132
- const client = opts.client ?? createClientFromEnv();
133
- const { environmentId } = await resolveEnvironment({ ...opts, client });
134
- return client.listVars(environmentId);
135
- }
136
-
137
- export async function loadVault(
138
- opts: ResolveOptions,
139
- ): Promise<Record<string, string>> {
140
- const rows = await fetchVars(opts);
141
- const record = varsToRecord(rows);
142
- for (const [key, value] of Object.entries(record)) {
143
- process.env[key] = value;
144
- }
145
- return record;
146
- }
147
-
148
- export async function pullVault(opts: PullOptions): Promise<{
149
- vars: Record<string, string>;
150
- out?: string;
151
- }> {
152
- const rows = await fetchVars(opts);
153
- const vars = varsToRecord(rows);
154
-
155
- if (opts.inject !== false) {
156
- for (const [key, value] of Object.entries(vars)) {
157
- process.env[key] = value;
158
- }
159
- }
160
-
161
- const out = opts.out;
162
- if (out) {
163
- await writeFile(out, toDotEnv(vars), "utf8");
164
- }
165
-
166
- return out ? { vars, out } : { vars };
167
- }
1
+ import { writeFile } from "node:fs/promises";
2
+ import {
3
+ createClientFromEnv,
4
+ DEFAULT_VAULT_URL,
5
+ VaultClient,
6
+ type VaultClientOptions,
7
+ } from "./client.js";
8
+ import { toDotEnv, varsToRecord } from "./dotenv.js";
9
+ import type { EnvVar, ProjectTree } from "./types.js";
10
+
11
+ export type { EnvVar, ProjectTree, ProjectTreeEnv } from "./types.js";
12
+ export {
13
+ VaultClient,
14
+ createClientFromEnv,
15
+ DEFAULT_VAULT_URL,
16
+ type VaultClientOptions,
17
+ };
18
+ export { toDotEnv, varsToRecord };
19
+
20
+ export type ResolveOptions = {
21
+ project: string;
22
+ env: string;
23
+ client?: VaultClient;
24
+ };
25
+
26
+ export type EnsureOptions = ResolveOptions & {
27
+ createProject?: boolean;
28
+ };
29
+
30
+ export type PullOptions = ResolveOptions & {
31
+ out?: string;
32
+ inject?: boolean;
33
+ };
34
+
35
+ export type CreateEnvOptions = {
36
+ project: string;
37
+ env: string;
38
+ /** URL da API do vault na VPN (cluster-internal) */
39
+ url?: string;
40
+ vars?: Record<string, string>;
41
+ client?: VaultClient;
42
+ };
43
+
44
+ async function findProject(
45
+ client: VaultClient,
46
+ name: string,
47
+ ): Promise<ProjectTree | undefined> {
48
+ const tree = await client.listProjects();
49
+ return tree.find((p) => p.name === name);
50
+ }
51
+
52
+ function resolveClient(opts: { client?: VaultClient; url?: string }): VaultClient {
53
+ if (opts.client) return opts.client;
54
+ if (opts.url) return new VaultClient({ baseUrl: opts.url });
55
+ return createClientFromEnv();
56
+ }
57
+
58
+ export async function resolveEnvironment(
59
+ opts: ResolveOptions,
60
+ ): Promise<{ projectId: string; environmentId: string }> {
61
+ const client = opts.client ?? createClientFromEnv();
62
+ const project = await findProject(client, opts.project);
63
+ if (!project) throw new Error(`Project not found: ${opts.project}`);
64
+ const environment = project.environments.find((e) => e.name === opts.env);
65
+ if (!environment) {
66
+ throw new Error(`Environment "${opts.env}" not found in project "${opts.project}"`);
67
+ }
68
+ return { projectId: project.id, environmentId: environment.id };
69
+ }
70
+
71
+ /** Garante projeto + environment na VPN (cria se não existir). */
72
+ export async function ensureEnvironment(opts: EnsureOptions): Promise<{
73
+ projectId: string;
74
+ environmentId: string;
75
+ createdProject: boolean;
76
+ createdEnvironment: boolean;
77
+ }> {
78
+ const client = opts.client ?? createClientFromEnv();
79
+ let createdProject = false;
80
+ let createdEnvironment = false;
81
+
82
+ let project = await findProject(client, opts.project);
83
+ if (!project) {
84
+ if (opts.createProject === false) {
85
+ throw new Error(`Project not found: ${opts.project}`);
86
+ }
87
+ await client.createProject(opts.project);
88
+ createdProject = true;
89
+ project = await findProject(client, opts.project);
90
+ if (!project) throw new Error(`Failed to create project: ${opts.project}`);
91
+ }
92
+
93
+ let environment = project.environments.find((e) => e.name === opts.env);
94
+ if (!environment) {
95
+ await client.createEnvironment(project.id, opts.env);
96
+ createdEnvironment = true;
97
+ const refreshed = await findProject(client, opts.project);
98
+ if (!refreshed) throw new Error(`Failed to reload project: ${opts.project}`);
99
+ project = refreshed;
100
+ environment = project.environments.find((e) => e.name === opts.env);
101
+ if (!environment) throw new Error(`Failed to create environment: ${opts.env}`);
102
+ }
103
+
104
+ return {
105
+ projectId: project.id,
106
+ environmentId: environment.id,
107
+ createdProject,
108
+ createdEnvironment,
109
+ };
110
+ }
111
+
112
+ /**
113
+ * Cria (ou garante) o environment no vault via URL da VPN
114
+ * e opcionalmente faz upsert das variáveis.
115
+ */
116
+ export async function createEnv(opts: CreateEnvOptions): Promise<{
117
+ projectId: string;
118
+ environmentId: string;
119
+ createdProject: boolean;
120
+ createdEnvironment: boolean;
121
+ upserted: string[];
122
+ }> {
123
+ const client = resolveClient(opts);
124
+ const ensured = await ensureEnvironment({
125
+ project: opts.project,
126
+ env: opts.env,
127
+ client,
128
+ });
129
+
130
+ const upserted: string[] = [];
131
+ if (opts.vars) {
132
+ for (const [key, value] of Object.entries(opts.vars)) {
133
+ await client.upsertVar(ensured.environmentId, key, value);
134
+ upserted.push(key);
135
+ }
136
+ }
137
+
138
+ return { ...ensured, upserted };
139
+ }
140
+
141
+ export async function fetchVars(opts: ResolveOptions): Promise<EnvVar[]> {
142
+ const client = opts.client ?? createClientFromEnv();
143
+ const { environmentId } = await resolveEnvironment({ ...opts, client });
144
+ return client.listVars(environmentId);
145
+ }
146
+
147
+ export async function loadVault(
148
+ opts: ResolveOptions,
149
+ ): Promise<Record<string, string>> {
150
+ const rows = await fetchVars(opts);
151
+ const record = varsToRecord(rows);
152
+ for (const [key, value] of Object.entries(record)) {
153
+ process.env[key] = value;
154
+ }
155
+ return record;
156
+ }
157
+
158
+ export async function pullVault(opts: PullOptions): Promise<{
159
+ vars: Record<string, string>;
160
+ out?: string;
161
+ }> {
162
+ const rows = await fetchVars(opts);
163
+ const vars = varsToRecord(rows);
164
+
165
+ if (opts.inject !== false) {
166
+ for (const [key, value] of Object.entries(vars)) {
167
+ process.env[key] = value;
168
+ }
169
+ }
170
+
171
+ const out = opts.out;
172
+ if (out) {
173
+ await writeFile(out, toDotEnv(vars), "utf8");
174
+ }
175
+
176
+ return out ? { vars, out } : { vars };
177
+ }
package/src/types.ts CHANGED
@@ -1,14 +1,14 @@
1
- export type ProjectTreeEnv = { id: string; name: string };
2
-
3
- export type ProjectTree = {
4
- id: string;
5
- name: string;
6
- environments: ProjectTreeEnv[];
7
- };
8
-
9
- export type EnvVar = {
10
- id: string;
11
- key: string;
12
- value: string;
13
- updated_at: string;
14
- };
1
+ export type ProjectTreeEnv = { id: string; name: string };
2
+
3
+ export type ProjectTree = {
4
+ id: string;
5
+ name: string;
6
+ environments: ProjectTreeEnv[];
7
+ };
8
+
9
+ export type EnvVar = {
10
+ id: string;
11
+ key: string;
12
+ value: string;
13
+ updated_at: string;
14
+ };