@adddog/env 0.0.1
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 +11 -0
- package/dist/main.cjs +128 -0
- package/dist/main.cjs.map +1 -0
- package/dist/main.d.cts +6 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.js +90 -0
- package/dist/main.js.map +1 -0
- package/dist/types.d.cjs +2 -0
- package/dist/types.d.cjs.map +1 -0
- package/dist/types.d.d.cts +2 -0
- package/dist/types.d.d.ts +2 -0
- package/dist/types.d.js +1 -0
- package/dist/types.d.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @adddog/env
|
|
2
|
+
|
|
3
|
+
## Scripts
|
|
4
|
+
|
|
5
|
+
| Script | Description |
|
|
6
|
+
|--------|-------------|
|
|
7
|
+
| `build` | `tsup ./src --outDir dist --clean --format esm,cjs --shims --dts --platform node` |
|
|
8
|
+
| `lint` | `eslint .` |
|
|
9
|
+
| `lint:fix` | `eslint --fix .` |
|
|
10
|
+
| `types` | `tsc -p tsconfig.typecheck.json` |
|
|
11
|
+
|
package/dist/main.cjs
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/main.ts
|
|
31
|
+
var main_exports = {};
|
|
32
|
+
__export(main_exports, {
|
|
33
|
+
encodeEnvFile: () => encodeEnvFile,
|
|
34
|
+
getEnv: () => getEnv,
|
|
35
|
+
isProd: () => isProd,
|
|
36
|
+
load: () => load
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(main_exports);
|
|
39
|
+
var import_node_buffer = require("buffer");
|
|
40
|
+
var import_node_fs = require("fs");
|
|
41
|
+
var import_node_process = __toESM(require("process"), 1);
|
|
42
|
+
var import_dotenv_flow = __toESM(require("dotenv-flow"), 1);
|
|
43
|
+
function getEncodedEnvKeys() {
|
|
44
|
+
return Object.keys(import_node_process.default.env).filter((key) => key.includes("X_ENV")).sort((a, b) => {
|
|
45
|
+
if (a.length !== b.length) {
|
|
46
|
+
return a.length - b.length;
|
|
47
|
+
}
|
|
48
|
+
return a.localeCompare(b);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function decodeAndPopulateEnv(encodedVarName) {
|
|
52
|
+
const keysToProcess = encodedVarName ? [encodedVarName] : getEncodedEnvKeys();
|
|
53
|
+
for (const key of keysToProcess) {
|
|
54
|
+
const encodedEnv = import_node_process.default.env[key];
|
|
55
|
+
if (!encodedEnv) {
|
|
56
|
+
console.error(`${key} not in process.env ... skipping ...`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const decodedEnv = import_node_buffer.Buffer.from(encodedEnv, "base64").toString("utf-8");
|
|
61
|
+
const envLines = decodedEnv.split("\n").filter((line) => line.trim());
|
|
62
|
+
for (const line of envLines) {
|
|
63
|
+
if (line.startsWith("#")) continue;
|
|
64
|
+
const firstEquals = line.indexOf("=");
|
|
65
|
+
if (firstEquals === -1) continue;
|
|
66
|
+
const key2 = line.slice(0, firstEquals).trim();
|
|
67
|
+
const value = line.slice(firstEquals + 1).trim();
|
|
68
|
+
const cleanValue = value.replace(/^["']|["']$/g, "");
|
|
69
|
+
if (key2) {
|
|
70
|
+
import_node_process.default.env[key2] = cleanValue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof Error) {
|
|
75
|
+
console.error(`Error setting up environment for ${key}:`, error.message);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
decodeAndPopulateEnv();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error instanceof Error) {
|
|
84
|
+
console.error("Error setting up environment:", error.message);
|
|
85
|
+
} else {
|
|
86
|
+
console.error("Error setting up environment:", String(error));
|
|
87
|
+
}
|
|
88
|
+
import_node_process.default.exit(1);
|
|
89
|
+
}
|
|
90
|
+
function encodeEnvFile(envContent) {
|
|
91
|
+
return import_node_buffer.Buffer.from(envContent).toString("base64");
|
|
92
|
+
}
|
|
93
|
+
function load(absPath) {
|
|
94
|
+
try {
|
|
95
|
+
const stat = (0, import_node_fs.statSync)(absPath);
|
|
96
|
+
if (stat.isFile()) {
|
|
97
|
+
const content = (0, import_node_fs.readFileSync)(absPath, "utf-8");
|
|
98
|
+
const lines = content.split("\n");
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
const trimmed = line.trim();
|
|
101
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
102
|
+
const eq = trimmed.indexOf("=");
|
|
103
|
+
if (eq === -1) continue;
|
|
104
|
+
const key = trimmed.slice(0, eq).trim();
|
|
105
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
106
|
+
value = value.replace(/^["']|["']$/g, "");
|
|
107
|
+
if (key) import_node_process.default.env[key] = value;
|
|
108
|
+
}
|
|
109
|
+
console.log(`[env] loaded=${absPath} NODE_ENV=${import_node_process.default.env.NODE_ENV}`);
|
|
110
|
+
} else {
|
|
111
|
+
import_dotenv_flow.default.config({ path: absPath });
|
|
112
|
+
console.log(`[env] loaded=${absPath} NODE_ENV=${import_node_process.default.env.NODE_ENV}`);
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function getEnv(k, defaultValue) {
|
|
118
|
+
return import_node_process.default.env[k] ?? defaultValue;
|
|
119
|
+
}
|
|
120
|
+
var isProd = getEnv("NODE_ENV") === "production";
|
|
121
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
122
|
+
0 && (module.exports = {
|
|
123
|
+
encodeEnvFile,
|
|
124
|
+
getEnv,
|
|
125
|
+
isProd,
|
|
126
|
+
load
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=main.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport process from \"node:process\";\nimport dotenv from \"dotenv-flow\";\n\n/**\n * Gets all environment variable keys containing X_ENV\n * Returns keys sorted by length and then alphabetically\n */\nfunction getEncodedEnvKeys(): string[] {\n return Object.keys(process.env)\n .filter(key => key.includes(\"X_ENV\"))\n .sort((a, b) => {\n // First sort by length\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n // If lengths are equal, sort alphabetically\n return a.localeCompare(b);\n });\n}\n\n/**\n * Decodes a base64 encoded environment string and populates process.env\n * Format should be standard .env format after decoding (KEY=value)\n * @param encodedVarName - Optional specific environment variable to decode\n */\nfunction decodeAndPopulateEnv(encodedVarName?: string): void {\n // Get the keys to process\n const keysToProcess = encodedVarName ? [encodedVarName] : getEncodedEnvKeys();\n\n for (const key of keysToProcess) {\n const encodedEnv = process.env[key];\n\n if (!encodedEnv) {\n console.error(`${key} not in process.env ... skipping ...`);\n continue;\n }\n\n try {\n // Decode base64 to string\n const decodedEnv = Buffer.from(encodedEnv, \"base64\").toString(\"utf-8\");\n\n // Split into lines and filter out empty lines\n const envLines = decodedEnv.split(\"\\n\").filter(line => line.trim());\n\n // Process each line\n for (const line of envLines) {\n // Skip comments\n if (line.startsWith(\"#\")) continue;\n\n // Find the first = symbol (supporting values that contain =)\n const firstEquals = line.indexOf(\"=\");\n if (firstEquals === -1) continue;\n\n // Split into key and value\n const key = line.slice(0, firstEquals).trim();\n const value = line.slice(firstEquals + 1).trim();\n\n // Remove surrounding quotes if they exist\n const cleanValue = value.replace(/^[\"']|[\"']$/g, \"\");\n\n // Set in process.env if key is valid\n if (key) {\n process.env[key] = cleanValue;\n }\n }\n } catch (error) {\n // Type guard to check if error is an Error object\n if (error instanceof Error) {\n console.error(`Error setting up environment for ${key}:`, error.message);\n }\n }\n }\n}\n\n// Example usage:\ntry {\n decodeAndPopulateEnv();\n // Note: import.meta.env is read-only and cannot be assigned to\n // Applications should access process.env directly after this setup\n} catch (error) {\n // Type guard to check if error is an Error object\n if (error instanceof Error) {\n console.error(\"Error setting up environment:\", error.message);\n } else {\n console.error(\"Error setting up environment:\", String(error));\n }\n process.exit(1);\n}\n\n// Helper function to encode a .env file for testing\nexport function encodeEnvFile(envContent: string): string {\n return Buffer.from(envContent).toString(\"base64\");\n}\n\n// Example of how to create multiple encoded env strings for testing:\n/*\n const testEnv1 = `\n DATABASE_URL=postgresql://user:pass@localhost:5432/db\n API_KEY=12345\n `;\n\n const testEnv2 = `\n FEATURE_FLAGS={\"flag1\":true,\"flag2\":false}\n QUOTED_VALUE=\"hello world\"\n `;\n\n process.env.FIRST_X_ENV = encodeEnvFile(testEnv1);\n process.env.SECOND_X_ENV = encodeEnvFile(testEnv2);\n decodeAndPopulateEnv(); // This will process both X_ENV variables\n*/\n\nexport function load(absPath: string) {\n try {\n const stat = statSync(absPath);\n if (stat.isFile()) {\n // Load single file directly\n const content = readFileSync(absPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) continue;\n const key = trimmed.slice(0, eq).trim();\n let value = trimmed.slice(eq + 1).trim();\n // Remove surrounding quotes\n value = value.replace(/^[\"']|[\"']$/g, \"\");\n if (key) process.env[key] = value;\n }\n console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);\n } else {\n // Directory - use dotenv-flow\n dotenv.config({ path: absPath });\n console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);\n }\n } catch {\n // Silently handle error loading environment variables\n }\n}\n\nexport function getEnv(k: string, defaultValue?: string): string | undefined {\n return process.env[k] ?? defaultValue;\n}\n\nexport const isProd = getEnv(\"NODE_ENV\") === \"production\";\n"],"mappings":"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","names":["process","key","dotenv"]}
|
package/dist/main.d.cts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare function encodeEnvFile(envContent: string): string;
|
|
2
|
+
declare function load(absPath: string): void;
|
|
3
|
+
declare function getEnv(k: string, defaultValue?: string): string | undefined;
|
|
4
|
+
declare const isProd: boolean;
|
|
5
|
+
|
|
6
|
+
export { encodeEnvFile, getEnv, isProd, load };
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare function encodeEnvFile(envContent: string): string;
|
|
2
|
+
declare function load(absPath: string): void;
|
|
3
|
+
declare function getEnv(k: string, defaultValue?: string): string | undefined;
|
|
4
|
+
declare const isProd: boolean;
|
|
5
|
+
|
|
6
|
+
export { encodeEnvFile, getEnv, isProd, load };
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/main.ts
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { readFileSync, statSync } from "fs";
|
|
4
|
+
import process from "process";
|
|
5
|
+
import dotenv from "dotenv-flow";
|
|
6
|
+
function getEncodedEnvKeys() {
|
|
7
|
+
return Object.keys(process.env).filter((key) => key.includes("X_ENV")).sort((a, b) => {
|
|
8
|
+
if (a.length !== b.length) {
|
|
9
|
+
return a.length - b.length;
|
|
10
|
+
}
|
|
11
|
+
return a.localeCompare(b);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function decodeAndPopulateEnv(encodedVarName) {
|
|
15
|
+
const keysToProcess = encodedVarName ? [encodedVarName] : getEncodedEnvKeys();
|
|
16
|
+
for (const key of keysToProcess) {
|
|
17
|
+
const encodedEnv = process.env[key];
|
|
18
|
+
if (!encodedEnv) {
|
|
19
|
+
console.error(`${key} not in process.env ... skipping ...`);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const decodedEnv = Buffer.from(encodedEnv, "base64").toString("utf-8");
|
|
24
|
+
const envLines = decodedEnv.split("\n").filter((line) => line.trim());
|
|
25
|
+
for (const line of envLines) {
|
|
26
|
+
if (line.startsWith("#")) continue;
|
|
27
|
+
const firstEquals = line.indexOf("=");
|
|
28
|
+
if (firstEquals === -1) continue;
|
|
29
|
+
const key2 = line.slice(0, firstEquals).trim();
|
|
30
|
+
const value = line.slice(firstEquals + 1).trim();
|
|
31
|
+
const cleanValue = value.replace(/^["']|["']$/g, "");
|
|
32
|
+
if (key2) {
|
|
33
|
+
process.env[key2] = cleanValue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error instanceof Error) {
|
|
38
|
+
console.error(`Error setting up environment for ${key}:`, error.message);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
decodeAndPopulateEnv();
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error instanceof Error) {
|
|
47
|
+
console.error("Error setting up environment:", error.message);
|
|
48
|
+
} else {
|
|
49
|
+
console.error("Error setting up environment:", String(error));
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
function encodeEnvFile(envContent) {
|
|
54
|
+
return Buffer.from(envContent).toString("base64");
|
|
55
|
+
}
|
|
56
|
+
function load(absPath) {
|
|
57
|
+
try {
|
|
58
|
+
const stat = statSync(absPath);
|
|
59
|
+
if (stat.isFile()) {
|
|
60
|
+
const content = readFileSync(absPath, "utf-8");
|
|
61
|
+
const lines = content.split("\n");
|
|
62
|
+
for (const line of lines) {
|
|
63
|
+
const trimmed = line.trim();
|
|
64
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
65
|
+
const eq = trimmed.indexOf("=");
|
|
66
|
+
if (eq === -1) continue;
|
|
67
|
+
const key = trimmed.slice(0, eq).trim();
|
|
68
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
69
|
+
value = value.replace(/^["']|["']$/g, "");
|
|
70
|
+
if (key) process.env[key] = value;
|
|
71
|
+
}
|
|
72
|
+
console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);
|
|
73
|
+
} else {
|
|
74
|
+
dotenv.config({ path: absPath });
|
|
75
|
+
console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getEnv(k, defaultValue) {
|
|
81
|
+
return process.env[k] ?? defaultValue;
|
|
82
|
+
}
|
|
83
|
+
var isProd = getEnv("NODE_ENV") === "production";
|
|
84
|
+
export {
|
|
85
|
+
encodeEnvFile,
|
|
86
|
+
getEnv,
|
|
87
|
+
isProd,
|
|
88
|
+
load
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport process from \"node:process\";\nimport dotenv from \"dotenv-flow\";\n\n/**\n * Gets all environment variable keys containing X_ENV\n * Returns keys sorted by length and then alphabetically\n */\nfunction getEncodedEnvKeys(): string[] {\n return Object.keys(process.env)\n .filter(key => key.includes(\"X_ENV\"))\n .sort((a, b) => {\n // First sort by length\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n // If lengths are equal, sort alphabetically\n return a.localeCompare(b);\n });\n}\n\n/**\n * Decodes a base64 encoded environment string and populates process.env\n * Format should be standard .env format after decoding (KEY=value)\n * @param encodedVarName - Optional specific environment variable to decode\n */\nfunction decodeAndPopulateEnv(encodedVarName?: string): void {\n // Get the keys to process\n const keysToProcess = encodedVarName ? [encodedVarName] : getEncodedEnvKeys();\n\n for (const key of keysToProcess) {\n const encodedEnv = process.env[key];\n\n if (!encodedEnv) {\n console.error(`${key} not in process.env ... skipping ...`);\n continue;\n }\n\n try {\n // Decode base64 to string\n const decodedEnv = Buffer.from(encodedEnv, \"base64\").toString(\"utf-8\");\n\n // Split into lines and filter out empty lines\n const envLines = decodedEnv.split(\"\\n\").filter(line => line.trim());\n\n // Process each line\n for (const line of envLines) {\n // Skip comments\n if (line.startsWith(\"#\")) continue;\n\n // Find the first = symbol (supporting values that contain =)\n const firstEquals = line.indexOf(\"=\");\n if (firstEquals === -1) continue;\n\n // Split into key and value\n const key = line.slice(0, firstEquals).trim();\n const value = line.slice(firstEquals + 1).trim();\n\n // Remove surrounding quotes if they exist\n const cleanValue = value.replace(/^[\"']|[\"']$/g, \"\");\n\n // Set in process.env if key is valid\n if (key) {\n process.env[key] = cleanValue;\n }\n }\n } catch (error) {\n // Type guard to check if error is an Error object\n if (error instanceof Error) {\n console.error(`Error setting up environment for ${key}:`, error.message);\n }\n }\n }\n}\n\n// Example usage:\ntry {\n decodeAndPopulateEnv();\n // Note: import.meta.env is read-only and cannot be assigned to\n // Applications should access process.env directly after this setup\n} catch (error) {\n // Type guard to check if error is an Error object\n if (error instanceof Error) {\n console.error(\"Error setting up environment:\", error.message);\n } else {\n console.error(\"Error setting up environment:\", String(error));\n }\n process.exit(1);\n}\n\n// Helper function to encode a .env file for testing\nexport function encodeEnvFile(envContent: string): string {\n return Buffer.from(envContent).toString(\"base64\");\n}\n\n// Example of how to create multiple encoded env strings for testing:\n/*\n const testEnv1 = `\n DATABASE_URL=postgresql://user:pass@localhost:5432/db\n API_KEY=12345\n `;\n\n const testEnv2 = `\n FEATURE_FLAGS={\"flag1\":true,\"flag2\":false}\n QUOTED_VALUE=\"hello world\"\n `;\n\n process.env.FIRST_X_ENV = encodeEnvFile(testEnv1);\n process.env.SECOND_X_ENV = encodeEnvFile(testEnv2);\n decodeAndPopulateEnv(); // This will process both X_ENV variables\n*/\n\nexport function load(absPath: string) {\n try {\n const stat = statSync(absPath);\n if (stat.isFile()) {\n // Load single file directly\n const content = readFileSync(absPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) continue;\n const key = trimmed.slice(0, eq).trim();\n let value = trimmed.slice(eq + 1).trim();\n // Remove surrounding quotes\n value = value.replace(/^[\"']|[\"']$/g, \"\");\n if (key) process.env[key] = value;\n }\n console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);\n } else {\n // Directory - use dotenv-flow\n dotenv.config({ path: absPath });\n console.log(`[env] loaded=${absPath} NODE_ENV=${process.env.NODE_ENV}`);\n }\n } catch {\n // Silently handle error loading environment variables\n }\n}\n\nexport function getEnv(k: string, defaultValue?: string): string | undefined {\n return process.env[k] ?? defaultValue;\n}\n\nexport const isProd = getEnv(\"NODE_ENV\") === \"production\";\n"],"mappings":"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","names":["key"]}
|
package/dist/types.d.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/types.d.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adddog/env",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"main": "./src/main.ts",
|
|
5
|
+
"types": "./src/main.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./package.json": "./package.json",
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./src/main.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": ["dist"],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"dotenv-flow": "^4.1.0"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup ./src --outDir dist --clean --format esm,cjs --shims --dts --platform node",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"lint:fix": "eslint --fix .",
|
|
20
|
+
"types": "tsc -p tsconfig.typecheck.json",
|
|
21
|
+
"test": "echo '⚠️⚠️⚠️no test vitest --watch=false'",
|
|
22
|
+
"dev": "tsx src/index.ts",
|
|
23
|
+
"knip": "knip",
|
|
24
|
+
"release": "bumpp --yes --no-push --no-tag --release patch",
|
|
25
|
+
"prepublishOnly": "pnpm run lint && pnpm run types && pnpm run build",
|
|
26
|
+
"prepack": "pnpm run prepublishOnly",
|
|
27
|
+
"version:patch": "npm version patch --no-git-tag-version"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@adddog/monorepo-consistency": "workspace:*",
|
|
31
|
+
"@types/dotenv-flow": "^3.3.3",
|
|
32
|
+
"bumpp": "^10.4.1",
|
|
33
|
+
"eslint": "^10.0.0",
|
|
34
|
+
"tsup": "^8.5.1",
|
|
35
|
+
"typescript": "^5.9.3"
|
|
36
|
+
},
|
|
37
|
+
"version": "0.0.1",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">= 22",
|
|
40
|
+
"pnpm": ">= 10",
|
|
41
|
+
"npm": ">= 11"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"registry": "https://registry.npmjs.org/",
|
|
46
|
+
"exports": {
|
|
47
|
+
"./package.json": "./package.json",
|
|
48
|
+
".": {
|
|
49
|
+
"types": "./dist/main.d.ts",
|
|
50
|
+
"import": "./dist/main.js",
|
|
51
|
+
"module": "./dist/main.js",
|
|
52
|
+
"require": "./dist/main.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"main": "./dist/main.js",
|
|
56
|
+
"types": "./dist/main.d.ts"
|
|
57
|
+
}
|
|
58
|
+
}
|