@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 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 getFirestoreProjectId(): Promise<string>;
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, getGcpUserEmail, 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 };
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 getFirestoreProjectId() {
65
- const projectId = await getEnvVar("FIRESTORE_PROJECT_ID");
66
- if (!projectId) {
67
- throw new Error("FIRESTORE_PROJECT_ID not found in environment variables.");
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": "1.1.1",
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": "^1.1.0"
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 SecretManagerClient automatically detects the GCP project ID from:
29
- // 1. SECRET_MANAGER_PROJECT_ID environment variable (for CI/CD deployments)
30
- // 2. Your local gcloud configuration (for development: `gcloud config get-value project`)
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}_{userEmail}_{secretId}
35
- // This ensures user-specific secrets that don't conflict across users or projects.
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 getFirestoreProjectId(): Promise<string> {
112
- const projectId = await getEnvVar('FIRESTORE_PROJECT_ID');
113
- if (!projectId) {
114
- throw new Error('FIRESTORE_PROJECT_ID not found in environment variables.');
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,