@cloudflare/sandbox 0.4.17 → 0.5.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.
@@ -0,0 +1,119 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { detectCredentials } from '../../src/storage-mount/credential-detection';
3
+
4
+ describe('Credential Detection', () => {
5
+ it('should use explicit credentials from options', () => {
6
+ const envVars = {};
7
+ const options = {
8
+ endpoint: 'https://test.r2.cloudflarestorage.com',
9
+ credentials: {
10
+ accessKeyId: 'explicit-key',
11
+ secretAccessKey: 'explicit-secret'
12
+ }
13
+ };
14
+
15
+ const credentials = detectCredentials(options, envVars);
16
+
17
+ expect(credentials.accessKeyId).toBe('explicit-key');
18
+ expect(credentials.secretAccessKey).toBe('explicit-secret');
19
+ });
20
+
21
+ it('should detect standard AWS env vars', () => {
22
+ const envVars = {
23
+ AWS_ACCESS_KEY_ID: 'aws-key',
24
+ AWS_SECRET_ACCESS_KEY: 'aws-secret'
25
+ };
26
+ const options = { endpoint: 'https://s3.us-west-2.amazonaws.com' };
27
+
28
+ const credentials = detectCredentials(options, envVars);
29
+
30
+ expect(credentials.accessKeyId).toBe('aws-key');
31
+ expect(credentials.secretAccessKey).toBe('aws-secret');
32
+ });
33
+
34
+ it('should ignore session token in environment', () => {
35
+ const envVars = {
36
+ AWS_ACCESS_KEY_ID: 'aws-key',
37
+ AWS_SECRET_ACCESS_KEY: 'aws-secret',
38
+ AWS_SESSION_TOKEN: 'session-token'
39
+ };
40
+ const options = { endpoint: 'https://s3.us-west-2.amazonaws.com' };
41
+
42
+ const credentials = detectCredentials(options, envVars);
43
+
44
+ expect(credentials.accessKeyId).toBe('aws-key');
45
+ expect(credentials.secretAccessKey).toBe('aws-secret');
46
+ });
47
+
48
+ it('should prioritize explicit credentials over env vars', () => {
49
+ const envVars = {
50
+ AWS_ACCESS_KEY_ID: 'env-key',
51
+ AWS_SECRET_ACCESS_KEY: 'env-secret'
52
+ };
53
+ const options = {
54
+ endpoint: 'https://test.r2.cloudflarestorage.com',
55
+ credentials: {
56
+ accessKeyId: 'explicit-key',
57
+ secretAccessKey: 'explicit-secret'
58
+ }
59
+ };
60
+
61
+ const credentials = detectCredentials(options, envVars);
62
+
63
+ expect(credentials.accessKeyId).toBe('explicit-key');
64
+ expect(credentials.secretAccessKey).toBe('explicit-secret');
65
+ });
66
+
67
+ it('should throw error when no credentials found', () => {
68
+ const envVars = {};
69
+ const options = { endpoint: 'https://test.r2.cloudflarestorage.com' };
70
+
71
+ expect(() => detectCredentials(options, envVars)).toThrow(
72
+ 'No credentials found'
73
+ );
74
+ });
75
+
76
+ it('should include helpful error message with env var hints', () => {
77
+ const envVars = {};
78
+ const options = { endpoint: 'https://test.r2.cloudflarestorage.com' };
79
+
80
+ let thrownError: Error | null = null;
81
+ try {
82
+ detectCredentials(options, envVars);
83
+ } catch (error) {
84
+ thrownError = error as Error;
85
+ }
86
+
87
+ expect(thrownError).toBeTruthy();
88
+ if (thrownError) {
89
+ const message = thrownError.message;
90
+ expect(message).toContain('AWS_ACCESS_KEY_ID');
91
+ expect(message).toContain('AWS_SECRET_ACCESS_KEY');
92
+ expect(message).toContain('explicit credentials');
93
+ }
94
+ });
95
+
96
+ it('should throw error when only access key is present', () => {
97
+ const envVars = {
98
+ AWS_ACCESS_KEY_ID: 'aws-key'
99
+ // Missing AWS_SECRET_ACCESS_KEY
100
+ };
101
+ const options = { endpoint: 'https://test.r2.cloudflarestorage.com' };
102
+
103
+ expect(() => detectCredentials(options, envVars)).toThrow(
104
+ 'No credentials found'
105
+ );
106
+ });
107
+
108
+ it('should throw error when only secret key is present', () => {
109
+ const envVars = {
110
+ AWS_SECRET_ACCESS_KEY: 'aws-secret'
111
+ // Missing AWS_ACCESS_KEY_ID
112
+ };
113
+ const options = { endpoint: 'https://test.r2.cloudflarestorage.com' };
114
+
115
+ expect(() => detectCredentials(options, envVars)).toThrow(
116
+ 'No credentials found'
117
+ );
118
+ });
119
+ });
@@ -0,0 +1,77 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ detectProviderFromUrl,
4
+ getProviderFlags,
5
+ resolveS3fsOptions
6
+ } from '../../src/storage-mount/provider-detection';
7
+
8
+ describe('Provider Detection', () => {
9
+ describe('detectProviderFromUrl', () => {
10
+ it.each([
11
+ ['https://abc123.r2.cloudflarestorage.com', 'r2'],
12
+ ['https://s3.us-west-2.amazonaws.com', 's3'],
13
+ ['https://storage.googleapis.com', 'gcs']
14
+ ])('should detect %s as %s', (url, expectedProvider) => {
15
+ expect(detectProviderFromUrl(url)).toBe(expectedProvider);
16
+ });
17
+
18
+ it.each([['https://custom.storage.example.com'], ['not-a-url'], ['']])(
19
+ 'should return null for unknown/invalid: %s',
20
+ (url) => {
21
+ expect(detectProviderFromUrl(url)).toBe(null);
22
+ }
23
+ );
24
+ });
25
+
26
+ describe('getProviderFlags', () => {
27
+ it.each([
28
+ ['r2', ['nomixupload']],
29
+ ['s3', []],
30
+ ['gcs', []]
31
+ ])('should return correct flags for %s', (provider, expected) => {
32
+ expect(getProviderFlags(provider as any)).toEqual(expected);
33
+ });
34
+
35
+ it('should return safe defaults for unknown providers', () => {
36
+ expect(getProviderFlags(null)).toEqual(['use_path_request_style']);
37
+ });
38
+ });
39
+
40
+ describe('resolveS3fsOptions', () => {
41
+ it('should use provider defaults when no user options', () => {
42
+ const options = resolveS3fsOptions('r2');
43
+ expect(options).toEqual(['nomixupload']);
44
+ });
45
+
46
+ it('should merge provider flags with user options', () => {
47
+ const options = resolveS3fsOptions('r2', ['custom_flag']);
48
+ expect(options).toContain('nomixupload');
49
+ expect(options).toContain('custom_flag');
50
+ });
51
+
52
+ it('should allow user options to override provider defaults', () => {
53
+ const options = resolveS3fsOptions('r2', ['endpoint=us-east']);
54
+ expect(options).toContain('nomixupload');
55
+ expect(options).toContain('endpoint=us-east');
56
+ expect(options).not.toContain('endpoint=auto');
57
+ });
58
+
59
+ it('should deduplicate flags keeping last occurrence', () => {
60
+ const options = resolveS3fsOptions(null, [
61
+ 'use_path_request_style',
62
+ 'custom_flag'
63
+ ]);
64
+ const count = options.filter(
65
+ (o) => o === 'use_path_request_style'
66
+ ).length;
67
+ expect(count).toBe(1);
68
+ expect(options).toContain('custom_flag');
69
+ });
70
+
71
+ it('should use safe defaults for unknown providers', () => {
72
+ const options = resolveS3fsOptions(null, ['nomixupload']);
73
+ expect(options).toContain('use_path_request_style');
74
+ expect(options).toContain('nomixupload');
75
+ });
76
+ });
77
+ });
package/tsdown.config.ts CHANGED
@@ -8,5 +8,6 @@ export default defineConfig({
8
8
  resolve: ['@repo/shared']
9
9
  },
10
10
  sourcemap: true,
11
- format: 'esm'
11
+ format: 'esm',
12
+ fixedExtension: false
12
13
  });