diff --git a/.github/actions/update-stars/action.yml b/.github/actions/update-stars/action.yml new file mode 100644 index 0000000..1d91f91 --- /dev/null +++ b/.github/actions/update-stars/action.yml @@ -0,0 +1,9 @@ +name: Update stars +description: Update Github stars count +inputs: + token: + description: GitHub token for GraphQL calls + required: false +runs: + using: node16 + main: 'main.js' diff --git a/.github/actions/update-stars/main.js b/.github/actions/update-stars/main.js new file mode 100644 index 0000000..ad822e2 --- /dev/null +++ b/.github/actions/update-stars/main.js @@ -0,0 +1,131 @@ +import core from '@actions/core'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { fetch } from 'undici'; + +const ghGraphQlUrl = 'https://api.github.com/graphql'; +const gitlabGraphQlUrl = 'https://gitlab.com/api/graphql'; +const githubNameRegexp = new RegExp( + 'https://github.com/([a-zA-Z0-9][a-zA-Z0-9-]{0,38}/[a-zA-Z0-9._-]{1,100})' +); +const gitlabNameRegExp = new RegExp('https://gitlab.com/([\\w-]+/[\\w-]+)'); + +async function doGraphQlQuery(url, query, headers = {}) { + try { + let fetchResponse = await fetch(url, { + body: JSON.stringify({ query }), + method: 'POST', + headers: { + 'content-type': 'application/json', + ...headers + } + }); + let data = await fetchResponse.json(); + return Object.values(data.data || {}); + } catch (e) { + console.error(e.message); + } + return []; +} + +function gatherUrls() { + let components = JSON.parse(readFileSync('src/routes/components/components.json')); + let tools = JSON.parse(readFileSync('src/routes/tools/tools.json')); + let templates = JSON.parse(readFileSync('src/routes/templates/templates.json')); + + return [ + ...components.map((component) => component.url), + ...tools.map((tool) => tool.url), + ...templates.map((template) => template.url) + ]; +} + +// Github + +function getAllGHRepos() { + return gatherUrls() + .filter((url) => url !== false && githubNameRegexp.test(url)) + .map((gitHubUrl) => gitHubUrl.match(githubNameRegexp)[1].toLowerCase()) + .map((validName) => ({ owner: validName.split('/')[0], repo: validName.split('/')[1] })); +} + +function ghRepoGraphQl({ owner, repo }) { + let identifier = owner + '_' + repo + '_' + Math.random() + ''; + identifier = identifier.replace(/[^a-zA-Z0-9_]/g, '_'); + identifier = identifier.replace(/^[0-9]/g, '_'); + return `${identifier}: repository(name: "${repo}", owner: "${owner}"){nameWithOwner stargazerCount}`; +} + +async function getGHStars() { + const repoData = getAllGHRepos(); + let body = + 'query{' + '\n' + repoData.map((repoInfo) => ghRepoGraphQl(repoInfo)).join('\n') + '\n' + '}'; + let lines = await doGraphQlQuery(ghGraphQlUrl, body, { + authorization: + 'Bearer ' + + core.getInput('token', { + // required: true, + trimWhitespace: true + }) + }); + return Object.fromEntries( + lines + .filter((line) => line?.nameWithOwner) + .map((line) => [line.nameWithOwner.toLowerCase(), line.stargazerCount]) + ); +} + +// Gitlab + +function getAllGitlabRepos() { + return gatherUrls() + .filter((url) => url !== false && gitlabNameRegExp.test(url)) + .map((url) => url.match(gitlabNameRegExp)[1]); +} + +function gitlabRepoGraphQl(name) { + let identifier = name + '_' + Math.random() + ''; + identifier = identifier.replace(/[^a-zA-Z0-9_]+/g, '_'); + identifier = identifier.replace(/^[0-9]/g, '_'); + return `${identifier}: project(fullPath: "${name}"){starCount fullPath}`; +} + +async function getGitlabStars() { + const repoData = getAllGitlabRepos(); + let body = + 'query{' + + '\n' + + repoData.map((repoInfo) => gitlabRepoGraphQl(repoInfo)).join('\n') + + '\n' + + '}'; + let lines = await doGraphQlQuery(gitlabGraphQlUrl, body); + return Object.fromEntries( + lines + .filter((line) => line?.fullPath) + .map((line) => [line.fullPath.toLowerCase(), line.starCount]) + ); +} + +async function main() { + const github = await getGHStars(); + const gitlab = await getGitlabStars(); + core.info( + `\tGithub: ${Object.keys(github).length} repositories (${Object.values(github).reduce( + (count, item) => count + item, + 0 + )} stars)` + ); + core.info( + `\tGitlab: ${Object.keys(gitlab).length} repositories (${Object.values(gitlab).reduce( + (count, item) => count + item, + 0 + )} stars)` + ); + writeFileSync('src/lib/stars.json', JSON.stringify({ github, gitlab })); +} + +try { + core.info('Start'); + main().then(() => core.info('Done')); +} catch (error) { + core.setFailed(error); +} diff --git a/.github/workflows/update-stars.yml b/.github/workflows/update-stars.yml new file mode 100644 index 0000000..318248b --- /dev/null +++ b/.github/workflows/update-stars.yml @@ -0,0 +1,35 @@ +name: Update stars count + +on: + schedule: + - cron: '0 0 1 * *' # Every 1st of every month at 00:00 + +jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup node with version 16 + uses: actions/setup-node@v3 + with: + node-version: '16.x' + registry-url: 'https://registry.npmjs.org' + - name: Install dependencies + run: npm ci + - name: Run script + uses: ./.github/actions/update-stars + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Run format + run: npm run format + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 + with: + author: github_actions + commit-message: "(AUTO) Update stars" + title: "BOT: Update stars" + body: Update all stars count from Github and Gitlab + branch: ci-update-stars + add-paths: src/lib/stars.json + delete-branch: true + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 16d7dc3..ae173f1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "prepare": "husky install" }, "devDependencies": { + "@actions/core": "^1.6.0", "@macfja/svelte-persistent-store": "2.3.1", "@sveltejs/adapter-static": "^2.0.2", "@sveltejs/kit": "^1.22.1", @@ -39,6 +40,7 @@ "svelte-select": "^4.4.0", "tslib": "^2.6.0", "typescript": "^5.1.6", + "undici": "^5.22.1", "vite": "^4.4.2", "vitest": "^0.33.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5579445..f65c2b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false devDependencies: + '@actions/core': + specifier: ^1.6.0 + version: 1.6.0 '@macfja/svelte-persistent-store': specifier: 2.3.1 version: 2.3.1(svelte@4.0.5) @@ -77,6 +80,9 @@ devDependencies: typescript: specifier: ^5.1.6 version: 5.1.6 + undici: + specifier: ^5.22.1 + version: 5.22.1 vite: specifier: ^4.4.2 version: 4.4.2(@types/node@20.3.3) @@ -91,6 +97,18 @@ packages: engines: {node: '>=0.10.0'} dev: true + /@actions/core@1.6.0: + resolution: {integrity: sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==} + dependencies: + '@actions/http-client': 1.0.11 + dev: true + + /@actions/http-client@1.0.11: + resolution: {integrity: sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==} + dependencies: + tunnel: 0.0.6 + dev: true + /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} @@ -2705,6 +2723,11 @@ packages: typescript: 5.1.6 dev: true + /tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + dev: true + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} diff --git a/src/lib/stars.json b/src/lib/stars.json new file mode 100755 index 0000000..7958c3b --- /dev/null +++ b/src/lib/stars.json @@ -0,0 +1,393 @@ +{ + "github": { + "n00nday/stwui": 158, + "sveltejs/kit": 13427, + "sawyerclick/svelte-lazy-loader": 16, + "dhyeymoliya/svelte-form-validation": 2, + "probablykasper/date-picker-svelte": 153, + "bernhardwebstudio/svelte-virtual-table": 16, + "bohnacker/svelte-number-spinner": 21, + "aantusahaa/svelte-remixicon": 32, + "abosch19/svelte-fast-marquee": 14, + "consoletvs/sswr": 156, + "jthegedus/svelte-adapter-firebase": 204, + "architect/sveltekit-adapter": 8, + "pluvial/svelte-adapter-deno": 215, + "codediodeio/sveltefire": 886, + "tanepiper/svelte-formula": 120, + "6edesign/svelte-calendar": 482, + "agustinl/svelte-tags-input": 239, + "alexprey/sveltedoc-parser": 81, + "alexxnb/aovi-svelte": 10, + "alexxnb/svelte-chota": 283, + "alexxnb/svelte-eventbus": 36, + "alexxnb/svelte-preprocess-markdown": 126, + "alexxnb/tinro": 653, + "alphapeter/fa-svelte": 71, + "andrelmlins/svelte-fullscreen": 53, + "andrelmlins/svelte-grid-responsive": 46, + "andrelmlins/svelte-infinite-scroll": 228, + "dyalicode/svelte-formly": 217, + "arlac77/svelte-websocket-store": 234, + "bestguy/sveltestrap": 1144, + "beyonk-adventures/gdpr-cookie-consent-banner": 168, + "beyonk-adventures/svelte-carousel": 212, + "beyonk-adventures/svelte-facebook-customer-chat": 5, + "beyonk-adventures/svelte-facebook-pixel": 13, + "beyonk-adventures/svelte-google-analytics": 64, + "beyonk-adventures/svelte-googlemaps": 63, + "beyonk-adventures/svelte-mapbox": 261, + "beyonk-adventures/svelte-notifications": 298, + "beyonk-adventures/svelte-scrollspy": 37, + "beyonk-adventures/svelte-simple-icons": 13, + "beyonk-adventures/svelte-trustpilot": 3, + "bluwy/svelte-router": 31, + "brunomolteni/svelte-sortable-list": 108, + "bsssshhhhhhh/svelte-data-grid": 193, + "buhrmi/query-store": 40, + "c0bra/svelma": 520, + "chainlist/svelte-forms": 357, + "charlyjazz/svelte-credit-card": 38, + "collardeau/svelte-headroom": 76, + "cweili/svelte-fa": 284, + "dasdaniel/svelte-table": 384, + "daybrush/moveable": 7641, + "daybrush/ruler": 215, + "dmitrykurmanov/waxwing-rating": 7, + "dopry/svelte-auth0": 64, + "dylanblokhuis/svelte-feather-icons": 119, + "easylogic/svelte-summernote": 11, + "ekhaled/svelte-dev-helper": 6, + "emiltholin/svelte-routing": 1737, + "emrekara37/svelte-rate-it": 38, + "equipmentshare/date-range-input": 15, + "esinx/svelte-tree": 19, + "theovidal/svelteify": 45, + "flekschas/svelte-simple-modal": 364, + "urql-graphql/urql": 7809, + "introvertuous/svelte-icons": 223, + "halfnelson/svelte-native": 1399, + "henriquehbr/svelte-typewriter": 201, + "himynameisdave/svelte-copyright": 10, + "himynameisdave/svelte-flex": 68, + "himynameisdave/svelte-frappe-charts": 253, + "heokhe/svmd": 8, + "hperrin/svelte-material-ui": 2846, + "carbon-design-system/carbon-components-svelte": 1997, + "illright/attractions": 811, + "italypaleale/svelte-spa-router": 1247, + "jacobmischka/svelte-flatpickr": 121, + "jacwright/svelte-navaid": 16, + "jamen/svelte-router": 9, + "jikkai/svelte-router": 63, + "jimutt/svelte-pick-a-place": 51, + "nickyhajal/svelte-tabs": 91, + "john--kane/svelteml": 66, + "johnwalley/compare-image-slider": 15, + "jorgegorka/svelte-router": 456, + "kaisermann/svelte-css-vars": 231, + "kaisermann/svelte-i18n": 887, + "nubolab-ffwd/svelte-fluent": 49, + "kaisermann/svelte-loadable": 314, + "kazzkiq/svero": 204, + "keenethics/svelte-notifications": 530, + "kenoxa/svelte-fragment-component": 3, + "kenoxa/svelte-htm": 11, + "kenoxa/svelte-jsx": 31, + "kevmodrome/svelte-favicon-badge": 95, + "kolodziejczak-sz/svelte-redux-connect": 16, + "svelteness/svelte-jester": 122, + "ktsn/svelte-jest": 37, + "liyuanqiu/echarts-for-svelte": 25, + "lottiefiles/svelte-lottie-player": 99, + "lukeed/pwa": 3101, + "easyroute-router/svelte-easyroute": 126, + "maciekgrzybek/svelte-inview": 423, + "matyunya/smelte": 1432, + "matyunya/svelte-image": 662, + "matyunya/svelte-waypoint": 79, + "mdauner/sveltejs-forms": 195, + "mefechoel/svelte-navigator": 427, + "mhkeller/layercake": 778, + "milafrerichs/browser-repl-js": 14, + "milahu/svelte-layout-resizable": 22, + "milahu/svelte-preval": 6, + "naver/egjs-infinitegrid": 1522, + "nomangul/svelte-page-progress": 17, + "okrad/svelte-progressbar": 114, + "panya/svelte-intl": 48, + "parables/svelta": 26, + "pateketrueke/svql": 59, + "pateketrueke/yrv": 160, + "sveltetools/svelte-asyncable": 115, + "paulmaly/svelte-content-loader": 146, + "paulmaly/svelte-image-compare": 18, + "paulmaly/svelte-imask": 64, + "paulmaly/svelte-page-router": 21, + "sveltetools/svelte-pathfinder": 96, + "paulmaly/svelte-ticker": 11, + "sveltetools/svelte-viewpoint": 33, + "pavish/select-madu": 48, + "pearofducks/svelte-match-media": 39, + "pixievoltno1/svelte-webext-storage-adapter": 21, + "pixievoltno1/svelte-writable-derived": 75, + "plrenaudin/svelte-storez": 25, + "gitbreaker222/sveltestore": 1, + "pngwn/mdsvex": 1636, + "pngwn/svelte-adapter": 267, + "pngwn/svelte-test": 24, + "fusioncharts/svelte-fusioncharts": 117, + "pstanoev/simple-svelte-autocomplete": 369, + "tienpv222/svelte-hash-router": 38, + "efeskucuk/svelte-color-picker": 97, + "qutran/svelte-inspector": 73, + "qutran/swheel": 43, + "reecelucas/svelte-accessible-dialog": 26, + "rich-harris/pancake": 1136, + "rob-balfre/svelte-select": 905, + "robbrazier/svelte-awesome": 370, + "rspieker/jest-transform-svelte": 35, + "saabi/svelte-image-encoder": 38, + "sciactive/multicarousel": 36, + "scottbedard/svelte-heatmap": 115, + "sharifclick/svelte-swipe": 278, + "shavyg2/slick-for-svelte": 24, + "silvestrevivo/svelte-marquee": 6, + "simeydotme/svelte-range-slider-pips": 283, + "skayo/svelte-infinite-loading": 177, + "spaceavocado/svelte-form": 49, + "spaceavocado/svelte-router": 57, + "stephane-vanraes/svelte-multitoneimage": 6, + "stephane-vanraes/svelte-progresscircle": 18, + "storybookjs/storybook": 76732, + "svelte-toolbox/svelte-toolbox": 76, + "roxiness/routify": 1670, + "sveltejs/gestures": 85, + "sveltejs/gl": 606, + "sveltejs/svelte-repl": 273, + "sveltejs/svelte-scroller": 280, + "sveltejs/svelte-subdivide": 125, + "sveltejs/svelte-virtual-list": 574, + "gitbreaker222/svelte-virtual-list": 12, + "tehshrike/svelte-state-renderer": 35, + "testing-library/svelte-testing-library": 538, + "thecodejack/svelte-file-dropzone": 152, + "timhall/svelte-apollo": 876, + "timhall/svelte-observable": 61, + "titans-inc/sveltemantic": 45, + "tjinauyeung/svelte-forms-lib": 552, + "vaheqelyan/svelte-grid": 774, + "vaheqelyan/svelte-popover": 55, + "valentinh/svelte-easy-crop": 134, + "vikignt/svelte-mui": 304, + "vime-js/vime": 2431, + "vinayakkulkarni/s-offline": 52, + "wearegenki/minna-ui": 90, + "xelaok/svelte-media-query": 50, + "xelaok/svelte-mobx": 40, + "xelaok/svelte-watch-resize": 26, + "xnimorz/svelte-input-mask": 90, + "yazonnile/svelidation": 51, + "yoglib/svelte-fullcalendar": 161, + "the-homeless-god/svelte-item-list": 2, + "zooplus/zoo-web-components": 43, + "skayo/svelte-tiny-virtual-list": 277, + "appwrite/sdk-for-svelte": 70, + "vinodnimbalkar/svelte-pdf": 127, + "ayndqy/svelte-micro": 87, + "ryu-man/svantic": 15, + "macfja/svelte-undoable": 42, + "stephane-vanraes/renderless-svelte": 269, + "alexxnb/svate": 12, + "sveltestack/svelte-query": 742, + "kindoflew/svelte-parallax": 103, + "macfja/svelte-persistent-store": 176, + "macfja/svelte-invalidable": 3, + "vadimkorr/svelte-carousel": 179, + "endenwer/svelte-restate": 21, + "metonym/svelte-pincode": 14, + "matteobruni/tsparticles": 4862, + "sibiraj-s/svelte-tiptap": 78, + "oli8/spaper": 147, + "vkurko/calendar": 243, + "novacbn/kahi-ui": 174, + "macfja/svelte-adapter-multi": 12, + "janosh/svelte-multiselect": 144, + "janosh/svelte-toc": 63, + "janosh/svelte-bricks": 44, + "macfja/svelte-oauth2": 29, + "paolotiu/svelte-boring-avatars": 40, + "chanced/filedrop-svelte": 93, + "chanced/focus-svelte": 29, + "noelmugnier/svelte-translate": 9, + "mskocik/svelecte": 246, + "geoffrich/svelte-adapter-azure-swa": 68, + "halfdanj/svelte-adapter-appengine": 26, + "antony/sveltekit-adapter-browser-extension": 117, + "kenkunz/svelte-fsm": 232, + "budgetdraw/sveltekit-cloudflare-adapter": 7, + "gcbenlloch/svelte-cleavejs": 6, + "mskocik/svelty-picker": 59, + "korywka/svelte-slider": 11, + "tomatrow/sveltekit-adapter-wordpress-shortcode": 21, + "macfja/svelte-expirable": 2, + "vkurko/svelte-store2": 3, + "macfja/svelte-adapter-neutralino": 13, + "idleberg/sveltekit-adapter-html-like": 10, + "rezi/svelte-gestures": 48, + "malynium/svelte-adapter-github": 38, + "shaozi/svelte-steps": 80, + "agnosticui/agnosticui": 580, + "torstendittmann/svelte-adapter-static-digitalocean": 8, + "oslabs-beta/svend3r": 243, + "jycouet/kitql": 275, + "anotherempty/svelte-brick-gallery": 32, + "gornostay25/svelte-adapter-bun": 262, + "rgossiaux/svelte-headlessui": 1299, + "beerui/beerui": 33, + "davipon/svelte-hover-draw-svg": 22, + "l-portet/svelte-switch-case": 95, + "casual-ui/casual-ui": 44, + "canutin/svelte-currency-input": 15, + "themesberg/flowbite-svelte": 600, + "ivanhofer/typesafe-i18n": 1367, + "tolgee/tolgee-js": 174, + "ivanhofer/sthemer": 20, + "noney1412/svelte-exstore": 0, + "macfja/svelte-scroll-video": 1, + "prgm-dev/sveltekit-progress-bar": 0, + "halfdanj/svelte-google-auth": 10, + "geoffcox/sterling-svelte": 0, + "tanstack/query": 32954, + "pragmatic-engineering/svelte-form-builder-community": 9, + "ptkdev/sveltekit-cordova-adapter": 16, + "ptkdev/sveltekit-electron-adapter": 13, + "sveltejs/rollup-plugin-svelte": 462, + "sveltejs/svelte-loader": 565, + "sveltejs/vite-plugin-svelte": 626, + "emh333/esbuild-svelte": 207, + "rixo/rollup-plugin-svelte-hot": 48, + "demoorjasper/parcel-plugin-svelte": 235, + "tehshrike/sveltify": 35, + "shinnn/gulp-svelte": 25, + "meteor-svelte/meteor-svelte": 115, + "starptech/sveltejs-brunch": 7, + "thelgevold/rules_svelte": 19, + "sveltejs/svelte-devtools": 892, + "sveltejs/svelte-preprocess": 1523, + "ls-age/svelte-preprocess-less": 13, + "tivac/modular-css": 268, + "ls-age/svelte-preprocess-sass": 91, + "jiangfengming/svelte-preprocess-css-hash": 6, + "jiangfengming/svelte-preprocess-html-asset": 3, + "kevmodrome/svelte-preprocessor-fetch": 49, + "sveltejs/eslint-plugin-svelte3": 353, + "sveltejs/prettier-plugin-svelte": 528, + "evanleck/vim-svelte": 271, + "leafoftree/vim-svelte-plugin": 108, + "coc-extensions/coc-svelte": 161, + "fxbois/web-mode": 1552, + "laosb/sveltenova": 15, + "proverbial-ninja/vscode-svelte-component-extractor": 23, + "stordahl/sveltekit-snippets": 31, + "srmullen/svelte-reactive-css-preprocess": 54, + "srmullen/svelte-subcomponent-preprocessor": 35, + "ota-meshi/eslint-plugin-svelte": 77, + "nstuyvesant/sveltekit-auth-example": 137, + "alessiogr/sveltekit-windicss-flowbite-template": 2, + "sawyerclick/cmsvelte": 16, + "agusid/boilerplate-svelte": 61, + "benjazehr/svelte-example-museums": 29, + "antony/svelte-box": 60, + "axelen123/svelte-ts-template": 21, + "beyonk-adventures/svelte-component-livereload-template": 14, + "vuesomedev/todomvc-svelte": 35, + "blade67/sveltron": 63, + "brandonxiang/svelte-webpack-mpa": 22, + "chuanqisun/svelte-electron-template": 12, + "dafn/svelte-typescript-parcel": 50, + "dafn/svelte-typescript-rollup": 77, + "devghost/svelte": 7, + "jonasmanser/svelte-ie11": 3, + "farhan2106/svelte-typescript": 36, + "farhan2106/svelte-typescript-ssr": 9, + "geakstr/svelte-3-rollup-typescript-vscode": 38, + "bholmesdev/svelte-starter-template": 43, + "itswadesh/svelte-commerce": 905, + "jerriclynsjohn/svelte-storybook-tailwind": 268, + "jorgegorka/svelte-firebase": 203, + "justinekizhak/svelte-tailwind-template": 2, + "lpshanley/svelte-phonegap": 9, + "lunatk/svelte-web-component-builder": 4, + "marcograhl/tailwindcss-svelte-starter": 112, + "markoboy/svelte-webpack-babel-scss": 6, + "muhajirdev/svelte-tailwind-template": 90, + "n0th1ng-else/svelte-typescript-sass": 11, + "nazimhali/svelte-template": 4, + "neighbourhoodie/svelte-pouchdb-couchdb": 57, + "ryburn52/svelte-typescript-sass-template": 16, + "nye/svelte-electron-better-sqlite3-starter": 17, + "ordinaryjellyfish/svelte-routing-template": 15, + "pankod/svelte-boilerplate": 273, + "patoi/svelte-component-library-template": 66, + "pbastowski/svelte-poi-starter": 10, + "processtract/svelte-ts-snowpack-vscode": 4, + "pyoner/svelte-typescript": 211, + "ricalamino/svelte-firebase-auth": 48, + "rich-harris/svelte-template-electron": 87, + "rixo/svelte-template-hot": 61, + "samuel-martineau/generator-svelte": 28, + "shyam-chen/svelte-starter": 108, + "soapdog/svelte-template-browserify": 6, + "spaceavocado/svelte-router-template": 12, + "stephanepericat/svelte-boilerplate": 17, + "stevealee/svelte-code-cypress-project": 5, + "sveltejs/component-template": 522, + "sveltejs/template": 1684, + "sveltejs/template-custom-element": 19, + "sveltejs/template-webpack": 291, + "syonip/svelte-cordova": 38, + "tommertom/svelte-ionic-app": 400, + "tonyrewin/svelte3-ts-boilerplate": 6, + "will-wow/svelte-typescript-template": 5, + "yoglib/svelte-component-template": 342, + "tejasag/sveltetron-9000": 38, + "navneetsharmaui/sveltekit-starter": 492, + "navneetsharmaui/sveltekit-blog": 128, + "kaladivo/svelte-kit-koa-boilerplate": 3, + "srmullen/sveltekit-stripe": 85, + "mvasigh/sveltekit-mdsvex-blog": 117, + "babichjacob/university-website": 1, + "svelte-add/postcss": 39, + "svelte-add/tailwindcss": 585, + "svelte-add/bulma": 30, + "svelte-add/coffeescript": 10, + "svelte-add/graphql-server": 31, + "svelte-add/firebase-hosting": 7, + "vhscom/svelte-headlessui-starter": 40, + "svelte-add/mdsvex": 77, + "leftium/pug-adder": 3, + "supabase-community/svelte-supabase": 60, + "rossyman/svelte-add-jest": 31, + "mailcheck-co/mailcheck.site": 9, + "ivanhofer/typesafe-i18n-demo-sveltekit": 68, + "colinbate/svelte-ts-tailwind-template": 66, + "the-homeless-god/sent-template": 68, + "sharu725/yuyutsu": 20, + "k-sato1995/sveltekit-blog-template": 15, + "importantimport/urara": 309, + "ryan-way-boilerplate/stew": 1, + "timoyo93/svelte-template": 0, + "microsoft/fast": 7997, + "sw-yx/swyxkit": 523, + "davipon/svelte-add-vitest": 12, + "kwchang0831/svelte-qwer": 270, + "kokizzu/svelte-mpa": 35, + "fede-rodes/hardhat-svelte-boilerplate": 0 + }, + "gitlab": { + "davidhund/svelte-carbonbadge": 0, + "public-e-soa-com/svelte-time-picker": 3, + "az67128/svelte-atoms": 17 + } +} diff --git a/src/lib/utils/stars.ts b/src/lib/utils/stars.ts new file mode 100644 index 0000000..ae29521 --- /dev/null +++ b/src/lib/utils/stars.ts @@ -0,0 +1,42 @@ +import stars from '$lib/stars.json'; + +type RepoInfo = { + type: 'Github' | 'Gitlab'; + identifier: string; +}; + +const githubNameRegexp = new RegExp( + 'https://github.com/([a-zA-Z0-9][a-zA-Z0-9-]{0,38}/[a-zA-Z0-9._-]{1,100})' +); +const gitlabNameRegExp = new RegExp('https://gitlab.com/([\\w-]+/[\\w-]+)'); + +export function getStarsCount(repositoryUrl: string): number | undefined { + const repoInfo = getType(repositoryUrl); + if (repoInfo === null) { + return undefined; + } + return stars[repoInfo.type === 'Gitlab' ? 'gitlab' : 'github'][repoInfo.identifier] ?? undefined; +} + +function getType(repositoryUrl: string): RepoInfo | null { + if (githubNameRegexp.test(repositoryUrl)) { + const identifier = repositoryUrl.match(githubNameRegexp)[1].toLowerCase(); + return { + type: 'Github', + identifier + }; + } + if (gitlabNameRegExp.test(repositoryUrl)) { + const identifier = repositoryUrl.match(gitlabNameRegExp)[1].toLowerCase(); + return { + type: 'Gitlab', + identifier + }; + } + return null; +} + +export function injectStars(data: Array): Array { + data.forEach((item) => (item.stars = getStarsCount(item.url))); + return data; +} diff --git a/src/routes/components/+page.svelte b/src/routes/components/+page.svelte index 495fca0..bb489d7 100644 --- a/src/routes/components/+page.svelte +++ b/src/routes/components/+page.svelte @@ -1,6 +1,7 @@