@dataformer/env-service 1.1.0 → 2.0.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,16 @@
1
1
  # @dataformer/env-service
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 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
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @dataformer/secret-manager-client@2.0.0
13
+
3
14
  ## 1.1.0
4
15
 
5
16
  ### 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>;
@@ -13,6 +13,7 @@ declare const setPostgresHostName: () => Promise<void>;
13
13
  declare const setPostgresIpType: () => Promise<void>;
14
14
  declare const setPostgresPoolSizeMax: () => Promise<void>;
15
15
  declare const setPostgresInstanceConnectionName: () => Promise<void>;
16
+ declare const setPostgresAuthType: () => Promise<void>;
16
17
  declare const setBigtableInstanceName: () => Promise<void>;
17
18
  declare const setBigtableTableName: () => Promise<void>;
18
19
  declare const setBigtableProjectId: () => Promise<void>;
@@ -31,18 +32,19 @@ declare const getPostgresHostName: () => Promise<string | null>;
31
32
  declare const getPostgresIpType: () => Promise<string | null>;
32
33
  declare const getPostgresPoolSizeMax: () => Promise<number | null>;
33
34
  declare const getPostgresInstanceConnectionName: () => Promise<string | null>;
35
+ declare const getPostgresAuthType: () => Promise<string | null>;
34
36
  declare const getBigtableInstanceName: () => Promise<string | null>;
35
37
  declare const getBigtableTableName: () => Promise<string | null>;
36
38
  declare const getBigtableProjectId: () => Promise<string | null>;
39
+ declare const getFirestoreProjectId: () => Promise<string | null>;
37
40
  declare const getJiraApiToken: () => Promise<string | null>;
38
41
  declare const getJiraApiBaseUrl: () => Promise<string | null>;
39
42
  declare const getJiraUserEmail: () => Promise<string | null>;
40
43
  declare const getGeminiApiKey: () => Promise<string | null>;
41
44
  declare const getNpmToken: () => Promise<string | null>;
42
45
  declare const getProjectRoot: () => string;
43
- declare const getGcpProjectId: () => Promise<string | null>;
44
46
  declare const getGcpUserEmail: () => Promise<string | null>;
45
47
  declare const printEnv: () => Promise<void>;
46
48
  declare const run: () => Promise<void>;
47
49
 
48
- export { askQuestion, getBigtableInstanceName, getBigtableProjectId, getBigtableTableName, getCustomSearchApiKey, getEnvVar, getFirestoreProjectId, getGcpProjectId, getGcpUserEmail, getGeminiApiKey, getJiraApiBaseUrl, getJiraApiToken, getJiraUserEmail, getLogToConsole, getNpmToken, getPostgresDatabase, getPostgresHostName, getPostgresInstanceConnectionName, getPostgresIpType, getPostgresPassword, getPostgresPoolSizeMax, getPostgresUser, getProjectRoot, getSearchEngineId, obfuscateCred, printEnv, run, setBigtableInstanceName, setBigtableProjectId, setBigtableTableName, setCustomSearchApiKey, setEnvVar, setFirestoreProjectId, setGeminiApiKey, setJiraApiBaseUrl, setJiraApiToken, setJiraUserEmail, setLogToConsole, setNpmToken, setPostgresDatabase, setPostgresHostName, setPostgresInstanceConnectionName, setPostgresIpType, setPostgresPassword, setPostgresPoolSizeMax, setPostgresUser };
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 };
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();
@@ -124,6 +138,12 @@ var setPostgresInstanceConnectionName = async () => {
124
138
  await setEnvVar("POSTGRES_INSTANCE_CONNECTION_NAME", instanceConnectionName);
125
139
  }
126
140
  };
