eas-cli 12.3.0 → 12.4.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.
@@ -7,8 +7,8 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.GitHubAppEnvironment = exports.FingerprintSourceType = exports.Feature = exports.Experiment = exports.EnvironmentVariableVisibility = exports.EnvironmentVariableScope = exports.EnvironmentVariableEnvironment = exports.EnvironmentSecretType = exports.EntityTypeName = exports.EasTotalPlanEnablementUnit = exports.EasServiceMetric = exports.EasService = exports.EasBuildWaiverType = exports.EasBuildDeprecationInfoType = exports.EasBuildBillingResourceClass = exports.DistributionType = exports.CustomDomainStatus = exports.CustomDomainDnsRecordType = exports.CrashSampleFor = exports.ContinentCode = exports.BuildWorkflow = exports.BuildTrigger = exports.BuildStatus = exports.BuildRetryDisabledReason = exports.BuildResourceClass = exports.BuildPriority = exports.BuildPhase = exports.BuildMode = exports.BuildLimitThresholdExceededMetadataType = exports.BuildIosEnterpriseProvisioning = exports.BuildCredentialsSource = exports.BackgroundJobState = exports.BackgroundJobResultType = exports.AuthProviderIdentifier = exports.AuthProtocolType = exports.AuditLogsExportFormat = exports.AssetMetadataStatus = exports.AppsFilter = exports.AppleTeamType = exports.AppleDeviceClass = exports.AppStoreConnectUserRole = exports.AppSort = exports.AppPrivacy = exports.AppPlatform = exports.AppInternalDistributionBuildPrivacy = exports.AndroidKeystoreType = exports.AndroidFcmVersion = exports.AndroidBuildType = exports.ActivityTimelineProjectActivityType = exports.AccountAppsSortByField = void 0;
10
- exports.WebhookType = exports.UserAgentOs = exports.UserAgentBrowser = exports.UsageMetricsGranularity = exports.UsageMetricType = exports.UploadSessionType = exports.TargetEntityMutationType = exports.SubmissionStatus = exports.SubmissionPriority = exports.SubmissionArchiveSourceType = exports.SubmissionAndroidTrack = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidArchiveType = exports.StatuspageServiceStatus = exports.StatuspageServiceName = exports.StatuspageIncidentStatus = exports.StatuspageIncidentImpact = exports.StandardOffer = exports.SecondFactorMethod = exports.Role = exports.ResourceClassExperiment = exports.RequestStatusPattern = exports.ProjectArchiveSourceType = exports.Permission = exports.Order = exports.OnboardingEnvironment = exports.OnboardingDeviceType = exports.OfferType = exports.NotificationType = exports.NotificationEvent = exports.MetricsStatusType = exports.MetricsRequestMethod = exports.MetricsCacheStatus = exports.MailchimpTag = exports.MailchimpAudience = exports.JobRunStatus = exports.JobRunPriority = exports.IosSchemeBuildConfiguration = exports.IosManagedBuildType = exports.IosDistributionType = exports.IosBuildType = exports.InvoiceDiscountType = exports.InsightsFilterType = exports.GitHubJobRunTriggerType = exports.GitHubJobRunTriggerRunStatus = exports.GitHubJobRunJobType = exports.GitHubBuildTriggerType = exports.GitHubBuildTriggerRunStatus = exports.GitHubBuildTriggerExecutionBehavior = exports.GitHubAppInstallationStatus = void 0;
11
- exports.WorkerLoggerLevel = exports.WorkerDeploymentRequestsInclude = exports.WorkerDeploymentRequestKind = exports.WorkerDeploymentLogLevel = void 0;
10
+ exports.UserEntityTypeName = exports.UserAgentOs = exports.UserAgentBrowser = exports.UsageMetricsGranularity = exports.UsageMetricType = exports.UploadSessionType = exports.TargetEntityMutationType = exports.SubmissionStatus = exports.SubmissionPriority = exports.SubmissionArchiveSourceType = exports.SubmissionAndroidTrack = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidArchiveType = exports.StatuspageServiceStatus = exports.StatuspageServiceName = exports.StatuspageIncidentStatus = exports.StatuspageIncidentImpact = exports.StandardOffer = exports.SecondFactorMethod = exports.Role = exports.ResponseType = exports.ResponseStatusType = exports.ResponseCacheStatus = exports.ResourceClassExperiment = exports.RequestMethod = exports.ProjectArchiveSourceType = exports.Permission = exports.Order = exports.OnboardingEnvironment = exports.OnboardingDeviceType = exports.OfferType = exports.NotificationType = exports.NotificationEvent = exports.MailchimpTag = exports.MailchimpAudience = exports.JobRunStatus = exports.JobRunPriority = exports.IosSchemeBuildConfiguration = exports.IosManagedBuildType = exports.IosDistributionType = exports.IosBuildType = exports.InvoiceDiscountType = exports.InsightsFilterType = exports.GitHubJobRunTriggerType = exports.GitHubJobRunTriggerRunStatus = exports.GitHubJobRunJobType = exports.GitHubBuildTriggerType = exports.GitHubBuildTriggerRunStatus = exports.GitHubBuildTriggerExecutionBehavior = exports.GitHubAppInstallationStatus = void 0;
11
+ exports.WorkerLoggerLevel = exports.WorkerDeploymentLogLevel = exports.WebhookType = void 0;
12
12
  var AccountAppsSortByField;
