UNPKG

@fto-consult/expo-ui

Version:

Bibliothèque de composants UI Expo,react-native

246 lines (242 loc) 9.3 kB
const {exec,thowError,copy,writeFile,createDirSync,FILE:{sanitizeFileName},JSONFileManager} = require("./utils"); const fs = require("fs"), path = require("path"); const getAppDir = x=>path.resolve(__dirname,"create-app"); const mainAppDependencies = require("./create-app/dependencies"); module.exports = function(appName,{projectRoot:root}){ const packageObj = require("../package.json"); root = root && fs.existsSync(root) && root || process.cwd(); let mainPackage = fs.existsSync(path.resolve(root,"package.json")) && require(`${path.resolve(root,"package.json")}`) || null; const name = appName && appName.trim() || mainPackage?.name && typeof mainPackage?.name=="string" && mainPackage.name.trim() || ""; if(!name){ return thowError(name," nom de l'application invalide, veuillez spécifier un nom d'application valide",argvName,process.argv); } root = root && fs.existsSync(path.resolve(root))? path.resolve(root) : process.cwd(); const devDependencies = packageObj.devDependencies; const inSameFolder = typeof mainPackage?.name =="string" && mainPackage?.name.trim().toLowerCase() === name?.toLowerCase().trim(); const projectRoot = path.join(`${root}/${!inSameFolder && name || ""}`); createDirSync(projectRoot); const mainPackagePath = path.join(projectRoot,"package.json"); mainPackage = fs.existsSync(mainPackagePath) && require(`${mainPackagePath}`) || null; let hasPackage = !!mainPackage; const devDeps = { ...defaultDevDependencies, ...(devDependencies && typeof devDependencies ==='object'? devDependencies : {}), }; delete devDeps.expo const euModule = "@fto-consult/expo-ui"; let hasUpdateDeps = false; console.log("creating application name "+name); if(!hasPackage){ mainPackage = { name, version : "1.0.0", "description": "", "main": "App.js", "tablesDataPath": "./src/database/tables", "theme": { "dark" : false, "primary": "#3D8B5F", "secondary": "#354448", "onPrimary" : "white", "onSecondary" : "white" }, "scripts" : { start : "npx expo start -c", "dev" : "npx expo start --no-dev --minify -c", "serve-web" : "npx serve dist --single", "build-web" : "npx expo export -p web", "build-android" : "npx eas build --platform android --profile preview", "build-ios" : "eas build --platform ios", "upgrade" : "npx @fto-consult/expo-ui upgrade", "generate-getTable" : "npx @fto-consult/expo-ui generate-getTable", "update" : "npx @fto-consult/expo-ui update" }, "dependencies" : { [euModule] : packageObj.version, ...mainAppDependencies, }, devDependencies : devDeps } } else { mainPackage.devDependencies = typeof mainPackage.devDependencies =='object' && mainPackage.devDependencies || {}; mainPackage.dependencies = typeof mainPackage.dependencies ==="object" && mainPackage.dependencies || {}; mainPackage.main = mainPackage.main || "node_modules/expo/AppEntry.js"; for(let i in devDeps){ if(!(i in mainPackage.devDependencies)){ hasUpdateDeps = true; mainPackage.devDependencies[i] = devDeps[i]; } } if(!(euModule in mainPackage.dependencies)){ hasUpdateDeps = true; mainPackage.dependencies[euModule] = packageObj?.version; } } if(hasUpdateDeps || !hasPackage || !fs.existsSync(mainPackagePath)){ writeFile(mainPackagePath,JSON.stringify(mainPackage,null,2),{overwrite:true}); } console.log("creating application ....."); ["babel.config.js","metro.config.js"].map((p)=>{ const rP = path.join(projectRoot,p); const pp = path.join(getAppDir(),p); if(!fs.existsSync(rP) && fs.existsSync(pp)){ copy(pp,rP,{overwrite:false}).catch((e)=>{}); } }); createAPPJSONFile(projectRoot,{...mainPackage,name}); createEntryFile(projectRoot); copy(path.resolve(getAppDir(),"src"),path.resolve(projectRoot,"src"),{recursive:true,overwrite:false}); console.log("installing dependencies ..."); return new Promise((resolve,reject)=>{ return exec(`npm install`,{projectRoot}).then(resolve).catch(resolve); }).then(()=>{ return exec('npx expo install --fix',{projectRoot}) }).finally(()=>{ setTimeout(()=>{ console.log("application ready. Please type cd "+name+" and then npx expo start to start your application"); process.exit(); },1000); }); } const defaultDevDependencies = { "@expo/metro-config" : "latest", } const createEntryFile = (projectRoot)=>{ const mainEntry = path.join(projectRoot,"App.js"); if(!fs.existsSync(mainEntry)){ writeFile(mainEntry,fs.readFileSync(path.join(getAppDir(),"App.js"))); return true; } return false; } const createAPPJSONFile = (projectRoot,{name,version})=>{ version = version ||"1.0.0"; copy(path.join(getAppDir(),"assets"),path.resolve(projectRoot,"assets"),{overwrite:false}).catch((e)=>{}); const gP = path.resolve(projectRoot,".gitignore") ; if(!fs.existsSync(gP)){ try { writeFile(gP,gitignore); } catch{}; } const easIgnore = path.resolve(projectRoot,".easignore") ; if(!fs.existsSync(easIgnore)){ try { writeFile(easIgnore,` node_modules/**/* .expo/* npm-debug.* *.jks *.p8 *.p12 *.key *.mobileprovision *.orig.* dist/**/* web-build/**/* web-report/**/* electron/**/* # macOS .DS_Store # Project .tmp/* `); } catch{}; } const imagePluginOptions = { "photosPermission": `Autoriser $(PRODUCT_NAME) à accéder à vos photos.`, "cameraPermission" : `Autoriser $(PRODUCT_NAME) à accéder à votre camera` }, cameraPluginsOptions = { "cameraPermission" : `Autoriser $(PRODUCT_NAME) à accéder à votre camera` } const plugins = [ ["expo-image-picker",imagePluginOptions], ["expo-camera",cameraPluginsOptions], ["expo-document-picker",{"iCloudContainerEnvironment": "Production" }] ]; appSheme = name? sanitizeFileName(name).replace(/ /g, '') : null; const appJSONPath = path.join(projectRoot,"app.json"); if(!fs.existsSync(appJSONPath)){ writeFile(appJSONPath,` { "expo": { "name": "${name}", ${appSheme ? `"scheme": "${appSheme}",`:""} "slug": "${name.toLowerCase().replace(/\s\s+/g, '-')}", "version":"${version}", "orientation": "portrait", "plugins":${JSON.stringify(plugins,null,2)}, "icon": "./assets/icon.png", "jsEngine": "hermes", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "userInterfaceStyle": "automatic", "assetBundlePatterns": [ "**/*" ], "ios": { "supportsTablet": true }, "android": { "blockedPermissions": [], "softwareKeyboardLayoutMode": "pan", "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" } }, "web": { "favicon": "./assets/favicon.png", "bundler": "metro" } } } `) } else { const appJSONManager = JSONFileManager(appJSONPath); if(appSheme && !appJSONManager.hasKey("expo.scheme")){ appJSONManager.set({ "expo": { "scheme":appSheme }, }); } appJSONManager.set({version}) let appPlugins = appJSONManager.get("expo.plugins"); if(!Array.isArray(appPlugins)){ appPlugins = plugins; } else { let hasFoundCamera = false, hasFoundImagePicker = false; appPlugins.map(pl=>{ if(Array.isArray(pl)){ if(typeof pl[0] ==="expo-image-picker"){ hasFoundImagePicker = true; } else if(pl[0] === "expo-camera"){ hasFoundCamera = true; } } }); if(!hasFoundImagePicker){ appPlugins.push(plugins[0]); } if(!hasFoundCamera){ appPlugins.push(plugins[1]); } } appJSONManager.set({ expo : {plugins:appPlugins} }); appJSONManager.save(); } const eas = path.resolve(projectRoot,"eas.json"); const cEas = path.resolve(__dirname,"create-app","eas.json"); if(!fs.existsSync(eas) && fs.existsSync(cEas)){ try { copy(cEas,eas,{overwrite:false}) } catch{} } return fs.existsSync(appJSONPath); } const gitignore = require("./gitignore");