141
+ var setPostgresAuthType = async () => {
142
+ const authType = await askQuestion("Enter PostgreSQL Auth Type (PASSWORD, IAM)", "PASSWORD");
143
+ if (authType) {
144
+ await setEnvVar("POSTGRES_AUTH_TYPE", authType);
145
+ }
146
+ };
127
147
  var setBigtableInstanceName = async () => {
128
148
  const btInstanceName = await askQuestion("Enter Bigtable Instance Name", "");
129
149
  if (btInstanceName) {
@@ -191,10 +211,12 @@ var getPostgresPoolSizeMax = async () => {
191
211
  return value ? parseInt(value, 10) : null;
192
212
  };
193
213
  var getPostgresInstanceConnectionName = async () => await getEnvVar("POSTGRES_INSTANCE_CONNECTION_NAME");
214
+ var getPostgresAuthType = async () => await getEnvVar("POSTGRES_AUTH_TYPE");
194
215
  var getBigtableInstanceName = async () => await getEnvVar("BIGTABLE_INSTANCE_NAME");
195
216
  var getBigtableTableName = async () => await getEnvVar("BIGTABLE_TABLE_NAME");
196
217
  var getBigtableProjectId = async () => await getEnvVar("BIGTABLE_PROJECT_ID");
197
218
  var _getFirestoreProjectId = async () => await getEnvVar("FIRESTORE_PROJECT_ID");
219
+ var getFirestoreProjectId = _getFirestoreProjectId;
198
220
  var getJiraApiToken = async () => await getEnvVar("JIRA_API_TOKEN");
199
221
  var getJiraApiBaseUrl = async () => await getEnvVar("JIRA_API_BASE_URL");
200
222
  var getJiraUserEmail = async () => await getEnvVar("JIRA_USER_EMAIL");
@@ -204,14 +226,6 @@ var getProjectRoot = () => {
204
226
  const currentDir = path.dirname(new URL(import.meta.url).pathname);
205
227
  return path.resolve(currentDir, "../..");
206
228
  };
207
- var _getResolvedGcpProjectId = async () => {
208
- const sm = await getSecretManager();
209
- if (!sm) {
210
- console.warn("[EnvService.ts] SecretManager not available for _getResolvedGcpProjectId");
211
- return null;
212
- }
213
- return sm.getResolvedProjectId();
214
- };
215
229
  var _getResolvedGcpUserEmail = async () => {
216
230
  const sm = await getSecretManager();
217
231
  if (!sm) {
@@ -220,7 +234,6 @@ var _getResolvedGcpUserEmail = async () => {
220
234
  }
221
235
  return sm.getResolvedUserEmail();
222
236
  };
223
- var getGcpProjectId = _getResolvedGcpProjectId;
224
237
  var getGcpUserEmail = _getResolvedGcpUserEmail;
225
238
  var printEnv = async () => {
226
239
  const logToConsole = await getLogToConsole();
@@ -231,6 +244,7 @@ var printEnv = async () => {
231
244
  const postgresIpType = await getPostgresIpType();
232
245
  const postgresPoolSizeMax = await getPostgresPoolSizeMax();
233
246
  const postgresInstanceConnectionName = await getPostgresInstanceConnectionName();
247
+ const postgresAuthType = await getPostgresAuthType();
234
248
  const bigtableInstanceName = await getBigtableInstanceName();
235
249
  const bigtableTableName = await getBigtableTableName();
236
250
  const bigtableProjectId = await getBigtableProjectId();
@@ -254,6 +268,7 @@ var printEnv = async () => {
254
268
  console.log(`PostgreSQL IP Type: ${postgresIpType}`);
255
269
  console.log(`PostgreSQL Pool Size Max: ${postgresPoolSizeMax}`);
256
270
  console.log(`PostgreSQL Instance Connection Name: ${postgresInstanceConnectionName}`);
271
+ console.log(`PostgreSQL Auth Type: ${postgresAuthType}`);
257
272
  console.log(`Bigtable Instance Name: ${bigtableInstanceName}`);
258
273
  console.log(`Bigtable Table Name: ${bigtableTableName}`);
259
274
  console.log(`Bigtable Project ID: ${bigtableProjectId}`);
@@ -292,6 +307,9 @@ var run = async () => {
292
307
  case "setPostgresInstanceConnectionName":
293
308
  await setPostgresInstanceConnectionName();
294
309
  break;
310
+ case "setPostgresAuthType":
311
+ await setPostgresAuthType();
312
+ break;
295
313
  case "setBigtableInstanceName":
296
314
  await setBigtableInstanceName();
297
315
  break;
@@ -353,6 +371,7 @@ export {
353
371
  getJiraUserEmail,
354
372
  getLogToConsole,
355
373
  getNpmToken,
374
+ getPostgresAuthType,
356
375
  getPostgresDatabase,
357
376
  getPostgresHostName,
358
377
  getPostgresInstanceConnectionName,
@@ -377,6 +396,7 @@ export {
377
396
  setJiraUserEmail,
378
397
  setLogToConsole,
379
398
  setNpmToken,
399
+ setPostgresAuthType,
380
400
  setPostgresDatabase,
381
401
  setPostgresHostName,
382
402
  setPostgresInstanceConnectionName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataformer/env-service",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Environment service for Dataformer",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@google-cloud/secret-manager": "^5.4.0",
16
- "@dataformer/secret-manager-client": "^1.1.0"
16
+ "@dataformer/secret-manager-client": "^2.0.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "tsup": "^8.0.0",
package/src/index.ts CHANGED
@@ -25,10 +25,9 @@
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
33
  // Secrets are named using the format: {projectId}_{userEmail}_{secretId}
@@ -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> {
@@ -184,6 +204,13 @@ const setPostgresInstanceConnectionName = async (): Promise<void> => {
184
204
  }
185
205
  };
186
206
 
207
+ const setPostgresAuthType = async (): Promise<void> => {
208
+ const authType = await askQuestion('Enter PostgreSQL Auth Type (PASSWORD, IAM)', 'PASSWORD');
209
+ if (authType) {
210
+ await setEnvVar('POSTGRES_AUTH_TYPE', authType);
211
+ }
212
+ };
213
+
187
214
  const setBigtableInstanceName = async (): Promise<void> => {
188
215
  const btInstanceName = await askQuestion('Enter Bigtable Instance Name', '');
189
216
  if (btInstanceName) {
@@ -262,10 +289,14 @@ const getPostgresPoolSizeMax = async (): Promise<number | null> => {
262
289
  return value ? parseInt(value, 10) : null;
263
290
  };
264
291
  const getPostgresInstanceConnectionName = async (): Promise<string | null> => await getEnvVar('POSTGRES_INSTANCE_CONNECTION_NAME');
292
+ const getPostgresAuthType = async (): Promise<string | null> => await getEnvVar('POSTGRES_AUTH_TYPE');
265
293
  const getBigtableInstanceName = async (): Promise<string | null> => await getEnvVar('BIGTABLE_INSTANCE_NAME');
266
294
  const getBigtableTableName = async (): Promise<string | null> => await getEnvVar('BIGTABLE_TABLE_NAME');
267
295
  const getBigtableProjectId = async (): Promise<string | null> => await getEnvVar('BIGTABLE_PROJECT_ID');
268
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;
269
300
  const getJiraApiToken = async (): Promise<string | null> => await getEnvVar('JIRA_API_TOKEN');
270
301
  const getJiraApiBaseUrl = async (): Promise<string | null> => await getEnvVar('JIRA_API_BASE_URL');
271
302
  const getJiraUserEmail = async (): Promise<string | null> => await getEnvVar('JIRA_USER_EMAIL');
@@ -297,7 +328,6 @@ const _getResolvedGcpUserEmail = async (): Promise<string | null> => {
297
328
  return sm.getResolvedUserEmail();
298
329
  };
299
330
 
300
- const getGcpProjectId = _getResolvedGcpProjectId;
301
331
  const getGcpUserEmail = _getResolvedGcpUserEmail;
302
332
 
303
333
  const printEnv = async (): Promise<void> => {
@@ -309,6 +339,7 @@ const printEnv = async (): Promise<void> => {
309
339
  const postgresIpType = await getPostgresIpType();
310
340
  const postgresPoolSizeMax = await getPostgresPoolSizeMax();
311
341
  const postgresInstanceConnectionName = await getPostgresInstanceConnectionName();
342
+ const postgresAuthType = await getPostgresAuthType();
312
343
  const bigtableInstanceName = await getBigtableInstanceName();
313
344
  const bigtableTableName = await getBigtableTableName();
314
345
  const bigtableProjectId = await getBigtableProjectId();
@@ -333,6 +364,7 @@ const printEnv = async (): Promise<void> => {
333
364
  console.log(`PostgreSQL IP Type: ${postgresIpType}`);
334
365
  console.log(`PostgreSQL Pool Size Max: ${postgresPoolSizeMax}`);
335
366
  console.log(`PostgreSQL Instance Connection Name: ${postgresInstanceConnectionName}`);
367
+ console.log(`PostgreSQL Auth Type: ${postgresAuthType}`);
336
368
  console.log(`Bigtable Instance Name: ${bigtableInstanceName}`);
337
369
  console.log(`Bigtable Table Name: ${bigtableTableName}`);
338
370
  console.log(`Bigtable Project ID: ${bigtableProjectId}`);
@@ -356,6 +388,7 @@ const run = async (): Promise<void> => {
356
388
  case 'setPostgresIpType': await setPostgresIpType(); break;
357
389
  case 'setPostgresPoolSizeMax': await setPostgresPoolSizeMax(); break;
358
390
  case 'setPostgresInstanceConnectionName': await setPostgresInstanceConnectionName(); break;
391
+ case 'setPostgresAuthType': await setPostgresAuthType(); break;
359
392
  case 'setBigtableInstanceName': await setBigtableInstanceName(); break;
360
393
  case 'setBigtableTableName': await setBigtableTableName(); break;
361
394
  case 'setBigtableProjectId': await setBigtableProjectId(); break;
@@ -396,6 +429,7 @@ export {
396
429
  setPostgresIpType,
397
430
  setPostgresPoolSizeMax,
398
431
  setPostgresInstanceConnectionName,
432
+ setPostgresAuthType,
399
433
  setBigtableInstanceName,
400
434
  setBigtableTableName,
401
435
  setBigtableProjectId,
@@ -416,6 +450,7 @@ export {
416
450
  getPostgresIpType,
417
451
  getPostgresPoolSizeMax,
418
452
  getPostgresInstanceConnectionName,
453
+ getPostgresAuthType,
419
454
  getBigtableInstanceName,
420
455
  getBigtableTableName,
421
456
  getBigtableProjectId,
@@ -427,7 +462,6 @@ export {
427
462
 
428
463
  // Synchronous Getters / Utility
429
464
  getProjectRoot,
430
- getGcpProjectId,
431
465
  getGcpUserEmail,
432
466
 
433
467
  // Generic accessors