13
13
  (function (AccountAppsSortByField) {
14
14
  AccountAppsSortByField["LatestActivityTime"] = "LATEST_ACTIVITY_TIME";
@@ -131,6 +131,7 @@ var BackgroundJobResultType;
131
131
  (function (BackgroundJobResultType) {
132
132
  BackgroundJobResultType["AuditLogsExport"] = "AUDIT_LOGS_EXPORT";
133
133
  BackgroundJobResultType["GithubBuild"] = "GITHUB_BUILD";
134
+ BackgroundJobResultType["UserAuditLogsExport"] = "USER_AUDIT_LOGS_EXPORT";
134
135
  BackgroundJobResultType["Void"] = "VOID";
135
136
  })(BackgroundJobResultType || (exports.BackgroundJobResultType = BackgroundJobResultType = {}));
136
137
  var BackgroundJobState;
@@ -279,6 +280,7 @@ var CrashSampleFor;
279
280
  })(CrashSampleFor || (exports.CrashSampleFor = CrashSampleFor = {}));
280
281
  var CustomDomainDnsRecordType;
281
282
  (function (CustomDomainDnsRecordType) {
283
+ CustomDomainDnsRecordType["A"] = "A";
282
284
  CustomDomainDnsRecordType["Cname"] = "CNAME";
283
285
  CustomDomainDnsRecordType["Txt"] = "TXT";
284
286
  })(CustomDomainDnsRecordType || (exports.CustomDomainDnsRecordType = CustomDomainDnsRecordType = {}));
@@ -352,8 +354,6 @@ var EntityTypeName;
352
354
  EntityTypeName["Customer"] = "Customer";
353
355
  EntityTypeName["GoogleServiceAccountKey"] = "GoogleServiceAccountKey";
354
356
  EntityTypeName["IosAppCredentials"] = "IosAppCredentials";
355
- EntityTypeName["TurtleBuild"] = "TurtleBuild";
356
- EntityTypeName["Update"] = "Update";
357
357
  EntityTypeName["UserInvitation"] = "UserInvitation";
358
358
  EntityTypeName["UserPermission"] = "UserPermission";
359
359
  })(EntityTypeName || (exports.EntityTypeName = EntityTypeName = {}));
@@ -500,28 +500,6 @@ var MailchimpTag;
500
500
  MailchimpTag["EasMasterList"] = "EAS_MASTER_LIST";
501
501
  MailchimpTag["NewsletterSignupList"] = "NEWSLETTER_SIGNUP_LIST";
502
502
  })(MailchimpTag || (exports.MailchimpTag = MailchimpTag = {}));
503
- var MetricsCacheStatus;
504
- (function (MetricsCacheStatus) {
505
- MetricsCacheStatus["Hit"] = "HIT";
506
- MetricsCacheStatus["Miss"] = "MISS";
507
- MetricsCacheStatus["Pass"] = "PASS";
508
- })(MetricsCacheStatus || (exports.MetricsCacheStatus = MetricsCacheStatus = {}));
509
- var MetricsRequestMethod;
510
- (function (MetricsRequestMethod) {
511
- MetricsRequestMethod["Delete"] = "DELETE";
512
- MetricsRequestMethod["Get"] = "GET";
513
- MetricsRequestMethod["Options"] = "OPTIONS";
514
- MetricsRequestMethod["Post"] = "POST";
515
- MetricsRequestMethod["Put"] = "PUT";
516
- })(MetricsRequestMethod || (exports.MetricsRequestMethod = MetricsRequestMethod = {}));
517
- var MetricsStatusType;
518
- (function (MetricsStatusType) {
519
- MetricsStatusType["ClientError"] = "CLIENT_ERROR";
520
- MetricsStatusType["None"] = "NONE";
521
- MetricsStatusType["Redirect"] = "REDIRECT";
522
- MetricsStatusType["ServerError"] = "SERVER_ERROR";
523
- MetricsStatusType["Successful"] = "SUCCESSFUL";
524
- })(MetricsStatusType || (exports.MetricsStatusType = MetricsStatusType = {}));
525
503
  var NotificationEvent;
