feat(expo): add submit executor (#17372)
This commit is contained in:
parent
2d76993e68
commit
1bc7965278
@ -4808,6 +4808,14 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"isExternal": false,
|
"isExternal": false,
|
||||||
"disableCollapsible": false
|
"disableCollapsible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "submit",
|
||||||
|
"path": "/packages/expo/executors/submit",
|
||||||
|
"name": "submit",
|
||||||
|
"children": [],
|
||||||
|
"isExternal": false,
|
||||||
|
"disableCollapsible": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"isExternal": false,
|
"isExternal": false,
|
||||||
|
|||||||
@ -817,6 +817,15 @@
|
|||||||
"originalFilePath": "/packages/expo/src/executors/export/schema.json",
|
"originalFilePath": "/packages/expo/src/executors/export/schema.json",
|
||||||
"path": "/packages/expo/executors/export",
|
"path": "/packages/expo/executors/export",
|
||||||
"type": "executor"
|
"type": "executor"
|
||||||
|
},
|
||||||
|
"/packages/expo/executors/submit": {
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store",
|
||||||
|
"file": "generated/packages/expo/executors/submit.json",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "submit",
|
||||||
|
"originalFilePath": "/packages/expo/src/executors/submit/schema.json",
|
||||||
|
"path": "/packages/expo/executors/submit",
|
||||||
|
"type": "executor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"generators": {
|
"generators": {
|
||||||
|
|||||||
@ -804,6 +804,15 @@
|
|||||||
"originalFilePath": "/packages/expo/src/executors/export/schema.json",
|
"originalFilePath": "/packages/expo/src/executors/export/schema.json",
|
||||||
"path": "expo/executors/export",
|
"path": "expo/executors/export",
|
||||||
"type": "executor"
|
"type": "executor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store",
|
||||||
|
"file": "generated/packages/expo/executors/submit.json",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "submit",
|
||||||
|
"originalFilePath": "/packages/expo/src/executors/submit/schema.json",
|
||||||
|
"path": "expo/executors/submit",
|
||||||
|
"type": "executor"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"generators": [
|
"generators": [
|
||||||
|
|||||||
@ -10,6 +10,12 @@
|
|||||||
"title": "Expo EAS Build executor",
|
"title": "Expo EAS Build executor",
|
||||||
"description": "Start an EAS build for your expo project.",
|
"description": "Start an EAS build for your expo project.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{ "name": "Build for a specific platform", "keys": ["platform"] },
|
||||||
|
{ "name": "Build using a specific profile", "keys": ["profile"] },
|
||||||
|
{ "name": "Run build locally", "keys": ["local"] },
|
||||||
|
{ "name": "Clear cache before the build", "keys": ["clearCache"] }
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"platform": {
|
"platform": {
|
||||||
"enum": ["ios", "android", "all"],
|
"enum": ["ios", "android", "all"],
|
||||||
@ -28,10 +34,10 @@
|
|||||||
"examples": ["production", "development", "preview"],
|
"examples": ["production", "development", "preview"],
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"nonInteractive": {
|
"interactive": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Run command in non-interactive mode",
|
"description": "Run command in interactive mode",
|
||||||
"default": false
|
"default": true
|
||||||
},
|
},
|
||||||
"local": {
|
"local": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -63,8 +69,7 @@
|
|||||||
"examples": ["production", "development", "preview"]
|
"examples": ["production", "development", "preview"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [],
|
"required": []
|
||||||
"presets": []
|
|
||||||
},
|
},
|
||||||
"description": "Start an EAS build for your expo project",
|
"description": "Start an EAS build for your expo project",
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
"install": {
|
"install": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Installing npm packages and CocoaPods.",
|
"description": "Installing npm packages and CocoaPods.",
|
||||||
"default": false,
|
"default": true,
|
||||||
"x-priority": "internal"
|
"x-priority": "internal"
|
||||||
},
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
|
|||||||
@ -56,7 +56,7 @@
|
|||||||
},
|
},
|
||||||
"install": {
|
"install": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Should install missing dependencies before building.",
|
"description": "Installing npm packages and CocoaPods before building.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"buildCache": {
|
"buildCache": {
|
||||||
|
|||||||
@ -84,6 +84,11 @@
|
|||||||
"offline": {
|
"offline": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Allows this command to run while offline"
|
"description": "Allows this command to run while offline"
|
||||||
|
},
|
||||||
|
"sync": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||||
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"examplesFile": "`project.json`:\n\n```json\n{\n \"name\": \"mobile\",\n //...\n \"targets\": {\n //...\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081\n }\n }\n //...\n }\n}\n```\n\n```shell\nnx run mobile:start\n```\n\n## Examples\n\n{% tabs %}\n{% tab label=\"Specify starting on platform\" %}\nThe `ios`, `android` and `web` option allows you to start the server on different platforms.\n\nOpens your app in Expo Go in a currently running iOS simulator on your computer:\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"ios\": true\n }\n }\n```\n\nOpens your app in Expo Go on a connected Android device\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"android\": true\n }\n }\n```\n\nOpens your app in a web browser:\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"web\": true\n }\n }\n```\n\n{% /tab %}\n{% tab label=\"Specify the host\" %}\nThe `host` option allows you to specify the type of host to use. `lan` uses the local network; `tunnel` ues any network by tunnel through ngrok; `localhost` connects to the dev server over localhost.\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"host\": \"localhost\"\n }\n }\n```\n\n{% /tab %}\n{% tab label=\"Starts the server with cache reset\" %}\n\nThe `clear` option allows you to remove Metro bundler cache.\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"clear\": true\n }\n }\n```\n\n{% /tab %}\n{% /tabs %}\n\n---\n",
|
"examplesFile": "`project.json`:\n\n```json\n{\n \"name\": \"mobile\",\n //...\n \"targets\": {\n //...\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081\n }\n }\n //...\n }\n}\n```\n\n```shell\nnx run mobile:start\n```\n\n## Examples\n\n{% tabs %}\n{% tab label=\"Specify starting on platform\" %}\nThe `ios`, `android` and `web` option allows you to start the server on different platforms.\n\nOpens your app in Expo Go in a currently running iOS simulator on your computer:\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"ios\": true\n }\n }\n```\n\nOpens your app in Expo Go on a connected Android device\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"android\": true\n }\n }\n```\n\nOpens your app in a web browser:\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"web\": true\n }\n }\n```\n\n{% /tab %}\n{% tab label=\"Specify the host\" %}\nThe `host` option allows you to specify the type of host to use. `lan` uses the local network; `tunnel` ues any network by tunnel through ngrok; `localhost` connects to the dev server over localhost.\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"host\": \"localhost\"\n }\n }\n```\n\n{% /tab %}\n{% tab label=\"Starts the server with cache reset\" %}\n\nThe `clear` option allows you to remove Metro bundler cache.\n\n```json\n \"start\": {\n \"executor\": \"@nx/expo:start\",\n \"options\": {\n \"port\": 8081,\n \"clear\": true\n }\n }\n```\n\n{% /tab %}\n{% /tabs %}\n\n---\n",
|
||||||
|
|||||||
57
docs/generated/packages/expo/executors/submit.json
Normal file
57
docs/generated/packages/expo/executors/submit.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"name": "submit",
|
||||||
|
"implementation": "/packages/expo/src/executors/submit/submit.impl.ts",
|
||||||
|
"schema": {
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"version": 2,
|
||||||
|
"title": "EXPO EAS Submit Executor",
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store.",
|
||||||
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{ "name": "Submit for a specific platform", "keys": ["platform"] },
|
||||||
|
{ "name": "Submit using a specific profile", "keys": ["profile"] }
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"profile": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the build profile from eas.json. Defaults to \"production\" if defined in eas.json.",
|
||||||
|
"examples": ["production", "development", "preview"],
|
||||||
|
"x-priority": "important"
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"enum": ["ios", "android", "all"],
|
||||||
|
"alias": "p",
|
||||||
|
"description": "The platform to build the app, example values: ios, android, all.",
|
||||||
|
"x-priority": "important"
|
||||||
|
},
|
||||||
|
"id": { "type": "string", "description": "Build ID to submit" },
|
||||||
|
"path": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the .apk/.aab/.ipa file"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "URL to the .apk/.aab/.ipa file, app archive url"
|
||||||
|
},
|
||||||
|
"latest": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Submit the latest build for specified platform"
|
||||||
|
},
|
||||||
|
"interactive": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Run command in interactive mode",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"wait": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Wait for build(s) to complete",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store",
|
||||||
|
"aliases": [],
|
||||||
|
"hidden": false,
|
||||||
|
"path": "/packages/expo/src/executors/submit/schema.json",
|
||||||
|
"type": "executor"
|
||||||
|
}
|
||||||
@ -10,6 +10,10 @@
|
|||||||
"title": "Expo EAS Update executor",
|
"title": "Expo EAS Update executor",
|
||||||
"description": "Start an EAS update for your expo project.",
|
"description": "Start an EAS update for your expo project.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{ "name": "Update for a specific platform", "keys": ["platform"] },
|
||||||
|
{ "name": "Update from a specific branch", "keys": ["branch"] }
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"branch": {
|
"branch": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -52,14 +56,13 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named \"private-key.pem\" in the certificate's directory."
|
"description": "File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named \"private-key.pem\" in the certificate's directory."
|
||||||
},
|
},
|
||||||
"nonInteractive": {
|
"interactive": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Run command in non-interactive mode",
|
"description": "Run command in interactive mode",
|
||||||
"default": false
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [],
|
"required": []
|
||||||
"presets": []
|
|
||||||
},
|
},
|
||||||
"description": "Start an EAS update for your expo project",
|
"description": "Start an EAS update for your expo project",
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
@ -54,6 +54,11 @@
|
|||||||
"implementation": "./src/executors/export/export.impl",
|
"implementation": "./src/executors/export/export.impl",
|
||||||
"schema": "./src/executors/export/schema.json",
|
"schema": "./src/executors/export/schema.json",
|
||||||
"description": "Export the JavaScript and assets for your app using Metro/webpack bundler"
|
"description": "Export the JavaScript and assets for your app using Metro/webpack bundler"
|
||||||
|
},
|
||||||
|
"submit": {
|
||||||
|
"implementation": "./src/executors/submit/submit.impl",
|
||||||
|
"schema": "./src/executors/submit/schema.json",
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"builders": {
|
"builders": {
|
||||||
@ -111,6 +116,11 @@
|
|||||||
"implementation": "./src/executors/export/compat",
|
"implementation": "./src/executors/export/compat",
|
||||||
"schema": "./src/executors/export/schema.json",
|
"schema": "./src/executors/export/schema.json",
|
||||||
"description": "Export the JavaScript and assets for your app using Metro/webpack bundler"
|
"description": "Export the JavaScript and assets for your app using Metro/webpack bundler"
|
||||||
|
},
|
||||||
|
"submit": {
|
||||||
|
"implementation": "./src/executors/submit/compat",
|
||||||
|
"schema": "./src/executors/submit/schema.json",
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -817,6 +817,27 @@
|
|||||||
"alwaysAddToPackageJson": false
|
"alwaysAddToPackageJson": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"16.2.2": {
|
||||||
|
"version": "16.2.2-beta.0",
|
||||||
|
"packages": {
|
||||||
|
"expo": {
|
||||||
|
"version": "^48.0.17",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"eas-cli": {
|
||||||
|
"version": "~3.13.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"version": "0.71.8",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@types/react-native": {
|
||||||
|
"version": "0.71.7",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
"@nx/webpack": "file:../webpack"
|
"@nx/webpack": "file:../webpack"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"expo": "^48.0.16"
|
"expo": "^48.0.17"
|
||||||
},
|
},
|
||||||
"builders": "./executors.json",
|
"builders": "./executors.json",
|
||||||
"ng-update": {
|
"ng-update": {
|
||||||
|
|||||||
@ -81,6 +81,11 @@ function createBuildOptions(options: ExpoEasBuildOptions) {
|
|||||||
return Object.keys(options).reduce((acc, k) => {
|
return Object.keys(options).reduce((acc, k) => {
|
||||||
const v = options[k];
|
const v = options[k];
|
||||||
if (typeof v === 'boolean') {
|
if (typeof v === 'boolean') {
|
||||||
|
if (k === 'interactive') {
|
||||||
|
if (v === false) {
|
||||||
|
acc.push('--non-interactive'); // when is false, the flag is --non-interactive
|
||||||
|
}
|
||||||
|
}
|
||||||
if (v === true) {
|
if (v === true) {
|
||||||
// when true, does not need to pass the value true, just need to pass the flag in kebob case
|
// when true, does not need to pass the value true, just need to pass the flag in kebob case
|
||||||
acc.push(`--${names(k).fileName}`);
|
acc.push(`--${names(k).fileName}`);
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
export interface ExpoEasBuildOptions {
|
export interface ExpoEasBuildOptions {
|
||||||
platform: 'ios' | 'android' | 'all';
|
platform: 'ios' | 'android' | 'all';
|
||||||
profile?: string;
|
profile?: string;
|
||||||
nonInteractive: boolean; // default is false
|
interactive: boolean; // default is true
|
||||||
local: boolean; // default is false
|
local: boolean; // default is false
|
||||||
output?: string;
|
output?: string;
|
||||||
wait: boolean; // default is true
|
wait: boolean; // default is true
|
||||||
|
|||||||
@ -7,6 +7,24 @@
|
|||||||
"title": "Expo EAS Build executor",
|
"title": "Expo EAS Build executor",
|
||||||
"description": "Start an EAS build for your expo project.",
|
"description": "Start an EAS build for your expo project.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{
|
||||||
|
"name": "Build for a specific platform",
|
||||||
|
"keys": ["platform"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Build using a specific profile",
|
||||||
|
"keys": ["profile"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Run build locally",
|
||||||
|
"keys": ["local"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Clear cache before the build",
|
||||||
|
"keys": ["clearCache"]
|
||||||
|
}
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"platform": {
|
"platform": {
|
||||||
"enum": ["ios", "android", "all"],
|
"enum": ["ios", "android", "all"],
|
||||||
@ -25,10 +43,10 @@
|
|||||||
"examples": ["production", "development", "preview"],
|
"examples": ["production", "development", "preview"],
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"nonInteractive": {
|
"interactive": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Run command in non-interactive mode",
|
"description": "Run command in interactive mode",
|
||||||
"default": false
|
"default": true
|
||||||
},
|
},
|
||||||
"local": {
|
"local": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -25,12 +25,10 @@ export default async function* prebuildExecutor(
|
|||||||
await prebuildAsync(context.root, projectRoot, options);
|
await prebuildAsync(context.root, projectRoot, options);
|
||||||
|
|
||||||
if (options.install) {
|
if (options.install) {
|
||||||
await installAsync(context.root, { fix: true });
|
await installAsync(context.root, {});
|
||||||
if (options.platform === 'ios') {
|
if (options.platform === 'ios') {
|
||||||
await podInstall(join(context.root, projectRoot, 'ios'));
|
await podInstall(join(context.root, projectRoot, 'ios'));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
await installAsync(context.root, {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
yield {
|
yield {
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
"install": {
|
"install": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Installing npm packages and CocoaPods.",
|
"description": "Installing npm packages and CocoaPods.",
|
||||||
"default": false,
|
"default": true,
|
||||||
"x-priority": "internal"
|
"x-priority": "internal"
|
||||||
},
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
|
|||||||
@ -49,17 +49,12 @@ export default async function* runExecutor(
|
|||||||
clean: options.clean,
|
clean: options.clean,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.install) {
|
if (options.install) {
|
||||||
await installAsync(context.root, {
|
await installAsync(context.root, {});
|
||||||
fix: true,
|
|
||||||
});
|
|
||||||
if (options.platform === 'ios') {
|
if (options.platform === 'ios') {
|
||||||
await podInstall(join(context.root, projectRoot, 'ios'));
|
await podInstall(join(context.root, projectRoot, 'ios'));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
await installAsync(context.root, {
|
|
||||||
check: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
},
|
},
|
||||||
"install": {
|
"install": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Should install missing dependencies before building.",
|
"description": "Installing npm packages and CocoaPods before building.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"buildCache": {
|
"buildCache": {
|
||||||
|
|||||||
@ -19,4 +19,7 @@ export interface ExpoStartOptions {
|
|||||||
localhost?: boolean;
|
localhost?: boolean;
|
||||||
tunnel?: boolean;
|
tunnel?: boolean;
|
||||||
offline?: boolean;
|
offline?: boolean;
|
||||||
|
|
||||||
|
// nx options
|
||||||
|
sync?: boolean; // default is true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,6 +87,11 @@
|
|||||||
"offline": {
|
"offline": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Allows this command to run while offline"
|
"description": "Allows this command to run while offline"
|
||||||
|
},
|
||||||
|
"sync": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||||
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"examplesFile": "../../../docs/start-examples.md"
|
"examplesFile": "../../../docs/start-examples.md"
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import { join } from 'path';
|
|||||||
|
|
||||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||||
import { ExpoStartOptions } from './schema';
|
import { ExpoStartOptions } from './schema';
|
||||||
|
import {
|
||||||
|
displayNewlyAddedDepsMessage,
|
||||||
|
syncDeps,
|
||||||
|
} from '../sync-deps/sync-deps.impl';
|
||||||
|
|
||||||
export interface ExpoStartOutput {
|
export interface ExpoStartOutput {
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
@ -20,6 +24,17 @@ export default async function* startExecutor(
|
|||||||
const projectRoot =
|
const projectRoot =
|
||||||
context.projectsConfigurations.projects[context.projectName].root;
|
context.projectsConfigurations.projects[context.projectName].root;
|
||||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||||
|
if (options.sync) {
|
||||||
|
displayNewlyAddedDepsMessage(
|
||||||
|
context.projectName,
|
||||||
|
await syncDeps(
|
||||||
|
context.projectName,
|
||||||
|
projectRoot,
|
||||||
|
context.root,
|
||||||
|
context.projectGraph
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const baseUrl = `http://localhost:${options.port}`;
|
const baseUrl = `http://localhost:${options.port}`;
|
||||||
@ -68,12 +83,16 @@ function startAsync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/index.ts
|
// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/index.ts
|
||||||
|
const nxOptions = ['sync'];
|
||||||
function createStartOptions(options: ExpoStartOptions) {
|
function createStartOptions(options: ExpoStartOptions) {
|
||||||
return Object.keys(options).reduce((acc, k) => {
|
return Object.keys(options).reduce((acc, k) => {
|
||||||
|
if (nxOptions.includes(k)) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
const v = options[k];
|
const v = options[k];
|
||||||
if (k === 'dev') {
|
if (k === 'dev') {
|
||||||
if (v === false) {
|
if (v === false) {
|
||||||
acc.push(`--no-dev`);
|
acc.push(`--no-dev`); // only no-dev flag is supported
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (typeof v === 'boolean') {
|
if (typeof v === 'boolean') {
|
||||||
|
|||||||
5
packages/expo/src/executors/submit/compat.ts
Normal file
5
packages/expo/src/executors/submit/compat.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { convertNxExecutor } from '@nx/devkit';
|
||||||
|
|
||||||
|
import submitExecutor from './submit.impl';
|
||||||
|
|
||||||
|
export default convertNxExecutor(submitExecutor);
|
||||||
12
packages/expo/src/executors/submit/schema.d.ts
vendored
Normal file
12
packages/expo/src/executors/submit/schema.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// command to run https://github.com/expo/eas-cli/tree/main#eas-submit
|
||||||
|
// options from https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/commands/submit.ts
|
||||||
|
export interface SubmitExecutorSchema {
|
||||||
|
profile?: string;
|
||||||
|
platform?: 'ios' | 'android' | 'all';
|
||||||
|
id?: string;
|
||||||
|
latest?: boolean;
|
||||||
|
interactive: boolean; // default is true
|
||||||
|
path?: string;
|
||||||
|
url?: string;
|
||||||
|
wait: boolean; // default is true
|
||||||
|
}
|
||||||
57
packages/expo/src/executors/submit/schema.json
Normal file
57
packages/expo/src/executors/submit/schema.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"version": 2,
|
||||||
|
"title": "EXPO EAS Submit Executor",
|
||||||
|
"description": "Submit app binary to App Store and/or Play Store.",
|
||||||
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{
|
||||||
|
"name": "Submit for a specific platform",
|
||||||
|
"keys": ["platform"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Submit using a specific profile",
|
||||||
|
"keys": ["profile"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"profile": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the build profile from eas.json. Defaults to \"production\" if defined in eas.json.",
|
||||||
|
"examples": ["production", "development", "preview"],
|
||||||
|
"x-priority": "important"
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"enum": ["ios", "android", "all"],
|
||||||
|
"alias": "p",
|
||||||
|
"description": "The platform to build the app, example values: ios, android, all.",
|
||||||
|
"x-priority": "important"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Build ID to submit"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the .apk/.aab/.ipa file"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "URL to the .apk/.aab/.ipa file, app archive url"
|
||||||
|
},
|
||||||
|
"latest": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Submit the latest build for specified platform"
|
||||||
|
},
|
||||||
|
"interactive": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Run command in interactive mode",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"wait": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Wait for build(s) to complete",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
packages/expo/src/executors/submit/submit.impl.ts
Normal file
89
packages/expo/src/executors/submit/submit.impl.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { ExecutorContext, names } from '@nx/devkit';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { ChildProcess, fork } from 'child_process';
|
||||||
|
|
||||||
|
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||||
|
|
||||||
|
import { SubmitExecutorSchema } from './schema';
|
||||||
|
|
||||||
|
export interface ReactNativeSubmitOutput {
|
||||||
|
success: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
let childProcess: ChildProcess;
|
||||||
|
|
||||||
|
export default async function* submitExecutor(
|
||||||
|
options: SubmitExecutorSchema,
|
||||||
|
context: ExecutorContext
|
||||||
|
): AsyncGenerator<ReactNativeSubmitOutput> {
|
||||||
|
const projectRoot =
|
||||||
|
context.projectsConfigurations.projects[context.projectName].root;
|
||||||
|
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await runCliSubmit(context.root, projectRoot, options);
|
||||||
|
|
||||||
|
yield { success: true };
|
||||||
|
} finally {
|
||||||
|
if (childProcess) {
|
||||||
|
childProcess.kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCliSubmit(
|
||||||
|
workspaceRoot: string,
|
||||||
|
projectRoot: string,
|
||||||
|
options: SubmitExecutorSchema
|
||||||
|
) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
childProcess = fork(
|
||||||
|
join(workspaceRoot, './node_modules/eas-cli/bin/run'),
|
||||||
|
['submit', ...createSubmitOptions(options)],
|
||||||
|
{
|
||||||
|
cwd: join(workspaceRoot, projectRoot),
|
||||||
|
env: process.env,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure the child process is killed when the parent exits
|
||||||
|
process.on('exit', () => childProcess.kill());
|
||||||
|
process.on('SIGTERM', () => childProcess.kill());
|
||||||
|
|
||||||
|
childProcess.on('error', (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
childProcess.on('exit', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve(code);
|
||||||
|
} else {
|
||||||
|
reject(code);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSubmitOptions(options: SubmitExecutorSchema) {
|
||||||
|
return Object.keys(options).reduce((acc, k) => {
|
||||||
|
const v = options[k];
|
||||||
|
if (typeof v === 'boolean') {
|
||||||
|
if (k === 'interactive') {
|
||||||
|
if (v === false) {
|
||||||
|
acc.push('--non-interactive'); // when is false, the flag is --non-interactive
|
||||||
|
}
|
||||||
|
} else if (k === 'wait') {
|
||||||
|
if (v === false) {
|
||||||
|
acc.push('--no-wait'); // when is false, the flag is --no-wait
|
||||||
|
} else {
|
||||||
|
acc.push('--wait');
|
||||||
|
}
|
||||||
|
} else if (v === true) {
|
||||||
|
// when true, does not need to pass the value true, just need to pass the flag in kebob case
|
||||||
|
acc.push(`--${names(k).fileName}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
acc.push(`--${names(k).fileName}`, v);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
@ -11,5 +11,5 @@ export interface ExpoEasUpdateOptions {
|
|||||||
json: boolean; // default is false
|
json: boolean; // default is false
|
||||||
auto: boolean; // default is false
|
auto: boolean; // default is false
|
||||||
privateKeyPath?: string;
|
privateKeyPath?: string;
|
||||||
nonInteractive: boolean; // default is false
|
interactive: boolean; // default is false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,16 @@
|
|||||||
"title": "Expo EAS Update executor",
|
"title": "Expo EAS Update executor",
|
||||||
"description": "Start an EAS update for your expo project.",
|
"description": "Start an EAS update for your expo project.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"presets": [
|
||||||
|
{
|
||||||
|
"name": "Update for a specific platform",
|
||||||
|
"keys": ["platform"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Update from a specific branch",
|
||||||
|
"keys": ["branch"]
|
||||||
|
}
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"branch": {
|
"branch": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -55,10 +65,10 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named \"private-key.pem\" in the certificate's directory."
|
"description": "File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named \"private-key.pem\" in the certificate's directory."
|
||||||
},
|
},
|
||||||
"nonInteractive": {
|
"interactive": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Run command in non-interactive mode",
|
"description": "Run command in interactive mode",
|
||||||
"default": false
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
|
|||||||
@ -5,6 +5,11 @@ import { ChildProcess, fork } from 'child_process';
|
|||||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||||
|
|
||||||
import { ExpoEasUpdateOptions } from './schema';
|
import { ExpoEasUpdateOptions } from './schema';
|
||||||
|
import {
|
||||||
|
displayNewlyAddedDepsMessage,
|
||||||
|
syncDeps,
|
||||||
|
} from '../sync-deps/sync-deps.impl';
|
||||||
|
import { installAsync } from '../install/install.impl';
|
||||||
|
|
||||||
export interface ReactNativeUpdateOutput {
|
export interface ReactNativeUpdateOutput {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
@ -18,6 +23,17 @@ export default async function* buildExecutor(
|
|||||||
): AsyncGenerator<ReactNativeUpdateOutput> {
|
): AsyncGenerator<ReactNativeUpdateOutput> {
|
||||||
const projectRoot =
|
const projectRoot =
|
||||||
context.projectsConfigurations.projects[context.projectName].root;
|
context.projectsConfigurations.projects[context.projectName].root;
|
||||||
|
await installAsync(context.root, { packages: ['expo-updates'] });
|
||||||
|
displayNewlyAddedDepsMessage(
|
||||||
|
context.projectName,
|
||||||
|
await syncDeps(
|
||||||
|
context.projectName,
|
||||||
|
projectRoot,
|
||||||
|
context.root,
|
||||||
|
context.projectGraph,
|
||||||
|
['expo-updates']
|
||||||
|
)
|
||||||
|
);
|
||||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -63,7 +79,11 @@ function createUpdateOptions(options: ExpoEasUpdateOptions) {
|
|||||||
return Object.keys(options).reduce((acc, k) => {
|
return Object.keys(options).reduce((acc, k) => {
|
||||||
const v = options[k];
|
const v = options[k];
|
||||||
if (typeof v === 'boolean') {
|
if (typeof v === 'boolean') {
|
||||||
if (v === true) {
|
if (k === 'interactive') {
|
||||||
|
if (v === false) {
|
||||||
|
acc.push('--non-interactive');
|
||||||
|
}
|
||||||
|
} else if (v === true) {
|
||||||
// when true, does not need to pass the value true, just need to pass the flag in kebob case
|
// when true, does not need to pass the value true, just need to pass the flag in kebob case
|
||||||
acc.push(`--${names(k).fileName}`);
|
acc.push(`--${names(k).fileName}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,11 @@ function getTargets(options: NormalizedSchema) {
|
|||||||
options: {},
|
options: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
architect['submit'] = {
|
||||||
|
executor: '@nx/expo:submit',
|
||||||
|
options: {},
|
||||||
|
};
|
||||||
|
|
||||||
architect['build-list'] = {
|
architect['build-list'] = {
|
||||||
executor: '@nx/expo:build-list',
|
executor: '@nx/expo:build-list',
|
||||||
options: {},
|
options: {},
|
||||||
|
|||||||
@ -12,7 +12,10 @@ export default async function update(tree: Tree) {
|
|||||||
const projects = getProjects(tree);
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
for (const [name, config] of projects.entries()) {
|
||||||
if (config.targets?.['start']?.executor === '@nrwl/expo:start') {
|
if (
|
||||||
|
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
||||||
|
config.targets?.['start']?.executor === '@nx/expo:start'
|
||||||
|
) {
|
||||||
const jestConfigPath = config.targets?.test?.options?.jestConfig;
|
const jestConfigPath = config.targets?.test?.options?.jestConfig;
|
||||||
if (!jestConfigPath || !tree.exists(jestConfigPath)) return;
|
if (!jestConfigPath || !tree.exists(jestConfigPath)) return;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -12,7 +12,10 @@ export default async function update(tree: Tree) {
|
|||||||
const projects = getProjects(tree);
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
for (const [name, config] of projects.entries()) {
|
||||||
if (config.targets?.['start']?.executor === '@nrwl/expo:start') {
|
if (
|
||||||
|
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
||||||
|
config.targets?.['start']?.executor === '@nx/expo:start'
|
||||||
|
) {
|
||||||
const targetsToDelete = [
|
const targetsToDelete = [
|
||||||
'build-ios',
|
'build-ios',
|
||||||
'build-android',
|
'build-android',
|
||||||
@ -28,9 +31,8 @@ export default async function update(tree: Tree) {
|
|||||||
delete config.targets[target];
|
delete config.targets[target];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
updateProjectConfiguration(tree, name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProjectConfiguration(tree, name, config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await formatFiles(tree);
|
await formatFiles(tree);
|
||||||
|
|||||||
@ -7,7 +7,10 @@ export default async function update(tree: Tree) {
|
|||||||
const projects = getProjects(tree);
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
projects.forEach((config) => {
|
projects.forEach((config) => {
|
||||||
if (config.targets?.['start']?.executor === '@nrwl/expo:start') {
|
if (
|
||||||
|
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
||||||
|
config.targets?.['start']?.executor === '@nx/expo:start'
|
||||||
|
) {
|
||||||
updateJson(tree, `${config.root}/app.json`, (json) => {
|
updateJson(tree, `${config.root}/app.json`, (json) => {
|
||||||
if (!json.expo.plugins) {
|
if (!json.expo.plugins) {
|
||||||
json.expo.plugins = [];
|
json.expo.plugins = [];
|
||||||
|
|||||||
@ -22,7 +22,10 @@ export default function update(tree: Tree) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
for (const [name, config] of projects.entries()) {
|
||||||
if (config.targets?.['start']?.executor === '@nrwl/expo:start') {
|
if (
|
||||||
|
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
||||||
|
config.targets?.['start']?.executor === '@nx/expo:start'
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
addEasScripts(tree);
|
addEasScripts(tree);
|
||||||
updateJson(tree, join(config.root, 'package.json'), (packageJson) => {
|
updateJson(tree, join(config.root, 'package.json'), (packageJson) => {
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
import { addProjectConfiguration, getProjects, Tree } from '@nx/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||||
|
import update from './add-submit-target';
|
||||||
|
|
||||||
|
describe('add-submit-target', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||||
|
addProjectConfiguration(tree, 'product', {
|
||||||
|
root: 'apps/product',
|
||||||
|
sourceRoot: 'apps/product/src',
|
||||||
|
targets: {
|
||||||
|
start: {
|
||||||
|
executor: '@nx/expo:start',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should update project.json with target submit`, async () => {
|
||||||
|
await update(tree);
|
||||||
|
|
||||||
|
getProjects(tree).forEach((project) => {
|
||||||
|
expect(project.targets['submit']).toEqual({
|
||||||
|
executor: '@nx/expo:submit',
|
||||||
|
options: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import {
|
||||||
|
Tree,
|
||||||
|
formatFiles,
|
||||||
|
getProjects,
|
||||||
|
updateProjectConfiguration,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new submit target
|
||||||
|
*/
|
||||||
|
export default async function update(tree: Tree) {
|
||||||
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
|
for (const [name, config] of projects.entries()) {
|
||||||
|
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
||||||
|
if (!config.targets['submit']) {
|
||||||
|
config.targets['submit'] = {
|
||||||
|
executor: '@nx/expo:submit',
|
||||||
|
options: {},
|
||||||
|
};
|
||||||
|
updateProjectConfiguration(tree, name, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
export const nxVersion = require('../../package.json').version;
|
export const nxVersion = require('../../package.json').version;
|
||||||
|
|
||||||
export const expoVersion = '48.0.16';
|
export const expoVersion = '48.0.17';
|
||||||
export const expoMetroConfigVersion = '0.7.1';
|
export const expoMetroConfigVersion = '0.7.1';
|
||||||
export const expoSplashScreenVersion = '~0.18.2';
|
export const expoSplashScreenVersion = '~0.18.2';
|
||||||
export const expoStatusBarVersion = '~1.4.4';
|
export const expoStatusBarVersion = '~1.4.4';
|
||||||
|
export const expoUpdatesVersion = '~0.16.4';
|
||||||
export const expoCliVersion = '~0.7.1'; // @expo/cli
|
export const expoCliVersion = '~0.7.1'; // @expo/cli
|
||||||
export const easCliVersion = '~3.12.0';
|
export const easCliVersion = '~3.13.2';
|
||||||
export const babelPresetExpoVersion = '~9.3.2';
|
export const babelPresetExpoVersion = '~9.3.2';
|
||||||
|
|
||||||
export const reactVersion = '18.2.0';
|
export const reactVersion = '18.2.0';
|
||||||
@ -13,8 +14,8 @@ export const reactDomVersion = '18.2.0';
|
|||||||
export const reactTestRendererVersion = '18.2.0';
|
export const reactTestRendererVersion = '18.2.0';
|
||||||
export const typesReactVersion = '18.0.28';
|
export const typesReactVersion = '18.0.28';
|
||||||
|
|
||||||
export const reactNativeVersion = '0.71.7';
|
export const reactNativeVersion = '0.71.8';
|
||||||
export const typesReactNativeVersion = '0.71.6';
|
export const typesReactNativeVersion = '0.71.7';
|
||||||
export const reactNativeWebVersion = '~0.18.12';
|
export const reactNativeWebVersion = '~0.18.12';
|
||||||
|
|
||||||
export const reactNativeSvgTransformerVersion = '1.0.0';
|
export const reactNativeSvgTransformerVersion = '1.0.0';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ExecutorContext, logger, names } from '@nx/devkit';
|
import { ExecutorContext } from '@nx/devkit';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { ChildProcess, fork } from 'child_process';
|
import { ChildProcess, fork } from 'child_process';
|
||||||
import { platform } from 'os';
|
import { platform } from 'os';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user