target-supabase-sdk 0.2.1 → 0.2.3
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/README.md +4 -2
- package/dist/chunks/{enable-log-persist-C_bSw6Kx.js → enable-log-persist-C7GJo_Nc.js} +193 -40
- package/dist/chunks/enable-log-persist-C7GJo_Nc.js.map +1 -0
- package/dist/node/env/index.d.ts +2 -2
- package/dist/node/env/index.d.ts.map +1 -1
- package/dist/node/env/init-supabase-from-env.d.ts +1 -1
- package/dist/node/env/init-supabase-from-env.d.ts.map +1 -1
- package/dist/node/env/load-env.d.ts +15 -1
- package/dist/node/env/load-env.d.ts.map +1 -1
- package/dist/node/preload/run-service-preload.d.ts +1 -1
- package/dist/node/preload/run-service-preload.d.ts.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +2 -2
- package/dist/node.js.map +1 -1
- package/dist/preload.js +3 -2
- package/dist/preload.js.map +1 -1
- package/dist/shared/log/log-persist-registry.d.ts +1 -0
- package/dist/shared/log/log-persist-registry.d.ts.map +1 -1
- package/dist/shared/log/log-persist.interface.d.ts +1 -1
- package/dist/shared/log/log-persist.interface.d.ts.map +1 -1
- package/package.json +1 -6
- package/src/node/env/index.ts +13 -2
- package/src/node/env/init-supabase-from-env.ts +1 -1
- package/src/node/env/load-env.ts +48 -2
- package/src/node/preload/run-service-preload.ts +3 -2
- package/src/node.ts +7 -0
- package/src/shared/log/log-persist-flush.ts +2 -2
- package/src/shared/log/log-persist-registry.ts +176 -33
- package/src/shared/log/log-persist.interface.ts +1 -1
- package/dist/chunks/enable-log-persist-C_bSw6Kx.js.map +0 -1
package/dist/preload.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
|
-
import { r as resolveProjectRootByPackageName, l as loadEnvFiles, v as validateLogPersistPreloadEnv, a as logPersistEnabledFromEnv } from './chunks/enable-log-persist-
|
|
2
|
+
import { r as resolveProjectRootByPackageName, p as pinEnvProfileFromArgv, l as loadEnvFiles, v as validateLogPersistPreloadEnv, a as logPersistEnabledFromEnv } from './chunks/enable-log-persist-C7GJo_Nc.js';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:url';
|
|
5
5
|
import 'node:fs/promises';
|
|
@@ -26,7 +26,7 @@ function applyServiceEnvDefaults(projectRoot, options) {
|
|
|
26
26
|
* Unified Node `--import` preload runner (sync only).
|
|
27
27
|
*
|
|
28
28
|
* Phase 1 — Resolve project root from service package name
|
|
29
|
-
* Phase 2 — Load `.env.local` / `.env`
|
|
29
|
+
* Phase 2 — Load env files (`.env.local` / `.env`, or `.env.prod` when `--prod`)
|
|
30
30
|
* Phase 3 — Apply SDK service env defaults + optional L3 hook
|
|
31
31
|
* Phase 4 — Validate log-persist env when enabled
|
|
32
32
|
* Phase 5 — Process diagnostics (TODO)
|
|
@@ -35,6 +35,7 @@ function applyServiceEnvDefaults(projectRoot, options) {
|
|
|
35
35
|
*/
|
|
36
36
|
function runServicePreload(options) {
|
|
37
37
|
const projectRoot = resolveProjectRootByPackageName(options.callerImportMetaUrl, options.packageName);
|
|
38
|
+
pinEnvProfileFromArgv();
|
|
38
39
|
loadEnvFiles(projectRoot, { afterLoad: options.afterLoadEnv });
|
|
39
40
|
applyServiceEnvDefaults(projectRoot, options);
|
|
40
41
|
options.applyEnvDefaults?.(projectRoot);
|
package/dist/preload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preload.js","sources":["../src/node/preload/run-service-preload.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { validateLogPersistPreloadEnv } from \"../../shared/log/enable-log-persist\";\nimport { logPersistEnabledFromEnv } from \"../../shared/log/log-persist.config\";\nimport { loadEnvFiles } from \"../env/load-env\";\nimport { resolveProjectRootByPackageName } from \"../env/project-root\";\nimport type { ServicePreloadOptions } from \"./service-preload.interface\";\n\nfunction applyServiceEnvDefaults(projectRoot: string, options: ServicePreloadOptions): void {\n if (!logPersistEnabledFromEnv()) {\n return;\n }\n\n const service = process.env.LOG_PERSIST_SERVICE?.trim();\n if (service == null || service === \"\") {\n process.env.LOG_PERSIST_SERVICE = options.serviceValue;\n }\n\n const runtimeDir = process.env.RUNTIME_DATA_DIR?.trim();\n if (runtimeDir == null || runtimeDir === \"\") {\n const relative = options.runtimeDataDirRelative ?? \"data/runtime\";\n process.env.RUNTIME_DATA_DIR = resolve(projectRoot, relative);\n }\n}\n\n/**\n * Unified Node `--import` preload runner (sync only).\n *\n * Phase 1 — Resolve project root from service package name\n * Phase 2 — Load `.env.local` / `.env
|
|
1
|
+
{"version":3,"file":"preload.js","sources":["../src/node/preload/run-service-preload.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { validateLogPersistPreloadEnv } from \"../../shared/log/enable-log-persist\";\nimport { logPersistEnabledFromEnv } from \"../../shared/log/log-persist.config\";\nimport { loadEnvFiles, pinEnvProfileFromArgv } from \"../env/load-env\";\nimport { resolveProjectRootByPackageName } from \"../env/project-root\";\nimport type { ServicePreloadOptions } from \"./service-preload.interface\";\n\nfunction applyServiceEnvDefaults(projectRoot: string, options: ServicePreloadOptions): void {\n if (!logPersistEnabledFromEnv()) {\n return;\n }\n\n const service = process.env.LOG_PERSIST_SERVICE?.trim();\n if (service == null || service === \"\") {\n process.env.LOG_PERSIST_SERVICE = options.serviceValue;\n }\n\n const runtimeDir = process.env.RUNTIME_DATA_DIR?.trim();\n if (runtimeDir == null || runtimeDir === \"\") {\n const relative = options.runtimeDataDirRelative ?? \"data/runtime\";\n process.env.RUNTIME_DATA_DIR = resolve(projectRoot, relative);\n }\n}\n\n/**\n * Unified Node `--import` preload runner (sync only).\n *\n * Phase 1 — Resolve project root from service package name\n * Phase 2 — Load env files (`.env.local` / `.env`, or `.env.prod` when `--prod`)\n * Phase 3 — Apply SDK service env defaults + optional L3 hook\n * Phase 4 — Validate log-persist env when enabled\n * Phase 5 — Process diagnostics (TODO)\n *\n * Supabase init and log-persist enable stay in app `main()` (async).\n */\nexport function runServicePreload(options: ServicePreloadOptions): void {\n const projectRoot = resolveProjectRootByPackageName(options.callerImportMetaUrl, options.packageName);\n\n pinEnvProfileFromArgv();\n loadEnvFiles(projectRoot, { afterLoad: options.afterLoadEnv });\n\n applyServiceEnvDefaults(projectRoot, options);\n options.applyEnvDefaults?.(projectRoot);\n\n validateLogPersistPreloadEnv();\n\n // TODO: Phase 5 — optional unhandledRejection / uncaughtException formatters\n // (formerly watch-service preload-diagnostics.mjs)\n}\n"],"names":[],"mappings":";;;;;;;;;;AAOA,SAAS,uBAAuB,CAAC,WAAmB,EAAE,OAA8B,EAAA;AAChF,IAAA,IAAI,CAAC,wBAAwB,EAAE,EAAE;QAC7B;IACJ;IAEA,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE;IACvD,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,KAAK,EAAE,EAAE;QACnC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC,YAAY;IAC1D;IAEA,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE;IACvD,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,KAAK,EAAE,EAAE;AACzC,QAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,sBAAsB,IAAI,cAAc;QACjE,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC;IACjE;AACJ;AAEA;;;;;;;;;;AAUG;AACG,SAAU,iBAAiB,CAAC,OAA8B,EAAA;AAC5D,IAAA,MAAM,WAAW,GAAG,+BAA+B,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,WAAW,CAAC;AAErG,IAAA,qBAAqB,EAAE;IACvB,YAAY,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;AAE9D,IAAA,uBAAuB,CAAC,WAAW,EAAE,OAAO,CAAC;AAC7C,IAAA,OAAO,CAAC,gBAAgB,GAAG,WAAW,CAAC;AAEvC,IAAA,4BAA4B,EAAE;;;AAIlC;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LogPersistRegistryState } from "./log-persist.interface";
|
|
2
|
+
/** Registry root directory — one shard file per process under this path. */
|
|
2
3
|
export declare function defaultLogPersistRegistryPath(registryDir: string): string;
|
|
3
4
|
export declare function registerLogPersistProcess(input: {
|
|
4
5
|
registryFilePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-persist-registry.d.ts","sourceRoot":"","sources":["../../../src/shared/log/log-persist-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log-persist-registry.d.ts","sourceRoot":"","sources":["../../../src/shared/log/log-persist-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA2B,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAiEhG,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzE;AAmDD,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhB;AAED,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpH;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDrH;AAED,wBAAsB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAKvG"}
|
|
@@ -30,7 +30,7 @@ export interface LogPersistConfig {
|
|
|
30
30
|
export interface EnableLogPersistOptions {
|
|
31
31
|
service: string;
|
|
32
32
|
process: string;
|
|
33
|
-
/** Shared registry
|
|
33
|
+
/** Shared registry root directory — all processes use the same path; each writes its own shard file. */
|
|
34
34
|
registryFilePath?: string;
|
|
35
35
|
config?: Partial<LogPersistConfig>;
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-persist.interface.d.ts","sourceRoot":"","sources":["../../../src/shared/log/log-persist.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,oBAAoB;IACjC,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,sBAAsB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"log-persist.interface.d.ts","sourceRoot":"","sources":["../../../src/shared/log/log-persist.interface.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "target-supabase-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Supabase client initializer and data access APIs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "KyLoc20",
|
|
@@ -53,10 +53,7 @@
|
|
|
53
53
|
"format": "biome check --write .",
|
|
54
54
|
"format:check": "biome ci",
|
|
55
55
|
"lint": "biome lint .",
|
|
56
|
-
"worker": "tsx scripts/run-node-worker.ts",
|
|
57
56
|
"worker:trigger": "tsx scripts/run-trigger-node.ts",
|
|
58
|
-
"chrome-sidecar": "tsx scripts/chrome-sidecar-hub.ts",
|
|
59
|
-
"post-task": "tsx scripts/post-task.ts",
|
|
60
57
|
"post-command": "tsx scripts/post-command.ts",
|
|
61
58
|
"post-trigger": "tsx scripts/post-trigger.ts",
|
|
62
59
|
"parcel:split": "tsx scripts/parcel-split-local.ts",
|
|
@@ -79,13 +76,11 @@
|
|
|
79
76
|
"@supabase/supabase-js": "2.50.3",
|
|
80
77
|
"@types/lodash-es": "^4.17.12",
|
|
81
78
|
"@types/wicg-file-system-access": "^2023.10.7",
|
|
82
|
-
"@types/ws": "^8.18.1",
|
|
83
79
|
"lodash-es": "^4.17.21",
|
|
84
80
|
"rollup": "^4.40.2",
|
|
85
81
|
"tslib": "^2.8.1",
|
|
86
82
|
"tsx": "^4.19.4",
|
|
87
83
|
"typescript": "~5.7.2",
|
|
88
|
-
"ws": "^8.18.0",
|
|
89
84
|
"zod": "^3.24.0"
|
|
90
85
|
},
|
|
91
86
|
"publishConfig": {
|
package/src/node/env/index.ts
CHANGED
|
@@ -2,8 +2,19 @@ export type { EnvIntOptions, EnvNumberOptions } from "./env-parsers";
|
|
|
2
2
|
export { envBool, envInt, envMs, envNumber, envPort } from "./env-parsers";
|
|
3
3
|
export type { InitSupabaseFromStandardEnvOptions } from "./init-supabase-from-env";
|
|
4
4
|
export { initSupabaseFromStandardEnv } from "./init-supabase-from-env";
|
|
5
|
-
export type { LoadEnvFilesOptions } from "./load-env";
|
|
6
|
-
export {
|
|
5
|
+
export type { EnvProfileFromProcessOptions, LoadEnvFilesOptions } from "./load-env";
|
|
6
|
+
export {
|
|
7
|
+
CLI_PROD_FLAG,
|
|
8
|
+
envProfileFromProcess,
|
|
9
|
+
loadEnvFiles,
|
|
10
|
+
parseEnvFile,
|
|
11
|
+
parseEnvFileContent,
|
|
12
|
+
parseEnvLine,
|
|
13
|
+
pinEnvProfileFromArgv,
|
|
14
|
+
resolveDefaultEnvFiles,
|
|
15
|
+
SERVICE_ENV_PROFILE_ENV_KEY,
|
|
16
|
+
SERVICE_ENV_PROFILE_PROD,
|
|
17
|
+
} from "./load-env";
|
|
7
18
|
export { resolveProjectRootByPackageName, resolveProjectRootFromModule } from "./project-root";
|
|
8
19
|
export type { PublicBaseUrlFromEnvOptions } from "./public-base-url";
|
|
9
20
|
export { publicBaseUrlFromEnv } from "./public-base-url";
|
|
@@ -5,7 +5,7 @@ import { readEnv, requireEnv } from "./require-env";
|
|
|
5
5
|
export interface InitSupabaseFromStandardEnvOptions {
|
|
6
6
|
/** Project root for `.env` files (required when `loadEnv` is true). */
|
|
7
7
|
root?: string;
|
|
8
|
-
/** Load
|
|
8
|
+
/** Load env files before initialize (default true). Uses `.env.prod` when profile is `prod`. */
|
|
9
9
|
loadEnv?: boolean;
|
|
10
10
|
/** Hook after env files loaded (legacy aliases, etc.). */
|
|
11
11
|
afterLoadEnv?: () => void;
|
package/src/node/env/load-env.ts
CHANGED
|
@@ -2,6 +2,51 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
|
|
4
4
|
const DEFAULT_ENV_FILES = [".env.local", ".env"] as const;
|
|
5
|
+
const PROD_ENV_FILES = [".env.prod"] as const;
|
|
6
|
+
|
|
7
|
+
export const SERVICE_ENV_PROFILE_ENV_KEY = "SERVICE_ENV_PROFILE" as const;
|
|
8
|
+
export const SERVICE_ENV_PROFILE_PROD = "prod" as const;
|
|
9
|
+
export const CLI_PROD_FLAG = "--prod" as const;
|
|
10
|
+
|
|
11
|
+
export interface EnvProfileFromProcessOptions {
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
argv?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Resolve active env profile from `SERVICE_ENV_PROFILE` or `--prod` on argv. */
|
|
17
|
+
export function envProfileFromProcess(options?: EnvProfileFromProcessOptions): string | undefined {
|
|
18
|
+
const env = options?.env ?? process.env;
|
|
19
|
+
const argv = options?.argv ?? process.argv;
|
|
20
|
+
const fromEnv = env[SERVICE_ENV_PROFILE_ENV_KEY]?.trim();
|
|
21
|
+
if (fromEnv != null && fromEnv !== "") {
|
|
22
|
+
return fromEnv;
|
|
23
|
+
}
|
|
24
|
+
if (argv.includes(CLI_PROD_FLAG)) {
|
|
25
|
+
return SERVICE_ENV_PROFILE_PROD;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Default env file list for a profile (`prod` → `.env.prod`; otherwise `.env.local` → `.env`). */
|
|
31
|
+
export function resolveDefaultEnvFiles(profile?: string): readonly string[] {
|
|
32
|
+
if (profile === SERVICE_ENV_PROFILE_PROD) {
|
|
33
|
+
return PROD_ENV_FILES;
|
|
34
|
+
}
|
|
35
|
+
return DEFAULT_ENV_FILES;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Pin `SERVICE_ENV_PROFILE=prod` when `--prod` is on argv (for child process inheritance). */
|
|
39
|
+
export function pinEnvProfileFromArgv(
|
|
40
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
41
|
+
argv: readonly string[] = process.argv,
|
|
42
|
+
): void {
|
|
43
|
+
if (env[SERVICE_ENV_PROFILE_ENV_KEY]?.trim()) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (argv.includes(CLI_PROD_FLAG)) {
|
|
47
|
+
env[SERVICE_ENV_PROFILE_ENV_KEY] = SERVICE_ENV_PROFILE_PROD;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
5
50
|
|
|
6
51
|
export interface LoadEnvFilesOptions {
|
|
7
52
|
/** Files to load in order (later files do not override existing env). */
|
|
@@ -52,12 +97,13 @@ export function parseEnvFile(filePath: string, env: NodeJS.ProcessEnv): void {
|
|
|
52
97
|
}
|
|
53
98
|
|
|
54
99
|
/**
|
|
55
|
-
* Load
|
|
100
|
+
* Load env files into `process.env` (or `options.env`).
|
|
101
|
+
* Default files: `.env.local` → `.env`, or `.env.prod` when profile is `prod` / `--prod`.
|
|
56
102
|
* Existing non-empty env values are not overwritten.
|
|
57
103
|
*/
|
|
58
104
|
export function loadEnvFiles(root: string, options?: LoadEnvFilesOptions): void {
|
|
59
105
|
const env = options?.env ?? process.env;
|
|
60
|
-
const files = options?.files ??
|
|
106
|
+
const files = options?.files ?? resolveDefaultEnvFiles(envProfileFromProcess({ env }));
|
|
61
107
|
|
|
62
108
|
for (const name of files) {
|
|
63
109
|
parseEnvFile(resolve(root, name), env);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { validateLogPersistPreloadEnv } from "../../shared/log/enable-log-persist";
|
|
3
3
|
import { logPersistEnabledFromEnv } from "../../shared/log/log-persist.config";
|
|
4
|
-
import { loadEnvFiles } from "../env/load-env";
|
|
4
|
+
import { loadEnvFiles, pinEnvProfileFromArgv } from "../env/load-env";
|
|
5
5
|
import { resolveProjectRootByPackageName } from "../env/project-root";
|
|
6
6
|
import type { ServicePreloadOptions } from "./service-preload.interface";
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ function applyServiceEnvDefaults(projectRoot: string, options: ServicePreloadOpt
|
|
|
26
26
|
* Unified Node `--import` preload runner (sync only).
|
|
27
27
|
*
|
|
28
28
|
* Phase 1 — Resolve project root from service package name
|
|
29
|
-
* Phase 2 — Load `.env.local` / `.env`
|
|
29
|
+
* Phase 2 — Load env files (`.env.local` / `.env`, or `.env.prod` when `--prod`)
|
|
30
30
|
* Phase 3 — Apply SDK service env defaults + optional L3 hook
|
|
31
31
|
* Phase 4 — Validate log-persist env when enabled
|
|
32
32
|
* Phase 5 — Process diagnostics (TODO)
|
|
@@ -36,6 +36,7 @@ function applyServiceEnvDefaults(projectRoot: string, options: ServicePreloadOpt
|
|
|
36
36
|
export function runServicePreload(options: ServicePreloadOptions): void {
|
|
37
37
|
const projectRoot = resolveProjectRootByPackageName(options.callerImportMetaUrl, options.packageName);
|
|
38
38
|
|
|
39
|
+
pinEnvProfileFromArgv();
|
|
39
40
|
loadEnvFiles(projectRoot, { afterLoad: options.afterLoadEnv });
|
|
40
41
|
|
|
41
42
|
applyServiceEnvDefaults(projectRoot, options);
|
package/src/node.ts
CHANGED
|
@@ -10,25 +10,32 @@ export * from "./command/command.interface";
|
|
|
10
10
|
export type {
|
|
11
11
|
EnvIntOptions,
|
|
12
12
|
EnvNumberOptions,
|
|
13
|
+
EnvProfileFromProcessOptions,
|
|
13
14
|
InitSupabaseFromStandardEnvOptions,
|
|
14
15
|
LoadEnvFilesOptions,
|
|
15
16
|
PublicBaseUrlFromEnvOptions,
|
|
16
17
|
} from "./node/env";
|
|
17
18
|
export {
|
|
19
|
+
CLI_PROD_FLAG,
|
|
18
20
|
envBool,
|
|
19
21
|
envInt,
|
|
20
22
|
envMs,
|
|
21
23
|
envNumber,
|
|
22
24
|
envPort,
|
|
25
|
+
envProfileFromProcess,
|
|
23
26
|
initSupabaseFromStandardEnv,
|
|
24
27
|
loadEnvFiles,
|
|
25
28
|
parseEnvFile,
|
|
26
29
|
parseEnvLine,
|
|
30
|
+
pinEnvProfileFromArgv,
|
|
27
31
|
publicBaseUrlFromEnv,
|
|
28
32
|
readEnv,
|
|
29
33
|
requireEnv,
|
|
34
|
+
resolveDefaultEnvFiles,
|
|
30
35
|
resolveProjectRootByPackageName,
|
|
31
36
|
resolveProjectRootFromModule,
|
|
37
|
+
SERVICE_ENV_PROFILE_ENV_KEY,
|
|
38
|
+
SERVICE_ENV_PROFILE_PROD,
|
|
32
39
|
} from "./node/env";
|
|
33
40
|
export type {
|
|
34
41
|
CreateJsonFileStateStoreOptions,
|
|
@@ -23,12 +23,12 @@ export function buildLogListDraft(input: BuildLogListDraftInput): LogListDraft {
|
|
|
23
23
|
const last = entries[entries.length - 1];
|
|
24
24
|
|
|
25
25
|
return {
|
|
26
|
-
name:
|
|
26
|
+
name: `log-batch:${service}:${process}:${lane}`,
|
|
27
27
|
value: idempotencyKey,
|
|
28
28
|
category: CategoryList.LIST,
|
|
29
29
|
tagList: ["log", lane, service],
|
|
30
30
|
details: {
|
|
31
|
-
manifestVersion:
|
|
31
|
+
manifestVersion: 0,
|
|
32
32
|
loaderKey: LOG_PERSIST_LOADER_KEY,
|
|
33
33
|
meta: JSON.stringify({
|
|
34
34
|
service,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import { createJsonFileStateStore } from "../../node/fs/json-state-store";
|
|
3
4
|
import type { LogPersistProcessRecord, LogPersistRegistryState } from "./log-persist.interface";
|
|
@@ -9,10 +10,33 @@ const DEFAULT_REGISTRY: LogPersistRegistryState = {
|
|
|
9
10
|
processes: {},
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
/** Per-process shard — each process owns one file; no cross-process RMW. */
|
|
14
|
+
interface LogPersistProcessShard extends LogPersistProcessRecord {
|
|
15
|
+
service: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DEFAULT_SHARD: LogPersistProcessShard = {
|
|
20
|
+
service: "",
|
|
21
|
+
updatedAt: new Date(0).toISOString(),
|
|
22
|
+
pid: 0,
|
|
23
|
+
enabledAt: new Date(0).toISOString(),
|
|
24
|
+
lastHeartbeatAt: new Date(0).toISOString(),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const legacyStores = new Map<
|
|
28
|
+
string,
|
|
29
|
+
ReturnType<typeof createJsonFileStateStore<LogPersistRegistryState, "processes">>
|
|
30
|
+
>();
|
|
13
31
|
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
const shardStores = new Map<string, ReturnType<typeof createJsonFileStateStore<LogPersistProcessShard>>>();
|
|
33
|
+
|
|
34
|
+
function isLegacyRegistryFile(registryPath: string): boolean {
|
|
35
|
+
return registryPath.endsWith(".json");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function legacyStoreFor(filePath: string) {
|
|
39
|
+
let store = legacyStores.get(filePath);
|
|
16
40
|
if (store == null) {
|
|
17
41
|
store = createJsonFileStateStore<LogPersistRegistryState, "processes">({
|
|
18
42
|
filePath,
|
|
@@ -20,13 +44,80 @@ function storeFor(filePath: string) {
|
|
|
20
44
|
nestedKeys: ["processes"],
|
|
21
45
|
updatedAtKey: "updatedAt",
|
|
22
46
|
});
|
|
23
|
-
|
|
47
|
+
legacyStores.set(filePath, store);
|
|
24
48
|
}
|
|
25
49
|
return store;
|
|
26
50
|
}
|
|
27
51
|
|
|
52
|
+
function shardStoreFor(shardFilePath: string) {
|
|
53
|
+
let store = shardStores.get(shardFilePath);
|
|
54
|
+
if (store == null) {
|
|
55
|
+
store = createJsonFileStateStore<LogPersistProcessShard>({
|
|
56
|
+
filePath: shardFilePath,
|
|
57
|
+
defaultState: DEFAULT_SHARD,
|
|
58
|
+
updatedAtKey: "updatedAt",
|
|
59
|
+
});
|
|
60
|
+
shardStores.set(shardFilePath, store);
|
|
61
|
+
}
|
|
62
|
+
return store;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function shardFilePath(registryDir: string, process: string): string {
|
|
66
|
+
return join(registryDir, `${process}.json`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Registry root directory — one shard file per process under this path. */
|
|
28
70
|
export function defaultLogPersistRegistryPath(registryDir: string): string {
|
|
29
|
-
return join(registryDir, "log-persist-registry
|
|
71
|
+
return join(registryDir, "log-persist-registry");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function readShardedLogPersistRegistry(registryDir: string): Promise<LogPersistRegistryState> {
|
|
75
|
+
await mkdir(registryDir, { recursive: true });
|
|
76
|
+
|
|
77
|
+
let entries: string[];
|
|
78
|
+
try {
|
|
79
|
+
entries = await readdir(registryDir);
|
|
80
|
+
} catch {
|
|
81
|
+
return { ...DEFAULT_REGISTRY };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const processes: Record<string, LogPersistProcessRecord> = {};
|
|
85
|
+
let service = "";
|
|
86
|
+
let updatedAt = new Date(0).toISOString();
|
|
87
|
+
|
|
88
|
+
for (const name of entries) {
|
|
89
|
+
if (!name.endsWith(".json")) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const processName = name.slice(0, -".json".length);
|
|
94
|
+
if (processName === "" || processName.startsWith("_")) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const raw = await readFile(join(registryDir, name), "utf8");
|
|
100
|
+
const shard = JSON.parse(raw) as Partial<LogPersistProcessShard>;
|
|
101
|
+
if (shard.service != null && shard.service !== "") {
|
|
102
|
+
service = shard.service;
|
|
103
|
+
}
|
|
104
|
+
if (shard.updatedAt != null && shard.updatedAt > updatedAt) {
|
|
105
|
+
updatedAt = shard.updatedAt;
|
|
106
|
+
}
|
|
107
|
+
processes[processName] = {
|
|
108
|
+
pid: shard.pid ?? 0,
|
|
109
|
+
enabledAt: shard.enabledAt ?? new Date(0).toISOString(),
|
|
110
|
+
lastHeartbeatAt: shard.lastHeartbeatAt ?? new Date(0).toISOString(),
|
|
111
|
+
};
|
|
112
|
+
} catch {
|
|
113
|
+
persistLogger.warn("registry shard read skipped — corrupt or missing", {
|
|
114
|
+
registryDir,
|
|
115
|
+
shard: name,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return { updatedAt, service, processes };
|
|
30
121
|
}
|
|
31
122
|
|
|
32
123
|
export async function registerLogPersistProcess(input: {
|
|
@@ -41,12 +132,21 @@ export async function registerLogPersistProcess(input: {
|
|
|
41
132
|
lastHeartbeatAt: now,
|
|
42
133
|
};
|
|
43
134
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
135
|
+
if (isLegacyRegistryFile(input.registryFilePath)) {
|
|
136
|
+
await legacyStoreFor(input.registryFilePath).write({
|
|
137
|
+
service: input.service,
|
|
138
|
+
processes: {
|
|
139
|
+
[input.process]: record,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
await shardStoreFor(shardFilePath(input.registryFilePath, input.process)).write({
|
|
144
|
+
service: input.service,
|
|
145
|
+
pid: record.pid,
|
|
146
|
+
enabledAt: record.enabledAt,
|
|
147
|
+
lastHeartbeatAt: record.lastHeartbeatAt,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
50
150
|
|
|
51
151
|
persistLogger.info("registry process registered", {
|
|
52
152
|
registryFilePath: input.registryFilePath,
|
|
@@ -57,9 +157,31 @@ export async function registerLogPersistProcess(input: {
|
|
|
57
157
|
}
|
|
58
158
|
|
|
59
159
|
export async function heartbeatLogPersistProcess(input: { registryFilePath: string; process: string }): Promise<void> {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
160
|
+
if (isLegacyRegistryFile(input.registryFilePath)) {
|
|
161
|
+
const current = await legacyStoreFor(input.registryFilePath).read();
|
|
162
|
+
const existing = current.processes[input.process];
|
|
163
|
+
if (existing == null) {
|
|
164
|
+
persistLogger.warn("registry heartbeat skipped — process not registered", {
|
|
165
|
+
registryFilePath: input.registryFilePath,
|
|
166
|
+
process: input.process,
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
await legacyStoreFor(input.registryFilePath).write({
|
|
172
|
+
processes: {
|
|
173
|
+
[input.process]: {
|
|
174
|
+
...existing,
|
|
175
|
+
lastHeartbeatAt: new Date().toISOString(),
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const store = shardStoreFor(shardFilePath(input.registryFilePath, input.process));
|
|
183
|
+
const current = await store.read();
|
|
184
|
+
if (current.pid === 0) {
|
|
63
185
|
persistLogger.warn("registry heartbeat skipped — process not registered", {
|
|
64
186
|
registryFilePath: input.registryFilePath,
|
|
65
187
|
process: input.process,
|
|
@@ -67,20 +189,43 @@ export async function heartbeatLogPersistProcess(input: { registryFilePath: stri
|
|
|
67
189
|
return;
|
|
68
190
|
}
|
|
69
191
|
|
|
70
|
-
await
|
|
71
|
-
|
|
72
|
-
[input.process]: {
|
|
73
|
-
...existing,
|
|
74
|
-
lastHeartbeatAt: new Date().toISOString(),
|
|
75
|
-
},
|
|
76
|
-
},
|
|
192
|
+
await store.write({
|
|
193
|
+
lastHeartbeatAt: new Date().toISOString(),
|
|
77
194
|
});
|
|
78
195
|
}
|
|
79
196
|
|
|
80
197
|
export async function unregisterLogPersistProcess(input: { registryFilePath: string; process: string }): Promise<void> {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
198
|
+
if (isLegacyRegistryFile(input.registryFilePath)) {
|
|
199
|
+
const current = await legacyStoreFor(input.registryFilePath).read();
|
|
200
|
+
const existing = current.processes[input.process];
|
|
201
|
+
if (existing == null) {
|
|
202
|
+
persistLogger.warn("registry unregister skipped — process not found", {
|
|
203
|
+
registryFilePath: input.registryFilePath,
|
|
204
|
+
process: input.process,
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await legacyStoreFor(input.registryFilePath).write({
|
|
210
|
+
processes: {
|
|
211
|
+
[input.process]: {
|
|
212
|
+
...existing,
|
|
213
|
+
pid: 0,
|
|
214
|
+
lastHeartbeatAt: new Date(0).toISOString(),
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
persistLogger.info("registry process unregistered", {
|
|
220
|
+
registryFilePath: input.registryFilePath,
|
|
221
|
+
process: input.process,
|
|
222
|
+
});
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const store = shardStoreFor(shardFilePath(input.registryFilePath, input.process));
|
|
227
|
+
const current = await store.read();
|
|
228
|
+
if (current.pid === 0) {
|
|
84
229
|
persistLogger.warn("registry unregister skipped — process not found", {
|
|
85
230
|
registryFilePath: input.registryFilePath,
|
|
86
231
|
process: input.process,
|
|
@@ -88,14 +233,9 @@ export async function unregisterLogPersistProcess(input: { registryFilePath: str
|
|
|
88
233
|
return;
|
|
89
234
|
}
|
|
90
235
|
|
|
91
|
-
await
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
...existing,
|
|
95
|
-
pid: 0,
|
|
96
|
-
lastHeartbeatAt: new Date(0).toISOString(),
|
|
97
|
-
},
|
|
98
|
-
},
|
|
236
|
+
await store.write({
|
|
237
|
+
pid: 0,
|
|
238
|
+
lastHeartbeatAt: new Date(0).toISOString(),
|
|
99
239
|
});
|
|
100
240
|
|
|
101
241
|
persistLogger.info("registry process unregistered", {
|
|
@@ -105,5 +245,8 @@ export async function unregisterLogPersistProcess(input: { registryFilePath: str
|
|
|
105
245
|
}
|
|
106
246
|
|
|
107
247
|
export async function readLogPersistRegistry(registryFilePath: string): Promise<LogPersistRegistryState> {
|
|
108
|
-
|
|
248
|
+
if (isLegacyRegistryFile(registryFilePath)) {
|
|
249
|
+
return legacyStoreFor(registryFilePath).read();
|
|
250
|
+
}
|
|
251
|
+
return readShardedLogPersistRegistry(registryFilePath);
|
|
109
252
|
}
|
|
@@ -36,7 +36,7 @@ export interface LogPersistConfig {
|
|
|
36
36
|
export interface EnableLogPersistOptions {
|
|
37
37
|
service: string;
|
|
38
38
|
process: string;
|
|
39
|
-
/** Shared registry
|
|
39
|
+
/** Shared registry root directory — all processes use the same path; each writes its own shard file. */
|
|
40
40
|
registryFilePath?: string;
|
|
41
41
|
config?: Partial<LogPersistConfig>;
|
|
42
42
|
}
|