526
504
  (function (NotificationEvent) {
527
505
  NotificationEvent["BuildComplete"] = "BUILD_COMPLETE";
@@ -576,18 +554,42 @@ var ProjectArchiveSourceType;
576
554
  ProjectArchiveSourceType["S3"] = "S3";
577
555
  ProjectArchiveSourceType["Url"] = "URL";
578
556
  })(ProjectArchiveSourceType || (exports.ProjectArchiveSourceType = ProjectArchiveSourceType = {}));
579
- var RequestStatusPattern;
580
- (function (RequestStatusPattern) {
581
- RequestStatusPattern["Http_2Xx"] = "HTTP_2XX";
582
- RequestStatusPattern["Http_3Xx"] = "HTTP_3XX";
583
- RequestStatusPattern["Http_4Xx"] = "HTTP_4XX";
584
- RequestStatusPattern["Http_5Xx"] = "HTTP_5XX";
585
- })(RequestStatusPattern || (exports.RequestStatusPattern = RequestStatusPattern = {}));
557
+ var RequestMethod;
558
+ (function (RequestMethod) {
559
+ RequestMethod["Delete"] = "DELETE";
560
+ RequestMethod["Get"] = "GET";
561
+ RequestMethod["Head"] = "HEAD";
562
+ RequestMethod["Options"] = "OPTIONS";
563
+ RequestMethod["Patch"] = "PATCH";
564
+ RequestMethod["Post"] = "POST";
565
+ RequestMethod["Put"] = "PUT";
566
+ })(RequestMethod || (exports.RequestMethod = RequestMethod = {}));
586
567
  var ResourceClassExperiment;
587
568
  (function (ResourceClassExperiment) {
588
569
  ResourceClassExperiment["C3D"] = "C3D";
589
570
  ResourceClassExperiment["N2"] = "N2";
590
571
  })(ResourceClassExperiment || (exports.ResourceClassExperiment = ResourceClassExperiment = {}));
572
+ var ResponseCacheStatus;
573
+ (function (ResponseCacheStatus) {
574
+ ResponseCacheStatus["Hit"] = "HIT";
575
+ ResponseCacheStatus["Miss"] = "MISS";
576
+ ResponseCacheStatus["Pass"] = "PASS";
577
+ })(ResponseCacheStatus || (exports.ResponseCacheStatus = ResponseCacheStatus = {}));
578
+ var ResponseStatusType;
579
+ (function (ResponseStatusType) {
580
+ ResponseStatusType["ClientError"] = "CLIENT_ERROR";
581
+ ResponseStatusType["None"] = "NONE";
582
+ ResponseStatusType["Redirect"] = "REDIRECT";
583
+ ResponseStatusType["ServerError"] = "SERVER_ERROR";
584
+ ResponseStatusType["Successful"] = "SUCCESSFUL";
585
+ })(ResponseStatusType || (exports.ResponseStatusType = ResponseStatusType = {}));
586
+ var ResponseType;
587
+ (function (ResponseType) {
588
+ ResponseType["Asset"] = "ASSET";
589
+ ResponseType["Crash"] = "CRASH";
590
+ ResponseType["Rejected"] = "REJECTED";
591
+ ResponseType["Route"] = "ROUTE";
592
+ })(ResponseType || (exports.ResponseType = ResponseType = {}));
591
593
  var Role;
592
594
  (function (Role) {
593
595
  Role["Admin"] = "ADMIN";
@@ -755,6 +757,17 @@ var UserAgentOs;
755
757
  UserAgentOs["MacOs"] = "MAC_OS";
756
758
  UserAgentOs["Windows"] = "WINDOWS";
757
759
  })(UserAgentOs || (exports.UserAgentOs = UserAgentOs = {}));
760
+ var UserEntityTypeName;
761
+ (function (UserEntityTypeName) {
762
+ UserEntityTypeName["AccessToken"] = "AccessToken";
763
+ UserEntityTypeName["DiscordUser"] = "DiscordUser";
764
+ UserEntityTypeName["GitHubUser"] = "GitHubUser";
765
+ UserEntityTypeName["Password"] = "Password";
766
+ UserEntityTypeName["SsoUser"] = "SSOUser";
767
+ UserEntityTypeName["User"] = "User";
768
+ UserEntityTypeName["UserSecondFactorBackupCodes"] = "UserSecondFactorBackupCodes";
769
+ UserEntityTypeName["UserSecondFactorDevice"] = "UserSecondFactorDevice";
770
+ })(UserEntityTypeName || (exports.UserEntityTypeName = UserEntityTypeName = {}));
758
771
  var WebhookType;
759
772
  (function (WebhookType) {
760
773
  WebhookType["Build"] = "BUILD";
@@ -769,17 +782,6 @@ var WorkerDeploymentLogLevel;
769
782
  WorkerDeploymentLogLevel["Log"] = "LOG";
770
783
  WorkerDeploymentLogLevel["Warn"] = "WARN";
771
784
  })(WorkerDeploymentLogLevel || (exports.WorkerDeploymentLogLevel = WorkerDeploymentLogLevel = {}));
