@dataformer/env-service 1.1.1 → 2.2.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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +20 -26
- package/package.json +8 -8
- package/src/index.ts +34 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @dataformer/env-service
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- removed requirement for user email from secret manager name
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @dataformer/secret-manager-client@2.2.0
|
|
13
|
+
|
|
14
|
+
## 2.0.0
|
|
15
|
+
|
|
16
|
+
### Major Changes
|
|
17
|
+
|
|
18
|
+
- Simplify GCP project ID resolution by removing SECRET_MANAGER_PROJECT_IDBREAKING: Replace SECRET_MANAGER_PROJECT_ID with GCP_PROJECT_ID for unified project approach. Eliminates cross-project complexity and chicken-and-egg problem with project ID resolution.Migration: Update GitHub repository secrets and CI/CD workflows to use GCP_PROJECT_ID
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @dataformer/secret-manager-client@2.0.0
|
|
24
|
+
|
|
3
25
|
## 1.1.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare function obfuscateCred(cred: string | null): string;
|
|
|
3
3
|
declare function getEnvVar(baseSecretKey: string): Promise<string | null>;
|
|
4
4
|
declare function getCustomSearchApiKey(): Promise<string>;
|
|
5
5
|
declare function getSearchEngineId(): Promise<string>;
|
|
6
|
-
declare function
|
|
6
|
+
declare function getGcpProjectId(): Promise<string>;
|
|
7
7
|
declare function setEnvVar(baseSecretKey: string, value: string): Promise<boolean>;
|
|
8
8
|
declare const setLogToConsole: () => Promise<void>;
|
|
9
9
|
declare const setPostgresUser: () => Promise<void>;
|
|
@@ -36,15 +36,14 @@ declare const getPostgresAuthType: () => Promise<string | null>;
|
|
|
36
36
|
declare const getBigtableInstanceName: () => Promise<string | null>;
|
|
37
37
|
declare const getBigtableTableName: () => Promise<string | null>;
|
|
38
38
|
declare const getBigtableProjectId: () => Promise<string | null>;
|
|
39
|
+
declare const getFirestoreProjectId: () => Promise<string | null>;
|
|
39
40
|
declare const getJiraApiToken: () => Promise<string | null>;
|
|
40
41
|
declare const getJiraApiBaseUrl: () => Promise<string | null>;
|
|
41
42
|
declare const getJiraUserEmail: () => Promise<string | null>;
|
|
42
43
|
declare const getGeminiApiKey: () => Promise<string | null>;
|
|
43
44
|
declare const getNpmToken: () => Promise<string | null>;
|
|
44
45
|
declare const getProjectRoot: () => string;
|
|
45
|
-
declare const getGcpProjectId: () => Promise<string | null>;
|
|
46
|
-
declare const getGcpUserEmail: () => Promise<string | null>;
|
|
47
46
|
declare const printEnv: () => Promise<void>;
|
|
48
47
|
declare const run: () => Promise<void>;
|
|
49
48
|
|
|
50
|
-
export { askQuestion, getBigtableInstanceName, getBigtableProjectId, getBigtableTableName, getCustomSearchApiKey, getEnvVar, getFirestoreProjectId, getGcpProjectId,
|
|
49
|
+
export { askQuestion, getBigtableInstanceName, getBigtableProjectId, getBigtableTableName, getCustomSearchApiKey, getEnvVar, getFirestoreProjectId, getGcpProjectId, getGeminiApiKey, getJiraApiBaseUrl, getJiraApiToken, getJiraUserEmail, getLogToConsole, getNpmToken, getPostgresAuthType, getPostgresDatabase, getPostgresHostName, getPostgresInstanceConnectionName, getPostgresIpType, getPostgresPassword, getPostgresPoolSizeMax, getPostgresUser, getProjectRoot, getSearchEngineId, obfuscateCred, printEnv, run, setBigtableInstanceName, setBigtableProjectId, setBigtableTableName, setCustomSearchApiKey, setEnvVar, setFirestoreProjectId, setGeminiApiKey, setJiraApiBaseUrl, setJiraApiToken, setJiraUserEmail, setLogToConsole, setNpmToken, setPostgresAuthType, setPostgresDatabase, setPostgresHostName, setPostgresInstanceConnectionName, setPostgresIpType, setPostgresPassword, setPostgresPoolSizeMax, setPostgresUser };
|
package/dist/index.js
CHANGED
|
@@ -61,12 +61,26 @@ async function getSearchEngineId() {
|
|
|
61
61
|
}
|
|
62
62
|
return searchEngineId;
|
|
63
63
|
}
|
|
64
|
-
async function
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
|
|
64
|
+
async function getGcpProjectId() {
|
|
65
|
+
const envProjectId = process.env.GCP_PROJECT_ID;
|
|
66
|
+
if (envProjectId) {
|
|
67
|
+
return envProjectId;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const { execSync } = await import("child_process");
|
|
71
|
+
const projectId = execSync("gcloud config get-value project", {
|
|
72
|
+
encoding: "utf8",
|
|
73
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
74
|
+
}).trim();
|
|
75
|
+
if (!projectId || projectId === "(unset)") {
|
|
76
|
+
throw new Error("No GCP project configured. Run `gcloud config set project YOUR_PROJECT_ID`");
|
|
77
|
+
}
|
|
78
|
+
return projectId;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
"GCP_PROJECT_ID not found. Either:\n1. Set GCP_PROJECT_ID environment variable (for deployed environments), or\n2. Configure gcloud: `gcloud config set project YOUR_PROJECT_ID` (for local development)"
|
|
82
|
+
);
|
|
68
83
|
}
|
|
69
|
-
return projectId;
|
|
70
84
|
}
|
|
71
85
|
async function setEnvVar(baseSecretKey, value) {
|
|
72
86
|
const sm = await getSecretManager();
|
|
@@ -202,6 +216,7 @@ var getBigtableInstanceName = async () => await getEnvVar("BIGTABLE_INSTANCE_NAM
|
|
|
202
216
|
var getBigtableTableName = async () => await getEnvVar("BIGTABLE_TABLE_NAME");
|
|
203
217
|
var getBigtableProjectId = async () => await getEnvVar("BIGTABLE_PROJECT_ID");
|
|
204
218
|
var _getFirestoreProjectId = async () => await getEnvVar("FIRESTORE_PROJECT_ID");
|
|
219
|
+
var getFirestoreProjectId = _getFirestoreProjectId;
|
|
205
220
|
var getJiraApiToken = async () => await getEnvVar("JIRA_API_TOKEN");
|
|
206
221
|
var getJiraApiBaseUrl = async () => await getEnvVar("JIRA_API_BASE_URL");
|
|
207
222
|
var getJiraUserEmail = async () => await getEnvVar("JIRA_USER_EMAIL");
|
|
@@ -211,24 +226,6 @@ var getProjectRoot = () => {
|
|
|
211
226
|
const currentDir = path.dirname(new URL(import.meta.url).pathname);
|
|
212
227
|
return path.resolve(currentDir, "../..");
|
|
213
228
|
};
|
|
214
|
-
var _getResolvedGcpProjectId = async () => {
|
|
215
|
-
const sm = await getSecretManager();
|
|
216
|
-
if (!sm) {
|
|
217
|
-
console.warn("[EnvService.ts] SecretManager not available for _getResolvedGcpProjectId");
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
return sm.getResolvedProjectId();
|
|
221
|
-
};
|
|
222
|
-
var _getResolvedGcpUserEmail = async () => {
|
|
223
|
-
const sm = await getSecretManager();
|
|
224
|
-
if (!sm) {
|
|
225
|
-
console.warn("[EnvService.ts] SecretManager not available for _getResolvedGcpUserEmail");
|
|
226
|
-
return null;
|
|
227
|
-
}
|
|
228
|
-
return sm.getResolvedUserEmail();
|
|
229
|
-
};
|
|
230
|
-
var getGcpProjectId = _getResolvedGcpProjectId;
|
|
231
|
-
var getGcpUserEmail = _getResolvedGcpUserEmail;
|
|
232
229
|
var printEnv = async () => {
|
|
233
230
|
const logToConsole = await getLogToConsole();
|
|
234
231
|
const postgresUser = await getPostgresUser();
|
|
@@ -249,11 +246,9 @@ var printEnv = async () => {
|
|
|
249
246
|
const geminiApiKey = await getGeminiApiKey();
|
|
250
247
|
const customSearchApiKey = await getCustomSearchApiKey();
|
|
251
248
|
const gcpProjectIdVal = await getGcpProjectId();
|
|
252
|
-
const gcpUserEmailVal = await getGcpUserEmail();
|
|
253
249
|
const npmToken = await getNpmToken();
|
|
254
250
|
console.log(`Project Root: ${getProjectRoot()}`);
|
|
255
251
|
console.log(`GCP Project ID: ${gcpProjectIdVal}`);
|
|
256
|
-
console.log(`GCP User Email (for Secret Manager naming): ${gcpUserEmailVal}`);
|
|
257
252
|
console.log(`Log to Console: ${logToConsole}`);
|
|
258
253
|
console.log(`PostgreSQL User: ${postgresUser}`);
|
|
259
254
|
console.log(`PostgreSQL Password: ${obfuscateCred(postgresPassword)}`);
|
|
@@ -358,7 +353,6 @@ export {
|
|
|
358
353
|
getEnvVar,
|
|
359
354
|
getFirestoreProjectId,
|
|
360
355
|
getGcpProjectId,
|
|
361
|
-
getGcpUserEmail,
|
|
362
356
|
getGeminiApiKey,
|
|
363
357
|
getJiraApiBaseUrl,
|
|
364
358
|
getJiraApiToken,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dataformer/env-service",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Environment service for Dataformer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,14 +11,9 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
16
|
-
"dev": "tsup src/index.ts --format esm --dts --watch",
|
|
17
|
-
"prepublish": "pnpm run build"
|
|
18
|
-
},
|
|
19
14
|
"dependencies": {
|
|
20
15
|
"@google-cloud/secret-manager": "^5.4.0",
|
|
21
|
-
"@dataformer/secret-manager-client": "^
|
|
16
|
+
"@dataformer/secret-manager-client": "^2.2.0"
|
|
22
17
|
},
|
|
23
18
|
"devDependencies": {
|
|
24
19
|
"tsup": "^8.0.0",
|
|
@@ -26,5 +21,10 @@
|
|
|
26
21
|
},
|
|
27
22
|
"peerDependencies": {
|
|
28
23
|
"typescript": "^5.0.0"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
27
|
+
"dev": "tsup src/index.ts --format esm --dts --watch",
|
|
28
|
+
"prepublish": "pnpm run build"
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -25,14 +25,13 @@
|
|
|
25
25
|
// for your GCP project.
|
|
26
26
|
//
|
|
27
27
|
// PROJECT ID DETECTION:
|
|
28
|
-
// The
|
|
29
|
-
// 1.
|
|
30
|
-
// 2.
|
|
31
|
-
// 3. Explicit override via createSecretManagerClient({ projectId: "your-project" })
|
|
28
|
+
// The GCP project ID is resolved from:
|
|
29
|
+
// 1. GCP_PROJECT_ID environment variable (for deployed environments - set as GitHub repository secret)
|
|
30
|
+
// 2. Local gcloud configuration (for development: `gcloud config get-value project`)
|
|
32
31
|
//
|
|
33
32
|
// SECRET NAMING CONVENTION:
|
|
34
|
-
// Secrets are named using the format: {projectId}_{
|
|
35
|
-
// This ensures
|
|
33
|
+
// Secrets are named using the format: {projectId}_{secretId}
|
|
34
|
+
// This ensures project-specific secrets that don't conflict across projects.
|
|
36
35
|
|
|
37
36
|
import readline from 'readline';
|
|
38
37
|
import path from 'path';
|
|
@@ -108,12 +107,33 @@ export async function getSearchEngineId(): Promise<string> {
|
|
|
108
107
|
return searchEngineId;
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
export async function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
export async function getGcpProjectId(): Promise<string> {
|
|
111
|
+
// First try environment variable (for deployed environments)
|
|
112
|
+
const envProjectId = process.env.GCP_PROJECT_ID;
|
|
113
|
+
if (envProjectId) {
|
|
114
|
+
return envProjectId;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Fall back to gcloud config for local development
|
|
118
|
+
try {
|
|
119
|
+
const { execSync } = await import('child_process');
|
|
120
|
+
const projectId = execSync('gcloud config get-value project', {
|
|
121
|
+
encoding: 'utf8',
|
|
122
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
123
|
+
}).trim();
|
|
124
|
+
|
|
125
|
+
if (!projectId || projectId === '(unset)') {
|
|
126
|
+
throw new Error('No GCP project configured. Run `gcloud config set project YOUR_PROJECT_ID`');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return projectId;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
'GCP_PROJECT_ID not found. Either:\n' +
|
|
133
|
+
'1. Set GCP_PROJECT_ID environment variable (for deployed environments), or\n' +
|
|
134
|
+
'2. Configure gcloud: `gcloud config set project YOUR_PROJECT_ID` (for local development)'
|
|
135
|
+
);
|
|
115
136
|
}
|
|
116
|
-
return projectId;
|
|
117
137
|
}
|
|
118
138
|
|
|
119
139
|
async function setEnvVar(baseSecretKey: string, value: string): Promise<boolean> {
|
|
@@ -274,6 +294,9 @@ const getBigtableInstanceName = async (): Promise<string | null> => await getEnv
|
|
|
274
294
|
const getBigtableTableName = async (): Promise<string | null> => await getEnvVar('BIGTABLE_TABLE_NAME');
|
|
275
295
|
const getBigtableProjectId = async (): Promise<string | null> => await getEnvVar('BIGTABLE_PROJECT_ID');
|
|
276
296
|
const _getFirestoreProjectId = async (): Promise<string | null> => await getEnvVar('FIRESTORE_PROJECT_ID');
|
|
297
|
+
|
|
298
|
+
// Export the firestore project ID getter
|
|
299
|
+
export const getFirestoreProjectId = _getFirestoreProjectId;
|
|
277
300
|
const getJiraApiToken = async (): Promise<string | null> => await getEnvVar('JIRA_API_TOKEN');
|
|
278
301
|
const getJiraApiBaseUrl = async (): Promise<string | null> => await getEnvVar('JIRA_API_BASE_URL');
|
|
279
302
|
const getJiraUserEmail = async (): Promise<string | null> => await getEnvVar('JIRA_USER_EMAIL');
|
|
@@ -296,18 +319,6 @@ const _getResolvedGcpProjectId = async (): Promise<string | null> => {
|
|
|
296
319
|
return sm.getResolvedProjectId();
|
|
297
320
|
};
|
|
298
321
|
|
|
299
|
-
const _getResolvedGcpUserEmail = async (): Promise<string | null> => {
|
|
300
|
-
const sm = await getSecretManager();
|
|
301
|
-
if (!sm) {
|
|
302
|
-
console.warn('[EnvService.ts] SecretManager not available for _getResolvedGcpUserEmail');
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
return sm.getResolvedUserEmail();
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const getGcpProjectId = _getResolvedGcpProjectId;
|
|
309
|
-
const getGcpUserEmail = _getResolvedGcpUserEmail;
|
|
310
|
-
|
|
311
322
|
const printEnv = async (): Promise<void> => {
|
|
312
323
|
const logToConsole = await getLogToConsole();
|
|
313
324
|
const postgresUser = await getPostgresUser();
|
|
@@ -328,12 +339,10 @@ const printEnv = async (): Promise<void> => {
|
|
|
328
339
|
const geminiApiKey = await getGeminiApiKey();
|
|
329
340
|
const customSearchApiKey = await getCustomSearchApiKey();
|
|
330
341
|
const gcpProjectIdVal = await getGcpProjectId();
|
|
331
|
-
const gcpUserEmailVal = await getGcpUserEmail();
|
|
332
342
|
const npmToken = await getNpmToken();
|
|
333
343
|
|
|
334
344
|
console.log(`Project Root: ${getProjectRoot()}`);
|
|
335
345
|
console.log(`GCP Project ID: ${gcpProjectIdVal}`);
|
|
336
|
-
console.log(`GCP User Email (for Secret Manager naming): ${gcpUserEmailVal}`);
|
|
337
346
|
console.log(`Log to Console: ${logToConsole}`);
|
|
338
347
|
console.log(`PostgreSQL User: ${postgresUser}`);
|
|
339
348
|
console.log(`PostgreSQL Password: ${obfuscateCred(postgresPassword)}`);
|
|
@@ -440,8 +449,6 @@ export {
|
|
|
440
449
|
|
|
441
450
|
// Synchronous Getters / Utility
|
|
442
451
|
getProjectRoot,
|
|
443
|
-
getGcpProjectId,
|
|
444
|
-
getGcpUserEmail,
|
|
445
452
|
|
|
446
453
|
// Generic accessors
|
|
447
454
|
getEnvVar,
|