From d2d12d9dd13b954149f35c11f09fa81ca6988feb Mon Sep 17 00:00:00 2001 From: Caleb Denio Date: Sun, 10 Sep 2023 21:24:18 -0400 Subject: [PATCH] more fun ci --- .eslintrc.js | 26 +++- .github/workflows/ci.yml | 13 ++ App.tsx | 20 +-- package-lock.json | 185 ++++++++++++++++++++++++ package.json | 6 +- src/components/PaymentCard.tsx | 3 +- src/components/Transaction.tsx | 7 +- src/lib/organization/useTransactions.ts | 4 +- src/pages/cards.tsx | 5 +- src/pages/index.tsx | 21 +-- src/pages/login.tsx | 13 +- src/pages/organization/index.tsx | 9 +- 12 files changed, 274 insertions(+), 38 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d443d4c..14dbc7f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,8 +14,30 @@ module.exports = { ecmaVersion: "latest", sourceType: "module", }, - plugins: ["react", "@typescript-eslint"], - rules: {}, + plugins: ["react", "@typescript-eslint", "import"], + rules: { + "import/no-duplicates": "error", + "import/order": [ + "error", + { + groups: [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index", + "object", + "type", + ], + "newlines-between": "always", + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + }, + ], + }, globals: { fetch: "readonly", process: "readonly", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4169fac..ba0d493 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,19 @@ jobs: - run: npm install - name: Run ESLint run: npm run lint + prettier: + name: Prettier + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Set up Node + uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm install + - name: Run Prettier + run: npm run format:check typecheck: name: Typecheck runs-on: ubuntu-latest diff --git a/App.tsx b/App.tsx index b4f5497..2309f61 100644 --- a/App.tsx +++ b/App.tsx @@ -1,20 +1,20 @@ +import Ionicons from "@expo/vector-icons/Ionicons"; +import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import { Text, View, Image, Button, StyleSheet } from "react-native"; -import Ionicons from "@expo/vector-icons/Ionicons"; -import { useState, useEffect } from "react"; +import { BlurView } from "expo-blur"; import * as SecureStorage from "expo-secure-store"; -import AuthContext from "./src/auth"; +import { useState, useEffect } from "react"; +import { Text, View, Image, Button, StyleSheet } from "react-native"; import { SWRConfig, useSWRConfig } from "swr"; -import { BlurView } from "expo-blur"; -import Login from "./src/pages/login"; +import AuthContext from "./src/auth"; +import { StackParamList, TabParamList } from "./src/lib/NavigatorParamList"; +import CardsPage from "./src/pages/cards"; import Home from "./src/pages/index"; -import { palette, theme } from "./src/theme"; -import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; +import Login from "./src/pages/login"; import Organization from "./src/pages/organization"; -import CardsPage from "./src/pages/cards"; -import { StackParamList, TabParamList } from "./src/lib/NavigatorParamList"; +import { palette, theme } from "./src/theme"; const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); diff --git a/package-lock.json b/package-lock.json index c302fc2..432d13a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,9 @@ "@typescript-eslint/eslint-plugin": "^6.6.0", "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.49.0", + "eslint-plugin-import": "^2.28.1", "eslint-plugin-react": "^7.33.2", + "prettier": "^3.0.3", "typescript": "^5.2.2" } }, @@ -5400,6 +5402,12 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/node": { "version": "20.5.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", @@ -5995,6 +6003,25 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -7697,6 +7724,104 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint-plugin-react": { "version": "7.33.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", @@ -12755,6 +12880,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "node_modules/object.hasown": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", @@ -13427,6 +13564,21 @@ "node": ">=4" } }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -14755,6 +14907,15 @@ "node": ">=6" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -15167,6 +15328,30 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", diff --git a/package.json b/package.json index 89de7ec..5d9ec2b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", - "lint": "eslint src/", + "lint": "eslint App.tsx src/", + "format": "prettier . --write", + "format:check": "prettier . --check", "ts:check": "tsc" }, "dependencies": { @@ -38,7 +40,9 @@ "@typescript-eslint/eslint-plugin": "^6.6.0", "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.49.0", + "eslint-plugin-import": "^2.28.1", "eslint-plugin-react": "^7.33.2", + "prettier": "^3.0.3", "typescript": "^5.2.2" }, "private": true diff --git a/src/components/PaymentCard.tsx b/src/components/PaymentCard.tsx index c2e2034..1e11492 100644 --- a/src/components/PaymentCard.tsx +++ b/src/components/PaymentCard.tsx @@ -1,6 +1,7 @@ import { Text, View, ViewProps } from "react-native"; -import { palette } from "../theme"; + import Card from "../lib/types/Card"; +import { palette } from "../theme"; export default function PaymentCard({ card, diff --git a/src/components/Transaction.tsx b/src/components/Transaction.tsx index 7dd0abd..24c216c 100644 --- a/src/components/Transaction.tsx +++ b/src/components/Transaction.tsx @@ -1,11 +1,12 @@ -import { View, Text } from "react-native"; import { Ionicons } from "@expo/vector-icons"; +import { View, Text } from "react-native"; + +import TransactionType from "../lib/types/Transaction"; import { palette } from "../theme"; import { renderMoney } from "../util"; -import TransactionType from "../lib/types/Transaction"; function transactionIcon( - code: TransactionType["code"] + code: TransactionType["code"], ): React.ComponentProps["name"] { switch (code) { case "000": diff --git a/src/lib/organization/useTransactions.ts b/src/lib/organization/useTransactions.ts index 15ce3fb..4d67839 100644 --- a/src/lib/organization/useTransactions.ts +++ b/src/lib/organization/useTransactions.ts @@ -14,12 +14,12 @@ export default function useTransactions(orgId: string) { return `/organizations/${orgId}/transactions?limit=${PAGE_SIZE}&after=${ previousPageData.data[previousPageData.data.length - 1].id }`; - } + }, ); const transactions = useMemo( () => data?.flatMap((d) => d.data) || [], - [data] + [data], ); const isLoadingMore = isLoading || (size > 0 && data && typeof data[size - 1] === "undefined"); diff --git a/src/pages/cards.tsx b/src/pages/cards.tsx index 555986f..1d9c19b 100644 --- a/src/pages/cards.tsx +++ b/src/pages/cards.tsx @@ -1,7 +1,8 @@ +import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; import { FlatList } from "react-native"; -import PaymentCard from "../components/PaymentCard"; import useSWR from "swr"; -import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; + +import PaymentCard from "../components/PaymentCard"; export default function CardsPage() { const { data: cards } = useSWR("/user/cards"); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 281d396..14df28d 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,22 +1,23 @@ +import { Ionicons } from "@expo/vector-icons"; +import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; +import { + NativeStackNavigationProp, + NativeStackScreenProps, +} from "@react-navigation/native-stack"; import { FlatList, Text, View, ActivityIndicator, TouchableHighlight, + Image, } from "react-native"; -import { Image } from "react-native"; import useSWR, { useSWRConfig } from "swr"; -import { palette } from "../theme"; -import { renderMoney } from "../util"; -import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; -import { Ionicons } from "@expo/vector-icons"; -import { - NativeStackNavigationProp, - NativeStackScreenProps, -} from "@react-navigation/native-stack"; + import { StackParamList } from "../lib/NavigatorParamList"; import Organization from "../lib/types/Organization"; +import { palette } from "../theme"; +import { renderMoney } from "../util"; function Event({ event, @@ -155,7 +156,7 @@ export default function App({ navigation }: Props) { mutate( (key: string) => key.startsWith("/organizations/") || - key == "/user/organizations" + key == "/user/organizations", ); }} renderItem={({ item }) => ( diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 590b95f..e6788e3 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -1,7 +1,14 @@ import { useAuthRequest, makeRedirectUri } from "expo-auth-session"; -import { Text, View, Pressable, Animated } from "react-native"; -import { StyleSheet, SafeAreaView } from "react-native"; import { useContext, useEffect, useRef } from "react"; +import { + Text, + View, + Pressable, + Animated, + StyleSheet, + SafeAreaView, +} from "react-native"; + import AuthContext from "../auth"; import { palette } from "../theme"; @@ -22,7 +29,7 @@ export default function Login() { no_app_shell: "true", }, }, - discovery + discovery, ); const { setToken } = useContext(AuthContext); diff --git a/src/pages/organization/index.tsx b/src/pages/organization/index.tsx index b313dfd..ff40a72 100644 --- a/src/pages/organization/index.tsx +++ b/src/pages/organization/index.tsx @@ -1,3 +1,5 @@ +import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; +import { NativeStackScreenProps } from "@react-navigation/native-stack"; import { Text, View, @@ -6,12 +8,11 @@ import { PlatformColor, } from "react-native"; import useSWR from "swr"; -import { renderMoney } from "../../util"; + import Transaction from "../../components/Transaction"; -import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs"; -import useTransactions from "../../lib/organization/useTransactions"; -import { NativeStackScreenProps } from "@react-navigation/native-stack"; import { StackParamList } from "../../lib/NavigatorParamList"; +import useTransactions from "../../lib/organization/useTransactions"; +import { renderMoney } from "../../util"; type Props = NativeStackScreenProps;