diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index d6c9537..a3bad5f 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -14,5 +14,8 @@ module.exports = {
'warn',
{ allowConstantExport: true },
],
+ 'max-len': ['error', { code: 100 }],
+ 'no-console': 'error',
+ 'semi': ['error', 'never']
},
}
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..8b7aa0e
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,17 @@
+Story: ...
+
+1. Why this change is required?
+ - ...
+2. What problem does it solve?
+ - ...
+
+## Implementation
+1.
+2.
+3.
+
+## Checklist
+- [x] Fulfilled specs
+- [x] Ensured code is readable
+- [x] Consistency in architecture
+- [x] Added Test
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 87b8219..6909961 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -13,4 +13,5 @@ jobs:
with:
node-version: '20.x'
- run: npm ci
+ - run: npm run lint
- run: npm run test
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..994a6e7
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,7 @@
+{
+ "tabWidth": 2,
+ "semi": false,
+ "singleQuote": true,
+ "arrowParens": "avoid",
+ "printWidth": 100
+}
diff --git a/package-lock.json b/package-lock.json
index 1a6ed5e..cf29925 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"happy-dom": "^14.12.0",
+ "prettier": "^3.3.1",
"typescript": "^5.2.2",
"vite": "^5.2.0",
"vitest": "^1.6.0",
@@ -5045,6 +5046,21 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz",
+ "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
diff --git a/package.json b/package.json
index feb7115..95132b5 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"happy-dom": "^14.12.0",
+ "prettier": "^3.3.1",
"typescript": "^5.2.2",
"vite": "^5.2.0",
"vitest": "^1.6.0",
diff --git a/src/App.test.tsx b/src/App.test.tsx
index 6e4ef93..ad60949 100644
--- a/src/App.test.tsx
+++ b/src/App.test.tsx
@@ -1,15 +1,16 @@
-import { render } from '@testing-library/react';
-import App from './App';
+import { test, expect } from 'vitest'
+import { render } from '@testing-library/react'
+import App from './App'
-it('runs vitest', () => {
- expect(1).toBe(1);
-});
+test('runs vitest', () => {
+ expect(1).toBe(1)
+})
-it('renders text', () => {
- const wrapper = render();
- expect(wrapper).toBeTruthy();
+test('renders text', () => {
+ const wrapper = render()
+ expect(wrapper).toBeTruthy()
- const { getByText } = wrapper;
- expect(getByText('Vite + React')).toBeTruthy();
-});
+ const { getByText } = wrapper
+ expect(getByText('Vite + React')).toBeTruthy()
+})
diff --git a/src/lib/pkce.ts b/src/lib/pkce.ts
index d2f061f..bbe653d 100644
--- a/src/lib/pkce.ts
+++ b/src/lib/pkce.ts
@@ -1,44 +1,44 @@
-import { Sha256 } from '@aws-crypto/sha256-js';
+import { Sha256 } from '@aws-crypto/sha256-js'
export const toSha256 = async (data: string): Promise => {
- if (!data) throw new Error('data is required');
+ if (!data) throw new Error('data is required')
- const hash = new Sha256();
- hash.update(data);
+ const hash = new Sha256()
+ hash.update(data)
- const hashed = await hash.digest();
- return hashed;
+ const hashed = await hash.digest()
+ return hashed
}
// refer to base64url-encoding in RFC 7636
// https://datatracker.ietf.org/doc/html/rfc7636#appendix-A
export const toBase64Url = (bytes: Uint8Array) => {
- if (bytes.length === 0) throw new Error('bytes must not be empty');
-
- const charCodes = Array.from(bytes);
- let str = btoa(String.fromCharCode.apply(null, charCodes));
- str = str.split('=')[0];
- str = str.replace(/\+/g, '-');
- str = str.replace(/\//g, '_');
- return str;
+ if (bytes.length === 0) throw new Error('bytes must not be empty')
+
+ const charCodes = Array.from(bytes)
+ let str = btoa(String.fromCharCode.apply(null, charCodes))
+ str = str.split('=')[0]
+ str = str.replace(/\+/g, '-')
+ str = str.replace(/\//g, '_')
+ return str
}
// refer to random string generation in RFC 7636
// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
export const createRandomString = (length: number = 34): string => {
- if (length === 0) throw new Error('length must be greater than 0');
+ if (length === 0) throw new Error('length must be greater than 0')
- const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
- let randomString = '';
+ const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'
+ let randomString = ''
for (let i = 0; i < length; i++) {
- const randomIndex = Math.floor(Math.random() * charset.length);
- randomString += charset[randomIndex];
+ const randomIndex = Math.floor(Math.random() * charset.length)
+ randomString += charset[randomIndex]
}
- return randomString;
+ return randomString
}
export const createPKCECodeChallenge = async (codeVerifier: string): string => {
const hashed: Uint8Array = await toSha256(codeVerifier)
const codeChallenge = toBase64Url(hashed)
- return codeChallenge;
+ return codeChallenge
}