@expo/eas-json 0.34.0 → 0.37.0

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.
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const eas_build_job_1 = require("@expo/eas-build-job");
6
6
  const json_file_1 = (0, tslib_1.__importDefault)(require("@expo/json-file"));
7
7
  const env_string_1 = (0, tslib_1.__importDefault)(require("env-string"));
8
+ const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
8
9
  const path_1 = (0, tslib_1.__importDefault)(require("path"));
9
10
  const EasJson_types_1 = require("./EasJson.types");
10
11
  const EasJsonSchema_1 = require("./EasJsonSchema");
@@ -46,7 +47,7 @@ class EasJsonReader {
46
47
  return value;
47
48
  }
48
49
  catch (err) {
49
- if (err.code === 'ENOENT') {
50
+ if (err instanceof errors_1.MissingEasJsonError) {
50
51
  return null;
51
52
  }
52
53
  throw err;
@@ -103,7 +104,7 @@ class EasJsonReader {
103
104
  const easJson = await this.readAndValidateAsync();
104
105
  const profile = (_a = easJson === null || easJson === void 0 ? void 0 : easJson.submit) === null || _a === void 0 ? void 0 : _a[profileName];
105
106
  if (!profile) {
106
- throw new Error(`There is no profile named ${profileName} in eas.json`);
107
+ throw new Error(`There is no submit profile named ${profileName} in eas.json`);
107
108
  }
108
109
  const platformProfile = profile[platform];
109
110
  if (platformProfile) {
@@ -128,6 +129,9 @@ class EasJsonReader {
128
129
  async readRawAsync() {
129
130
  try {
130
131
  const easJsonPath = EasJsonReader.formatEasJsonPath(this.projectDir);
132
+ if (!(await fs_extra_1.default.pathExists(easJsonPath))) {
133
+ throw new errors_1.MissingEasJsonError(`An eas.json file could not be found at ${easJsonPath}. You must make one in order to proceed. Learn more at https://expo.fyi/eas-json`);
134
+ }
131
135
  const rawEasJson = json_file_1.default.read(easJsonPath);
132
136
  const { value, error } = EasJsonSchema_1.MinimalEasJsonSchema.validate(rawEasJson, { abortEarly: false });
133
137
  if (error) {
@@ -148,7 +152,7 @@ class EasJsonReader {
148
152
  }
149
153
  const buildProfile = easJson.build[profileName];
150
154
  if (!buildProfile) {
151
- throw new Error(`There is no profile named ${profileName} in eas.json`);
155
+ throw new Error(`There is no build profile named ${profileName} in eas.json`);
152
156
  }
153
157
  const { extends: baseProfileName, ...buildProfileRest } = buildProfile;
154
158
  if (baseProfileName) {
@@ -160,7 +164,7 @@ class EasJsonReader {
160
164
  }
161
165
  ensureBuildProfileExists(easJson, profileName) {
162
166
  if (!easJson.build || !easJson.build[profileName]) {
163
- throw new Error(`There is no profile named ${profileName} in eas.json`);
167
+ throw new Error(`There is no build profile named ${profileName} in eas.json`);
164
168
  }
165
169
  }
166
170
  evaluateFields(platform, profile) {
@@ -23,8 +23,8 @@ const CommonBuildProfileSchema = joi_1.default.object({
23
23
  credentialsSource: joi_1.default.string().valid('local', 'remote'),
24
24
  distribution: joi_1.default.string().valid('store', 'internal'),
25
25
  cache: CacheSchema,
26
- releaseChannel: joi_1.default.string(),
27
- channel: joi_1.default.string(),
26
+ releaseChannel: joi_1.default.string().regex(/^[a-z\d][a-z\d._-]*$/),
27
+ channel: joi_1.default.string().regex(/^[a-z\d][a-z\d._-]*$/),
28
28
  developmentClient: joi_1.default.boolean(),
29
29
  node: joi_1.default.string().empty(null).custom(semverSchemaCheck),
30
30
  yarn: joi_1.default.string().empty(null).custom(semverSchemaCheck),
@@ -66,6 +66,7 @@ exports.AndroidSubmitProfileSchema = joi_1.default.object({
66
66
  .valid(...Object.values(EasSubmit_types_1.AndroidReleaseStatus))
67
67
  .default(EasSubmit_types_1.AndroidReleaseStatus.completed),
68
68
  changesNotSentForReview: joi_1.default.boolean().default(false),
69
+ applicationId: joi_1.default.string(),
69
70
  });
70
71
  exports.IosSubmitProfileSchema = joi_1.default.object({
71
72
  ascApiKeyPath: joi_1.default.string(),
@@ -78,6 +79,7 @@ exports.IosSubmitProfileSchema = joi_1.default.object({
78
79
  language: joi_1.default.string().default('en-US'),
79
80
  companyName: joi_1.default.string(),
80
81
  appName: joi_1.default.string(),
82
+ bundleIdentifier: joi_1.default.string(),
81
83
  });
82
84
  const EasJsonSubmitConfigurationSchema = joi_1.default.object({
83
85
  android: exports.AndroidSubmitProfileSchema,
@@ -16,6 +16,7 @@ export interface AndroidSubmitProfile {
16
16
  track: AndroidReleaseTrack;
17
17
  releaseStatus: AndroidReleaseStatus;
18
18
  changesNotSentForReview: boolean;
19
+ applicationId?: string;
19
20
  }
20
21
  export declare const AndroidSubmitProfileFieldsToEvaluate: (keyof AndroidSubmitProfile)[];
21
22
  export interface IosSubmitProfile {
@@ -29,6 +30,7 @@ export interface IosSubmitProfile {
29
30
  language: string;
30
31
  companyName?: string;
31
32
  appName?: string;
33
+ bundleIdentifier?: string;
32
34
  }
33
35
  export declare const IosSubmitProfileFieldsToEvaluate: (keyof IosSubmitProfile)[];
34
36
  export declare type SubmitProfile<TPlatform extends Platform = Platform> = TPlatform extends Platform.ANDROID ? AndroidSubmitProfile : TPlatform extends Platform.IOS ? IosSubmitProfile : TPlatform extends Platform ? AndroidSubmitProfile | IosSubmitProfile : never;
package/build/errors.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export declare class InvalidEasJsonError extends Error {
2
2
  }
3
+ export declare class MissingEasJsonError extends Error {
4
+ }
package/build/errors.js CHANGED
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InvalidEasJsonError = void 0;
3
+ exports.MissingEasJsonError = exports.InvalidEasJsonError = void 0;
4
4
  class InvalidEasJsonError extends Error {
5
5
  }
6
6
  exports.InvalidEasJsonError = InvalidEasJsonError;
7
+ class MissingEasJsonError extends Error {
8
+ }
9
+ exports.MissingEasJsonError = MissingEasJsonError;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@expo/eas-json",
3
- "description": "A library for interacting with the eas.json",
4
- "version": "0.34.0",
3
+ "description": "A library for interacting with eas.json",
4
+ "version": "0.37.0",
5
5
  "author": "Expo <support@expo.dev>",
6
6
  "bugs": "https://github.com/expo/eas-cli/issues",
7
7
  "dependencies": {
@@ -24,16 +24,18 @@
24
24
  "homepage": "https://github.com/expo/eas-cli",
25
25
  "license": "MIT",
26
26
  "main": "build/index.js",
27
+ "types": "build/index.d.ts",
27
28
  "repository": "expo/eas-cli",
28
29
  "scripts": {
29
30
  "build": "tsc --project tsconfig.build.json",
30
31
  "watch": "yarn build --watch --preserveWatchOutput",
31
32
  "typecheck": "tsc",
32
33
  "prepack": "rm -rf build && yarn build",
33
- "test": "jest"
34
+ "test": "jest",
35
+ "clean": "rm -rf build node_modules yarn-error.log"
34
36
  },
35
37
  "publishConfig": {
36
38
  "access": "public"
37
39
  },
38
- "gitHead": "36118b700f4cadc184bddd733b568fe7abde69fe"
40
+ "gitHead": "558c3670387cb32d135cfebe9bdd9fb2afd25237"
39
41
  }
@@ -1,6 +1,7 @@
1
1
  import { Platform } from '@expo/eas-build-job';
2
2
  import JsonFile from '@expo/json-file';
3
3
  import envString from 'env-string';
4
+ import fs from 'fs-extra';
4
5
  import path from 'path';
5
6
 
6
7
  import { BuildProfile } from './EasBuild.types';
@@ -17,7 +18,7 @@ import {
17
18
  IosSubmitProfileFieldsToEvaluate,
18
19
  SubmitProfile,
19
20
  } from './EasSubmit.types';
20
- import { InvalidEasJsonError } from './errors';
21
+ import { InvalidEasJsonError, MissingEasJsonError } from './errors';
21
22
 
22
23
  interface EasJsonPreValidation {
23
24
  cli?: object;
@@ -71,7 +72,7 @@ export class EasJsonReader {
71
72
  }
72
73
  return value as CliConfig;
73
74
  } catch (err: any) {
74
- if (err.code === 'ENOENT') {
75
+ if (err instanceof MissingEasJsonError) {
75
76
  return null;
76
77
  }
77
78
  throw err;
@@ -141,7 +142,7 @@ export class EasJsonReader {
141
142
  const easJson = await this.readAndValidateAsync();
142
143
  const profile = easJson?.submit?.[profileName];
143
144
  if (!profile) {
144
- throw new Error(`There is no profile named ${profileName} in eas.json`);
145
+ throw new Error(`There is no submit profile named ${profileName} in eas.json`);
145
146
  }
146
147
  const platformProfile = profile[platform];
147
148
  if (platformProfile) {
@@ -168,6 +169,11 @@ export class EasJsonReader {
168
169
  public async readRawAsync(): Promise<EasJsonPreValidation> {
169
170
  try {
170
171
  const easJsonPath = EasJsonReader.formatEasJsonPath(this.projectDir);
172
+ if (!(await fs.pathExists(easJsonPath))) {
173
+ throw new MissingEasJsonError(
174
+ `An eas.json file could not be found at ${easJsonPath}. You must make one in order to proceed. Learn more at https://expo.fyi/eas-json`
175
+ );
176
+ }
171
177
  const rawEasJson = JsonFile.read(easJsonPath);
172
178
  const { value, error } = MinimalEasJsonSchema.validate(rawEasJson, { abortEarly: false });
173
179
  if (error) {
@@ -194,7 +200,7 @@ export class EasJsonReader {
194
200
  }
195
201
  const buildProfile = easJson.build[profileName];
196
202
  if (!buildProfile) {
197
- throw new Error(`There is no profile named ${profileName} in eas.json`);
203
+ throw new Error(`There is no build profile named ${profileName} in eas.json`);
198
204
  }
199
205
  const { extends: baseProfileName, ...buildProfileRest } = buildProfile;
200
206
  if (baseProfileName) {
@@ -209,7 +215,7 @@ export class EasJsonReader {
209
215
 
210
216
  private ensureBuildProfileExists(easJson: EasJson, profileName: string): void {
211
217
  if (!easJson.build || !easJson.build[profileName]) {
212
- throw new Error(`There is no profile named ${profileName} in eas.json`);
218
+ throw new Error(`There is no build profile named ${profileName} in eas.json`);
213
219
  }
214
220
  }
215
221
 
@@ -22,8 +22,8 @@ const CommonBuildProfileSchema = Joi.object({
22
22
  credentialsSource: Joi.string().valid('local', 'remote'),
23
23
  distribution: Joi.string().valid('store', 'internal'),
24
24
  cache: CacheSchema,
25
- releaseChannel: Joi.string(),
26
- channel: Joi.string(),
25
+ releaseChannel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
26
+ channel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
27
27
  developmentClient: Joi.boolean(),
28
28
 
29
29
  node: Joi.string().empty(null).custom(semverSchemaCheck),
@@ -87,6 +87,7 @@ export const AndroidSubmitProfileSchema = Joi.object({
87
87
  .valid(...Object.values(AndroidReleaseStatus))
88
88
  .default(AndroidReleaseStatus.completed),
89
89
  changesNotSentForReview: Joi.boolean().default(false),
90
+ applicationId: Joi.string(),
90
91
  });
91
92
 
92
93
  export const IosSubmitProfileSchema = Joi.object({
@@ -100,6 +101,7 @@ export const IosSubmitProfileSchema = Joi.object({
100
101
  language: Joi.string().default('en-US'),
101
102
  companyName: Joi.string(),
102
103
  appName: Joi.string(),
104
+ bundleIdentifier: Joi.string(),
103
105
  });
104
106
 
105
107
  const EasJsonSubmitConfigurationSchema = Joi.object({
@@ -19,6 +19,7 @@ export interface AndroidSubmitProfile {
19
19
  track: AndroidReleaseTrack;
20
20
  releaseStatus: AndroidReleaseStatus;
21
21
  changesNotSentForReview: boolean;
22
+ applicationId?: string;
22
23
  }
23
24
 
24
25
  export const AndroidSubmitProfileFieldsToEvaluate: (keyof AndroidSubmitProfile)[] = [
@@ -36,6 +37,7 @@ export interface IosSubmitProfile {
36
37
  language: string;
37
38
  companyName?: string;
38
39
  appName?: string;
40
+ bundleIdentifier?: string;
39
41
  }
40
42
 
41
43
  export const IosSubmitProfileFieldsToEvaluate: (keyof IosSubmitProfile)[] = [
@@ -225,7 +225,7 @@ test('valid eas.json with missing profile', async () => {
225
225
 
226
226
  const reader = new EasJsonReader('/project');
227
227
  const promise = reader.readBuildProfileAsync(Platform.ANDROID, 'debug');
228
- await expect(promise).rejects.toThrowError('There is no profile named debug in eas.json');
228
+ await expect(promise).rejects.toThrowError('There is no build profile named debug in eas.json');
229
229
  });
230
230
 
231
231
  test('invalid eas.json when using wrong buildType', async () => {
@@ -247,7 +247,9 @@ test('empty json', async () => {
247
247
 
248
248
  const reader = new EasJsonReader('/project');
249
249
  const promise = reader.readBuildProfileAsync(Platform.ANDROID, 'production');
250
- await expect(promise).rejects.toThrowError('There is no profile named production in eas.json');
250
+ await expect(promise).rejects.toThrowError(
251
+ 'There is no build profile named production in eas.json'
252
+ );
251
253
  });
252
254
 
253
255
  test('invalid semver value', async () => {
@@ -264,6 +266,18 @@ test('invalid semver value', async () => {
264
266
  );
265
267
  });
266
268
 
269
+ test('invalid release channel', async () => {
270
+ await fs.writeJson('/project/eas.json', {
271
+ build: {
272
+ production: { releaseChannel: 'feature/myfeature' },
273
+ },
274
+ });
275
+
276
+ const reader = new EasJsonReader('/project');
277
+ const promise = reader.readBuildProfileAsync(Platform.ANDROID, 'production');
278
+ await expect(promise).rejects.toThrowError(/fails to match the required pattern/);
279
+ });
280
+
267
281
  test('get profile names', async () => {
268
282
  await fs.writeJson('/project/eas.json', {
269
283
  build: {
package/src/errors.ts CHANGED
@@ -1 +1,3 @@
1
1
  export class InvalidEasJsonError extends Error {}
2
+
3
+ export class MissingEasJsonError extends Error {}