@golden-frijoles/kit 1.2.0 → 1.4.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.
@@ -12,13 +12,14 @@
12
12
  // node scripts/roadmap-push.mjs # push to $GROWTH_ENGINE_URL
13
13
  // node scripts/roadmap-push.mjs --dry-run # print the envelope, send nothing
14
14
  // node scripts/roadmap-push.mjs --url http://localhost:3000
15
+ // node scripts/roadmap-push.mjs --env-file .env.local # the key and URL `frijoles init --ingest` wrote
15
16
  //
16
17
  // Env: GROWTH_ENGINE_URL (default http://localhost:3000) and the project's ingest key: SELF_PROJECT_API_KEY FIRST (it only
17
18
  // ever means this project's own key), else the SDK's GROWTH_ENGINE_API_KEY. Not the other way round — see apiKeyFrom.
18
19
  // A missing key is a CLEAN SKIP (exit 0), not a failure — see the note in the CI step.
19
20
 
20
21
  import { spawnSync } from 'node:child_process';
21
- import { writeSync } from 'node:fs';
22
+ import { readFileSync, writeSync } from 'node:fs';
22
23
  import { dirname, resolve } from 'node:path';
23
24
  import { fileURLToPath } from 'node:url';
24
25
  import { getKey } from './lib/config.mjs';
@@ -166,6 +167,23 @@ export async function pushRoadmap(
166
167
  return { ok: res.ok, skipped: false, status: res.status, text: await res.text() };
167
168
  }
168
169
 
170
+ /**
171
+ * setup-instruments-connects D8 — the push's own variables from a dotenv file (`frijoles init --ingest` writes them to
172
+ * `.env.local`). Pure, and it reads ONLY these names: nothing is evaluated (a shell `source` would run whatever the file
173
+ * holds), and the last assignment wins, as dotenv does. Quotes are stripped; `export ` is allowed.
174
+ */
175
+ export const ENV_FILE_NAMES = ['GROWTH_ENGINE_URL', 'GROWTH_ENGINE_API_KEY', 'SELF_PROJECT_API_KEY'];
176
+ export function readEnvFile(text) {
177
+ const out = {};
178
+ for (const line of String(text).split(/\r?\n/)) {
179
+ const m = /^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/.exec(line);
180
+ if (!m || !ENV_FILE_NAMES.includes(m[1])) continue;
181
+ const value = m[2].trim().replace(/^(['"])(.*)\1$/, '$2');
182
+ if (value) out[m[1]] = value;
183
+ }
184
+ return out;
185
+ }
186
+
169
187
  /** The CLI's report for one push result. Exported so `roadmap-extract --sink hub` says it the same way. */
170
188
  export function reportPush(result, count) {
171
189
  if (result.skipped) {
@@ -189,16 +207,37 @@ export function reportPush(result, count) {
189
207
  async function main() {
190
208
  const args = process.argv.slice(2);
191
209
  const urlFlag = args.indexOf('--url');
210
+ const envFlag = args.indexOf('--env-file');
211
+ let fromFile = {};
212
+ if (envFlag !== -1) {
213
+ const path = args[envFlag + 1];
214
+ if (!path) {
215
+ process.stderr.write('--env-file needs a path, for example --env-file .env.local\n');
216
+ process.exitCode = 1;
217
+ return;
218
+ }
219
+ try {
220
+ fromFile = readEnvFile(readFileSync(resolve(REPO_ROOT, path), 'utf8'));
221
+ } catch (err) {
222
+ process.stderr.write(`could not read ${path}: ${err.message}\n`);
223
+ process.exitCode = 1;
224
+ return;
225
+ }
226
+ }
227
+ // An explicit --url wins, then the file, then the shell's environment.
192
228
  const baseUrl =
193
229
  (urlFlag !== -1 ? args[urlFlag + 1] : undefined) ||
230
+ fromFile.GROWTH_ENGINE_URL ||
194
231
  process.env.GROWTH_ENGINE_URL ||
195
232
  'http://localhost:3000';
233
+ // A key in the file wins over the shell's, so the key and the URL come from the same place (verifier, #338).
234
+ const apiKey = apiKeyFrom(fromFile) ?? apiKeyFrom(process.env);
196
235
  const items = readExtract();
197
236
  if (args.includes('--dry-run')) {
198
237
  writeSync(1, `${JSON.stringify(envelopeFor(items), null, 2)}\n`);
199
238
  return;
200
239
  }
201
- process.exitCode = reportPush(await pushRoadmap(items, { baseUrl }), items.length);
240
+ process.exitCode = reportPush(await pushRoadmap(items, { baseUrl, apiKey }), items.length);
202
241
  }
203
242
 
204
243
  const isMain = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golden-frijoles/kit",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "The scripts the Golden Frijoles skills run, packaged so they work in any repo: planning, build-order, reporting and verification rails. Zero dependencies.",
5
5
  "type": "module",
6
6
  "bin": {