@output.ai/core 0.0.11 → 0.0.12
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/package.json +1 -1
- package/src/configs.js +3 -45
- package/src/configs.spec.js +14 -115
package/package.json
CHANGED
package/src/configs.js
CHANGED
|
@@ -1,51 +1,9 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
|
|
3
|
-
class InvalidEnvVarsErrors extends Error {}
|
|
4
|
-
|
|
5
|
-
const ipv4Validator = z.ipv4();
|
|
6
|
-
const ipv6Validator = z.ipv6();
|
|
7
|
-
const portValidator = z.number().int().min( 10 ).max( 65535 ).optional();
|
|
8
|
-
|
|
9
|
-
const ipValidator = z.union( [ ipv4Validator, ipv6Validator ] );
|
|
10
|
-
|
|
11
|
-
const likelyIpv6 = val => val.startsWith( '[' );
|
|
12
|
-
|
|
13
|
-
const splitIpWithPort = val => {
|
|
14
|
-
// ipv6
|
|
15
|
-
if ( likelyIpv6( val ) ) {
|
|
16
|
-
const address = val.slice( 1, val.lastIndexOf( ']' ) );
|
|
17
|
-
const portString = val.split( ']' )[1].slice( 1 ); // remove the :
|
|
18
|
-
const port = portString ? parseInt( portString, 10 ) : undefined;
|
|
19
|
-
return { address, port };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ipv4
|
|
23
|
-
const parts = val.split( ':' );
|
|
24
|
-
if ( parts.length !== 2 ) {
|
|
25
|
-
return { address: val, port: undefined };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const [ address, portString ] = parts;
|
|
29
|
-
const port = portString ? parseInt( portString, 10 ) : undefined;
|
|
30
|
-
return { address, port };
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const ipWithOptionalPort = z.string().refine(
|
|
34
|
-
val => {
|
|
35
|
-
const { address, port } = splitIpWithPort( val );
|
|
36
|
-
return ipValidator.safeParse( address ).success && portValidator.safeParse( port ).success;
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
message: 'Must be a valid IP address'
|
|
40
|
-
}
|
|
41
|
-
);
|
|
3
|
+
class InvalidEnvVarsErrors extends Error { }
|
|
42
4
|
|
|
43
5
|
const envVarSchema = z.object( {
|
|
44
|
-
TEMPORAL_ADDRESS: z.
|
|
45
|
-
z.string().regex( /^https?:\/\/.+/ ), // HTTP or HTTPS URLs
|
|
46
|
-
z.string().regex( /^[a-z0-9_-]+:\d{2,5}$/i ), // local docker container name like worker:7233
|
|
47
|
-
ipWithOptionalPort // IP address (IPv4 or IPv6) with port
|
|
48
|
-
] ),
|
|
6
|
+
TEMPORAL_ADDRESS: z.string().optional().default( 'localhost:7233' ),
|
|
49
7
|
TEMPORAL_NAMESPACE: z.string().optional().default( 'default' ),
|
|
50
8
|
TEMPORAL_API_KEY: z.string().optional(),
|
|
51
9
|
CATALOG_ID: z.string().regex( /^[a-z0-9_.@-]+$/i ),
|
|
@@ -55,7 +13,7 @@ const envVarSchema = z.object( {
|
|
|
55
13
|
|
|
56
14
|
const { data: safeEnvVar, error } = envVarSchema.safeParse( process.env );
|
|
57
15
|
if ( error ) {
|
|
58
|
-
throw new InvalidEnvVarsErrors( JSON.stringify( error
|
|
16
|
+
throw new InvalidEnvVarsErrors( JSON.stringify( error, null, 2 ) );
|
|
59
17
|
}
|
|
60
18
|
|
|
61
19
|
export const worker = {
|
package/src/configs.spec.js
CHANGED
|
@@ -14,139 +14,38 @@ describe( 'configs', () => {
|
|
|
14
14
|
|
|
15
15
|
describe( 'Environment Variable Validation', () => {
|
|
16
16
|
describe( 'TEMPORAL_ADDRESS', () => {
|
|
17
|
-
it( 'should accept
|
|
17
|
+
it( 'should accept string addresses', async () => {
|
|
18
18
|
process.env = {
|
|
19
|
-
TEMPORAL_ADDRESS: '
|
|
20
|
-
CATALOG_ID: 'test-catalog'
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const { worker } = await import( './configs.js' );
|
|
24
|
-
expect( worker.address ).toBe( 'http://localhost:7233' );
|
|
25
|
-
} );
|
|
26
|
-
|
|
27
|
-
it( 'should accept valid https URLs', async () => {
|
|
28
|
-
process.env = {
|
|
29
|
-
TEMPORAL_ADDRESS: 'https://temporal.example.com',
|
|
30
|
-
CATALOG_ID: 'test-catalog'
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const { worker } = await import( './configs.js' );
|
|
34
|
-
expect( worker.address ).toBe( 'https://temporal.example.com' );
|
|
35
|
-
} );
|
|
36
|
-
|
|
37
|
-
it( 'should accept docker container names with ports', async () => {
|
|
38
|
-
process.env = {
|
|
39
|
-
TEMPORAL_ADDRESS: 'temporal-server:7233',
|
|
40
|
-
CATALOG_ID: 'test-catalog'
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const { worker } = await import( './configs.js' );
|
|
44
|
-
expect( worker.address ).toBe( 'temporal-server:7233' );
|
|
45
|
-
} );
|
|
46
|
-
|
|
47
|
-
it( 'should accept container names with underscores and hyphens', async () => {
|
|
48
|
-
process.env = {
|
|
49
|
-
TEMPORAL_ADDRESS: 'my_temporal-server:7233',
|
|
50
|
-
CATALOG_ID: 'test-catalog'
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const { worker } = await import( './configs.js' );
|
|
54
|
-
expect( worker.address ).toBe( 'my_temporal-server:7233' );
|
|
55
|
-
} );
|
|
56
|
-
|
|
57
|
-
it( 'should accept IP addresses with HTTP', async () => {
|
|
58
|
-
process.env = {
|
|
59
|
-
TEMPORAL_ADDRESS: 'http://192.168.1.100:7233',
|
|
60
|
-
CATALOG_ID: 'test-catalog'
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const { worker } = await import( './configs.js' );
|
|
64
|
-
expect( worker.address ).toBe( 'http://192.168.1.100:7233' );
|
|
65
|
-
} );
|
|
66
|
-
|
|
67
|
-
it( 'should accept IP addresses with HTTPS', async () => {
|
|
68
|
-
process.env = {
|
|
69
|
-
TEMPORAL_ADDRESS: 'https://10.0.0.1:7233',
|
|
70
|
-
CATALOG_ID: 'test-catalog'
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const { worker } = await import( './configs.js' );
|
|
74
|
-
expect( worker.address ).toBe( 'https://10.0.0.1:7233' );
|
|
75
|
-
} );
|
|
76
|
-
|
|
77
|
-
it( 'should accept IP addresses without protocol for docker format', async () => {
|
|
78
|
-
process.env = {
|
|
79
|
-
TEMPORAL_ADDRESS: '172.17.0.2:7233',
|
|
80
|
-
CATALOG_ID: 'test-catalog'
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const { worker } = await import( './configs.js' );
|
|
84
|
-
expect( worker.address ).toBe( '172.17.0.2:7233' );
|
|
85
|
-
} );
|
|
86
|
-
|
|
87
|
-
it( 'should accept IPv6 addresses with brackets and port', async () => {
|
|
88
|
-
process.env = {
|
|
89
|
-
TEMPORAL_ADDRESS: '[2001:db8::1]:7233',
|
|
19
|
+
TEMPORAL_ADDRESS: 'localhost:7233',
|
|
90
20
|
CATALOG_ID: 'test-catalog'
|
|
91
21
|
};
|
|
92
22
|
|
|
93
23
|
const { worker } = await import( './configs.js' );
|
|
94
|
-
expect( worker.address ).toBe( '
|
|
24
|
+
expect( worker.address ).toBe( 'localhost:7233' );
|
|
95
25
|
} );
|
|
96
26
|
|
|
97
|
-
it( 'should
|
|
27
|
+
it( 'should use default when omitted', async () => {
|
|
98
28
|
process.env = {
|
|
99
|
-
TEMPORAL_ADDRESS: 'http://[2001:db8::1]:7233',
|
|
100
29
|
CATALOG_ID: 'test-catalog'
|
|
101
30
|
};
|
|
102
31
|
|
|
103
32
|
const { worker } = await import( './configs.js' );
|
|
104
|
-
expect( worker.address ).toBe( '
|
|
33
|
+
expect( worker.address ).toBe( 'localhost:7233' );
|
|
105
34
|
} );
|
|
106
35
|
|
|
107
|
-
it( 'should
|
|
36
|
+
it( 'should reject non-string values', async () => {
|
|
108
37
|
process.env = {
|
|
109
|
-
TEMPORAL_ADDRESS: '
|
|
38
|
+
TEMPORAL_ADDRESS: '123',
|
|
110
39
|
CATALOG_ID: 'test-catalog'
|
|
111
40
|
};
|
|
112
41
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
it( 'should reject invalid addresses', async () => {
|
|
118
|
-
process.env = {
|
|
119
|
-
TEMPORAL_ADDRESS: 'not-a-valid-address',
|
|
120
|
-
CATALOG_ID: 'test-catalog'
|
|
121
|
-
};
|
|
42
|
+
// Convert to number to test non-string
|
|
43
|
+
const originalEnv = process.env.TEMPORAL_ADDRESS;
|
|
44
|
+
process.env.TEMPORAL_ADDRESS = 123;
|
|
122
45
|
|
|
123
46
|
await expect( import( './configs.js' ) ).rejects.toThrow();
|
|
124
|
-
} );
|
|
125
47
|
|
|
126
|
-
|
|
127
|
-
process.env = {
|
|
128
|
-
TEMPORAL_ADDRESS: 'temporal-server',
|
|
129
|
-
CATALOG_ID: 'test-catalog'
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
await expect( import( './configs.js' ) ).rejects.toThrow();
|
|
133
|
-
} );
|
|
134
|
-
|
|
135
|
-
it( 'should reject addresses with single digit port numbers', async () => {
|
|
136
|
-
process.env = {
|
|
137
|
-
TEMPORAL_ADDRESS: 'temporal-server:1',
|
|
138
|
-
CATALOG_ID: 'test-catalog'
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
await expect( import( './configs.js' ) ).rejects.toThrow();
|
|
142
|
-
} );
|
|
143
|
-
|
|
144
|
-
it( 'should reject when TEMPORAL_ADDRESS is missing', async () => {
|
|
145
|
-
process.env = {
|
|
146
|
-
CATALOG_ID: 'test-catalog'
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
await expect( import( './configs.js' ) ).rejects.toThrow();
|
|
48
|
+
process.env.TEMPORAL_ADDRESS = originalEnv;
|
|
150
49
|
} );
|
|
151
50
|
} );
|
|
152
51
|
|
|
@@ -385,8 +284,8 @@ describe( 'configs', () => {
|
|
|
385
284
|
describe( 'Error Handling', () => {
|
|
386
285
|
it( 'should throw InvalidEnvVarsErrors for invalid configuration', async () => {
|
|
387
286
|
process.env = {
|
|
388
|
-
TEMPORAL_ADDRESS: '
|
|
389
|
-
CATALOG_ID: '
|
|
287
|
+
TEMPORAL_ADDRESS: 'localhost:7233',
|
|
288
|
+
CATALOG_ID: 'invalid!@#'
|
|
390
289
|
};
|
|
391
290
|
|
|
392
291
|
await expect( import( './configs.js' ) ).rejects.toThrow();
|
|
@@ -394,7 +293,7 @@ describe( 'configs', () => {
|
|
|
394
293
|
|
|
395
294
|
it( 'should handle multiple validation errors', async () => {
|
|
396
295
|
process.env = {
|
|
397
|
-
TEMPORAL_ADDRESS: '
|
|
296
|
+
TEMPORAL_ADDRESS: 'localhost:7233',
|
|
398
297
|
CATALOG_ID: 'invalid!@#'
|
|
399
298
|
};
|
|
400
299
|
|