├── .eslintrc
├── .gitattributes
├── .gitignore
├── .markdownlint.json
├── .prettierrc.json
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── README.zh-CN.md
├── architure
├── diagram.py
├── techstack.png
└── web_service.png
├── img
├── 1.png
├── 2.png
├── 3.png
├── chrome.en.png
├── chrome.svg
├── chrome.zh.png
├── edge.en.png
├── edge.svg
├── edge.zh.png
├── firefox.en.png
├── firefox.svg
├── firefox.zh.png
├── image.png
├── install.html
└── logo.png
├── package.json
├── privacy
├── src
├── _locales
│ └── en
│ │ ├── message.json
│ │ └── messages.json
├── assets
│ ├── icons
│ │ ├── icon-128.png
│ │ ├── icon-16.png
│ │ ├── icon-24.png
│ │ ├── icon-32.png
│ │ ├── icon-48.png
│ │ └── icon-64.png
│ └── options
│ │ ├── 1.png
│ │ ├── 2.png
│ │ └── 3.png
├── background
│ └── index.ts
├── baseManifest_chrome.json
├── baseManifest_edge.json
├── baseManifest_firefox.json
├── baseManifest_opera.json
├── components
│ ├── Category
│ │ └── Category.tsx
│ ├── Check
│ │ └── Check.tsx
│ ├── Dependency
│ │ └── Dependency.tsx
│ ├── Failed
│ │ └── Failed.tsx
│ ├── Feedback
│ │ └── Feedback.tsx
│ ├── Loading
│ │ └── Loading.tsx
│ ├── PrivateRepo
│ │ └── PrivateRepo.tsx
│ └── Radio
│ │ └── Radio.tsx
├── content
│ ├── TechStacks.tsx
│ ├── content.css
│ ├── index.tsx
│ ├── isGithubRepoPage.ts
│ ├── messageListener.ts
│ └── test.js
├── i18n.js
├── options
│ ├── Container.tsx
│ ├── index.html
│ ├── options.css
│ └── options.tsx
├── popup
│ ├── index.html
│ └── index.tsx
├── types
│ ├── message.d.ts
│ ├── openControl.d.ts
│ ├── response.d.ts
│ └── techstack.ts
└── utils
│ ├── get_option.ts
│ ├── isGithubRepoPage.ts
│ ├── isGithubRepoPage_test.js
│ ├── sendMessages.ts
│ └── storage.ts
├── tsconfig.json
├── webpack.config.ts
├── webpack.config.utils.ts
└── yarn.lock
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@typescript-eslint/parser",
3 | "parserOptions": {
4 | "ecmaVersion": 2020, // Allows for the parsing of modern ECMAScript features
5 | "sourceType": "module", // Allows for the use of imports
6 | "ecmaFeatures": {
7 | "jsx": true // Allows for the parsing of JSX
8 | }
9 | },
10 | "settings": {
11 | "react": {
12 | "version": "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
13 | }
14 | },
15 | "plugins": ["@typescript-eslint", "prettier"],
16 | "rules": {
17 | "react/prop-types": [1],
18 | "prettier/prettier": [2],
19 | "@typescript-eslint/ban-ts-comment": [0],
20 | "@typescript-eslint/no-explicit-any": [1],
21 | "@typescript-eslint/no-var-requires": [0]
22 | },
23 | "extends": ["plugin:react/recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"]
24 | }
25 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dev
4 | dist
5 | temp
6 | yarn-error.log
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "no-inline-html": {
3 | "allowed_elements": ["details", "p", "div", "h1", "strong"]
4 | },
5 | "line-length": false
6 | }
7 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 2,
3 | "semi": true,
4 | "singleQuote": true,
5 | "useTabs": false,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[markdown]": {
3 | "editor.formatOnSave": false
4 | },
5 | "editor.codeActionsOnSave": {
6 | "source.fixAll": true
7 | },
8 | "editor.tabSize": 4,
9 | "editor.defaultFormatter": "esbenp.prettier-vscode",
10 | "editor.formatOnSave": true,
11 | "editor.formatOnType": true,
12 | "i18n-ally.localesPaths": [],
13 | "cSpell.words": ["fingerprintjs", "techstack", "webextension"]
14 | }
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 WebEXP0528
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | English | [简体中文](./README.zh-CN.md)
6 | # What is Tech Stack
7 | Tech Stack is a browser extension that will display the tech stack of the GitHub repository you are visiting.
8 |
9 | Discuss in [Discord](https://discord.gg/hEXF9utNHH) / [Telegram](https://t.me/gettechstack)
10 |
11 |
16 |
17 | Request a new tech stack through [this page](https://submit-techstack.zeabur.app/). It will be added to the System as soon as possible.
18 | We also welcome any developer to submit their own tech stack.😎
19 |
20 |
21 |
22 | 
23 | 
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | ## Feedback
38 | If you have any questions or suggestions, please feel free to contact us by opening an [issue on GitHub](https://github.com/Get-Tech-Stack/TechStack/issues).
39 |
40 | ## About TechStack
41 | TechStack will be free forever. But for now, open source is only one part of TechStack. Since the extension is running in users's browsers, we need open source to be transparent and let users know what we are doing in the extension. It enforces the "Don't be evil" policy.
42 |
43 | ## Support ❤️
44 | You can support the development and maintenance of TechStack with a small contribution through [TechStack's Olostep page](https://donations.olostep.com/tech-stack-github)
45 |
--------------------------------------------------------------------------------
/README.zh-CN.md:
--------------------------------------------------------------------------------
1 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/img/logo.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tech-stack",
3 | "version": "0.1.2",
4 | "description": "",
5 | "main": "webpack.config.js",
6 | "scripts": {
7 | "dev:chrome": "cross-env NODE_ENV=development TARGET=chrome webpack",
8 | "dev:firefox": "cross-env NODE_ENV=development TARGET=firefox webpack",
9 | "dev:opera": "cross-env NODE_ENV=development TARGET=opera webpack",
10 | "dev:edge": "cross-env NODE_ENV=development TARGET=edge webpack",
11 | "profile:chrome": "cross-env NODE_ENV=profile TARGET=chrome webpack",
12 | "profile:firefox": "cross-env NODE_ENV=profile TARGET=firefox webpack",
13 | "profile:opera": "cross-env NODE_ENV=profile TARGET=opera webpack",
14 | "profile:edge": "cross-env NODE_ENV=profile TARGET=edge webpack",
15 | "build:chrome": "cross-env NODE_ENV=production TARGET=chrome webpack",
16 | "build:firefox": "cross-env NODE_ENV=production TARGET=firefox webpack",
17 | "build:opera": "cross-env NODE_ENV=production TARGET=opera webpack",
18 | "build:edge": "cross-env NODE_ENV=production TARGET=edge webpack",
19 | "upload:chrome": "cross-env NODE_ENV=upload TARGET=chrome webpack",
20 | "upload:firefox": "cross-env NODE_ENV=upload TARGET=firefox webpack",
21 | "upload:opera": "cross-env NODE_ENV=upload TARGET=opera webpack",
22 | "upload:edge": "cross-env NODE_ENV=upload TARGET=edge webpack",
23 | "build": "yarn run build:chrome && yarn run build:firefox && yarn run build:opera && yarn run build:edge",
24 | "upload": "yarn run upload:chrome && yarn run upload:firefox && yarn run upload:opera && yarn run upload:edge",
25 | "lint-fix": "eslint --ext js,jsx,ts,tsx, src --fix"
26 | },
27 | "author": "Web Dev",
28 | "dependencies": {
29 | "@fingerprintjs/fingerprintjs": "v3.3.4",
30 | "@radix-ui/colors": "^2.1.0",
31 | "@radix-ui/react-icons": "^1.3.0",
32 | "@radix-ui/react-radio-group": "^1.1.3",
33 | "@radix-ui/react-switch": "^1.0.3",
34 | "@radix-ui/react-toggle-group": "^1.0.4",
35 | "clean-webpack-plugin": "^4.0.0",
36 | "copy-webpack-plugin": "^11.0.0",
37 | "core-js": "^3.32.0",
38 | "cross-env": "^7.0.3",
39 | "css-loader": "^6.8.1",
40 | "dotenv": "^16.3.1",
41 | "html-webpack-plugin": "^5.5.3",
42 | "i18next": "^23.4.4",
43 | "i18next-browser-languagedetector": "^7.1.0",
44 | "i18next-http-backend": "^2.2.1",
45 | "prop-types": "^15.8.1",
46 | "react": "^18.2.0",
47 | "react-animate-height": "^3.2.2",
48 | "react-dom": "^18.2.0",
49 | "react-i18next": "^13.1.1",
50 | "react-use-firework": "^1.0.2",
51 | "style-loader": "^3.3.3",
52 | "swr": "^2.2.0",
53 | "terser-webpack-plugin": "^5.3.9",
54 | "ts-node": "^10.9.1",
55 | "webextension-polyfill": "^0.10.0",
56 | "webpack": "^5.88.2",
57 | "webpack-bundle-analyzer": "^4.9.0",
58 | "webpack-ext-reloader-mv3": "^2.1.1",
59 | "webpack-extension-manifest-plugin": "^0.8.0",
60 | "zip-webpack-plugin": "^4.0.1"
61 | },
62 | "devDependencies": {
63 | "@types/chrome": "^0.0.242",
64 | "@types/inboxsdk": "^2.0.10",
65 | "@types/jquery": "^3.5.16",
66 | "@types/lodash": "^4.14.196",
67 | "@types/node": "^20.4.5",
68 | "@types/react": "^18.2.18",
69 | "@types/react-dom": "^18.2.7",
70 | "@types/react-router-dom": "^5.3.3",
71 | "@types/redux": "^3.6.31",
72 | "@types/webpack-bundle-analyzer": "^4.6.0",
73 | "@types/zip-webpack-plugin": "^3.0.3",
74 | "@typescript-eslint/eslint-plugin": "^6.2.1",
75 | "@typescript-eslint/parser": "^6.2.1",
76 | "eslint": "^8.46.0",
77 | "eslint-config-airbnb": "^19.0.4",
78 | "eslint-config-prettier": "^8.9.0",
79 | "eslint-plugin-babel": "^5.3.1",
80 | "eslint-plugin-import": "^2.28.0",
81 | "eslint-plugin-jsx-a11y": "^6.7.1",
82 | "eslint-plugin-prettier": "^5.0.0",
83 | "eslint-plugin-react": "^7.33.1",
84 | "eslint-plugin-react-hooks": "^4.6.0",
85 | "eslint-webpack-plugin": "^4.0.1",
86 | "prettier": "^3.0.0",
87 | "ts-loader": "^9.4.4",
88 | "typescript": "^5.1.6",
89 | "webpack-cli": "^5.1.4"
90 | },
91 | "license": "SEE LICENSE IN LICENSE",
92 | "repository": {
93 | "type": "git",
94 | "url": "https://github.com/WebExp0528/React-Extension-Boilerplate"
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/privacy:
--------------------------------------------------------------------------------
1 | Privacy Policy
2 | Introduction
3 | Welcome to TechStack Corporation(“us”, “we”, or “our”) operates https://github.com/Get-Tech-Stack/TechStack(opens in a new tab) (hereinafter referred to as “Service”).
4 |
5 | Our Privacy Policy governs your visit to https://github.com/Get-Tech-Stack/TechStack(opens in a new tab), and explains how we collect, safeguard and disclose information that results from your use of our Service. We use your data to provide and improve Service.
6 |
7 | By using Service, you agree to the collection and use of information in accordance with this policy.
8 |
9 | Unless otherwise defined in this Privacy Policy, the terms used in this Privacy Policy have the same meanings as in our Terms and Conditions.
10 |
11 | Our Terms and Conditions (“Terms”) govern all use of our Service and together with the Privacy Policy constitutes your agreement with us (“agreement”).
12 |
13 | Definitions
14 | SERVICE means the https://github.com/Get-Tech-Stack/TechStack(opens in a new tab) website operated by TechStack Corporation.
15 |
16 | PERSONAL DATA means data about a living individual who can be identified from those data (or from those and other information either in our possession or likely to come into our possession).
17 |
18 | USAGE DATA is data collected automatically either generated by the use of Service or from Service infrastructure itself (for example, the duration of a page visit).
19 |
20 | COOKIES are small files stored on your device (computer or mobile device).
21 |
22 | DATA CONTROLLER means a natural or legal person who (either alone or jointly or in common with other persons) determines the purposes for which and the manner in which any personal data are, or are to be, processed. For the purpose of this Privacy Policy, we are a Data Controller of your data.
23 |
24 | DATA PROCESSORS (OR SERVICE PROVIDERS) means any natural or legal person who processes the data on behalf of the Data Controller. We may use the services of various Service Providers in order to process your data more effectively.
25 |
26 | DATA SUBJECT is any living individual who is the subject of Personal Data.
27 |
28 | THE USER is the individual using our Service. The User corresponds to the Data Subject, who is the subject of Personal Data.
29 |
30 | Information Collection and Use
31 | We collect several different types of information for various purposes to provide and improve our Service to you.
32 |
33 | Types of Data Collected
34 | Personal Data
35 | While using our Service, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you (“Personal Data”). Personally identifiable information may include, but is not limited to:
36 |
37 | Email address
38 | First name and last name
39 | Cookies and usage data
40 | We may use your Personal Data to contact you with newsletters, marketing or promotional materials and other information that may be of interest to you. You may opt out of receiving any, or all, of these communications from us by following the unsubscribe link.
41 |
42 | Usage Data
43 | We may also collect information that your browser sends whenever you visit our Service or when you access Service by or through a mobile device (“Usage Data”).
44 |
45 | This Usage Data may include information such as your computer's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that you visit, the time and date of your visit, the time spent on those pages, unique device identifiers and other diagnostic data.
46 |
47 | When you access Service with a mobile device, this Usage Data may include information such as the type of mobile device you use, your mobile device unique ID, the IP address of your mobile device, your mobile operating system, the type of mobile Internet browser you use, unique device identifiers and other diagnostic data.
48 |
49 | Tracking Cookies Data
50 | We use cookies and similar tracking technologies to track the activity on our Service and we hold certain information.
51 |
52 | Cookies are files with a small amount of data which may include an anonymous unique identifier. Cookies are sent to your browser from a website and stored on your device. Other tracking technologies are also used such as beacons, tags and scripts to collect and track information and to improve and analyze our Service.
53 |
54 | You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent. However, if you do not accept cookies, you may not be able to use some portions of our Service.
55 |
56 | Examples of Cookies we use:
57 |
58 | Session Cookies: We use Session Cookies to operate our Service.
59 | Preference Cookies: We use Preference Cookies to remember your preferences and various settings.
60 | Security Cookies: We use Security Cookies for security purposes.
61 | Other Data
62 | While using our Service, we may also collect the following information: sex, age, date of birth, place of birth, passport details, citizenship, registration at place of residence and actual address, telephone number (work, mobile), details of documents on education, qualification, professional training, employment agreements, non-disclosure agreements, information on bonuses and compensation, information on marital status, family members, social security (or other taxpayer identification) number, office location and other data.
63 |
64 | Use of Data
65 | TechStack Corporation uses the collected data for various purposes:
66 |
67 | to provide and maintain our Service;
68 | to notify you about changes to our Service;
69 | to allow you to participate in interactive features of our Service when you choose to do so;
70 | to provide customer support;
71 | to gather analysis or valuable information so that we can improve our Service;
72 | to monitor the usage of our Service;
73 | to detect, prevent and address technical issues;
74 | to fulfill any other purpose for which you provide it;
75 | to carry out our obligations and enforce our rights arising from any contracts entered into between you and us, including for billing and collection;
76 | to provide you with notices about your account and/or subscription, including expiration and renewal notices, email-instructions, etc.;
77 | to provide you with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless you have opted not to receive such information;
78 | in any other way we may describe when you provide the information;
79 | for any other purpose with your consent.
80 | Retention of Data
81 | We will retain your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.
82 |
83 | We will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period, except when this data is used to strengthen the security or to improve the functionality of our Service, or we are legally obligated to retain this data for longer time periods.
84 |
85 | Disclosure Of Data
86 | We may disclose personal information that we collect, or you provide:
87 |
88 | Disclosure for Law Enforcement. Under certain circumstances, we may be required to disclose your Personal Data if required to do so by law or in response to valid requests by public authorities.
89 |
90 | Business Transaction. If we or our subsidiaries are involved in a merger, acquisition or asset sale, your Personal Data may be transferred.
91 |
92 | Other cases. We may disclose your information also:
93 |
94 | to our subsidiaries and affiliates;
95 |
96 | to fulfill the purpose for which you provide it;
97 |
98 | for the purpose of including your company’s logo on our website;
99 |
100 | if we believe disclosure is necessary or appropriate to protect the rights, property, or safety of the Company, our customers, or others.
101 |
102 | Security of Data
103 | The security of your data is important to us but remember that no method of transmission over the Internet or method of electronic storage is 100% secure. While we strive to use commercially acceptable means to protect your Personal Data, we cannot guarantee its absolute security.
104 |
105 | GDPR
106 | If you are a resident of the European Union (EU) and European Economic Area (EEA), you have certain data protection rights, covered by GDPR. – See more at https://eur-lex.europa.eu/eli/reg/2016/679/oj(opens in a new tab)
107 |
108 | We aim to take reasonable steps to allow you to correct, amend, delete, or limit the use of your Personal Data.
109 |
110 | If you wish to be informed what Personal Data we hold about you and if you want it to be removed from our systems, please email us at support@TechStack.com.
111 |
112 | In certain circumstances, you have the following data protection rights:
113 |
114 | the right to access, update or to delete the information we have on you;
115 |
116 | the right of rectification. You have the right to have your information rectified if that information is inaccurate or incomplete;
117 |
118 | the right to object. You have the right to object to our processing of your Personal Data;
119 |
120 | the right of restriction. You have the right to request that we restrict the processing of your personal information;
121 |
122 | the right to data portability. You have the right to be provided with a copy of your Personal Data in a structured, machine-readable and commonly used format;
123 |
124 | the right to withdraw consent. You also have the right to withdraw your consent at any time where we rely on your consent to process your personal information;
125 |
126 | Please note that we may ask you to verify your identity before responding to such requests. Please note, we may not able to provide Service without some necessary data.
127 |
128 | Service Providers
129 | We may employ third party companies and individuals to facilitate our Service (“Service Providers”), provide Service on our behalf, perform Service-related services or assist us in analysing how our Service is used.
130 |
131 | These third parties have access to your Personal Data only to perform these tasks on our behalf and are obligated not to disclose or use it for any other purpose.
132 |
133 | Analytics
134 | We may use third-party Service Providers to monitor and analyze the use of our Service.
135 |
136 | Google Analytics
137 |
138 | CI/CD tools
139 | We may use third-party Service Providers to automate the development process of our Service.
140 |
141 | GitHub
142 | GitHub is provided by GitHub, Inc.
143 |
144 | GitHub is a development platform to host and review code, manage projects, and build software.
145 |
146 | For more information on what data GitHub collects for what purpose and how the protection of the data is ensured, please visit GitHub Privacy Policy page:
147 |
148 | Behavioral Remarketing
149 | TechStack Corporation uses remarketing services to advertise on third party websites to you after you visited our Service. We and our third-party vendors use cookies to inform, optimise and serve ads based on your past visits to our Service.
150 |
151 | Google Ads (AdWords)
152 | Google Ads (AdWords) remarketing service is provided by Google Inc.
153 |
154 | You can opt-out of Google Analytics for Display Advertising and customize the Google Display Network ads by visiting the Google Ads Settings page: http://www.google.com/settings/ads
155 |
156 | Google also recommends installing the Google Analytics Opt-out Browser Add-on – https://tools.google.com/dlpage/gaoptout(opens in a new tab) – for your web browser. Google Analytics Opt-out Browser Add-on provides visitors with the ability to prevent their data from being collected and used by Google Analytics.
157 |
158 | For more information on the privacy practices of Google, please visit the Google Privacy Terms web page: https://policies.google.com/privacy?hl=en(opens in a new tab)
159 |
160 | Twitter
161 | Twitter remarketing service is provided by Twitter Inc.
162 |
163 | You can opt-out from Twitter's interest-based ads by following their instructions: https://support.twitter.com/articles/20170405(opens in a new tab)
164 |
165 | You can learn more about the privacy practices and policies of Twitter by visiting their Privacy Policy page: https://twitter.com/privacy(opens in a new tab)
166 |
167 | Payments
168 | We may provide paid products and/or services within Service. In that case, we use third-party services
169 |
170 | We will not store or collect your payment card details. That information is provided directly to our third-party payment processors whose use of your personal information is governed by their Privacy Policy. These payment processors adhere to the standards set by PCI-DSS as managed by the PCI Security Standards Council, which is a joint effort of brands like Visa, Mastercard, American Express and Discover. PCI-DSS requirements help ensure the secure handling of payment information.
171 |
172 | The payment processor we work with is Stripe(opens in a new tab). You can view their Privacy Policy here: https://stripe.com/privacy(opens in a new tab)
173 |
174 | Links to Other Sites
175 | Our Service may contain links to other sites that are not operated by us. If you click a third party link, you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every site you visit.
176 |
177 | We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.
178 |
179 | Children's Privacy
180 | Our Services are not intended for use by children under the age of 13 (“Children”).
181 |
182 | We do not knowingly collect personally identifiable information from Children under 13. If you become aware that a Child has provided us with Personal Data, please contact us. If we become aware that we have collected Personal Data from Children without verification of parental consent, we take steps to remove that information from our servers.
183 |
184 | Changes to This Privacy Policy
185 | We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page.
186 |
187 | We will let you know via email and/or a prominent notice on our Service, prior to the change becoming effective and update “effective date” at the top of this Privacy Policy.
188 |
189 | You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.
190 |
191 | Contact Us
192 | If you have any questions about this Privacy Policy, please contact us:
193 |
194 | By email: a778917369@gmail.com
--------------------------------------------------------------------------------
/src/_locales/en/message.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": {
3 | "message": "Tech Stack: Show Github Repo Tech Stack",
4 | "description": "The name of the react extension."
5 | },
6 | "appDescription": {
7 | "message": "When a user visits a Github public repository, the extension will display that repository's tech stack alongside the page.",
8 | "description": "The description of the extension."
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/_locales/en/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": {
3 | "message": "Tech Stack: Show Github Repo Tech Stack",
4 | "description": "The name of the react extension."
5 | },
6 | "appDescription": {
7 | "message": "When a user visits a Github public repository, the extension will display that repository's tech stack alongside the page.",
8 | "description": "The description of the extension."
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/assets/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-128.png
--------------------------------------------------------------------------------
/src/assets/icons/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-16.png
--------------------------------------------------------------------------------
/src/assets/icons/icon-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-24.png
--------------------------------------------------------------------------------
/src/assets/icons/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-32.png
--------------------------------------------------------------------------------
/src/assets/icons/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-48.png
--------------------------------------------------------------------------------
/src/assets/icons/icon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/icons/icon-64.png
--------------------------------------------------------------------------------
/src/assets/options/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/options/1.png
--------------------------------------------------------------------------------
/src/assets/options/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/options/2.png
--------------------------------------------------------------------------------
/src/assets/options/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Get-Tech-Stack/TechStack/d1698f0ca5751e7760874e5fa1895ae623889b38/src/assets/options/3.png
--------------------------------------------------------------------------------
/src/background/index.ts:
--------------------------------------------------------------------------------
1 | import { runtime, tabs, Tabs, Runtime } from "webextension-polyfill";
2 | /**
3 | * Define background script functions
4 | * @type {class}
5 | */
6 | class Background {
7 | _port: number;
8 | constructor() {
9 | this.init();
10 | }
11 |
12 | /**
13 | * Document Ready
14 | *
15 | * @returns {void}
16 | */
17 | init = () => {
18 | console.log("[===== Loaded Background Scripts =====]");
19 |
20 | //When extension installed
21 | runtime.onInstalled.addListener(this.onInstalled);
22 |
23 | //Add message listener in Browser.
24 | runtime.onMessage.addListener(this.onMessage);
25 |
26 | //Add Update listener for tab
27 | tabs.onUpdated.addListener(this.onUpdatedTab);
28 |
29 | //Add New tab create listener
30 | tabs.onCreated.addListener(this.onCreatedTab);
31 | };
32 |
33 | //TODO: Listeners
34 |
35 | /**
36 | * Extension Installed
37 | */
38 | onInstalled = () => {
39 | console.log("[===== Installed Extension!] =====");
40 | };
41 |
42 | /**
43 | * Message Handler Function
44 | *
45 | * @param message
46 | * @param sender
47 | * @returns
48 | */
49 | onMessage = async (message: EXTMessage, sender: Runtime.MessageSender) => {
50 | try {
51 | console.log("[===== Received message =====]", message, sender);
52 | switch (message.type) {
53 | }
54 | return true; // result to reply
55 | } catch (error) {
56 | console.log("[===== Error in MessageListener =====]", error);
57 | return error;
58 | }
59 | };
60 |
61 | /**
62 | * Message from Long Live Connection
63 | *
64 | * @param msg
65 | */
66 | onMessageFromExtension = (msg: EXTMessage) => {
67 | console.log("[===== Message from Long Live Connection =====]");
68 | console.log(msg);
69 | };
70 |
71 | /**
72 | *
73 | * @param tab
74 | */
75 | onCreatedTab = (tab: Tabs.Tab) => {
76 | console.log("[===== New Tab Created =====]", tab);
77 | };
78 |
79 | /**
80 | * When changes tabs
81 | *
82 | * @param {*} tabId
83 | * @param {*} changeInfo
84 | * @param {*} tab
85 | */
86 | onUpdatedTab = (
87 | tabId: number,
88 | changeInfo: Tabs.OnUpdatedChangeInfoType,
89 | tab: Tabs.Tab
90 | ) => {
91 | console.log("[===== Tab Created =====]", tabId);
92 | if (changeInfo.status === "complete") {
93 | this.sendMessage(tab, { type: "REJECT", data: {} });
94 | }
95 | };
96 |
97 | /**
98 | * Get url from tabId
99 | *
100 | */
101 | getURLFromTab = async (tabId: number) => {
102 | try {
103 | const tab = await tabs.get(tabId);
104 | return tab.url || "";
105 | } catch (error) {
106 | console.log(
107 | `[===== Could not get Tab Info$(tabId) in getURLFromTab =====]`,
108 | error
109 | );
110 | throw "";
111 | }
112 | };
113 |
114 | /**
115 | * Open new tab by url
116 | *
117 | */
118 | openNewTab = async (url: string) => {
119 | try {
120 | const tab = await tabs.create({ url });
121 | return tab;
122 | } catch (error) {
123 | console.log(`[===== Error in openNewTab =====]`, error);
124 | return null;
125 | }
126 | };
127 |
128 | /**
129 | * Close specific tab
130 | *
131 | * @param {number} tab
132 | */
133 | closeTab = async (tab: Tabs.Tab) => {
134 | try {
135 | await tabs.remove(tab.id ?? 0);
136 | } catch (error) {
137 | console.log(`[===== Error in closeTab =====]`, error);
138 | }
139 | };
140 |
141 | /**
142 | * send message
143 | */
144 | sendMessage = async (tab: Tabs.Tab, msg: EXTMessage) => {
145 | try {
146 | const res = await tabs.sendMessage(tab.id ?? 0, msg);
147 | return res;
148 | } catch (error) {
149 | console.log(`[===== Error in sendMessage =====]`, error);
150 | return null;
151 | }
152 | };
153 | }
154 |
155 | export const background = new Background();
156 |
--------------------------------------------------------------------------------
/src/baseManifest_chrome.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TechStack: Show Github Repo Tech Stack",
3 | "author": "CorrectRoadH",
4 | "version": "1.25",
5 | "manifest_version": 3,
6 | "description": "The extension will display the tech stack of the Repo when the user visits a GitHub Public Repo.",
7 | "icons": {
8 | "16": "assets/icons/icon-16.png",
9 | "24": "assets/icons/icon-24.png",
10 | "64": "assets/icons/icon-64.png",
11 | "128": "assets/icons/icon-128.png"
12 | },
13 | "default_locale": "en",
14 | "content_scripts": [
15 | {
16 | "matches": ["*://github.com/*"],
17 | "js": ["content/content.js"],
18 | "css": ["content/content.css"],
19 | "all_frames": true,
20 | "run_at": "document_start"
21 | }
22 | ],
23 | "background": {
24 | "service_worker": "background/background.js"
25 | },
26 | "permissions": ["tabs", "storage"],
27 | "options_ui": {
28 | "page": "options/index.html",
29 | "open_in_tab": true
30 | },
31 | "action": {
32 | "default_icon": {
33 | "16": "assets/icons/icon-16.png",
34 | "48": "assets/icons/icon-48.png"
35 | },
36 | "default_popup": "popup/index.html",
37 | "default_title": "Teach Stack"
38 | },
39 | "web_accessible_resources": [
40 | {
41 | "resources": ["assets/*", "content/*", "options/*", "popup/*", "background/*"],
42 | "matches": [""]
43 | }
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/src/baseManifest_edge.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TechStack: Display Github Repo Tech Stack",
3 | "author": "CorrectRoadH",
4 | "version": "1.25",
5 | "manifest_version": 3,
6 | "description": "The extension will display the tech stack of the Repo when the user visits a GitHub Public Repo.",
7 | "short description": "Display a Github repo's tech stack",
8 | "icons": {
9 | "16": "assets/icons/icon-16.png",
10 | "24": "assets/icons/icon-24.png",
11 | "64": "assets/icons/icon-64.png",
12 | "128": "assets/icons/icon-128.png"
13 | },
14 | "default_locale": "en",
15 | "content_scripts": [
16 | {
17 | "matches": ["*://github.com/*"],
18 | "js": ["content/content.js"],
19 | "css": ["content/content.css"],
20 | "all_frames": true,
21 | "run_at": "document_start"
22 | }
23 | ],
24 | "background": {
25 | "service_worker": "background/background.js"
26 | },
27 | "permissions": ["tabs", "storage"],
28 | "options_ui": {
29 | "page": "options/index.html",
30 | "open_in_tab": true
31 | },
32 | "action": {
33 | "default_icon": {
34 | "16": "assets/icons/icon-16.png",
35 | "48": "assets/icons/icon-48.png"
36 | },
37 | "default_title": "Teach Stack",
38 | "default_popup": "popup/index.html"
39 | },
40 | "web_accessible_resources": [
41 | {
42 | "resources": ["assets/*", "content/*", "options/*", "popup/*", "background/*"],
43 | "matches": [""]
44 | }
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/src/baseManifest_firefox.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TechStack: Show Github Repo Tech Stack",
3 | "author": "CorrectRoadH",
4 | "version": "1.25",
5 | "manifest_version": 2,
6 | "description": "The extension will display the tech stack of the Repo when the user visits a GitHub Public Repo. The user can easily get more info about the repo.",
7 | "icons": {
8 | "16": "assets/icons/icon-16.png",
9 | "24": "assets/icons/icon-24.png",
10 | "64": "assets/icons/icon-64.png",
11 | "128": "assets/icons/icon-128.png"
12 | },
13 | "default_locale": "en",
14 | "options_ui": {
15 | "page": "options/index.html",
16 | "open_in_tab": true
17 | },
18 | "content_scripts": [
19 | {
20 | "matches": ["*://github.com/*"],
21 | "js": ["content/content.js"],
22 | "css": ["content/content.css"],
23 | "all_frames": true,
24 | "run_at": "document_start"
25 | }
26 | ],
27 | "background": {
28 | "scripts": ["background/background.js"]
29 | },
30 | "permissions": ["*://*.github.com/*", "*://*.zeabur.app/", "activeTab", "webRequest", "tabs", "storage"],
31 | "browser_specific_settings": {
32 | "gecko": {
33 | "id": "a778917369@gmail.com",
34 | "strict_min_version": "54.0a1"
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/baseManifest_opera.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "__MSG_appName__",
3 | "author": "WebDEV",
4 | "version": "1.0",
5 | "manifest_version": 3,
6 | "description": "__MSG_appDescription__",
7 | "icons": {
8 | "16": "assets/icons/icon-16.png",
9 | "24": "assets/icons/icon-24.png",
10 | "64": "assets/icons/icon-64.png",
11 | "128": "assets/icons/icon-128.png"
12 | },
13 | "default_locale": "en",
14 | "content_scripts": [
15 | {
16 | "matches": ["http://*/*", "https://*/*"],
17 | "js": ["content/content.js"]
18 | }
19 | ],
20 | "background": {
21 | "service_worker": "background/background.js"
22 | },
23 | "host_permissions": ["http://*/*", "https://*/*"],
24 | "web_accessible_resources": [
25 | {
26 | "resources": ["assets/*", "content/*", "options/*", "popup/*", "background/*"],
27 | "matches": [""]
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/Category/Category.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useTranslation } from 'react-i18next';
3 | import Dependency from '../Dependency/Dependency';
4 | interface CategoryProps {
5 | name: string;
6 | deps: any;
7 | }
8 | const Category = ({ name, deps }: CategoryProps) => {
9 | const { t } = useTranslation();
10 | return (
11 |