@odeva/cli 0.0.9 → 0.0.10
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/dist/commands/webhook/trigger.js +4 -4
- package/dist/lib/app-env.js +14 -2
- package/dist/lib/dev-runner.js +16 -17
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Args, Command, Flags } from "@oclif/core";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
-
import { resolve } from "node:path";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { APP_DEV_ENV_FILE, readEnvFile } from "../../lib/app-env.js";
|
|
4
5
|
import { loadAppConfig, findAppConfigPath } from "../../lib/config.js";
|
|
5
6
|
import { buildFixture, signPayload } from "../../lib/webhook-fixtures.js";
|
|
6
7
|
import { CliError } from "../../lib/errors.js";
|
|
7
8
|
import { withErrorHandling } from "../../lib/run.js";
|
|
8
|
-
import {
|
|
9
|
+
import { webhookSecretForEvent } from "../../lib/dev-runner.js";
|
|
9
10
|
import { ui } from "../../lib/ui.js";
|
|
10
|
-
import { join } from "node:path";
|
|
11
11
|
class WebhookTrigger extends Command {
|
|
12
12
|
static description = "Fire a sample webhook payload at a local handler (uses the secret from .env.odeva.local if present)";
|
|
13
13
|
static examples = [
|
|
@@ -107,7 +107,7 @@ class WebhookTrigger extends Command {
|
|
|
107
107
|
secretFromEnvFile(event) {
|
|
108
108
|
const cfgPath = findAppConfigPath();
|
|
109
109
|
if (!cfgPath) return void 0;
|
|
110
|
-
const envPath = join(resolve(cfgPath, ".."),
|
|
110
|
+
const envPath = join(resolve(cfgPath, ".."), APP_DEV_ENV_FILE);
|
|
111
111
|
const env = readEnvFile(envPath);
|
|
112
112
|
return webhookSecretForEvent(event, env);
|
|
113
113
|
}
|
package/dist/lib/app-env.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
const APP_ENV_FILE = ".odeva.env";
|
|
4
|
+
const APP_ENV_LOCAL_FILE = ".odeva.env.local";
|
|
5
|
+
const APP_DEV_ENV_FILE = ".env.odeva.local";
|
|
4
6
|
function loadAppEnv(appConfigPath) {
|
|
5
|
-
const
|
|
7
|
+
const dir = dirname(appConfigPath);
|
|
8
|
+
return {
|
|
9
|
+
...readEnvFile(join(dir, APP_DEV_ENV_FILE)),
|
|
10
|
+
...readEnvFile(join(dir, APP_ENV_FILE)),
|
|
11
|
+
...readEnvFile(join(dir, APP_ENV_LOCAL_FILE))
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function readEnvFile(envPath) {
|
|
6
15
|
if (!existsSync(envPath)) return {};
|
|
7
16
|
const raw = readFileSync(envPath, "utf8");
|
|
8
17
|
const result = {};
|
|
@@ -19,7 +28,7 @@ function loadAppEnv(appConfigPath) {
|
|
|
19
28
|
}
|
|
20
29
|
function saveAppEnv(appConfigPath, values) {
|
|
21
30
|
const envPath = join(dirname(appConfigPath), APP_ENV_FILE);
|
|
22
|
-
const merged = { ...
|
|
31
|
+
const merged = { ...readEnvFile(envPath), ...values };
|
|
23
32
|
const body = [
|
|
24
33
|
"# Auto-managed by `odeva` \u2014 do not commit. Add `.odeva.env` to .gitignore.",
|
|
25
34
|
...Object.entries(merged).map(([k, v]) => `${k}=${v}`),
|
|
@@ -33,7 +42,10 @@ function saveAppEnv(appConfigPath, values) {
|
|
|
33
42
|
return envPath;
|
|
34
43
|
}
|
|
35
44
|
export {
|
|
45
|
+
APP_DEV_ENV_FILE,
|
|
36
46
|
APP_ENV_FILE,
|
|
47
|
+
APP_ENV_LOCAL_FILE,
|
|
37
48
|
loadAppEnv,
|
|
49
|
+
readEnvFile,
|
|
38
50
|
saveAppEnv
|
|
39
51
|
};
|
package/dist/lib/dev-runner.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
-
import { APP_ENV_FILE } from "./app-env.js";
|
|
4
|
+
import { APP_DEV_ENV_FILE, APP_ENV_FILE, APP_ENV_LOCAL_FILE, readEnvFile } from "./app-env.js";
|
|
5
5
|
import { CliError } from "./errors.js";
|
|
6
6
|
async function registerWebhookSubscriptions(api, appName, tunnelUrl, subscriptions) {
|
|
7
7
|
const created = [];
|
|
@@ -167,7 +167,8 @@ function devAppTunnelUrl(opts) {
|
|
|
167
167
|
}
|
|
168
168
|
function writeDevEnvFile(cwd, registered) {
|
|
169
169
|
if (registered.length === 0) return null;
|
|
170
|
-
const path = join(cwd,
|
|
170
|
+
const path = join(cwd, APP_DEV_ENV_FILE);
|
|
171
|
+
const preserved = Object.entries(readEnvFile(path)).filter(([key]) => !key.startsWith("ODEVA_WEBHOOK_SECRET"));
|
|
171
172
|
const lines = [
|
|
172
173
|
"# Auto-generated by `odeva app dev`. Do not commit.",
|
|
173
174
|
"# Reload your dev server to pick up these values."
|
|
@@ -178,6 +179,13 @@ function writeDevEnvFile(cwd, registered) {
|
|
|
178
179
|
lines.push(`# ${reg.config.topic} \u2192 ${reg.fullUrl}`);
|
|
179
180
|
lines.push(`ODEVA_WEBHOOK_SECRET__${webhookSecretEnvKey(reg.config.topic)}=${reg.secret}`);
|
|
180
181
|
}
|
|
182
|
+
if (preserved.length > 0) {
|
|
183
|
+
lines.push("");
|
|
184
|
+
lines.push("# Preserved local values.");
|
|
185
|
+
for (const [key, value] of preserved) {
|
|
186
|
+
lines.push(`${key}=${value}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
181
189
|
writeFileSync(path, lines.join("\n") + "\n", { mode: 384 });
|
|
182
190
|
return path;
|
|
183
191
|
}
|
|
@@ -196,7 +204,11 @@ function webhookSecretForEvent(event, env) {
|
|
|
196
204
|
return env[`ODEVA_WEBHOOK_SECRET__${webhookSecretEnvKey(event)}`] ?? env["ODEVA_WEBHOOK_SECRET"];
|
|
197
205
|
}
|
|
198
206
|
function watchedDevInputPaths(appConfigPath) {
|
|
199
|
-
return [
|
|
207
|
+
return [
|
|
208
|
+
appConfigPath,
|
|
209
|
+
join(dirname(appConfigPath), APP_ENV_FILE),
|
|
210
|
+
join(dirname(appConfigPath), APP_ENV_LOCAL_FILE)
|
|
211
|
+
];
|
|
200
212
|
}
|
|
201
213
|
function joinUrl(base, path) {
|
|
202
214
|
const trimmedBase = base.replace(/\/$/, "");
|
|
@@ -341,25 +353,12 @@ function preflightChecks(cwd) {
|
|
|
341
353
|
}
|
|
342
354
|
return { warnings };
|
|
343
355
|
}
|
|
344
|
-
function readEnvFile(path) {
|
|
345
|
-
if (!existsSync(path)) return {};
|
|
346
|
-
const out = {};
|
|
347
|
-
for (const line of readFileSync(path, "utf8").split("\n")) {
|
|
348
|
-
const trimmed = line.trim();
|
|
349
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
350
|
-
const eq = trimmed.indexOf("=");
|
|
351
|
-
if (eq === -1) continue;
|
|
352
|
-
out[trimmed.slice(0, eq)] = trimmed.slice(eq + 1);
|
|
353
|
-
}
|
|
354
|
-
return out;
|
|
355
|
-
}
|
|
356
356
|
export {
|
|
357
357
|
cleanupSubscriptions,
|
|
358
358
|
devAppTunnelUrl,
|
|
359
359
|
devInstallCallbackUrl,
|
|
360
360
|
ensureDevAppInstalled,
|
|
361
361
|
preflightChecks,
|
|
362
|
-
readEnvFile,
|
|
363
362
|
registerWebhookSubscriptions,
|
|
364
363
|
registeredWebhookEnv,
|
|
365
364
|
spawnDevServer,
|