@expo/eas-json 0.36.0 → 0.38.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/build/build/resolver.d.ts +8 -0
- package/build/build/resolver.js +67 -0
- package/build/build/schema.d.ts +2 -0
- package/build/{EasJsonSchema.js → build/schema.js} +18 -55
- package/build/{EasBuild.types.d.ts → build/types.d.ts} +6 -1
- package/build/{EasJson.types.js → build/types.js} +0 -0
- package/build/errors.d.ts +6 -0
- package/build/errors.js +10 -1
- package/build/index.d.ts +5 -4
- package/build/index.js +10 -8
- package/build/reader.d.ts +15 -0
- package/build/reader.js +75 -0
- package/build/schema.d.ts +2 -0
- package/build/schema.js +15 -0
- package/build/submit/resolver.d.ts +9 -0
- package/build/submit/resolver.js +72 -0
- package/build/submit/schema.d.ts +4 -0
- package/build/submit/schema.js +35 -0
- package/build/{EasSubmit.types.d.ts → submit/types.d.ts} +8 -1
- package/build/{EasSubmit.types.js → submit/types.js} +1 -0
- package/build/types.d.ts +20 -0
- package/build/{EasBuild.types.js → types.js} +0 -0
- package/package.json +4 -3
- package/src/__tests__/{EasJsonReader-build-test.ts → reader-build-test.ts} +60 -48
- package/src/__tests__/{EasJsonReader-submit-test.ts → reader-submit-test.ts} +49 -7
- package/src/build/resolver.ts +97 -0
- package/src/{EasJsonSchema.ts → build/schema.ts} +16 -60
- package/src/{EasBuild.types.ts → build/types.ts} +7 -5
- package/src/errors.ts +6 -0
- package/src/index.ts +6 -13
- package/src/reader.ts +87 -0
- package/src/schema.ts +13 -0
- package/src/submit/resolver.ts +114 -0
- package/src/submit/schema.ts +35 -0
- package/src/{EasSubmit.types.ts → submit/types.ts} +9 -7
- package/src/types.ts +21 -0
- package/build/EasJson.types.d.ts +0 -29
- package/build/EasJsonReader.d.ts +0 -39
- package/build/EasJsonReader.js +0 -204
- package/build/EasJsonSchema.d.ts +0 -6
- package/src/EasJson.types.ts +0 -31
- package/src/EasJsonReader.ts +0 -259
|
@@ -2,7 +2,7 @@ import { Platform } from '@expo/eas-build-job';
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import { vol } from 'memfs';
|
|
4
4
|
|
|
5
|
-
import { EasJsonReader } from '../
|
|
5
|
+
import { EasJsonReader } from '../reader';
|
|
6
6
|
|
|
7
7
|
jest.mock('fs');
|
|
8
8
|
|
|
@@ -19,18 +19,18 @@ test('minimal valid eas.json for both platforms', async () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const reader = new EasJsonReader('/project');
|
|
22
|
-
const iosProfile = await reader.
|
|
23
|
-
const androidProfile = await reader.
|
|
22
|
+
const iosProfile = await reader.getBuildProfileAsync(Platform.IOS, 'production');
|
|
23
|
+
const androidProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'production');
|
|
24
24
|
|
|
25
|
-
expect({
|
|
25
|
+
expect(androidProfile).toEqual({
|
|
26
26
|
distribution: 'store',
|
|
27
27
|
credentialsSource: 'remote',
|
|
28
|
-
})
|
|
28
|
+
});
|
|
29
29
|
|
|
30
|
-
expect({
|
|
30
|
+
expect(iosProfile).toEqual({
|
|
31
31
|
distribution: 'store',
|
|
32
32
|
credentialsSource: 'remote',
|
|
33
|
-
})
|
|
33
|
+
});
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
test('valid eas.json for development client builds', async () => {
|
|
@@ -47,20 +47,20 @@ test('valid eas.json for development client builds', async () => {
|
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
const reader = new EasJsonReader('/project');
|
|
50
|
-
const iosProfile = await reader.
|
|
51
|
-
const androidProfile = await reader.
|
|
52
|
-
expect({
|
|
50
|
+
const iosProfile = await reader.getBuildProfileAsync(Platform.IOS, 'debug');
|
|
51
|
+
const androidProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'debug');
|
|
52
|
+
expect(androidProfile).toEqual({
|
|
53
53
|
credentialsSource: 'remote',
|
|
54
54
|
distribution: 'store',
|
|
55
55
|
developmentClient: true,
|
|
56
56
|
withoutCredentials: true,
|
|
57
|
-
})
|
|
57
|
+
});
|
|
58
58
|
|
|
59
|
-
expect({
|
|
59
|
+
expect(iosProfile).toEqual({
|
|
60
60
|
credentialsSource: 'remote',
|
|
61
61
|
distribution: 'store',
|
|
62
62
|
developmentClient: true,
|
|
63
|
-
})
|
|
63
|
+
});
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
test('valid profile for internal distribution on Android', async () => {
|
|
@@ -73,11 +73,11 @@ test('valid profile for internal distribution on Android', async () => {
|
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
const reader = new EasJsonReader('/project');
|
|
76
|
-
const profile = await reader.
|
|
77
|
-
expect({
|
|
76
|
+
const profile = await reader.getBuildProfileAsync(Platform.ANDROID, 'internal');
|
|
77
|
+
expect(profile).toEqual({
|
|
78
78
|
distribution: 'internal',
|
|
79
79
|
credentialsSource: 'remote',
|
|
80
|
-
})
|
|
80
|
+
});
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
test('valid profile extending other profile', async () => {
|
|
@@ -95,18 +95,18 @@ test('valid profile extending other profile', async () => {
|
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
const reader = new EasJsonReader('/project');
|
|
98
|
-
const baseProfile = await reader.
|
|
99
|
-
const extendedProfile = await reader.
|
|
100
|
-
expect({
|
|
98
|
+
const baseProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'base');
|
|
99
|
+
const extendedProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'extension');
|
|
100
|
+
expect(baseProfile).toEqual({
|
|
101
101
|
distribution: 'store',
|
|
102
102
|
credentialsSource: 'remote',
|
|
103
103
|
node: '12.0.0',
|
|
104
|
-
})
|
|
105
|
-
expect({
|
|
104
|
+
});
|
|
105
|
+
expect(extendedProfile).toEqual({
|
|
106
106
|
distribution: 'internal',
|
|
107
107
|
credentialsSource: 'remote',
|
|
108
108
|
node: '13.0.0',
|
|
109
|
-
})
|
|
109
|
+
});
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
test('valid profile extending other profile with platform specific envs', async () => {
|
|
@@ -134,33 +134,33 @@ test('valid profile extending other profile with platform specific envs', async
|
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
const reader = new EasJsonReader('/project');
|
|
137
|
-
const baseProfile = await reader.
|
|
138
|
-
const extendedAndroidProfile = await reader.
|
|
139
|
-
const extendedIosProfile = await reader.
|
|
140
|
-
expect({
|
|
137
|
+
const baseProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'base');
|
|
138
|
+
const extendedAndroidProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'extension');
|
|
139
|
+
const extendedIosProfile = await reader.getBuildProfileAsync(Platform.IOS, 'extension');
|
|
140
|
+
expect(baseProfile).toEqual({
|
|
141
141
|
distribution: 'store',
|
|
142
142
|
credentialsSource: 'remote',
|
|
143
143
|
env: {
|
|
144
144
|
BASE_ENV: '1',
|
|
145
145
|
PROFILE: 'base',
|
|
146
146
|
},
|
|
147
|
-
})
|
|
148
|
-
expect({
|
|
147
|
+
});
|
|
148
|
+
expect(extendedAndroidProfile).toEqual({
|
|
149
149
|
distribution: 'internal',
|
|
150
150
|
credentialsSource: 'remote',
|
|
151
151
|
env: {
|
|
152
152
|
BASE_ENV: '1',
|
|
153
153
|
PROFILE: 'extension:android',
|
|
154
154
|
},
|
|
155
|
-
})
|
|
156
|
-
expect({
|
|
155
|
+
});
|
|
156
|
+
expect(extendedIosProfile).toEqual({
|
|
157
157
|
distribution: 'internal',
|
|
158
158
|
credentialsSource: 'remote',
|
|
159
159
|
env: {
|
|
160
160
|
BASE_ENV: '1',
|
|
161
161
|
PROFILE: 'extension',
|
|
162
162
|
},
|
|
163
|
-
})
|
|
163
|
+
});
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
test('valid profile extending other profile with platform specific caching', async () => {
|
|
@@ -188,32 +188,32 @@ test('valid profile extending other profile with platform specific caching', asy
|
|
|
188
188
|
});
|
|
189
189
|
|
|
190
190
|
const reader = new EasJsonReader('/project');
|
|
191
|
-
const baseProfile = await reader.
|
|
192
|
-
const extendedAndroidProfile = await reader.
|
|
193
|
-
const extendedIosProfile = await reader.
|
|
194
|
-
expect({
|
|
191
|
+
const baseProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'base');
|
|
192
|
+
const extendedAndroidProfile = await reader.getBuildProfileAsync(Platform.ANDROID, 'extension');
|
|
193
|
+
const extendedIosProfile = await reader.getBuildProfileAsync(Platform.IOS, 'extension');
|
|
194
|
+
expect(baseProfile).toEqual({
|
|
195
195
|
distribution: 'store',
|
|
196
196
|
credentialsSource: 'remote',
|
|
197
197
|
cache: {
|
|
198
198
|
disabled: true,
|
|
199
199
|
},
|
|
200
|
-
})
|
|
201
|
-
expect({
|
|
200
|
+
});
|
|
201
|
+
expect(extendedAndroidProfile).toEqual({
|
|
202
202
|
distribution: 'internal',
|
|
203
203
|
credentialsSource: 'remote',
|
|
204
204
|
cache: {
|
|
205
205
|
cacheDefaultPaths: false,
|
|
206
206
|
customPaths: ['somefakepath'],
|
|
207
207
|
},
|
|
208
|
-
})
|
|
209
|
-
expect({
|
|
208
|
+
});
|
|
209
|
+
expect(extendedIosProfile).toEqual({
|
|
210
210
|
distribution: 'internal',
|
|
211
211
|
credentialsSource: 'remote',
|
|
212
212
|
|
|
213
213
|
cache: {
|
|
214
214
|
key: 'extend-key',
|
|
215
215
|
},
|
|
216
|
-
})
|
|
216
|
+
});
|
|
217
217
|
});
|
|
218
218
|
|
|
219
219
|
test('valid eas.json with missing profile', async () => {
|
|
@@ -224,8 +224,8 @@ test('valid eas.json with missing profile', async () => {
|
|
|
224
224
|
});
|
|
225
225
|
|
|
226
226
|
const reader = new EasJsonReader('/project');
|
|
227
|
-
const promise = reader.
|
|
228
|
-
await expect(promise).rejects.toThrowError('
|
|
227
|
+
const promise = reader.getBuildProfileAsync(Platform.ANDROID, 'debug');
|
|
228
|
+
await expect(promise).rejects.toThrowError('Missing build profile in eas.json: debug');
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
test('invalid eas.json when using wrong buildType', async () => {
|
|
@@ -236,7 +236,7 @@ test('invalid eas.json when using wrong buildType', async () => {
|
|
|
236
236
|
});
|
|
237
237
|
|
|
238
238
|
const reader = new EasJsonReader('/project');
|
|
239
|
-
const promise = reader.
|
|
239
|
+
const promise = reader.getBuildProfileAsync(Platform.ANDROID, 'production');
|
|
240
240
|
await expect(promise).rejects.toThrowError(
|
|
241
241
|
'eas.json is not valid [ValidationError: "build.production.android.buildType" must be one of [apk, app-bundle]]'
|
|
242
242
|
);
|
|
@@ -246,8 +246,8 @@ test('empty json', async () => {
|
|
|
246
246
|
await fs.writeJson('/project/eas.json', {});
|
|
247
247
|
|
|
248
248
|
const reader = new EasJsonReader('/project');
|
|
249
|
-
const promise = reader.
|
|
250
|
-
await expect(promise).rejects.toThrowError('
|
|
249
|
+
const promise = reader.getBuildProfileAsync(Platform.ANDROID, 'production');
|
|
250
|
+
await expect(promise).rejects.toThrowError('Missing build profile in eas.json: production');
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
test('invalid semver value', async () => {
|
|
@@ -258,17 +258,29 @@ test('invalid semver value', async () => {
|
|
|
258
258
|
});
|
|
259
259
|
|
|
260
260
|
const reader = new EasJsonReader('/project');
|
|
261
|
-
const promise = reader.
|
|
261
|
+
const promise = reader.getBuildProfileAsync(Platform.ANDROID, 'production');
|
|
262
262
|
await expect(promise).rejects.toThrowError(
|
|
263
263
|
'eas.json is not valid [ValidationError: "build.production.node" failed custom validation because 12.0.0-alpha is not a valid version]'
|
|
264
264
|
);
|
|
265
265
|
});
|
|
266
266
|
|
|
267
|
+
test('invalid release channel', async () => {
|
|
268
|
+
await fs.writeJson('/project/eas.json', {
|
|
269
|
+
build: {
|
|
270
|
+
production: { releaseChannel: 'feature/myfeature' },
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const reader = new EasJsonReader('/project');
|
|
275
|
+
const promise = reader.getBuildProfileAsync(Platform.ANDROID, 'production');
|
|
276
|
+
await expect(promise).rejects.toThrowError(/fails to match the required pattern/);
|
|
277
|
+
});
|
|
278
|
+
|
|
267
279
|
test('get profile names', async () => {
|
|
268
280
|
await fs.writeJson('/project/eas.json', {
|
|
269
281
|
build: {
|
|
270
|
-
production: { node: '12.0.0
|
|
271
|
-
blah: { node: '12.0.0
|
|
282
|
+
production: { node: '12.0.0' },
|
|
283
|
+
blah: { node: '12.0.0' },
|
|
272
284
|
},
|
|
273
285
|
});
|
|
274
286
|
|
|
@@ -2,7 +2,7 @@ import { Platform } from '@expo/eas-build-job';
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import { vol } from 'memfs';
|
|
4
4
|
|
|
5
|
-
import { EasJsonReader } from '../
|
|
5
|
+
import { EasJsonReader } from '../reader';
|
|
6
6
|
|
|
7
7
|
jest.mock('fs');
|
|
8
8
|
|
|
@@ -19,8 +19,8 @@ test('minimal allowed eas.json for both platforms', async () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const reader = new EasJsonReader('/project');
|
|
22
|
-
const iosProfile = await reader.
|
|
23
|
-
const androidProfile = await reader.
|
|
22
|
+
const iosProfile = await reader.getSubmitProfileAsync(Platform.IOS, 'production');
|
|
23
|
+
const androidProfile = await reader.getSubmitProfileAsync(Platform.ANDROID, 'production');
|
|
24
24
|
|
|
25
25
|
expect(androidProfile).toEqual({
|
|
26
26
|
changesNotSentForReview: false,
|
|
@@ -46,7 +46,7 @@ test('android config with all required values', async () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
const reader = new EasJsonReader('/project');
|
|
49
|
-
const androidProfile = await reader.
|
|
49
|
+
const androidProfile = await reader.getSubmitProfileAsync(Platform.ANDROID, 'production');
|
|
50
50
|
|
|
51
51
|
expect(androidProfile).toEqual({
|
|
52
52
|
serviceAccountKeyPath: './path.json',
|
|
@@ -72,7 +72,7 @@ test('android config with serviceAccountKeyPath set to env var', async () => {
|
|
|
72
72
|
try {
|
|
73
73
|
process.env.GOOGLE_SERVICE_ACCOUNT = './path.json';
|
|
74
74
|
const reader = new EasJsonReader('/project');
|
|
75
|
-
const androidProfile = await reader.
|
|
75
|
+
const androidProfile = await reader.getSubmitProfileAsync(Platform.ANDROID, 'production');
|
|
76
76
|
|
|
77
77
|
expect(androidProfile).toEqual({
|
|
78
78
|
serviceAccountKeyPath: './path.json',
|
|
@@ -102,7 +102,7 @@ test('ios config with all required values', async () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
const reader = new EasJsonReader('/project');
|
|
105
|
-
const iosProfile = await reader.
|
|
105
|
+
const iosProfile = await reader.getSubmitProfileAsync(Platform.IOS, 'production');
|
|
106
106
|
|
|
107
107
|
expect(iosProfile).toEqual({
|
|
108
108
|
appleId: 'some@email.com',
|
|
@@ -136,7 +136,7 @@ test('ios config with ascApiKey fields set to env var', async () => {
|
|
|
136
136
|
process.env.ASC_API_KEY_ISSUER_ID = 'abc-123-def-456';
|
|
137
137
|
process.env.ASC_API_KEY_ID = 'ABCD';
|
|
138
138
|
const reader = new EasJsonReader('/project');
|
|
139
|
-
const iosProfile = await reader.
|
|
139
|
+
const iosProfile = await reader.getSubmitProfileAsync(Platform.IOS, 'release');
|
|
140
140
|
|
|
141
141
|
expect(iosProfile).toEqual({
|
|
142
142
|
appleId: 'some@email.com',
|
|
@@ -153,3 +153,45 @@ test('ios config with ascApiKey fields set to env var', async () => {
|
|
|
153
153
|
process.env.ASC_API_KEY_ID = undefined;
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
|
+
|
|
157
|
+
test('valid profile extending other profile', async () => {
|
|
158
|
+
await fs.writeJson('/project/eas.json', {
|
|
159
|
+
submit: {
|
|
160
|
+
base: {
|
|
161
|
+
ios: {
|
|
162
|
+
appleId: 'some@email.com',
|
|
163
|
+
ascAppId: '1223423523',
|
|
164
|
+
appleTeamId: 'QWERTY',
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
extension: {
|
|
168
|
+
extends: 'base',
|
|
169
|
+
ios: {
|
|
170
|
+
appleTeamId: 'ABCDEF',
|
|
171
|
+
ascApiKeyPath: './path-ABCD.p8',
|
|
172
|
+
ascApiKeyIssuerId: 'abc-123-def-456',
|
|
173
|
+
ascApiKeyId: 'ABCD',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const reader = new EasJsonReader('/project');
|
|
180
|
+
const baseProfile = await reader.getSubmitProfileAsync(Platform.IOS, 'base');
|
|
181
|
+
const extendedProfile = await reader.getSubmitProfileAsync(Platform.IOS, 'extension');
|
|
182
|
+
expect(baseProfile).toEqual({
|
|
183
|
+
language: 'en-US',
|
|
184
|
+
appleId: 'some@email.com',
|
|
185
|
+
ascAppId: '1223423523',
|
|
186
|
+
appleTeamId: 'QWERTY',
|
|
187
|
+
});
|
|
188
|
+
expect(extendedProfile).toEqual({
|
|
189
|
+
language: 'en-US',
|
|
190
|
+
appleId: 'some@email.com',
|
|
191
|
+
ascAppId: '1223423523',
|
|
192
|
+
appleTeamId: 'ABCDEF',
|
|
193
|
+
ascApiKeyPath: './path-ABCD.p8',
|
|
194
|
+
ascApiKeyIssuerId: 'abc-123-def-456',
|
|
195
|
+
ascApiKeyId: 'ABCD',
|
|
196
|
+
});
|
|
197
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
2
|
+
|
|
3
|
+
import { MissingParentProfileError, MissingProfileError } from '../errors';
|
|
4
|
+
import { EasJson } from '../types';
|
|
5
|
+
import { BuildProfileSchema } from './schema';
|
|
6
|
+
import { BuildProfile, EasJsonBuildProfile } from './types';
|
|
7
|
+
|
|
8
|
+
type EasJsonBuildProfileResolved = Omit<EasJsonBuildProfile, 'extends'>;
|
|
9
|
+
|
|
10
|
+
export function resolveBuildProfile<T extends Platform>({
|
|
11
|
+
easJson,
|
|
12
|
+
platform,
|
|
13
|
+
profileName,
|
|
14
|
+
}: {
|
|
15
|
+
easJson: EasJson;
|
|
16
|
+
platform: T;
|
|
17
|
+
profileName: string;
|
|
18
|
+
}): BuildProfile<T> {
|
|
19
|
+
const easJsonProfile = resolveProfile({
|
|
20
|
+
easJson,
|
|
21
|
+
profileName,
|
|
22
|
+
});
|
|
23
|
+
const { android, ios, ...base } = easJsonProfile;
|
|
24
|
+
const withoutDefaults = mergeProfiles(base, easJsonProfile[platform] ?? {});
|
|
25
|
+
return mergeProfiles(getDefaultProfile(platform), withoutDefaults) as BuildProfile<T>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resolveProfile({
|
|
29
|
+
easJson,
|
|
30
|
+
profileName,
|
|
31
|
+
depth = 0,
|
|
32
|
+
}: {
|
|
33
|
+
easJson: EasJson;
|
|
34
|
+
profileName: string;
|
|
35
|
+
depth?: number;
|
|
36
|
+
}): EasJsonBuildProfileResolved {
|
|
37
|
+
if (depth >= 2) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
'Too long chain of profile extensions, make sure "extends" keys do not make a cycle'
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const profile = easJson.build?.[profileName];
|
|
44
|
+
if (!profile) {
|
|
45
|
+
if (depth === 0) {
|
|
46
|
+
throw new MissingProfileError(`Missing build profile in eas.json: ${profileName}`);
|
|
47
|
+
} else {
|
|
48
|
+
throw new MissingParentProfileError(
|
|
49
|
+
`Extending non-existent build profile in eas.json: ${profileName}`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { extends: baseProfileName, ...rest } = profile;
|
|
55
|
+
if (baseProfileName) {
|
|
56
|
+
const baseProfile = resolveProfile({
|
|
57
|
+
easJson,
|
|
58
|
+
profileName: baseProfileName,
|
|
59
|
+
depth: depth + 1,
|
|
60
|
+
});
|
|
61
|
+
return mergeProfiles(baseProfile, rest);
|
|
62
|
+
} else {
|
|
63
|
+
return rest;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function mergeProfiles(
|
|
68
|
+
base: EasJsonBuildProfileResolved,
|
|
69
|
+
update: EasJsonBuildProfileResolved
|
|
70
|
+
): EasJsonBuildProfileResolved {
|
|
71
|
+
const result = {
|
|
72
|
+
...base,
|
|
73
|
+
...update,
|
|
74
|
+
};
|
|
75
|
+
if (base.env && update.env) {
|
|
76
|
+
result.env = {
|
|
77
|
+
...base.env,
|
|
78
|
+
...update.env,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (base.android && update.android) {
|
|
82
|
+
result.android = mergeProfiles(base.android, update.android);
|
|
83
|
+
}
|
|
84
|
+
if (base.ios && update.ios) {
|
|
85
|
+
result.ios = mergeProfiles(base.ios, update.ios);
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getDefaultProfile<T extends Platform>(platform: T): EasJsonBuildProfile {
|
|
91
|
+
const defaultProfile = BuildProfileSchema.validate(
|
|
92
|
+
{},
|
|
93
|
+
{ allowUnknown: false, abortEarly: false, convert: true }
|
|
94
|
+
).value;
|
|
95
|
+
const { android, ios, ...base } = defaultProfile;
|
|
96
|
+
return mergeProfiles(base, defaultProfile[platform]);
|
|
97
|
+
}
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { Android, Ios } from '@expo/eas-build-job';
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
|
|
4
|
-
import { AndroidReleaseStatus, AndroidReleaseTrack } from './EasSubmit.types';
|
|
5
|
-
|
|
6
|
-
const semverSchemaCheck = (value: any): any => {
|
|
7
|
-
if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(value)) {
|
|
8
|
-
return value;
|
|
9
|
-
} else {
|
|
10
|
-
throw new Error(`${value} is not a valid version`);
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
4
|
const CacheSchema = Joi.object({
|
|
15
5
|
disabled: Joi.boolean(),
|
|
16
6
|
key: Joi.string().max(128),
|
|
@@ -19,11 +9,11 @@ const CacheSchema = Joi.object({
|
|
|
19
9
|
});
|
|
20
10
|
|
|
21
11
|
const CommonBuildProfileSchema = Joi.object({
|
|
22
|
-
credentialsSource: Joi.string().valid('local', 'remote'),
|
|
23
|
-
distribution: Joi.string().valid('store', 'internal'),
|
|
12
|
+
credentialsSource: Joi.string().valid('local', 'remote').default('remote'),
|
|
13
|
+
distribution: Joi.string().valid('store', 'internal').default('store'),
|
|
24
14
|
cache: CacheSchema,
|
|
25
|
-
releaseChannel: Joi.string(),
|
|
26
|
-
channel: Joi.string(),
|
|
15
|
+
releaseChannel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
|
|
16
|
+
channel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
|
|
27
17
|
developmentClient: Joi.boolean(),
|
|
28
18
|
|
|
29
19
|
node: Joi.string().empty(null).custom(semverSchemaCheck),
|
|
@@ -34,6 +24,8 @@ const CommonBuildProfileSchema = Joi.object({
|
|
|
34
24
|
|
|
35
25
|
const AndroidBuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
36
26
|
Joi.object({
|
|
27
|
+
credentialsSource: Joi.string().valid('local', 'remote'),
|
|
28
|
+
distribution: Joi.string().valid('store', 'internal'),
|
|
37
29
|
withoutCredentials: Joi.boolean(),
|
|
38
30
|
|
|
39
31
|
image: Joi.string().valid(...Android.builderBaseImages),
|
|
@@ -52,6 +44,8 @@ const AndroidBuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
|
52
44
|
|
|
53
45
|
const IosBuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
54
46
|
Joi.object({
|
|
47
|
+
credentialsSource: Joi.string().valid('local', 'remote'),
|
|
48
|
+
distribution: Joi.string().valid('store', 'internal'),
|
|
55
49
|
enterpriseProvisioning: Joi.string().valid('adhoc', 'universal'),
|
|
56
50
|
autoIncrement: Joi.alternatives().try(
|
|
57
51
|
Joi.boolean(),
|
|
@@ -70,7 +64,7 @@ const IosBuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
|
70
64
|
})
|
|
71
65
|
);
|
|
72
66
|
|
|
73
|
-
const
|
|
67
|
+
export const BuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
74
68
|
Joi.object({
|
|
75
69
|
extends: Joi.string(),
|
|
76
70
|
android: AndroidBuildProfileSchema,
|
|
@@ -78,48 +72,10 @@ const EasJsonBuildProfileSchema = CommonBuildProfileSchema.concat(
|
|
|
78
72
|
})
|
|
79
73
|
);
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.default(AndroidReleaseStatus.completed),
|
|
89
|
-
changesNotSentForReview: Joi.boolean().default(false),
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
export const IosSubmitProfileSchema = Joi.object({
|
|
93
|
-
ascApiKeyPath: Joi.string(),
|
|
94
|
-
ascApiKeyId: Joi.string(),
|
|
95
|
-
ascApiKeyIssuerId: Joi.string(),
|
|
96
|
-
appleId: Joi.string(),
|
|
97
|
-
ascAppId: Joi.string(),
|
|
98
|
-
appleTeamId: Joi.string(),
|
|
99
|
-
sku: Joi.string(),
|
|
100
|
-
language: Joi.string().default('en-US'),
|
|
101
|
-
companyName: Joi.string(),
|
|
102
|
-
appName: Joi.string(),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const EasJsonSubmitConfigurationSchema = Joi.object({
|
|
106
|
-
android: AndroidSubmitProfileSchema,
|
|
107
|
-
ios: IosSubmitProfileSchema,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
export const CliConfigSchema = Joi.object({
|
|
111
|
-
version: Joi.string(),
|
|
112
|
-
requireCommit: Joi.boolean(),
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
export const MinimalEasJsonSchema = Joi.object({
|
|
116
|
-
cli: Joi.object(),
|
|
117
|
-
build: Joi.object().pattern(Joi.string(), Joi.object()),
|
|
118
|
-
submit: Joi.object().pattern(Joi.string(), Joi.object()),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
export const EasJsonSchema = Joi.object({
|
|
122
|
-
cli: CliConfigSchema,
|
|
123
|
-
build: Joi.object().pattern(Joi.string(), EasJsonBuildProfileSchema),
|
|
124
|
-
submit: Joi.object().pattern(Joi.string(), EasJsonSubmitConfigurationSchema),
|
|
125
|
-
});
|
|
75
|
+
function semverSchemaCheck(value: any): any {
|
|
76
|
+
if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(value)) {
|
|
77
|
+
return value;
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error(`${value} is not a valid version`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -55,8 +55,10 @@ export interface IosBuildProfile extends CommonBuildProfile {
|
|
|
55
55
|
|
|
56
56
|
export type BuildProfile<TPlatform extends Platform = Platform> = TPlatform extends Platform.ANDROID
|
|
57
57
|
? AndroidBuildProfile
|
|
58
|
-
:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
: IosBuildProfile;
|
|
59
|
+
|
|
60
|
+
export interface EasJsonBuildProfile extends Partial<CommonBuildProfile> {
|
|
61
|
+
extends?: string;
|
|
62
|
+
[Platform.ANDROID]?: Partial<AndroidBuildProfile>;
|
|
63
|
+
[Platform.IOS]?: Partial<IosBuildProfile>;
|
|
64
|
+
}
|
package/src/errors.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
|
+
export { AndroidReleaseStatus, AndroidReleaseTrack, SubmitProfile } from './submit/types';
|
|
2
|
+
export { getDefaultProfile as getDefaultSubmitProfile } from './submit/resolver';
|
|
3
|
+
export { EasJson, ProfileType } from './types';
|
|
1
4
|
export {
|
|
2
|
-
|
|
3
|
-
AndroidReleaseStatus,
|
|
4
|
-
AndroidReleaseTrack,
|
|
5
|
-
IosSubmitProfile,
|
|
6
|
-
SubmitProfile,
|
|
7
|
-
} from './EasSubmit.types';
|
|
8
|
-
export { EasJson } from './EasJson.types';
|
|
9
|
-
export {
|
|
10
|
-
AndroidBuildProfile,
|
|
5
|
+
AndroidVersionAutoIncrement,
|
|
11
6
|
BuildProfile,
|
|
12
7
|
CredentialsSource,
|
|
13
8
|
DistributionType,
|
|
14
|
-
IosBuildProfile,
|
|
15
9
|
IosEnterpriseProvisioning,
|
|
16
10
|
IosVersionAutoIncrement,
|
|
17
|
-
|
|
18
|
-
} from './
|
|
19
|
-
export { EasJsonReader } from './EasJsonReader';
|
|
11
|
+
} from './build/types';
|
|
12
|
+
export { EasJsonReader } from './reader';
|
|
20
13
|
export * as errors from './errors';
|