772
- var WorkerDeploymentRequestKind;
773
- (function (WorkerDeploymentRequestKind) {
774
- WorkerDeploymentRequestKind["Asset"] = "ASSET";
775
- WorkerDeploymentRequestKind["Crash"] = "CRASH";
776
- WorkerDeploymentRequestKind["Rejected"] = "REJECTED";
777
- })(WorkerDeploymentRequestKind || (exports.WorkerDeploymentRequestKind = WorkerDeploymentRequestKind = {}));
778
- var WorkerDeploymentRequestsInclude;
779
- (function (WorkerDeploymentRequestsInclude) {
780
- WorkerDeploymentRequestsInclude["Assets"] = "ASSETS";
781
- WorkerDeploymentRequestsInclude["Routes"] = "ROUTES";
782
- })(WorkerDeploymentRequestsInclude || (exports.WorkerDeploymentRequestsInclude = WorkerDeploymentRequestsInclude = {}));
783
785
  var WorkerLoggerLevel;
784
786
  (function (WorkerLoggerLevel) {
785
787
  WorkerLoggerLevel["Debug"] = "DEBUG";
@@ -8,6 +8,7 @@ export type PublicExpoConfig = Omit<ExpoConfig, '_internal' | 'hooks' | 'ios' |
8
8
  export interface ExpoConfigOptions {
9
9
  env?: Env;
10
10
  skipSDKVersionRequirement?: boolean;
11
+ skipPlugins?: boolean;
11
12
  }
12
13
  export declare function createOrModifyExpoConfigAsync(projectDir: string, exp: Partial<ExpoConfig>, readOptions?: {
13
14
  skipSDKVersionRequirement?: boolean;
@@ -29,6 +29,7 @@ function getExpoConfigInternal(projectDir, opts = {}) {
29
29
  const { exp } = (0, config_1.getConfig)(projectDir, {
30
30
  skipSDKVersionRequirement: true,
31
31
  ...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
32
+ ...(opts.skipPlugins ? { skipPlugins: true } : {}),
32
33
  });
33
34
  const { error } = MinimalAppConfigSchema.validate(exp, {
34
35
  allowUnknown: true,
@@ -2,6 +2,8 @@
2
2
  /// <reference types="node" />
3
3
  import { GzipOptions } from 'minizlib';
4
4
  import { HashOptions } from 'node:crypto';
5
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
6
+ import { EnvironmentVariableEnvironment } from '../graphql/generated';
5
7
  interface AssetMapOptions {
6
8
  hashOptions?: HashOptions;
7
9
  }
@@ -9,6 +11,16 @@ interface AssetMapOptions {
9
11
  export type AssetMap = Record<string, string>;
10
12
  /** Creates an asset map of a given target path */
11
13
  declare function createAssetMapAsync(assetPath: string, options?: AssetMapOptions): Promise<AssetMap>;
14
+ export interface Manifest {
15
+ env: Record<string, string | undefined>;
16
+ }
17
+ interface CreateManifestParams {
18
+ projectId: string;
19
+ projectDir: string;
20
+ environment?: EnvironmentVariableEnvironment;
21
+ }
22
+ /** Creates a manifest configuration sent up for deployment */
23
+ export declare function createManifestAsync(params: CreateManifestParams, graphqlClient: ExpoGraphqlClient): Promise<Manifest>;
12
24
  interface WorkerFileEntry {
13
25
  normalizedPath: string;
14
26
  path: string;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.packFilesIterableAsync = exports.listAssetMapFilesAsync = exports.listWorkerFilesAsync = exports.createAssetMapAsync = void 0;
3
+ exports.packFilesIterableAsync = exports.listAssetMapFilesAsync = exports.listWorkerFilesAsync = exports.createAssetMapAsync = exports.createManifestAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const env_1 = require("@expo/env");
5
6
  const minizlib_1 = require("minizlib");
6
7
  const node_crypto_1 = require("node:crypto");
7
8
  const node_fs_1 = tslib_1.__importStar(require("node:fs"));
@@ -9,6 +10,7 @@ const node_os_1 = tslib_1.__importDefault(require("node:os"));
9
10
  const node_path_1 = tslib_1.__importDefault(require("node:path"));
10
11
  const promises_1 = require("node:stream/promises");
11
12
  const tar_stream_1 = require("tar-stream");
13
+ const EnvironmentVariablesQuery_1 = require("../graphql/queries/EnvironmentVariablesQuery");
12
14
  /** Returns whether a file or folder is ignored */
13
15
  function isIgnoredName(name) {
14
16
  switch (name) {
@@ -69,6 +71,23 @@ async function createAssetMapAsync(assetPath, options) {
69
71
  return map;
70
72
  }
71
73
  exports.createAssetMapAsync = createAssetMapAsync;
74
+ /** Creates a manifest configuration sent up for deployment */
75
+ async function createManifestAsync(params, graphqlClient) {
76
+ let env;
77
+ if (params.environment) {
78
+ env = Object.fromEntries((await EnvironmentVariablesQuery_1.EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(graphqlClient, {
79
+ appId: params.projectId,
80
+ environment: params.environment,
81
+ })).map(variable => [variable.name, variable.value ?? undefined]));
82
+ }
83
+ else {
84
+ // NOTE: This is required for the .env resolution
85
+ process.env.NODE_ENV = 'production';
86
+ env = (0, env_1.get)(params.projectDir).env;
87
+ }
88
+ return { env };
89
+ }
90
+ exports.createManifestAsync = createManifestAsync;
72
91
  /** Reads worker files while normalizing sourcemaps and providing normalized paths */
73
92
  async function* listWorkerFilesAsync(workerPath) {
74
93
  for await (const file of listFilesRecursively(workerPath)) {
@@ -1,6 +1,29 @@
1
- import { ExpoConfig } from '@expo/config-types';
1
+ import { DeploymentsMutation } from './mutations';
2
2
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
3
- export declare function getSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlClient, exp: ExpoConfig, deploymentVariables: {
3
+ import { WorkerDeploymentFragment } from '../graphql/generated';
4
+ import { selectPaginatedAsync } from '../utils/relay';
5
+ export declare function getSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlClient, options: {
4
6
  appId: string;
5
7
  deploymentIdentifier?: string | null;
8
+ /** Callback which is invoked when the project is going to setup the dev domain */
9
+ onSetupDevDomain?: () => any;
10
+ /** If the terminal is running in non interactive mode or not */
11
+ nonInteractive?: boolean;
6
12
  }): Promise<string>;
13
+ export declare function assignWorkerDeploymentAliasAsync({ graphqlClient, appId, deploymentId, aliasName, }: {
14
+ graphqlClient: ExpoGraphqlClient;
15
+ appId: string;
16
+ deploymentId: string;
17
+ aliasName: string;
18
+ }): ReturnType<typeof DeploymentsMutation.assignAliasAsync>;
19
+ export declare function assignWorkerDeploymentProductionAsync({ graphqlClient, appId, deploymentId, }: {
20
+ graphqlClient: ExpoGraphqlClient;
21
+ appId: string;
22
+ deploymentId: string;
23
+ }): ReturnType<typeof DeploymentsMutation.assignAliasAsync>;
24
+ export declare function selectWorkerDeploymentOnAppAsync({ graphqlClient, appId, selectTitle, pageSize, }: {
25
+ graphqlClient: ExpoGraphqlClient;
26
+ appId: string;
27
+ selectTitle?: string;
28
+ pageSize?: number;
29
+ }): ReturnType<typeof selectPaginatedAsync<WorkerDeploymentFragment>>;
@@ -1,39 +1,98 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSignedDeploymentUrlAsync = void 0;
3
+ exports.selectWorkerDeploymentOnAppAsync = exports.assignWorkerDeploymentProductionAsync = exports.assignWorkerDeploymentAliasAsync = exports.getSignedDeploymentUrlAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
6
  const mutations_1 = require("./mutations");
7
+ const queries_1 = require("./queries");
8
+ const logs_1 = require("./utils/logs");
6
9
  const log_1 = tslib_1.__importDefault(require("../log"));
7
10
  const prompts_1 = require("../prompts");
8
- async function getSignedDeploymentUrlAsync(graphqlClient, exp, deploymentVariables) {
11
+ const memoize_1 = require("../utils/expodash/memoize");
12
+ const relay_1 = require("../utils/relay");
13
+ async function getSignedDeploymentUrlAsync(graphqlClient, options) {
9
14
  try {
10
- return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables);
15
+ return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, {
16
+ appId: options.appId,
17
+ deploymentIdentifier: options.deploymentIdentifier,
18
+ });
11
19
  }
12
20
  catch (error) {
13
21
  const isMissingDevDomain = error?.graphQLErrors?.some(e => ['APP_NO_DEV_DOMAIN_NAME'].includes(e?.extensions?.errorCode));
14
22
  if (!isMissingDevDomain) {
15
23
  throw error;
16
24
  }
25
+ if (options.nonInteractive) {
26
+ throw new Error('The project URL needs to be set up, but the terminal is running in non-interactive mode.');
27
+ }
28
+ const suggestedDevDomainName = await queries_1.DeploymentsQuery.getSuggestedDevDomainByAppIdAsync(graphqlClient, { appId: options.appId });
29
+ options.onSetupDevDomain?.();
17
30
  await chooseDevDomainNameAsync({
18
31
  graphqlClient,
19
- appId: deploymentVariables.appId,
20
- slug: exp.slug,
32
+ appId: options.appId,
33
+ initial: suggestedDevDomainName,
34
+ });
35
+ return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, {
36
+ appId: options.appId,
37
+ deploymentIdentifier: options.deploymentIdentifier,
21
38
  });
22
- return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables);
23
39
  }
24
40
  }
25
41
  exports.getSignedDeploymentUrlAsync = getSignedDeploymentUrlAsync;
26
- async function chooseDevDomainNameAsync({ graphqlClient, appId, slug, }) {
27
- const validationMessage = 'The project does not have a dev domain name.';
42
+ const DEV_DOMAIN_INVALID_START_END_CHARACTERS = /^[^a-z0-9]+|[^a-z0-9-]+$/;
43
+ const DEV_DOMAIN_INVALID_REPLACEMENT_HYPHEN = /[^a-z0-9-]+/;
44
+ const DEV_DOMAIN_INVALID_MULTIPLE_HYPHENS = /(-{2,})/;
45
+ /**
46
+ * Format a dev domain name to match whats allowed on the backend.
47
+ * This is equal to our `DEV_DOMAIN_NAME_REGEX`, but implemented as a filtering function
48
+ * to help users find a valid name while typing.
49
+ */
50
+ function formatDevDomainName(name = '') {
51
+ return name
52
+ .toLowerCase()
53
+ .replace(DEV_DOMAIN_INVALID_REPLACEMENT_HYPHEN, '-')
54
+ .replace(DEV_DOMAIN_INVALID_START_END_CHARACTERS, '')
55
+ .replace(DEV_DOMAIN_INVALID_MULTIPLE_HYPHENS, '-')
56
+ .trim();
57
+ }
58
+ async function chooseDevDomainNameAsync({ graphqlClient, appId, initial, }) {
59
+ const rootDomain = `.${logs_1.EXPO_BASE_DOMAIN}.app`;
60
+ const memoizedFormatDevDomainName = (0, memoize_1.memoize)(formatDevDomainName);
28
61
  const { name } = await (0, prompts_1.promptAsync)({
29
62
  type: 'text',
30
63
  name: 'name',
31
- message: 'Choose a dev domain name for your project:',
32
- validate: value => (value && value.length > 3 ? true : validationMessage),
33
- initial: slug,
64
+ message: 'Choose a URL for your project:',
65
+ initial,
66
+ validate: (value) => {
67
+ if (!value) {
68
+ return 'You have to choose a URL for your project';
69
+ }
70
+ if (value.length < 3) {
71
+ return 'Project URLs must be at least 3 characters long';
72
+ }
73
+ if (value.endsWith('-')) {
74
+ return 'Project URLs cannot end with a hyphen (-)';
75
+ }
76
+ return true;
77
+ },
78
+ onState(state) {
79
+ const value = memoizedFormatDevDomainName(state.value);
80
+ if (value !== state.value) {
81
+ this.value = value;
82
+ }
83
+ },
84
+ onRender(kleur) {
85
+ this.cursorOffset = -rootDomain.length - 1;
86
+ if (this.placeholder) {
87
+ this.rendered = kleur.dim(`${this.initial} ${rootDomain}`);
88
+ }
89
+ else {
90
+ this.rendered = this.value + kleur.dim(` ${rootDomain}`);
91
+ }
92
+ },
34
93
  });
35
94
  if (!name) {
36
- throw new Error('Prompt failed');
95
+ throw new Error('No project URL provided, aborting deployment.');
37
96
  }
38
97
  try {
39
98
  const success = await mutations_1.DeploymentsMutation.assignDevDomainNameAsync(graphqlClient, {
@@ -41,17 +100,45 @@ async function chooseDevDomainNameAsync({ graphqlClient, appId, slug, }) {
41
100
  name,
42
101
  });
43
102
  if (!success) {
44
- throw new Error('Failed to assign dev domain name');
103
+ throw new Error('Failed to assign project URL');
45
104
  }
46
105
  }
47
106
  catch (error) {
48
107
  const isChosenNameTaken = error?.graphQLErrors?.some(e => ['DEV_DOMAIN_NAME_TAKEN'].includes(e?.extensions?.errorCode));
49
108
  if (isChosenNameTaken) {
50
- log_1.default.error(`The entered dev domain name "${name}" is taken. Choose a different name.`);
51
- await chooseDevDomainNameAsync({ graphqlClient, appId, slug });
109
+ log_1.default.error(`The project URL "${name}" is already taken, choose a different name.`);
110
+ await chooseDevDomainNameAsync({ graphqlClient, appId, initial });
52
111
  }
53
112
  if (!isChosenNameTaken) {
54
113
  throw error;
55
114
  }
56
115
  }
57
116
  }
117
+ async function assignWorkerDeploymentAliasAsync({ graphqlClient, appId, deploymentId, aliasName, }) {
118
+ return await mutations_1.DeploymentsMutation.assignAliasAsync(graphqlClient, {
119
+ appId,
120
+ deploymentId,
121
+ aliasName,
122
+ });
123
+ }
124
+ exports.assignWorkerDeploymentAliasAsync = assignWorkerDeploymentAliasAsync;
125
+ async function assignWorkerDeploymentProductionAsync({ graphqlClient, appId, deploymentId, }) {
126
+ return await mutations_1.DeploymentsMutation.assignAliasAsync(graphqlClient, {
127
+ appId,
128
+ deploymentId,
129
+ aliasName: null, // this will assign the deployment as production
130
+ });
131
+ }
132
+ exports.assignWorkerDeploymentProductionAsync = assignWorkerDeploymentProductionAsync;
133
+ async function selectWorkerDeploymentOnAppAsync({ graphqlClient, appId, selectTitle, pageSize, }) {
134
+ return await (0, relay_1.selectPaginatedAsync)({
135
+ pageSize: pageSize ?? 25,
136
+ printedType: selectTitle ?? 'worker deployment',
137
+ queryAsync: async (queryParams) => await queries_1.DeploymentsQuery.getAllDeploymentsPaginatedAsync(graphqlClient, {
138
+ ...queryParams,
139
+ appId,
140
+ }),
141
+ getTitleAsync: async (deployment) => (0, chalk_1.default) `${deployment.deploymentIdentifier}{dim - created at: ${new Date(deployment.createdAt).toLocaleString()}}`,
142
+ });
143
+ }
144
+ exports.selectWorkerDeploymentOnAppAsync = selectWorkerDeploymentOnAppAsync;
@@ -0,0 +1 @@
1
+ export declare const WorkerDeploymentFragmentNode: import("graphql").DocumentNode;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkerDeploymentFragmentNode = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
6
+ exports.WorkerDeploymentFragmentNode = (0, graphql_tag_1.default) `
7
+ fragment WorkerDeploymentFragment on WorkerDeployment {
8
+ id
9
+ url
10
+ deploymentIdentifier
11
+ deploymentDomain
12
+ createdAt
13
+ }
14
+ `;
@@ -0,0 +1 @@
1
+ export declare const WorkerDeploymentAliasFragmentNode: import("graphql").DocumentNode;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkerDeploymentAliasFragmentNode = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
6
+ exports.WorkerDeploymentAliasFragmentNode = (0, graphql_tag_1.default) `
7
+ fragment WorkerDeploymentAliasFragment on WorkerDeploymentAlias {
8
+ id
9
+ aliasName
10
+ url
11
+ }
12
+ `;
@@ -1,4 +1,5 @@
1
1
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
2
+ import { AssignAliasMutation } from '../graphql/generated';
2
3
  export declare const DeploymentsMutation: {
3
4
  createSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlClient, deploymentVariables: {
4
5
  appId: string;
@@ -8,4 +9,9 @@ export declare const DeploymentsMutation: {
8
9
  appId: string;
9
10
  name: string;
10
11
  }): Promise<boolean>;
12
+ assignAliasAsync(graphqlClient: ExpoGraphqlClient, aliasVariables: {
13
+ appId: string;
14
+ deploymentId: string;
15
+ aliasName: string | null;
16
+ }): Promise<AssignAliasMutation['deployments']['assignAlias']>;
11
17
  };
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DeploymentsMutation = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const graphql_1 = require("graphql");
6
7
  const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
8
+ const WorkerDeployment_1 = require("./fragments/WorkerDeployment");
9
+ const WorkerDeploymentAlias_1 = require("./fragments/WorkerDeploymentAlias");
7
10
  const client_1 = require("../graphql/client");
8
11
  exports.DeploymentsMutation = {
9
12
  async createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables) {
@@ -42,4 +45,34 @@ exports.DeploymentsMutation = {
42
45
  .toPromise());
43
46
  return data.devDomainName.assignDevDomainName.name === devDomainNameVariables.name;
44
47
  },
48
+ async assignAliasAsync(graphqlClient, aliasVariables) {
49
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
50
+ .mutation((0, graphql_tag_1.default) `
51
+ mutation AssignAlias(
52
+ $appId: ID!
53
+ $deploymentId: ID!
54
+ $aliasName: WorkerDeploymentIdentifier
55
+ ) {
56
+ deployments {
57
+ assignAlias(
58
+ appId: $appId
59
+ deploymentIdentifier: $deploymentId
60
+ aliasName: $aliasName
61
+ ) {
62
+ id
63
+ ...WorkerDeploymentAliasFragment
64
+ workerDeployment {
65
+ id
66
+ ...WorkerDeploymentFragment
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ ${(0, graphql_1.print)(WorkerDeployment_1.WorkerDeploymentFragmentNode)}
73
+ ${(0, graphql_1.print)(WorkerDeploymentAlias_1.WorkerDeploymentAliasFragmentNode)}
74
+ `, aliasVariables)
75
+ .toPromise());
76
+ return data.deployments.assignAlias;
77
+ },
45
78
  };
@@ -0,0 +1,7 @@
1
+ import type { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
2
+ import { type PaginatedWorkerDeploymentsQueryVariables, SuggestedDevDomainNameQueryVariables, type WorkerDeploymentFragment } from '../graphql/generated';
3
+ import type { Connection } from '../utils/relay';
4
+ export declare const DeploymentsQuery: {
5
+ getAllDeploymentsPaginatedAsync(graphqlClient: ExpoGraphqlClient, { appId, first, after, last, before }: PaginatedWorkerDeploymentsQueryVariables): Promise<Connection<WorkerDeploymentFragment>>;
6
+ getSuggestedDevDomainByAppIdAsync(graphqlClient: ExpoGraphqlClient, { appId }: SuggestedDevDomainNameQueryVariables): Promise<string>;
7
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeploymentsQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql_1 = require("graphql");
6
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
7
+ const WorkerDeployment_1 = require("./fragments/WorkerDeployment");
8
+ const client_1 = require("../graphql/client");
9
+ exports.DeploymentsQuery = {
10
+ async getAllDeploymentsPaginatedAsync(graphqlClient, { appId, first, after, last, before }) {
11
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
12
+ .query((0, graphql_tag_1.default) `
13
+ query PaginatedWorkerDeployments(
14
+ $appId: String!
15
+ $first: Int
16
+ $after: String
17
+ $last: Int
18
+ $before: String
19
+ ) {
20
+ app {
21
+ byId(appId: $appId) {
22
+ id
23
+ workerDeployments(first: $first, after: $after, last: $last, before: $before) {
24
+ pageInfo {
25
+ hasNextPage
26
+ hasPreviousPage
27
+ startCursor
28
+ endCursor
29
+ }
30
+ edges {
31
+ cursor
32
+ node {
33
+ id
34
+ ...WorkerDeploymentFragment
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ${(0, graphql_1.print)(WorkerDeployment_1.WorkerDeploymentFragmentNode)}
42
+ `, { appId, first, after, last, before }, { additionalTypenames: ['WorkerDeployment'] })
43
+ .toPromise());
44
+ return data.app.byId.workerDeployments;
45
+ },
46
+ async getSuggestedDevDomainByAppIdAsync(graphqlClient, { appId }) {
47
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
48
+ .query((0, graphql_tag_1.default) `
49
+ query SuggestedDevDomainName($appId: String!) {
50
+ app {
51
+ byId(appId: $appId) {
52
+ id
53
+ suggestedDevDomainName
54
+ }
55
+ }
56
+ }
57
+ `, { appId }, { additionalTypenames: ['App'] })
58
+ .toPromise());
59
+ return data.app.byId.suggestedDevDomainName;
60
+ },
61
+ };
@@ -0,0 +1,35 @@
1
+ import type { WorkerDeploymentAliasFragment, WorkerDeploymentFragment } from '../../graphql/generated';
2
+ export declare const EXPO_BASE_DOMAIN: string;
3
+ export declare function getDeploymentUrlFromFullName(deploymentFullName: string): string;
4
+ export declare function getDashboardUrl(projectId: string): string;
5
+ type WorkerDeploymentData = {
6
+ /** Used to generate the dashboard URL to `expo.dev` */
7
+ projectId: string;
8
+ /** The actual deployment information */
9
+ deployment: Pick<WorkerDeploymentFragment, 'deploymentIdentifier' | 'url'>;
10
+ /** All modified aliases of the deployment, if any */
11
+ aliases?: WorkerDeploymentAliasFragment[];
12
+ /** The production promoting alias of the deployment, if any */
13
+ production?: WorkerDeploymentAliasFragment | null;
14
+ };
15
+ export declare function formatWorkerDeploymentTable(data: WorkerDeploymentData): string;
16
+ type WorkerDeploymentOutput = {
17
+ /** The absolute URL to the dashboard on `expo.dev` */
18
+ dashboardUrl: string;
19
+ /** The deployment information */
20
+ deployment: {
21
+ identifier: string;
22
+ url: string;
23
+ aliases?: {
24
+ id: string;
25
+ name: string;
26
+ url: string;
27
+ }[];
28
+ production?: {
29
+ id: string;
30
+ url: string;
31
+ };
32
+ };
33
+ };
34
+ export declare function formatWorkerDeploymentJson(data: WorkerDeploymentData): WorkerDeploymentOutput;
35
+ export {};