diff --git a/.npmrc b/.npmrc deleted file mode 100644 index cfcb8e31b..000000000 --- a/.npmrc +++ /dev/null @@ -1,5 +0,0 @@ -# Expo doesn't play nice with pnpm by default. -# The symbolic links of pnpm break the rules of Expo monorepos. -# @link https://docs.expo.dev/guides/monorepos/#common-issues -node-linker=hoisted -strict-peer-dependencies=false diff --git a/.vscode/settings.json b/.vscode/settings.json index 3526263c8..2797d923d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { - "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }], @@ -12,7 +14,7 @@ ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] ], - "tailwindCSS.experimental.configFile": "./tooling/tailwind/index.ts", + "tailwindCSS.experimental.configFile": "./tooling/tailwind/web.ts", "typescript.enablePromptUseWorkspaceTsdk": true, "typescript.preferences.autoImportFileExcludePatterns": [ "next/router.d.ts", diff --git a/apps/auth-proxy/package.json b/apps/auth-proxy/package.json index df729bee0..4d466534a 100644 --- a/apps/auth-proxy/package.json +++ b/apps/auth-proxy/package.json @@ -11,14 +11,16 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@auth/core": "0.24.0" + "@auth/core": "0.20.0" }, "devDependencies": { "@acme/eslint-config": "workspace:^0.2.0", "@acme/prettier-config": "workspace:^0.1.0", "@acme/tailwind-config": "workspace:^0.1.0", "@acme/tsconfig": "workspace:^0.1.0", + "@types/node": "^20.10.6", "eslint": "^8.56.0", + "h3": "^1.9.0", "nitropack": "^2.8.1", "prettier": "^3.1.1", "typescript": "^5.3.3" diff --git a/apps/expo/app.config.ts b/apps/expo/app.config.ts index f6c21c940..d0556be13 100644 --- a/apps/expo/app.config.ts +++ b/apps/expo/app.config.ts @@ -1,4 +1,4 @@ -import type { ExpoConfig } from "@expo/config"; +import type { ExpoConfig } from "expo/config"; const defineConfig = (): ExpoConfig => ({ name: "expo", @@ -7,7 +7,7 @@ const defineConfig = (): ExpoConfig => ({ version: "0.1.0", orientation: "portrait", icon: "./assets/icon.png", - userInterfaceStyle: "light", + userInterfaceStyle: "automatic", splash: { image: "./assets/icon.png", resizeMode: "contain", @@ -37,7 +37,7 @@ const defineConfig = (): ExpoConfig => ({ tsconfigPaths: true, typedRoutes: true, }, - plugins: ["expo-router", "./expo-plugins/with-modify-gradle.js"], + plugins: ["expo-router"], }); export default defineConfig; diff --git a/apps/expo/babel.config.js b/apps/expo/babel.config.js index 143cb0858..582ef1a45 100644 --- a/apps/expo/babel.config.js +++ b/apps/expo/babel.config.js @@ -1,15 +1,11 @@ /** @type {import("@babel/core").ConfigFunction} */ module.exports = function (api) { - api.cache.forever(); - + api.cache(true); return { presets: [ ["babel-preset-expo", { jsxImportSource: "nativewind" }], "nativewind/babel", ], - plugins: [ - require.resolve("expo-router/babel"), - require.resolve("react-native-reanimated/plugin"), - ], + plugins: ["react-native-reanimated/plugin"], }; }; diff --git a/apps/expo/expo-plugins/with-modify-gradle.js b/apps/expo/expo-plugins/with-modify-gradle.js deleted file mode 100644 index 343c579b3..000000000 --- a/apps/expo/expo-plugins/with-modify-gradle.js +++ /dev/null @@ -1,44 +0,0 @@ -// This plugin is required for fixing `.apk` build issue -// It appends Expo and RN versions into the `build.gradle` file -// References: -// https://github.com/t3-oss/create-t3-turbo/issues/120 -// https://github.com/expo/expo/issues/18129 - -/** @type {import("@expo/config-plugins").ConfigPlugin} */ -const defineConfig = (config) => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - return require("@expo/config-plugins").withProjectBuildGradle( - config, - (config) => { - if (!config.modResults.contents.includes("ext.getPackageJsonVersion =")) { - config.modResults.contents = config.modResults.contents.replace( - "buildscript {", - `buildscript { - ext.getPackageJsonVersion = { packageName -> - new File(['node', '--print', "JSON.parse(require('fs').readFileSync(require.resolve('\${packageName}/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim()) - }`, - ); - } - - if (!config.modResults.contents.includes("reactNativeVersion =")) { - config.modResults.contents = config.modResults.contents.replace( - "ext {", - `ext { - reactNativeVersion = "\${ext.getPackageJsonVersion('react-native')}"`, - ); - } - - if (!config.modResults.contents.includes("expoPackageVersion =")) { - config.modResults.contents = config.modResults.contents.replace( - "ext {", - `ext { - expoPackageVersion = "\${ext.getPackageJsonVersion('expo')}"`, - ); - } - - return config; - }, - ); -}; - -module.exports = defineConfig; diff --git a/apps/expo/metro.config.js b/apps/expo/metro.config.js index 3754383a1..4944183bc 100644 --- a/apps/expo/metro.config.js +++ b/apps/expo/metro.config.js @@ -1,29 +1,55 @@ // Learn more: https://docs.expo.dev/guides/monorepos/ -const { getDefaultConfig } = require("@expo/metro-config"); +const { getDefaultConfig } = require("expo/metro-config"); +const { FileStore } = require("metro-cache"); const { withNativeWind } = require("nativewind/metro"); const path = require("path"); -const projectRoot = __dirname; -const workspaceRoot = path.resolve(projectRoot, "../.."); +module.exports = withTurborepoManagedCache( + withMonorepoPaths( + withNativeWind(getDefaultConfig(__dirname), { + input: "./src/styles.css", + configPath: "./tailwind.config.ts", + }), + ), +); -// Create the default Metro config -const config = getDefaultConfig(projectRoot, { isCSSEnabled: true }); +/** + * Add the monorepo paths to the Metro config. + * This allows Metro to resolve modules from the monorepo. + * + * @see https://docs.expo.dev/guides/monorepos/#modify-the-metro-config + * @param {import('expo/metro-config').MetroConfig} config + * @returns {import('expo/metro-config').MetroConfig} + */ +function withMonorepoPaths(config) { + const projectRoot = __dirname; + const workspaceRoot = path.resolve(projectRoot, "../.."); -if (config.resolver) { - // 1. Watch all files within the monorepo + // #1 - Watch all files in the monorepo config.watchFolders = [workspaceRoot]; - // 2. Let Metro know where to resolve packages and in what order + + // #2 - Resolve modules within the project's `node_modules` first, then all monorepo modules config.resolver.nodeModulesPaths = [ path.resolve(projectRoot, "node_modules"), path.resolve(workspaceRoot, "node_modules"), ]; - // 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths` - config.resolver.disableHierarchicalLookup = true; + + return config; } -// @ts-expect-error - FIXME: type is mismatching? -module.exports = withNativeWind(config, { - input: "./src/styles.css", - configPath: "./tailwind.config.ts", -}); +/** + * Move the Metro cache to the `node_modules/.cache/metro` folder. + * This repository configured Turborepo to use this cache location as well. + * If you have any environment variables, you can configure Turborepo to invalidate it when needed. + * + * @see https://turbo.build/repo/docs/reference/configuration#env + * @param {import('expo/metro-config').MetroConfig} config + * @returns {import('expo/metro-config').MetroConfig} + */ +function withTurborepoManagedCache(config) { + config.cacheStores = [ + new FileStore({ root: path.join(__dirname, "node_modules/.cache/metro") }), + ]; + return config; +} diff --git a/apps/expo/package.json b/apps/expo/package.json index 1d0d1812d..d500e9865 100644 --- a/apps/expo/package.json +++ b/apps/expo/package.json @@ -5,7 +5,7 @@ "main": "expo-router/entry", "scripts": { "clean": "git clean -xdf .expo .turbo node_modules", - "dev": "expo start --ios", + "dev": "expo start", "dev:android": "expo start --android", "dev:ios": "expo start --ios", "android": "expo run:android", @@ -15,26 +15,27 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@expo/metro-config": "^0.10.7", - "@shopify/flash-list": "1.4.3", + "@expo/metro-config": "^0.17.3", + "@shopify/flash-list": "1.6.3", "@tanstack/react-query": "^5.17.7", "@trpc/client": "11.0.0-next-beta.236", "@trpc/react-query": "11.0.0-next-beta.236", "@trpc/server": "11.0.0-next-beta.236", - "expo": "^49.0.21", - "expo-constants": "~14.4.2", - "expo-linking": "~5.0.2", - "expo-router": "2.0.14", - "expo-splash-screen": "~0.22.0", - "expo-status-bar": "~1.7.1", - "nativewind": "^4.0.22", + "expo": "~50.0.4", + "expo-constants": "~15.4.5", + "expo-linking": "~6.2.2", + "expo-router": "~3.4.6", + "expo-splash-screen": "~0.26.4", + "expo-status-bar": "~1.11.1", + "nativewind": "~4.0.13", "react": "18.2.0", "react-dom": "18.2.0", - "react-native": "0.73.1", - "react-native-gesture-handler": "~2.12.0", - "react-native-reanimated": "~3.3.0", - "react-native-safe-area-context": "4.6.3", - "react-native-screens": "~3.22.1", + "react-native": "~0.73.2", + "react-native-css-interop": "~0.0.13", + "react-native-gesture-handler": "~2.14.0", + "react-native-reanimated": "~3.6.2", + "react-native-safe-area-context": "~4.8.2", + "react-native-screens": "~3.29.0", "superjson": "2.2.1" }, "devDependencies": { @@ -43,11 +44,10 @@ "@acme/prettier-config": "workspace:^0.1.0", "@acme/tailwind-config": "workspace:^0.1.0", "@acme/tsconfig": "workspace:^0.1.0", - "@babel/core": "^7.23.7", - "@babel/preset-env": "^7.23.7", - "@babel/runtime": "^7.23.7", - "@expo/config-plugins": "^7.2.5", - "@types/babel__core": "^7.20.4", + "@babel/core": "^7.23.9", + "@babel/preset-env": "^7.23.9", + "@babel/runtime": "^7.23.9", + "@types/babel__core": "^7.20.5", "@types/react": "^18.2.48", "eslint": "^8.56.0", "prettier": "^3.1.1", diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx index 23ff5a630..78084f5b3 100644 --- a/apps/expo/src/app/_layout.tsx +++ b/apps/expo/src/app/_layout.tsx @@ -5,9 +5,12 @@ import { TRPCProvider } from "~/utils/api"; import "../styles.css"; +import { useColorScheme } from "nativewind"; + // This is the main layout of the app // It wraps your pages with the providers they need export default function RootLayout() { + const { colorScheme } = useColorScheme(); return ( {/* @@ -19,6 +22,9 @@ export default function RootLayout() { headerStyle: { backgroundColor: "#f472b6", }, + contentStyle: { + backgroundColor: colorScheme == "dark" ? "#09090B" : "#FFFFFF", + }, }} /> diff --git a/apps/expo/src/app/index.tsx b/apps/expo/src/app/index.tsx index f53e76676..35795de59 100644 --- a/apps/expo/src/app/index.tsx +++ b/apps/expo/src/app/index.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Button, Pressable, Text, TextInput, View } from "react-native"; +import { Pressable, Text, TextInput, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import { Link, Stack } from "expo-router"; import { FlashList } from "@shopify/flash-list"; @@ -12,7 +12,7 @@ function PostCard(props: { onDelete: () => void; }) { return ( - + - - + + {props.post.title} - {props.post.content} + {props.post.content} - Delete + Delete ); @@ -51,33 +51,31 @@ function CreatePost() { }); return ( - + {error?.data?.zodError?.fieldErrors.title && ( - + {error.data.zodError.fieldErrors.title} )} {error?.data?.zodError?.fieldErrors.content && ( - + {error.data.zodError.fieldErrors.content} )} { mutate({ title, @@ -85,10 +83,10 @@ function CreatePost() { }); }} > - Publish post + Create {error?.data?.code === "UNAUTHORIZED" && ( - + You need to be logged in to create a post )} @@ -102,26 +100,27 @@ export default function Index() { const postQuery = api.post.all.useQuery(); const deletePostMutation = api.post.delete.useMutation({ - onSettled: () => utils.post.all.invalidate(), + onSettled: () => utils.post.all.invalidate().then(), }); return ( - + {/* Changes page title visible on the header */} - - - Create T3 Turbo + + + Create T3 Turbo -