@amodalai/amodal 0.1.2 → 0.1.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/CHANGELOG.md +11 -0
- package/dist/src/main.js +3 -0
- package/dist/src/main.js.map +1 -1
- package/dist/src/shared/load-env.d.ts +12 -0
- package/dist/src/shared/load-env.d.ts.map +1 -0
- package/dist/src/shared/load-env.js +27 -0
- package/dist/src/shared/load-env.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/main.ts +4 -0
- package/src/shared/load-env.test.ts +89 -0
- package/src/shared/load-env.ts +27 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amodalai/amodal",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Amodal CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"semver": "^7.6.0",
|
|
31
31
|
"yargs": "^17.7.2",
|
|
32
32
|
"zod": "^4.3.6",
|
|
33
|
-
"@amodalai/core": "0.1.
|
|
34
|
-
"@amodalai/runtime": "0.1.
|
|
33
|
+
"@amodalai/core": "0.1.3",
|
|
34
|
+
"@amodalai/runtime": "0.1.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@amodalai/runtime-app": "0.1.
|
|
37
|
+
"@amodalai/runtime-app": "0.1.3"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@amodalai/runtime-app": {
|
package/src/main.ts
CHANGED
|
@@ -9,6 +9,10 @@ import {readFileSync} from 'node:fs';
|
|
|
9
9
|
import yargs from 'yargs';
|
|
10
10
|
import {hideBin} from 'yargs/helpers';
|
|
11
11
|
import {amodalCommands} from './commands/index.js';
|
|
12
|
+
import {loadEnvFile} from './shared/load-env.js';
|
|
13
|
+
|
|
14
|
+
// Load .env from current directory before anything else
|
|
15
|
+
loadEnvFile(process.cwd());
|
|
12
16
|
|
|
13
17
|
const raw: unknown = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf-8'));
|
|
14
18
|
if (typeof raw !== 'object' || raw === null || !('version' in raw) || typeof raw.version !== 'string') {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {mkdtempSync, writeFileSync, rmSync} from 'node:fs';
|
|
8
|
+
import {join} from 'node:path';
|
|
9
|
+
import {tmpdir} from 'node:os';
|
|
10
|
+
import {describe, it, expect, beforeEach, afterEach} from 'vitest';
|
|
11
|
+
import {loadEnvFile} from './load-env.js';
|
|
12
|
+
|
|
13
|
+
describe('loadEnvFile', () => {
|
|
14
|
+
let tempDir: string;
|
|
15
|
+
const savedEnv: Record<string, string | undefined> = {};
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
tempDir = mkdtempSync(join(tmpdir(), 'env-test-'));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
rmSync(tempDir, {recursive: true, force: true});
|
|
23
|
+
for (const key of Object.keys(savedEnv)) {
|
|
24
|
+
if (savedEnv[key] === undefined) {
|
|
25
|
+
delete process.env[key];
|
|
26
|
+
} else {
|
|
27
|
+
process.env[key] = savedEnv[key];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function trackEnv(key: string) {
|
|
33
|
+
savedEnv[key] = process.env[key];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
it('should load simple KEY=value pairs', () => {
|
|
37
|
+
writeFileSync(join(tempDir, '.env'), 'TEST_LOAD_A=hello\nTEST_LOAD_B=world\n');
|
|
38
|
+
trackEnv('TEST_LOAD_A');
|
|
39
|
+
trackEnv('TEST_LOAD_B');
|
|
40
|
+
|
|
41
|
+
loadEnvFile(tempDir);
|
|
42
|
+
|
|
43
|
+
expect(process.env['TEST_LOAD_A']).toBe('hello');
|
|
44
|
+
expect(process.env['TEST_LOAD_B']).toBe('world');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should handle export prefix', () => {
|
|
48
|
+
writeFileSync(join(tempDir, '.env'), 'export TEST_LOAD_C=exported\n');
|
|
49
|
+
trackEnv('TEST_LOAD_C');
|
|
50
|
+
|
|
51
|
+
loadEnvFile(tempDir);
|
|
52
|
+
|
|
53
|
+
expect(process.env['TEST_LOAD_C']).toBe('exported');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should strip quotes', () => {
|
|
57
|
+
writeFileSync(join(tempDir, '.env'), 'TEST_LOAD_D="double"\nTEST_LOAD_E=\'single\'\n');
|
|
58
|
+
trackEnv('TEST_LOAD_D');
|
|
59
|
+
trackEnv('TEST_LOAD_E');
|
|
60
|
+
|
|
61
|
+
loadEnvFile(tempDir);
|
|
62
|
+
|
|
63
|
+
expect(process.env['TEST_LOAD_D']).toBe('double');
|
|
64
|
+
expect(process.env['TEST_LOAD_E']).toBe('single');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should skip comments and blank lines', () => {
|
|
68
|
+
writeFileSync(join(tempDir, '.env'), '# comment\n\nTEST_LOAD_F=value\n \n');
|
|
69
|
+
trackEnv('TEST_LOAD_F');
|
|
70
|
+
|
|
71
|
+
loadEnvFile(tempDir);
|
|
72
|
+
|
|
73
|
+
expect(process.env['TEST_LOAD_F']).toBe('value');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should not override existing env vars', () => {
|
|
77
|
+
writeFileSync(join(tempDir, '.env'), 'TEST_LOAD_G=from-file\n');
|
|
78
|
+
trackEnv('TEST_LOAD_G');
|
|
79
|
+
process.env['TEST_LOAD_G'] = 'already-set';
|
|
80
|
+
|
|
81
|
+
loadEnvFile(tempDir);
|
|
82
|
+
|
|
83
|
+
expect(process.env['TEST_LOAD_G']).toBe('already-set');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should do nothing if .env does not exist', () => {
|
|
87
|
+
expect(() => loadEnvFile(tempDir)).not.toThrow();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {existsSync, readFileSync} from 'node:fs';
|
|
8
|
+
import {resolve} from 'node:path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load a .env file into process.env.
|
|
12
|
+
* Supports comments (#), `export` prefix, and quoted values.
|
|
13
|
+
* Does not override existing env vars.
|
|
14
|
+
*/
|
|
15
|
+
export function loadEnvFile(dir: string): void {
|
|
16
|
+
const envPath = resolve(dir, '.env');
|
|
17
|
+
if (!existsSync(envPath)) return;
|
|
18
|
+
|
|
19
|
+
for (const line of readFileSync(envPath, 'utf-8').split('\n')) {
|
|
20
|
+
const trimmed = line.trim();
|
|
21
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
22
|
+
const match = trimmed.replace(/^export\s+/, '').match(/^([^=]+)=(.*)/);
|
|
23
|
+
if (match && !process.env[match[1]]) {
|
|
24
|
+
process.env[match[1]] = match[2].replace(/^["']|["']$/g, '');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|