diff --git a/.vscode/settings.json b/.vscode/settings.json index 87589341d8..a6b1d9843e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,12 @@ "mode": "auto" } ], + "json.schemas": [ + { + "fileMatch": ["manifest.json"], + "url": "https://json.schemastore.org/chrome-manifest.json" + } + ], "cSpell.words": [ "accountsstage", "adduser", diff --git a/package-lock.json b/package-lock.json index b95d0b128f..1f8e4639fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33280,16 +33280,16 @@ }, "packages/backend": { "name": "@clerk/backend", - "version": "1.0.0-alpha-v5.4", + "version": "1.0.0-alpha-v5.5", "license": "MIT", "dependencies": { - "@clerk/shared": "2.0.0-alpha-v5.3", + "@clerk/shared": "2.0.0-alpha-v5.4", "cookie": "0.5.0", "snakecase-keys": "5.4.4", "tslib": "2.4.1" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@cloudflare/workers-types": "^3.18.0", "@types/chai": "^4.3.3", "@types/cookie": "^0.5.1", @@ -33319,11 +33319,11 @@ }, "packages/chrome-extension": { "name": "@clerk/chrome-extension", - "version": "1.0.0-alpha-v5.6", + "version": "1.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.6", - "@clerk/clerk-react": "5.0.0-alpha-v5.6" + "@clerk/clerk-js": "5.0.0-alpha-v5.7", + "@clerk/clerk-react": "5.0.0-alpha-v5.7" }, "devDependencies": { "@types/chrome": "*", @@ -33344,12 +33344,12 @@ }, "packages/clerk-js": { "name": "@clerk/clerk-js", - "version": "5.0.0-alpha-v5.6", + "version": "5.0.0-alpha-v5.7", "license": "MIT", "dependencies": { "@clerk/localizations": "2.0.0-alpha-v5.5", - "@clerk/shared": "2.0.0-alpha-v5.3", - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/shared": "2.0.0-alpha-v5.4", + "@clerk/types": "4.0.0-alpha-v5.7", "@emotion/cache": "11.11.0", "@emotion/react": "11.11.1", "@floating-ui/react": "0.25.4", @@ -33684,17 +33684,17 @@ }, "packages/expo": { "name": "@clerk/clerk-expo", - "version": "1.0.0-alpha-v5.6", + "version": "1.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.6", - "@clerk/clerk-react": "5.0.0-alpha-v5.6", - "@clerk/shared": "2.0.0-alpha-v5.3", + "@clerk/clerk-js": "5.0.0-alpha-v5.7", + "@clerk/clerk-react": "5.0.0-alpha-v5.7", + "@clerk/shared": "2.0.0-alpha-v5.4", "base-64": "^1.0.0", "react-native-url-polyfill": "2.0.0" }, "devDependencies": { - "@clerk/types": "^4.0.0-alpha-v5.6", + "@clerk/types": "^4.0.0-alpha-v5.7", "@types/base-64": "^1.0.2", "@types/node": "^18.17.0", "@types/react": "*", @@ -33717,12 +33717,12 @@ }, "packages/fastify": { "name": "@clerk/fastify", - "version": "1.0.0-alpha-v5.6", + "version": "1.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/backend": "1.0.0-alpha-v5.4", - "@clerk/shared": "2.0.0-alpha-v5.3", - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/backend": "1.0.0-alpha-v5.5", + "@clerk/shared": "2.0.0-alpha-v5.4", + "@clerk/types": "4.0.0-alpha-v5.7", "cookies": "0.8.0" }, "devDependencies": { @@ -33740,17 +33740,17 @@ } }, "packages/gatsby-plugin-clerk": { - "version": "5.0.0-alpha-v5.6", + "version": "5.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/backend": "1.0.0-alpha-v5.4", - "@clerk/clerk-react": "5.0.0-alpha-v5.6", - "@clerk/clerk-sdk-node": "5.0.0-alpha-v5.4", + "@clerk/backend": "1.0.0-alpha-v5.5", + "@clerk/clerk-react": "5.0.0-alpha-v5.7", + "@clerk/clerk-sdk-node": "5.0.0-alpha-v5.5", "cookie": "0.5.0", "tslib": "2.4.1" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/cookie": "^0.5.0", "@types/node": "^18.17.0", "eslint-config-custom": "*", @@ -33773,7 +33773,7 @@ "version": "2.0.0-alpha-v5.5", "license": "MIT", "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/node": "^18.17.0", "eslint-config-custom": "*", "tsup": "*", @@ -33789,16 +33789,16 @@ }, "packages/nextjs": { "name": "@clerk/nextjs", - "version": "5.0.0-alpha-v5.6", + "version": "5.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/backend": "1.0.0-alpha-v5.4", - "@clerk/clerk-react": "5.0.0-alpha-v5.6", - "@clerk/shared": "2.0.0-alpha-v5.3", + "@clerk/backend": "1.0.0-alpha-v5.5", + "@clerk/clerk-react": "5.0.0-alpha-v5.7", + "@clerk/shared": "2.0.0-alpha-v5.4", "path-to-regexp": "6.2.1" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/node": "^18.17.0", "@types/react": "*", "@types/react-dom": "*", @@ -33823,11 +33823,11 @@ }, "packages/react": { "name": "@clerk/clerk-react", - "version": "5.0.0-alpha-v5.6", + "version": "5.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/shared": "2.0.0-alpha-v5.3", - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/shared": "2.0.0-alpha-v5.4", + "@clerk/types": "4.0.0-alpha-v5.7", "eslint-config-custom": "*", "semver": "^7.5.4", "tslib": "2.4.1" @@ -33855,17 +33855,17 @@ }, "packages/remix": { "name": "@clerk/remix", - "version": "4.0.0-alpha-v5.6", + "version": "4.0.0-alpha-v5.7", "license": "MIT", "dependencies": { - "@clerk/backend": "1.0.0-alpha-v5.4", - "@clerk/clerk-react": "5.0.0-alpha-v5.6", - "@clerk/shared": "2.0.0-alpha-v5.3", + "@clerk/backend": "1.0.0-alpha-v5.5", + "@clerk/clerk-react": "5.0.0-alpha-v5.7", + "@clerk/shared": "2.0.0-alpha-v5.4", "cookie": "0.5.0", "tslib": "2.4.1" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@remix-run/react": "^2.0.0", "@remix-run/server-runtime": "^2.0.0", "@types/cookie": "^0.5.0", @@ -33891,16 +33891,16 @@ }, "packages/sdk-node": { "name": "@clerk/clerk-sdk-node", - "version": "5.0.0-alpha-v5.4", + "version": "5.0.0-alpha-v5.5", "license": "MIT", "dependencies": { - "@clerk/backend": "1.0.0-alpha-v5.4", - "@clerk/shared": "2.0.0-alpha-v5.3", + "@clerk/backend": "1.0.0-alpha-v5.5", + "@clerk/shared": "2.0.0-alpha-v5.4", "camelcase-keys": "6.2.2", "snakecase-keys": "3.2.1" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/express": "4.17.14", "@types/node": "^18.17.0", "eslint-config-custom": "*", @@ -33933,7 +33933,7 @@ }, "packages/shared": { "name": "@clerk/shared", - "version": "2.0.0-alpha-v5.3", + "version": "2.0.0-alpha-v5.4", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -33942,7 +33942,7 @@ "swr": "2.2.0" }, "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/glob-to-regexp": "0.4.1", "@types/js-cookie": "3.0.2", "@types/node": "^18.17.0", @@ -33978,7 +33978,7 @@ "version": "2.0.0-alpha-v5.2", "license": "MIT", "devDependencies": { - "@clerk/types": "4.0.0-alpha-v5.6", + "@clerk/types": "4.0.0-alpha-v5.7", "@types/node": "^18.17.0", "eslint-config-custom": "*", "typescript": "*" @@ -33993,7 +33993,7 @@ }, "packages/types": { "name": "@clerk/types", - "version": "4.0.0-alpha-v5.6", + "version": "4.0.0-alpha-v5.7", "license": "MIT", "dependencies": { "csstype": "3.1.1" diff --git a/playground/chrome-extension/.env.example b/playground/chrome-extension/.env.example new file mode 100644 index 0000000000..4f4796f3fc --- /dev/null +++ b/playground/chrome-extension/.env.example @@ -0,0 +1 @@ +VITE_CLERK_PUBLISHABLE_KEY=YOUR_CLERK_PUBLISHABLE_KEY_GOES_HERE diff --git a/playground/chrome-extension/.gitignore b/playground/chrome-extension/.gitignore new file mode 100644 index 0000000000..a7b798ef93 --- /dev/null +++ b/playground/chrome-extension/.gitignore @@ -0,0 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yalc/ +yalc.lock + +# manifests + +manifest.* +!manifest.*.example + +# testing +/coverage + +# production +/build +/dist + +# misc +.DS_Store +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/playground/chrome-extension/README.md b/playground/chrome-extension/README.md new file mode 100644 index 0000000000..44af404008 --- /dev/null +++ b/playground/chrome-extension/README.md @@ -0,0 +1,79 @@ +

+ + + + + + +
+

+ +# Clerk Chrome Extension Starter + +This starter project shows how to use [Clerk](https://www.clerk.dev/?utm_source=github&utm_medium=starter_repos&utm_campaign=chrome_extension_start) authentication in a React based [Chrome Extension](https://developer.chrome.com/docs/extensions/). + +[![chat on Discord](https://img.shields.io/discord/856971667393609759.svg?logo=discord)](https://discord.com/invite/b5rXHjAg7A) +[![documentation](https://img.shields.io/badge/documentation-clerk-green.svg)](https://docs.clerk.dev) +[![twitter](https://img.shields.io/twitter/follow/ClerkDev?style=social)](https://twitter.com/intent/follow?screen_name=ClerkDev) + +If you run into issues, be sure to check our [main npm page](https://www.npmjs.com/package/@clerk/chrome-extension) for any updated settings/steps you may need to be aware of. + +--- + +**Clerk is Hiring!** + +Would you like to work on Open Source software and help maintain this repository? [Apply today!](https://apply.workable.com/clerk-dev/) + +--- + +## Introduction + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). It demonstrates a basic password or OTP flow using ClerkJS Components in a Chrome Extension Popup. + + + +This repo will be enhanced with examples of authentication redirection flows such as OAuth or Magic Links and advance extension patterns +using [Manifest V3 service workers](https://developer.chrome.com/docs/extensions/mv3/service_workers/) and the new [chrome.storage API](https://developer.chrome.com/docs/extensions/reference/storage/). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in the browser. + +The page will reload if you make edits.\ +You will also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can’t go back!** + +If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. + +You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). diff --git a/playground/chrome-extension/demo.png b/playground/chrome-extension/demo.png new file mode 100644 index 0000000000..4f7f1975a5 Binary files /dev/null and b/playground/chrome-extension/demo.png differ diff --git a/playground/chrome-extension/manifest.dev.json.example b/playground/chrome-extension/manifest.dev.json.example new file mode 100644 index 0000000000..fcad1a80f1 --- /dev/null +++ b/playground/chrome-extension/manifest.dev.json.example @@ -0,0 +1,5 @@ +{ + "host_permissions": [ + "*://localhost:*/*" + ] +} diff --git a/playground/chrome-extension/manifest.json.example b/playground/chrome-extension/manifest.json.example new file mode 100644 index 0000000000..a3ba1fc727 --- /dev/null +++ b/playground/chrome-extension/manifest.json.example @@ -0,0 +1,21 @@ +{ + "manifest_version": 3, + "name": "Clerk Chrome Extension Playground", + "description": "Playground App for the Clerk Chrome Extension", + "action": { + "default_popup": "src/pages/popup/index.html", + "default_icon": { + "32": "icon-32.png" + } + }, + "icons": { + "128": "icon-128.png" + }, + "permissions": [ + "cookies", + "storage" + ], + "host_permissions": [ + "*:///" + ] +} diff --git a/playground/chrome-extension/nodemon.json b/playground/chrome-extension/nodemon.json new file mode 100644 index 0000000000..72faa88892 --- /dev/null +++ b/playground/chrome-extension/nodemon.json @@ -0,0 +1,14 @@ +{ + "env": { + "__DEV__": "true" + }, + "watch": [ + ".yalc/**/*", "src", "utils", "vite.config.ts", "manifest.json", "manifest.dev.json", "node_modules/@clerk/**/*" + ], + "ext": "tsx,css,html,ts,json", + "ignore": [ + "src/**/*.spec.ts" + ], + "exec": "vite build", + "delay": "1000" +} diff --git a/playground/chrome-extension/package.json b/playground/chrome-extension/package.json new file mode 100644 index 0000000000..e3b991cb02 --- /dev/null +++ b/playground/chrome-extension/package.json @@ -0,0 +1,49 @@ +{ + "name": "clerk-chrome-extension-starter", + "version": "0.1.0", + "private": true, + "type": "module", + "dependencies": { + "@clerk/chrome-extension": "file:.yalc/@clerk/chrome-extension", + "@clerk/clerk-js": "file:.yalc/@clerk/clerk-js", + "@clerk/clerk-react": "file:.yalc/@clerk/clerk-react", + "@clerk/localizations": "file:.yalc/@clerk/localizations", + "@clerk/shared": "file:.yalc/@clerk/shared", + "@clerk/themes": "file:.yalc/@clerk/themes", + "@clerk/types": "file:.yalc/@clerk/types", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0", + "webextension-polyfill": "^0.10.0" + }, + "devDependencies": { + "@crxjs/vite-plugin": "^1.0.14", + "@types/chrome": "^0.0.253", + "@types/node": "^18.17.1", + "@types/react": "^18.2.39", + "@types/react-dom": "^18.2.17", + "@types/webextension-polyfill": "^0.10.0", + "@typescript-eslint/eslint-plugin": "^5.49.0", + "@typescript-eslint/parser": "^5.49.0", + "@vitejs/plugin-react-swc": "^3.0.1", + "autoprefixer": "^10.4.16", + "eslint": "^8.32.0", + "eslint-config-prettier": "^8.6.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.32.1", + "eslint-plugin-react-hooks": "^4.3.0", + "fs-extra": "^11.1.0", + "nodemon": "^2.0.20", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "ts-node": "^10.9.1", + "typescript": "^4.9.4", + "vite": "^4.5.0" + }, + "scripts": { + "build": "vite build", + "dev": "npm run yalc:add && nodemon", + "yalc:add": "yalc add -- @clerk/chrome-extension @clerk/clerk-react @clerk/clerk-js @clerk/localizations @clerk/themes @clerk/types @clerk/shared" + } +} diff --git a/playground/chrome-extension/public/clerk-logo-dark.png b/playground/chrome-extension/public/clerk-logo-dark.png new file mode 100644 index 0000000000..1faeb9411d Binary files /dev/null and b/playground/chrome-extension/public/clerk-logo-dark.png differ diff --git a/playground/chrome-extension/public/clerk-logo-light.png b/playground/chrome-extension/public/clerk-logo-light.png new file mode 100644 index 0000000000..fe83c60323 Binary files /dev/null and b/playground/chrome-extension/public/clerk-logo-light.png differ diff --git a/playground/chrome-extension/public/contentStyle.css b/playground/chrome-extension/public/contentStyle.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/playground/chrome-extension/public/dev-icon-128.png b/playground/chrome-extension/public/dev-icon-128.png new file mode 100644 index 0000000000..2272f3c288 Binary files /dev/null and b/playground/chrome-extension/public/dev-icon-128.png differ diff --git a/playground/chrome-extension/public/dev-icon-32.png b/playground/chrome-extension/public/dev-icon-32.png new file mode 100644 index 0000000000..2b72ebdb2c Binary files /dev/null and b/playground/chrome-extension/public/dev-icon-32.png differ diff --git a/playground/chrome-extension/public/icon-128.png b/playground/chrome-extension/public/icon-128.png new file mode 100644 index 0000000000..15bd934a11 Binary files /dev/null and b/playground/chrome-extension/public/icon-128.png differ diff --git a/playground/chrome-extension/public/icon-32.png b/playground/chrome-extension/public/icon-32.png new file mode 100644 index 0000000000..d93c9d3a09 Binary files /dev/null and b/playground/chrome-extension/public/icon-32.png differ diff --git a/playground/chrome-extension/src/assets/img/logo.svg b/playground/chrome-extension/src/assets/img/logo.svg new file mode 100644 index 0000000000..9dfc1c058c --- /dev/null +++ b/playground/chrome-extension/src/assets/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/chrome-extension/src/assets/styles/index.css b/playground/chrome-extension/src/assets/styles/index.css new file mode 100644 index 0000000000..ca96954435 --- /dev/null +++ b/playground/chrome-extension/src/assets/styles/index.css @@ -0,0 +1,17 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + width: 800px; + height: 600px; + max-width: 780px; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} \ No newline at end of file diff --git a/playground/chrome-extension/src/assets/styles/tailwind.css b/playground/chrome-extension/src/assets/styles/tailwind.css new file mode 100644 index 0000000000..b5c61c9567 --- /dev/null +++ b/playground/chrome-extension/src/assets/styles/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/playground/chrome-extension/src/global.d.ts b/playground/chrome-extension/src/global.d.ts new file mode 100644 index 0000000000..7ad3edd14d --- /dev/null +++ b/playground/chrome-extension/src/global.d.ts @@ -0,0 +1,11 @@ +declare module '*.svg' { + import React = require('react'); + export const ReactComponent: React.SFC>; + const src: string; + export default src; +} + +declare module '*.json' { + const content: string; + export default content; +} diff --git a/playground/chrome-extension/src/pages/background/index.ts b/playground/chrome-extension/src/pages/background/index.ts new file mode 100644 index 0000000000..def0db5c2c --- /dev/null +++ b/playground/chrome-extension/src/pages/background/index.ts @@ -0,0 +1 @@ +console.log('background script loaded'); diff --git a/playground/chrome-extension/src/pages/content/index.tsx b/playground/chrome-extension/src/pages/content/index.tsx new file mode 100644 index 0000000000..693adb4fc2 --- /dev/null +++ b/playground/chrome-extension/src/pages/content/index.tsx @@ -0,0 +1,20 @@ +import { createRoot } from 'react-dom/client'; +import './style.css' +const div = document.createElement('div'); +div.id = '__root'; +document.body.appendChild(div); + +const rootContainer = document.querySelector('#__root'); +if (!rootContainer) throw new Error("Can't find Options root element"); +const root = createRoot(rootContainer); +root.render( +
+ content script loaded +
+); + +try { + console.log('content script loaded'); +} catch (e) { + console.error(e); +} diff --git a/playground/chrome-extension/src/pages/content/style.css b/playground/chrome-extension/src/pages/content/style.css new file mode 100644 index 0000000000..954c6f5f4f --- /dev/null +++ b/playground/chrome-extension/src/pages/content/style.css @@ -0,0 +1,6 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; +.langin{ + color: aliceblue; +} \ No newline at end of file diff --git a/playground/chrome-extension/src/pages/devtools/index.html b/playground/chrome-extension/src/pages/devtools/index.html new file mode 100644 index 0000000000..e17e5b9ded --- /dev/null +++ b/playground/chrome-extension/src/pages/devtools/index.html @@ -0,0 +1,10 @@ + + + + + Devtools + + + + + diff --git a/playground/chrome-extension/src/pages/devtools/index.ts b/playground/chrome-extension/src/pages/devtools/index.ts new file mode 100644 index 0000000000..11a69a5ec4 --- /dev/null +++ b/playground/chrome-extension/src/pages/devtools/index.ts @@ -0,0 +1,7 @@ +import Browser from 'webextension-polyfill'; + +Browser + .devtools + .panels + .create('Dev Tools', 'icon-32.png', 'src/pages/panel/index.html') + .catch(console.error); diff --git a/playground/chrome-extension/src/pages/newtab/Newtab.css b/playground/chrome-extension/src/pages/newtab/Newtab.css new file mode 100644 index 0000000000..74b5e05345 --- /dev/null +++ b/playground/chrome-extension/src/pages/newtab/Newtab.css @@ -0,0 +1,38 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/playground/chrome-extension/src/pages/newtab/Newtab.tsx b/playground/chrome-extension/src/pages/newtab/Newtab.tsx new file mode 100644 index 0000000000..38ce5dc4dc --- /dev/null +++ b/playground/chrome-extension/src/pages/newtab/Newtab.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import logo from '@assets/img/logo.svg'; +import '@pages/newtab/Newtab.css'; + +export default function Newtab(): JSX.Element { + return ( +
+
+ logo +

+ Edit src/pages/newtab/Newtab.tsx and save to reload. +

+ + Learn React! + +
+
+ ); +} diff --git a/playground/chrome-extension/src/pages/newtab/index.css b/playground/chrome-extension/src/pages/newtab/index.css new file mode 100644 index 0000000000..ec2585e8c0 --- /dev/null +++ b/playground/chrome-extension/src/pages/newtab/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/playground/chrome-extension/src/pages/newtab/index.html b/playground/chrome-extension/src/pages/newtab/index.html new file mode 100644 index 0000000000..7e455b9a87 --- /dev/null +++ b/playground/chrome-extension/src/pages/newtab/index.html @@ -0,0 +1,12 @@ + + + + + New tab + + + +
+ + + diff --git a/playground/chrome-extension/src/pages/newtab/index.tsx b/playground/chrome-extension/src/pages/newtab/index.tsx new file mode 100644 index 0000000000..61c4bd4c60 --- /dev/null +++ b/playground/chrome-extension/src/pages/newtab/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import Newtab from '@pages/newtab/Newtab'; +import '@pages/newtab/index.css'; +import '@assets/styles/tailwind.css'; + +function init() { + const rootContainer = document.querySelector("#__root"); + if (!rootContainer) throw new Error("Can't find Newtab root element"); + const root = createRoot(rootContainer); + root.render(); +} + +init(); diff --git a/playground/chrome-extension/src/pages/options/Options.css b/playground/chrome-extension/src/pages/options/Options.css new file mode 100644 index 0000000000..1ea51cba69 --- /dev/null +++ b/playground/chrome-extension/src/pages/options/Options.css @@ -0,0 +1,8 @@ +.container { + width: 100%; + height: 50vh; + font-size: 2rem; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/playground/chrome-extension/src/pages/options/Options.tsx b/playground/chrome-extension/src/pages/options/Options.tsx new file mode 100644 index 0000000000..b6c79c8683 --- /dev/null +++ b/playground/chrome-extension/src/pages/options/Options.tsx @@ -0,0 +1,6 @@ +import React from 'react'; +import '@pages/options/Options.css'; + +export default function Options(): JSX.Element { + return
Options
; +} diff --git a/playground/chrome-extension/src/pages/options/index.html b/playground/chrome-extension/src/pages/options/index.html new file mode 100644 index 0000000000..fe96b7fd26 --- /dev/null +++ b/playground/chrome-extension/src/pages/options/index.html @@ -0,0 +1,12 @@ + + + + + Options + + + +
+ + + diff --git a/playground/chrome-extension/src/pages/options/index.tsx b/playground/chrome-extension/src/pages/options/index.tsx new file mode 100644 index 0000000000..da48ac11b0 --- /dev/null +++ b/playground/chrome-extension/src/pages/options/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import Options from '@pages/options/Options'; + +function init() { + const rootContainer = document.querySelector("#__root"); + if (!rootContainer) throw new Error("Can't find Options root element"); + const root = createRoot(rootContainer); + root.render(); +} + +init(); diff --git a/playground/chrome-extension/src/pages/panel/Panel.css b/playground/chrome-extension/src/pages/panel/Panel.css new file mode 100644 index 0000000000..843f23e8c8 --- /dev/null +++ b/playground/chrome-extension/src/pages/panel/Panel.css @@ -0,0 +1,7 @@ +body { + background-color: #242424; +} + +.container { + color: #ffffff; +} \ No newline at end of file diff --git a/playground/chrome-extension/src/pages/panel/Panel.tsx b/playground/chrome-extension/src/pages/panel/Panel.tsx new file mode 100644 index 0000000000..44eb2ed1ce --- /dev/null +++ b/playground/chrome-extension/src/pages/panel/Panel.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import '@pages/panel/Panel.css'; + +export default function Panel(): JSX.Element { + return ( +
+

Dev Tools Panel

+
+ ); +} diff --git a/playground/chrome-extension/src/pages/panel/index.html b/playground/chrome-extension/src/pages/panel/index.html new file mode 100644 index 0000000000..564b65b3b8 --- /dev/null +++ b/playground/chrome-extension/src/pages/panel/index.html @@ -0,0 +1,12 @@ + + + + + Devtools Panel + + + +
+ + + diff --git a/playground/chrome-extension/src/pages/panel/index.tsx b/playground/chrome-extension/src/pages/panel/index.tsx new file mode 100644 index 0000000000..88de29b661 --- /dev/null +++ b/playground/chrome-extension/src/pages/panel/index.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import Panel from '@pages/panel/Panel'; +import '@assets/styles/tailwind.css'; + +function init() { + const rootContainer = document.querySelector("#__root"); + if (!rootContainer) throw new Error("Can't find Panel root element"); + const root = createRoot(rootContainer); + root.render(); +} + +init(); diff --git a/playground/chrome-extension/src/pages/popup/Popup.tsx b/playground/chrome-extension/src/pages/popup/Popup.tsx new file mode 100644 index 0000000000..6e74decc36 --- /dev/null +++ b/playground/chrome-extension/src/pages/popup/Popup.tsx @@ -0,0 +1,127 @@ +import React from 'react'; +import { Routes, Route, MemoryRouter, useNavigate } from "react-router-dom"; +import { + SignedIn, + SignedOut, + SignIn, + SignUp, + useAuth, + useUser, + ClerkProvider, +} from "@clerk/chrome-extension"; + +import "./index.css"; + +function HelloUser() { + const { isSignedIn, user } = useUser(); + const { getToken, signOut } = useAuth(); + + const [sessionToken, setSessionToken] = React.useState(""); + + React.useEffect(() => { + const scheduler = setInterval(async () => { + const token = await getToken(); + setSessionToken(token as string); + }, 1000); + + return () => clearInterval(scheduler); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (!isSignedIn) { + return null; + } + + return ( +
+

Hi, {user.primaryEmailAddress?.emailAddress}!

+

Clerk Session Token: {sessionToken}

+

+ +

+
+ ); +} + +const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY || ""; + +function ClerkProviderWithRoutes() { + const navigate = useNavigate(); + + return ( + navigate(to)} + routerReplace={to => navigate(to, { replace: true })} + syncSessionWithTab + > +
+
+

Welcome to Clerk Chrome Extension Starter!

+ + Learn more about Clerk + +
+
+ + } /> + + + + + + + + + } + /> + +
+
+
+ ); +} + +function App() { + return ( + + + + ); +} + +export default App; + + +// export default function Popup(): JSX.Element { +// return ( +//
+//
+// logo +//

+// Edit src/pages/popup/Popup.jsx and save to reload. +//

+// +// Learn React! +// +//

Popup styled with TailwindCSS!

+//
+//
+// ); +// } + + + diff --git a/playground/chrome-extension/src/pages/popup/index.css b/playground/chrome-extension/src/pages/popup/index.css new file mode 100644 index 0000000000..0ce546ca43 --- /dev/null +++ b/playground/chrome-extension/src/pages/popup/index.css @@ -0,0 +1,37 @@ +body { + width: 300px; + height: 260px; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + position: relative; +} + + +.App { + text-align: center; +} + +.App-header { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: #282c34; +} + +.App-main { + margin-top: 1em; + display: flex; + justify-content: center; +} + +.App-link { + font-size: 1rem; + color: #6C47FF; +} diff --git a/playground/chrome-extension/src/pages/popup/index.html b/playground/chrome-extension/src/pages/popup/index.html new file mode 100644 index 0000000000..7b8317aab8 --- /dev/null +++ b/playground/chrome-extension/src/pages/popup/index.html @@ -0,0 +1,12 @@ + + + + + Popup + + + +
+ + + diff --git a/playground/chrome-extension/src/pages/popup/index.tsx b/playground/chrome-extension/src/pages/popup/index.tsx new file mode 100644 index 0000000000..c62dee0cc1 --- /dev/null +++ b/playground/chrome-extension/src/pages/popup/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import '@pages/popup/index.css'; +import '@assets/styles/tailwind.css'; +import Popup from '@pages/popup/Popup'; + +function init() { + const rootContainer = document.querySelector("#__root"); + if (!rootContainer) throw new Error("Can't find Popup root element"); + const root = createRoot(rootContainer); + root.render(); +} + +init(); diff --git a/playground/chrome-extension/src/vite-env.d.ts b/playground/chrome-extension/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/playground/chrome-extension/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/playground/chrome-extension/tailwind.config.cjs b/playground/chrome-extension/tailwind.config.cjs new file mode 100644 index 0000000000..6369be41f7 --- /dev/null +++ b/playground/chrome-extension/tailwind.config.cjs @@ -0,0 +1,12 @@ +module.exports = { + content: ["./src/**/*.{js,jsx,ts,tsx}"], + theme: { + extend: { + animation: { + 'spin-slow': 'spin 20s linear infinite', + } + }, + }, + prefix: '', + plugins: [], +} diff --git a/playground/chrome-extension/tsconfig.json b/playground/chrome-extension/tsconfig.json new file mode 100644 index 0000000000..e7dd692222 --- /dev/null +++ b/playground/chrome-extension/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "esnext", + "types": ["vite/client", "node", "chrome"], + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "noEmit": true, + "jsx": "react-jsx", + "baseUrl": ".", + "paths": { + "@src/*": ["src/*"], + "@assets/*": ["src/assets/*"], + "@pages/*": ["src/pages/*"] + } + }, + "include": ["src", "utils", "vite.config.ts"], +} diff --git a/playground/chrome-extension/vite.config.ts b/playground/chrome-extension/vite.config.ts new file mode 100644 index 0000000000..fba72e7638 --- /dev/null +++ b/playground/chrome-extension/vite.config.ts @@ -0,0 +1,70 @@ +import react from '@vitejs/plugin-react-swc'; +import { resolve } from 'path'; +import fs from 'fs'; +import { defineConfig } from 'vite'; +import { crx, ManifestV3Export } from '@crxjs/vite-plugin'; + +import manifest from './manifest.json'; +import devManifest from './manifest.dev.json'; +import pkg from './package.json'; + +const root = resolve(__dirname, 'src'); +const pagesDir = resolve(root, 'pages'); +const assetsDir = resolve(root, 'assets'); +const outDir = resolve(__dirname, 'dist'); +const publicDir = resolve(__dirname, 'public'); + +const isDev = process.env.__DEV__ === 'true'; + +const extensionManifest = { + ...manifest, + ...(isDev ? devManifest : {} as ManifestV3Export), + name: isDev ? `DEV: ${ manifest.name }` : manifest.name, + version: pkg.version, +}; + +// plugin to remove dev icons from prod build +function stripDevIcons (apply: boolean) { + if (apply) return null + + return { + name: 'strip-dev-icons', + resolveId (source: string) { + return source === 'virtual-module' ? source : null + }, + renderStart (outputOptions: any, inputOptions: any) { + const outDir = outputOptions.dir + fs.rm(resolve(outDir, 'dev-icon-32.png'), () => console.log(`Deleted dev-icon-32.png frm prod build`)) + fs.rm(resolve(outDir, 'dev-icon-128.png'), () => console.log(`Deleted dev-icon-128.png frm prod build`)) + } + } +} + +const crxPlugin = crx({ + manifest: extensionManifest as ManifestV3Export, + contentScripts: { + injectCss: true, + } +}) + +export default defineConfig({ + resolve: { + alias: { + '@src': root, + '@assets': assetsDir, + '@pages': pagesDir, + }, + }, + plugins: [ + react(), + crxPlugin, + stripDevIcons(isDev) + ], + publicDir, + build: { + emptyOutDir: true, // !isDev, + outDir, + minify: !isDev, + sourcemap: isDev + }, +}); diff --git a/playground/vite-react-ts/.gitignore b/playground/vite-react-ts/.gitignore index a547bf36d8..d7de12f381 100644 --- a/playground/vite-react-ts/.gitignore +++ b/playground/vite-react-ts/.gitignore @@ -12,6 +12,8 @@ dist dist-ssr *.local +.env + # Editor directories and files .vscode/* !.vscode/extensions.json