diff --git a/packages/app-harness/package.json b/packages/app-harness/package.json index 90ce9f3b3..52990216d 100644 --- a/packages/app-harness/package.json +++ b/packages/app-harness/package.json @@ -62,6 +62,7 @@ "react-native-tvos": "0.73.6-0", "react-native-web": "0.19.12", "rn-fetch-blob": "0.12.0" + "dotenv": "16.4.5" }, "devDependencies": { "@flexn/assets-renative-outline": "0.3.5", diff --git a/packages/core/src/engines/index.ts b/packages/core/src/engines/index.ts index c35e5c14b..7e36ad30a 100644 --- a/packages/core/src/engines/index.ts +++ b/packages/core/src/engines/index.ts @@ -90,7 +90,7 @@ export const generateEngineExtensions = (id: string, exts: Array, engine export const configureEngines = async (c: RnvContext) => { logDefault('configureEngines'); - const engines = _getFilteredEngines(c); + const engines = getFilteredEngines(c); const devDependencies = c.files.project.package.devDependencies || {}; c.files.project.package.devDependencies = devDependencies; let needsPackageUpdate = false; @@ -348,7 +348,7 @@ export const loadEnginePackageDeps = async (engineConfigs: Array { +export const getFilteredEngines = (c: RnvContext) => { const engines = c.buildConfig?.engines; if (!engines) { logError('Engine configs missing in your renative.json. FIXING...DONE'); @@ -383,11 +383,11 @@ const _getFilteredEngines = (c: RnvContext) => { return filteredEngines; }; -const getScopedVersion = ( +export const getScopedVersion = ( c: RnvContext, key: string, val: RenativeConfigVersion, - sourceObjKey: 'engineTemplates' | 'plugins' + sourceObjKey: 'engineTemplates' | 'plugins' | 'pluginTemplates' ) => { if (typeof val === 'string') { if (val.startsWith('source:')) { @@ -413,7 +413,7 @@ export const installEngines = async (failOnMissingDeps?: boolean): Promise = _getFilteredEngines(c); + const filteredEngines: Record = getFilteredEngines(c); const enginesToInstall: Array = []; const readyEngines: Array = []; const engineConfigs: Array = []; diff --git a/packages/engine-core/src/tasks/bootstrap/questions/installEngines.ts b/packages/engine-core/src/tasks/bootstrap/questions/installEngines.ts new file mode 100644 index 000000000..13906fcb4 --- /dev/null +++ b/packages/engine-core/src/tasks/bootstrap/questions/installEngines.ts @@ -0,0 +1,123 @@ +import { + RnvEngineInstallConfig, + getFilteredEngines, + executeAsync, + fsExistsSync, + getContext, + getScopedVersion, + isYarnInstalled, + writeFileSync, + readObjectSync, + ConfigFileEngine, + RnvFileName, + getMergedPlugin, + RnvPlugin, + RnvPlatformKey, + inquirerPrompt, +} from '@rnv/core'; +import type { NewProjectData } from '../types'; +import path from 'path'; + +const _mergeDependencies = (target: Record, source?: Record) => { + if (source) { + Object.keys(source).forEach((dep) => { + if (!target[dep]) { + target[dep] = source[dep]; + } + }); + } +}; + +const _isPluginRequired = (plugin: RnvPlugin, supportedPlatforms: Array) => { + if (!plugin.supportedPlatforms) return true; + return plugin.supportedPlatforms.some((platform) => supportedPlatforms.includes(platform)); +}; +const Question = async (data: NewProjectData) => { + const c = getContext(); + + if (!fsExistsSync(c.paths.project.config)) return true; + const { confirmInstallEngines } = await inquirerPrompt({ + name: 'confirmInstallEngines', + type: 'confirm', + message: 'You do not have any engines installed. Do you want to install them now?', + }); + if (!confirmInstallEngines) return true; + + const filteredEngines: Record = getFilteredEngines(c); + const enginesToInstall: Array = []; + const pkg = c.files.project.package; + const devDeps = pkg.devDependencies || {}; + const deps = pkg.dependencies || {}; + pkg.devDependencies = devDeps; + pkg.dependencies = deps; + const supportedPlatforms = data?.inputs?.supportedPlatforms; + + Object.keys(filteredEngines).forEach((k) => { + const engVersion = getScopedVersion(c, k, filteredEngines[k], 'engineTemplates'); + if (engVersion) { + enginesToInstall.push({ + key: k, + version: engVersion, + }); + } + }); + if (enginesToInstall.length) { + const cwd = c.paths.project.dir; + + for (const engine of enginesToInstall) { + const { key, version } = engine; + if (key && version) { + const installCommand = `${isYarnInstalled() ? 'yarn' : 'npm'} add ${key}@${version} --dev`; + await executeAsync(installCommand, { + cwd, + }); + devDeps[key] = version; + + const nmDir = path.join(cwd, 'node_modules'); + const engineConfigPath = path.join(nmDir, key, RnvFileName.renativeEngine); + const engineConfig = readObjectSync(engineConfigPath); + + if (engineConfig && supportedPlatforms) { + supportedPlatforms.forEach((platform) => { + const npmDeps = engineConfig?.platforms?.[platform]?.npm; + if (npmDeps) { + _mergeDependencies(deps, npmDeps.dependencies); + _mergeDependencies(devDeps, npmDeps.devDependencies); + } + }); + if (engineConfig?.npm) { + _mergeDependencies(deps, engineConfig.npm.dependencies); + _mergeDependencies(devDeps, engineConfig.npm.devDependencies); + } + } + } + } + } + + const { plugins } = c.buildConfig; + + if (plugins) { + Object.keys(plugins).forEach((k) => { + const plugin = getMergedPlugin(c, k); + if (!plugin) return; + + const { version } = plugin; + if (supportedPlatforms) { + if ( + plugin.disabled !== true && + plugin.disableNpm !== true && + _isPluginRequired(plugin, supportedPlatforms) + ) { + if (version) { + if (!deps[k]) { + deps[k] = version; + } + } + } + } + }); + } + writeFileSync(c.paths.project.package, c.files.project.package); +}; + +export default Question; diff --git a/packages/engine-core/src/tasks/bootstrap/taskNew.ts b/packages/engine-core/src/tasks/bootstrap/taskNew.ts index a62455ec7..d0e92574a 100644 --- a/packages/engine-core/src/tasks/bootstrap/taskNew.ts +++ b/packages/engine-core/src/tasks/bootstrap/taskNew.ts @@ -24,6 +24,7 @@ import inquiryBookmarkTemplate from './questions/bookmarkTemplate'; import inquiryAppConfigs from './questions/appConfigs'; import inquiryConfigTemplates from './questions/configTemplates'; import inquiryProjectInstall from './questions/installProject'; +import inquiryInstallEngines from './questions/installEngines'; import { configureConfigOverrides, generateProjectOverview, @@ -73,8 +74,10 @@ export default createTask({ await configureTemplateFiles(); await generateLocalJsonSchemas(); await inquiryAppConfigs(payload); + await inquiryInstallEngines(payload); // Telementry await telemetryNewProject(payload); + await inquiryProjectInstall(payload); logToSummary(generateProjectOverview(payload)); diff --git a/packages/engine-rn-tvos/renative.engine.json b/packages/engine-rn-tvos/renative.engine.json index 771ff88e8..65d0cc0aa 100644 --- a/packages/engine-rn-tvos/renative.engine.json +++ b/packages/engine-rn-tvos/renative.engine.json @@ -17,7 +17,9 @@ "tvos": { "engine": "engine-rn-tvos", "npm": { - "devDependencies": {} + "dependencies": { + "dotenv": "16.4.5" + } } } } diff --git a/packages/engine-rn/renative.engine.json b/packages/engine-rn/renative.engine.json index 5d3594a8b..4e8e585cc 100644 --- a/packages/engine-rn/renative.engine.json +++ b/packages/engine-rn/renative.engine.json @@ -14,7 +14,12 @@ }, "platforms": { "ios": { - "engine": "engine-rn" + "engine": "engine-rn", + "npm": { + "dependencies": { + "dotenv": "16.4.5" + } + } }, "macos": { "engine": "engine-rn" diff --git a/packages/template-starter/renative.template.json b/packages/template-starter/renative.template.json index 031f0e3b5..11d6a5804 100644 --- a/packages/template-starter/renative.template.json +++ b/packages/template-starter/renative.template.json @@ -21,7 +21,9 @@ }, { "paths": ["Gemfile", "metro.config.js", ".bundle", "react-native.config.js"], + "platforms": ["ios", "android", "androidwear", "tvos", "firetv", "androidtv"] + }, { "paths": ["next.config.js", "next-env.d.ts", "src/pages"], @@ -29,6 +31,7 @@ }, { "paths": ["webpack.config.js"], + "platforms": [ "windows", "macos", @@ -58,9 +61,7 @@ "@rnv/cli": "1.0.0-rc.19", "@rnv/adapter": "1.0.0-rc.19", "@rnv/config-templates": "1.0.0-rc.19", - "babel-loader": "9.1.3", - "readable-stream": "4.5.2", - "dotenv": "16.4.5" + "babel-loader": "9.1.3" }, "browserslist": { "production": [">0.2%", "not dead", "not op_mini all"], diff --git a/yarn.lock b/yarn.lock index 4186c992e..ec236fabc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9714,16 +9714,16 @@ dotenv-expand@^5.1.0: resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== +dotenv@16.4.5, dotenv@^16.0.3, dotenv@^16.3.1: + version "16.4.5" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + dotenv@^10.0.0, dotenv@~10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== -dotenv@^16.0.3, dotenv@^16.3.1: - version "16.4.5" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" - integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== - dotenv@^9.0.2: version "9.0.2" resolved "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"