diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..c6c8b362 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintrc.json b/.eslintrc.json index e407eb2f..8bcb472a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,7 +26,10 @@ "rules": { "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }], + "@typescript-eslint/no-unused-vars": [ + "error", + { "ignoreRestSiblings": true } + ], "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", @@ -52,7 +55,13 @@ "caseInsensitive": true }, "newlines-between": "ignore", - "groups": [["builtin", "external"], "internal", "parent", "sibling", "index"] + "groups": [ + ["builtin", "external"], + "internal", + "parent", + "sibling", + "index" + ] } ] }, diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d2abb5c5..50572892 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,13 @@ ## What? + A description about what this pull request implements and its purpose. Try to be detailed and describe any technical details to simplify the job of the reviewer and the individual on production support. ## Why? + ... ## Testing / Proof + ... @bigcommerce/api-client-developers diff --git a/.github/workflows/validate-workflow.yml b/.github/workflows/validate-workflow.yml index d21f4ada..f108c6c2 100644 --- a/.github/workflows/validate-workflow.yml +++ b/.github/workflows/validate-workflow.yml @@ -11,7 +11,6 @@ on: jobs: build: - runs-on: ubuntu-latest strategy: @@ -19,24 +18,24 @@ jobs: node-version: [18.x, 20.x] steps: - - name: Checkout code - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} + - name: Use Node.js ${{ matrix.node }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} - - name: Install Dependencies - run: | - npm i -g npm@8.13.1 - npm ci + - name: Install Dependencies + run: | + npm i -g npm@8.13.1 + npm ci - - name: Run Build - run: npm run build + - name: Run Build + run: npm run build - - name: Lint Check - run: npm run lint --if-present + - name: Lint Check + run: npm run lint --if-present - - name: Validate tests - run: npm run test --if-present + - name: Validate tests + run: npm run test --if-present diff --git a/.gitignore b/.gitignore index 67045665..b5cc869b 100644 --- a/.gitignore +++ b/.gitignore @@ -70,7 +70,7 @@ typings/ # dotenv environment variables file .env -.env.test +.env.* # parcel-bundler cache (https://parceljs.org/) .cache @@ -102,3 +102,7 @@ dist # TernJS port file .tern-port +blobfish.db +blobfish.db.bak + +.DS_Store diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..a27716bc --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +min-release-age=2 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..b79037cf --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +graphql-env.d.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..fd36598c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b8b82ff6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "js/ts.tsdk.path": "node_modules/typescript/lib" +} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 040a617b..5068f4e1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b303643e..efede29f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,5 @@ # Contributing to Sample App NodeJS + Thanks for showing interest in contributing! The following is a set of guidelines for contributing to the Sample App NodeJS. These are just guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. @@ -8,40 +9,42 @@ The following is a set of guidelines for contributing to the Sample App NodeJS. [API Documentation](https://developer.bigcommerce.com/api) How Can I Contribute? - * [Pull Requests](#pull-requests) - * [Issues / Bugs](#issues--bugs) - * [Other Ways to Contribute](#other-ways-to-contribute) + +- [Pull Requests](#pull-requests) +- [Issues / Bugs](#issues--bugs) +- [Other Ways to Contribute](#other-ways-to-contribute) Styleguides - * [Git Commit Messages](#git-commit-messages) + +- [Git Commit Messages](#git-commit-messages) ## Pull Requests -First ensure that your feature isn't already being developed or considered (see open PRs and issues). +First ensure that your feature isn't already being developed or considered (see open PRs and issues). If it is, please consider contributing to those initiatives. All PRs require test coverage to be accepted when applicable. ## Issues / Bugs - -* Please include a clear, specific title and replicable description. -* Please include your environment, OS, and any exceptions/backtraces that occur. The more -information that is given, the more likely we can debug and fix the issue. +- Please include a clear, specific title and replicable description. + +- Please include your environment, OS, and any exceptions/backtraces that occur. The more + information that is given, the more likely we can debug and fix the issue. -**If you find a security bug, please do not post as an issue. Send directly to security@bigcommerce.com +**If you find a security bug, please do not post as an issue. Send directly to security@bigcommerce.com instead.** ## Other Ways to Contribute -* Consider contributing to sample-app-nodejs documentation on the wiki, reporting bugs, contributing to test coverage, -or helping spread the word about sample-app-nodejs. +- Consider contributing to sample-app-nodejs documentation on the wiki, reporting bugs, contributing to test coverage, + or helping spread the word about sample-app-nodejs. ## Git Commit Messages -* Use the present tense ("Add feature" not "Added feature") -* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") -* Limit the first line to 72 characters or less -* Reference pull requests and external links liberally +- Use the present tense ("Add feature" not "Added feature") +- Use the imperative mood ("Move cursor to..." not "Moves cursor to...") +- Limit the first line to 72 characters or less +- Reference pull requests and external links liberally Thank you again for your interest in contributing to sample-app-nodejs! diff --git a/README.md b/README.md index dc11014e..9d05eca5 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ cp .env-sample .env 1. Creating a new project in Firebase 2. Adding a Cloud Firestore 3. And generating a new Private Key under Project Settings > Service Accounts - See the [Firebase quickstart (Google)](https://firebase.google.com/docs/firestore/quickstart) for more detailed information. + See the [Firebase quickstart (Google)](https://firebase.google.com/docs/firestore/quickstart) for more detailed information. If using MySQL, supply the `MYSQL_` config keys listed in the `.env` file, then do the initial database migration by running the following npm script: `npm run db:setup` diff --git a/app.json b/app.json index c22cdf05..220d401e 100644 --- a/app.json +++ b/app.json @@ -8,18 +8,18 @@ "CLIENT_ID": { "description": "The client id of your app, provided by the BigCommerce developer portal." }, - "CLIENT_SECRET":{ + "CLIENT_SECRET": { "description": "The client secret of your app, provided by the BigCommerce developer portal." }, - "AUTH_CALLBACK":{ + "AUTH_CALLBACK": { "description": "The fully qualified authentication endpoint provided by this app. Replace the app name with the app name chosen above.", "value": "https://.herokuapp.com/api/auth" }, - "DB_TYPE":{ + "DB_TYPE": { "description": "Which type of database we are using. Options are 'mysql' or 'firebase'. Can safely leave unchanged.", "value": "mysql" }, - "JWT_KEY":{ + "JWT_KEY": { "description": "Key the app will use for signing JWT. Can safely leave unchanged.", "generator": "secret" } diff --git a/components/error.tsx b/components/error.tsx index e38986e2..7ba4c288 100644 --- a/components/error.tsx +++ b/components/error.tsx @@ -1,23 +1,23 @@ -import { H3, Panel } from '@bigcommerce/big-design'; -import { ErrorMessageProps, ErrorProps } from '../types'; +import { H3, Panel } from '@bigcommerce/big-design' +import { ErrorMessageProps, ErrorProps } from '../types' const ErrorContent = ({ message }: Pick) => ( - <> -

Failed to load

- {message} - + <> +

Failed to load

+ {message} + ) const ErrorMessage = ({ error, renderPanel = true }: ErrorMessageProps) => { - if (renderPanel) { - return ( - - - - ) - } + if (renderPanel) { + return ( + + + + ) + } - return -}; + return +} -export default ErrorMessage; +export default ErrorMessage diff --git a/components/form.tsx b/components/form.tsx index 1f494b2b..9aff0367 100644 --- a/components/form.tsx +++ b/components/form.tsx @@ -1,126 +1,149 @@ -import { Button, Checkbox, Flex, FormGroup, Input, Panel, Select, Form as StyledForm, Textarea } from '@bigcommerce/big-design'; -import { ChangeEvent, FormEvent, useState } from 'react'; -import { FormData, StringKeyValue } from '../types'; +import { + Button, + Checkbox, + Flex, + FormGroup, + Input, + Panel, + Select, + Form as StyledForm, + Textarea, +} from '@bigcommerce/big-design' +import { ChangeEvent, FormEvent, useState } from 'react' +import { FormData, StringKeyValue } from '../types' interface FormProps { - formData: FormData; - onCancel(): void; - onSubmit(form: FormData): void; + formData: FormData + onCancel(): void + onSubmit(form: FormData): void } const FormErrors = { - name: 'Product name is required', - price: 'Default price is required', -}; + name: 'Product name is required', + price: 'Default price is required', +} const Form = ({ formData, onCancel, onSubmit }: FormProps) => { - const { description, isVisible, name, price, type } = formData; - const [form, setForm] = useState({ description, isVisible, name, price, type }); - const [errors, setErrors] = useState({}); + const { description, isVisible, name, price, type } = formData + const [form, setForm] = useState({ + description, + isVisible, + name, + price, + type, + }) + const [errors, setErrors] = useState({}) - const handleChange = (event: ChangeEvent) => { - const { name: formName, value } = event.target || {}; - setForm(prevForm => ({ ...prevForm, [formName]: value })); + const handleChange = ( + event: ChangeEvent + ) => { + const { name: formName, value } = event.target || {} + setForm((prevForm) => ({ ...prevForm, [formName]: value })) - // Add error if it exists in FormErrors and the input is empty, otherwise remove from errors - !value && FormErrors[formName] - ? setErrors(prevErrors => ({ ...prevErrors, [formName]: FormErrors[formName] })) - : setErrors(({ [formName]: removed, ...prevErrors }) => ({ ...prevErrors })); - }; + // Add error if it exists in FormErrors and the input is empty, otherwise remove from errors + !value && FormErrors[formName] + ? setErrors((prevErrors) => ({ + ...prevErrors, + [formName]: FormErrors[formName], + })) + : setErrors(({ [formName]: removed, ...prevErrors }) => ({ + ...prevErrors, + })) + } - const handleSelectChange = (value: string) => { - setForm(prevForm => ({ ...prevForm, type: value })); - }; + const handleSelectChange = (value: string) => { + setForm((prevForm) => ({ ...prevForm, type: value })) + } - const handleCheckboxChange = (event: ChangeEvent) => { - const { checked, name: formName } = event.target || {}; - setForm(prevForm => ({ ...prevForm, [formName]: checked })); - }; + const handleCheckboxChange = (event: ChangeEvent) => { + const { checked, name: formName } = event.target || {} + setForm((prevForm) => ({ ...prevForm, [formName]: checked })) + } - const handleSubmit = (event: FormEvent) => { - event.preventDefault(); + const handleSubmit = (event: FormEvent) => { + event.preventDefault() - // If there are errors, do not submit the form - const hasErrors = Object.keys(errors).length > 0; - if (hasErrors) return; + // If there are errors, do not submit the form + const hasErrors = Object.keys(errors).length > 0 + if (hasErrors) return - onSubmit(form); - }; + onSubmit(form) + } - return ( - - - - - - - - - - - - - - - {/* Using description for demo purposes. Consider using a wysiwig instead (e.g. TinyMCE) */} -