Mocked tests and remove ncc compilation (#32)
* Mocked tests and remove ncc compilation * Update workflow.yml * Update Dockerfile
This commit is contained in:
1 parent
03bede5482
commit
b4d0e85148
22 files changed
+6460
-1189
No files matched your search
@@ -0,0 +1,20 @@
|
|||||||
|
name: Publish Docker image
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [ published ]
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
name: Push Docker image to GitHub Packages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Publish image to GitHub Packages
|
||||||
|
uses: docker/build-push-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
registry: docker.pkg.github.com
|
||||||
|
repository: lowlighter/metrics/metrics
|
||||||
|
tag_with_ref: true
|
||||||
|
|
||||||
@@ -8,7 +8,8 @@ jobs:
|
|||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v3
|
- name: Flag stale issues and pull requests
|
||||||
|
uses: actions/stale@v3
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
stale-issue-message: This issue has been open 30 days without activity. It will be closed in 5 days if it remains inactive.
|
stale-issue-message: This issue has been open 30 days without activity. It will be closed in 5 days if it remains inactive.
|
||||||
|
|||||||
+10
-224
@@ -1,4 +1,4 @@
|
|||||||
name: Build
|
name: Build, tests and analyze
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -10,237 +10,23 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Setup
|
- name: Build lowlighter/metrics:${{ github.head_ref || github.base_ref }}
|
||||||
uses: actions/setup-node@v1
|
run: docker build -t lowlighter/metrics:${{ github.head_ref || github.base_ref }} .
|
||||||
with:
|
- name: Run tests
|
||||||
node-version: 15.x
|
run: docker run --workdir=/metrics --entrypoint="" lowlighter/metrics:${{ github.head_ref || github.base_ref }} npm test
|
||||||
- name: Install
|
|
||||||
run: npm ci
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
- name: Test
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
analyze:
|
analyze:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: ["test-master"]
|
needs: [ build ]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Setup
|
- name: Setup CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
config-file: ./.github/config/codeql.yml
|
config-file: ./.github/config/codeql.yml
|
||||||
- name: Analyze
|
- name: Analyze code
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
|
|
||||||
# Tests cases below are auto generated through `npm run build`
|
|
||||||
# Edit utils/workflow.yml instead if you need to update workflow
|
|
||||||
|
|
||||||
test-master:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
template: ["classic","terminal"]
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Base
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: header, activity, community, repositories, metadata
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > PageSpeed
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_pagespeed: yes
|
|
||||||
plugin_pagespeed_token: ${{ secrets.PAGESPEED_TOKEN }}
|
|
||||||
plugin_pagespeed_detailed: yes
|
|
||||||
plugin_pagespeed_screenshot: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (playlist - apple)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_music: yes
|
|
||||||
plugin_music_playlist: ${{ secrets.MUSIC_PLAYLIST_APPLE }}
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (playlist - spotify)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_music: yes
|
|
||||||
plugin_music_playlist: ${{ secrets.MUSIC_PLAYLIST_SPOTIFY }}
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (recent - spotify)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_music: yes
|
|
||||||
plugin_music_provider: spotify
|
|
||||||
plugin_music_token: ${{ secrets.SPOTIFY_TOKENS }}
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Posts (dev.to)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_posts: yes
|
|
||||||
plugin_posts_source: dev.to
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Isocalendar
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_isocalendar: yes
|
|
||||||
plugin_isocalendar_duration: full-year
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Habits
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_habits: yes
|
|
||||||
plugin_habits_from: 5
|
|
||||||
plugin_habits_charts: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Languages
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_languages: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Follow-up
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_followup: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Lines and Traffic
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_lines: yes
|
|
||||||
plugin_traffic: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Gists
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_gists: yes
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Topics (starred)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_topics: yes
|
|
||||||
plugin_topics_mode: starred
|
|
||||||
plugin_topics_sort: random
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Topics (mastered)
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_topics: yes
|
|
||||||
plugin_topics_mode: mastered
|
|
||||||
plugin_topics_sort: stars
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Projects
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_projects: yes
|
|
||||||
plugin_projects_repositories: lowlighter/metrics/projects/1
|
|
||||||
plugin_projects_limit: 2
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Tweets
|
|
||||||
uses: lowlighter/metrics@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.METRICS_TOKEN }}
|
|
||||||
dryrun: yes
|
|
||||||
repositories: 0
|
|
||||||
template: ${{ matrix.template }}
|
|
||||||
base: ""
|
|
||||||
plugins_errors_fatal: yes
|
|
||||||
plugin_tweets: yes
|
|
||||||
plugin_tweets_limit: 2
|
|
||||||
plugin_tweets_token: ${{ secrets.TWITTER_TOKEN }}
|
|
||||||
|
|
||||||
|
|
||||||
+3
-3
@@ -117,7 +117,7 @@ It should be avoided when possible as it increases drastically the size of gener
|
|||||||
* To optimize generated SVG
|
* To optimize generated SVG
|
||||||
* [axios/axios](https://github.com/axios/axios)
|
* [axios/axios](https://github.com/axios/axios)
|
||||||
* To make HTTP/S requests
|
* To make HTTP/S requests
|
||||||
* [actions/toolkit](https://github.com/actions/toolkit/tree/master) and [vercel/ncc](https://github.com/vercel/ncc)
|
* [actions/toolkit](https://github.com/actions/toolkit/tree/master)
|
||||||
* To build the GitHub Action
|
* To build the GitHub Action
|
||||||
* [vuejs/vue](https://github.com/vuejs/vue) and [egoist/vue-prism-component](https://github.com/egoist/vue-prism-component) + [PrismJS/prism](https://github.com/PrismJS/prism)
|
* [vuejs/vue](https://github.com/vuejs/vue) and [egoist/vue-prism-component](https://github.com/egoist/vue-prism-component) + [PrismJS/prism](https://github.com/PrismJS/prism)
|
||||||
* To display server application
|
* To display server application
|
||||||
@@ -127,5 +127,5 @@ It should be avoided when possible as it increases drastically the size of gener
|
|||||||
* To test and verify SVG validity
|
* To test and verify SVG validity
|
||||||
* [Marak/colors.js](https://github.com/Marak/colors.js)
|
* [Marak/colors.js](https://github.com/Marak/colors.js)
|
||||||
* To print colors in console
|
* To print colors in console
|
||||||
* [babel/minify](https://github.com/babel/minify)
|
* [facebook/jest](https://github.com/facebook/jest) and [nodeca/js-yaml](https://github.com/nodeca/js-yaml)
|
||||||
* To minify code
|
* For unit testing
|
||||||
+11
-5
@@ -1,11 +1,11 @@
|
|||||||
# Base image
|
# Base image
|
||||||
FROM node:15-buster-slim
|
FROM node:15-buster-slim
|
||||||
|
|
||||||
# Copy GitHub action
|
# Copy repository
|
||||||
COPY action/dist/index.js /index.js
|
COPY . /metrics
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
RUN chmod +x /index.js \
|
RUN chmod +x /metrics/action/index.mjs \
|
||||||
# Install latest chrome dev package, fonts to support major charsets and skip chromium download on puppeteer install
|
# Install latest chrome dev package, fonts to support major charsets and skip chromium download on puppeteer install
|
||||||
# Based on https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker
|
# Based on https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
@@ -21,9 +21,15 @@ RUN chmod +x /index.js \
|
|||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y ruby-full \
|
&& apt-get install -y ruby-full \
|
||||||
&& apt-get install -y git g++ cmake pkg-config libicu-dev zlib1g-dev libcurl4-openssl-dev libssl-dev ruby-dev \
|
&& apt-get install -y git g++ cmake pkg-config libicu-dev zlib1g-dev libcurl4-openssl-dev libssl-dev ruby-dev \
|
||||||
&& gem install github-linguist
|
&& gem install github-linguist \
|
||||||
|
# Install python for node-gyp
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y python3 \
|
||||||
|
# Install node modules
|
||||||
|
&& cd /metrics \
|
||||||
|
&& npm ci
|
||||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
|
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
|
||||||
ENV PUPPETEER_BROWSER_PATH "google-chrome-stable"
|
ENV PUPPETEER_BROWSER_PATH "google-chrome-stable"
|
||||||
|
|
||||||
# Execute GitHub action
|
# Execute GitHub action
|
||||||
ENTRYPOINT node /index.js
|
ENTRYPOINT node /metrics/action/index.mjs
|
||||||
+12
-6
@@ -324,18 +324,18 @@ inputs:
|
|||||||
description: Die on plugins errors
|
description: Die on plugins errors
|
||||||
default: no
|
default: no
|
||||||
|
|
||||||
# Verify SVG after generation
|
|
||||||
# Test whether SVG can be correctly parsed (used for testing)
|
|
||||||
verify:
|
|
||||||
description: Verify SVG after genaration
|
|
||||||
default: no
|
|
||||||
|
|
||||||
# Enable debug mode
|
# Enable debug mode
|
||||||
# Ensure you correctly put all sensitive informations in your repository secrets before !
|
# Ensure you correctly put all sensitive informations in your repository secrets before !
|
||||||
debug:
|
debug:
|
||||||
description: Enable debug logs
|
description: Enable debug logs
|
||||||
default: no
|
default: no
|
||||||
|
|
||||||
|
# Verify SVG after generation
|
||||||
|
# Test whether SVG can be correctly parsed (used for testing)
|
||||||
|
verify:
|
||||||
|
description: Verify SVG after generation
|
||||||
|
default: no
|
||||||
|
|
||||||
# Debug flags (used for testing)
|
# Debug flags (used for testing)
|
||||||
debug_flags:
|
debug_flags:
|
||||||
description: Debug flags
|
description: Debug flags
|
||||||
@@ -346,3 +346,9 @@ inputs:
|
|||||||
dryrun:
|
dryrun:
|
||||||
description: Enable dry-run
|
description: Enable dry-run
|
||||||
default: no
|
default: no
|
||||||
|
|
||||||
|
# Use mocked data
|
||||||
|
# Bypass external APIs which requires a token and sent mocked data (used for testing)
|
||||||
|
use_mocked_data:
|
||||||
|
description: Use mocked data instead of real APIs
|
||||||
|
default: no
|
||||||
Vendored
-123
@@ -1,123 +0,0 @@
|
|||||||
module.exports=(()=>{var _Mathhypot=Math.hypot,_Mathacos=Math.acos,_Mathtan=Math.tan,_Mathasin=Math.asin,_Mathsin=Math.sin,_Mathcos=Math.cos,_MathPI=Math.PI,_Mathsqrt=Math.sqrt,_NumberisInteger=Number.isInteger,_NumberPOSITIVE_INFINITY=Number.POSITIVE_INFINITY,_NumberNEGATIVE_INFINITY=Number.NEGATIVE_INFINITY,_Stringprototype=String.prototype,_NumberMAX_SAFE_INTEGER=Number.MAX_SAFE_INTEGER,_StringfromCharCode=String.fromCharCode,_Mathpow=Math.pow,_Mathabs=Math.abs,_Mathround=Math.round,_Mathfloor=Math.floor,_Mathceil=Math.ceil,_Mathmax=Math.max,_Mathmin=Math.min;function __webpack_require__(e){if(__webpack_module_cache__[e])return __webpack_module_cache__[e].exports;var t=__webpack_module_cache__[e]={exports:{}},r=!0;try{__webpack_modules__[e].call(t.exports,t,t.exports,__webpack_require__),r=!1}finally{r&&delete __webpack_module_cache__[e]}return t.exports}var __webpack_modules__={83994:(e,t,r)=>{"use strict";async function n({log:e=!0}={}){const t=e?console.debug:()=>null;t(`metrics/setup > setup`);const n="src/templates",a="src/queries",o={templates:{},queries:{},settings:{},statics:r.ab+"html",node_modules:b.resolve("node_modules")};if(t(`metrics/setup > load settings.json`),y.existsSync(r.ab+"settings.json")?(o.settings=JSON.parse(`${await y.promises.readFile(b.resolve("settings.json"))}`),t(`metrics/setup > load settings.json > success`)):t(`metrics/setup > load settings.json > (missing)`),o.settings.templates||(o.settings.templates={default:"classic",enabled:[]}),o.settings.plugins||(o.settings.plugins={}),o.settings.plugins.base={parts:["header","activity","community","repositories","metadata"]},o.settings.debug&&t(S.inspect(o.settings,{depth:1/0,maxStringLength:256})),t(`metrics/setup > load package.json`),y.existsSync(r.ab+"package.json")?(o.package=JSON.parse(`${await y.promises.readFile(b.resolve("package.json"))}`),t(`metrics/setup > load package.json > success`)):(t(`metrics/setup > load package.json > (missing)`),o.package={version:"2.10.0-beta",author:"lowlighter"}),y.existsSync(r.ab+"templates"))for(const e of await y.promises.readdir(n)){if(/.*[.]mjs$/.test(e))continue;t(`metrics/setup > load template [${e}]`);const r=[`${n}/${e}/image.svg`,`${n}/${e}/style.css`,`${n}/${e}/fonts.css`].map(t=>y.existsSync(b.resolve(t))?t:t.replace(`${n}/${e}/`,`${n}/classic/`)).map(e=>b.resolve(e)),[a,i,s]=await Promise.all(r.map(async e=>`${await y.promises.readFile(e)}`));o.templates[e]={image:a,style:i,fonts:s},t(`metrics/setup > load template [${e}] > success`),o.settings.debug&&Object.defineProperty(o.templates,e,{get(){t(`metrics/setup > reload template [${e}]`);const[n,a,o]=r.map(e=>`${y.readFileSync(e)}`);return t(`metrics/setup > reload template [${e}] > success`),{image:n,style:a,fonts:o}}})}else t(`metrics/setup > load templates from build`),o.templates=JSON.parse(Buffer.from(`eyJjbGFzc2ljIjp7ImltYWdlIjoiPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCI0ODBcIiBoZWlnaHQ9XCI8JT0gMTJcclxuICArICghIWJhc2UuaGVhZGVyKSo4MCArICh1c2VyLmlzSGlyZWFibGUpKjE2XHJcbiAgKyAoISFiYXNlLm1ldGFkYXRhKSozOFxyXG4gICsgKCghIWJhc2UuYWN0aXZpdHkpfHwoISFiYXNlLmNvbW11bml0eSkpKjEyOFxyXG4gICsgKCEhYmFzZS5yZXBvc2l0b3JpZXMpKjEwOFxyXG4gICsgKCghIWJhc2UucmVwb3NpdG9yaWVzKSooKCEhcGx1Z2lucy50cmFmZmljKXx8KCEhcGx1Z2lucy5saW5lcykpKSoxNlxyXG4gICsgKCEhcGx1Z2lucy5mb2xsb3d1cCkqNjhcclxuICArICghIXBsdWdpbnMucGFnZXNwZWVkKSoxMjYgKyAocGx1Z2lucy5wYWdlc3BlZWQ/LmRldGFpbGVkID8/IDApKjYqMjAgKyAoISFwbHVnaW5zLnBhZ2VzcGVlZD8uc2NyZWVuc2hvdCkqMzMwXHJcbiAgKyAoISFwbHVnaW5zLmhhYml0cykqMjggKyAoISFwbHVnaW5zLmhhYml0cz8uZmFjdHMpKjU4ICsgKCEhcGx1Z2lucy5oYWJpdHM/LmNoYXJ0cykqMjI2XHJcbiAgKyAoISFwbHVnaW5zLmxhbmd1YWdlcykqOTZcclxuICArICghIXBsdWdpbnMubXVzaWMpKjY0ICsgKHBsdWdpbnMubXVzaWM/LnRyYWNrcz8ubGVuZ3RoID8gMTQrTWF0aC5tYXgoMCwgcGx1Z2lucy5tdXNpYy50cmFja3MubGVuZ3RoLTEpKjM2IDogMClcclxuICArICghIXBsdWdpbnMucG9zdHMpKjY0ICsgKHBsdWdpbnMucG9zdHM/Lmxpc3Q/Lmxlbmd0aCA/PyAwKSo0MFxyXG4gICsgKCEhcGx1Z2lucy5pc29jYWxlbmRhcikqMTkyICsgKHBsdWdpbnMuaXNvY2FsZW5kYXI/LmR1cmF0aW9uID09PSAnZnVsbC15ZWFyJykqMTAwXHJcbiAgKyAoISFwbHVnaW5zLmdpc3RzKSo2OFxyXG4gICsgKCEhcGx1Z2lucy50b3BpY3MpKjE2MFxyXG4gICsgKCEhcGx1Z2lucy5wcm9qZWN0cykqMjIgKyAocGx1Z2lucy5wcm9qZWN0cz8ubGlzdD8ubGVuZ3RoID8/IDApKjYwICsgKCEhcGx1Z2lucy5wcm9qZWN0cz8uZXJyb3IpKjIyXHJcbiAgKyAoISFwbHVnaW5zLnR3ZWV0cykqNjQgKyAocGx1Z2lucy50d2VldHM/Lmxpc3Q/Lmxlbmd0aCA/PyAwKSo5MFxyXG4gICsgTWF0aC5tYXgoMCwgKCgoISFiYXNlLm1ldGFkYXRhKSsoISFiYXNlLmhlYWRlcikrKCghIWJhc2UuYWN0aXZpdHkpfHwoISFiYXNlLmNvbW11bml0eSkpKyghIWJhc2UucmVwb3NpdG9yaWVzKSsoKCEhcGx1Z2lucy5oYWJpdHMpKSsoISFwbHVnaW5zLnBhZ2VzcGVlZCkrKCEhcGx1Z2lucy5sYW5ndWFnZXMpKyghIXBsdWdpbnMubXVzaWMpKyghIXBsdWdpbnMucG9zdHMpKyghIXBsdWdpbnMuaXNvY2FsZW5kYXIpKyghIXBsdWdpbnMuZ2lzdHMpKyghIXBsdWdpbnMudG9waWNzKSsoISFwbHVnaW5zLnByb2plY3RzKSktMSkpKjRcclxuJT5cIj5cclxuXHJcbiAgPGRlZnM+PHN0eWxlPjwlPSBmb250cyAlPjwvc3R5bGU+PC9kZWZzPlxyXG5cclxuICA8c3R5bGU+XHJcbiAgICA8JT0gc3R5bGUgJT5cclxuICA8L3N0eWxlPlxyXG5cclxuICA8Zm9yZWlnbk9iamVjdCB4PVwiMFwiIHk9XCIwXCIgd2lkdGg9XCIxMDAlXCIgaGVpZ2h0PVwiMTAwJVwiPlxyXG4gICAgPGRpdiB4bWxucz1cImh0
Line truncated
|
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" style="margin-top: -52px;" viewBox="0,0 480,${"full-year"===o?270:170}">
|
|
||||||
${[1,2].map(e=>`
|
|
||||||
<filter id="brightness${e}">
|
|
||||||
<feComponentTransfer>
|
|
||||||
${[..."RGB"].map(t=>`<feFunc${t} type="linear" slope="${1-.4*e}" />`).join("")}
|
|
||||||
</feComponentTransfer>
|
|
||||||
</filter>`).join("")}
|
|
||||||
<g transform="scale(4) translate(12, 0)">`;for(const e of p.weeks){S+=`<g transform="translate(${1.7*b}, ${b})">`,i=0;for(const t of e.contributionDays){const e=t.contributionCount/m;S+=`
|
|
||||||
<g transform="translate(${-1.7*i}, ${i+(1-e)*y})">
|
|
||||||
<path fill="${t.color}" d="M1.7,2 0,1 1.7,0 3.4,1 z" />
|
|
||||||
<path fill="${t.color}" filter="url(#brightness1)" d="M0,1 1.7,2 1.7,${2+e*y} 0,${1+e*y} z" />
|
|
||||||
<path fill="${t.color}" filter="url(#brightness2)" d="M1.7,2 3.4,1 3.4,${1+e*y} 1.7,${2+e*y} z" />
|
|
||||||
</g>`,i++}S+=`</g>`,b++}return S+=`</g></svg>`,{streak:g,max:m,average:f,svg:S,duration:o}}catch(e){throw{error:{message:"An error occured",instance:e}}}},languages:async function({login:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.languages)return null;let{"languages.ignored":a="","languages.skipped":o=""}=r;a=decodeURIComponent(a).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),o=decodeURIComponent(o).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),console.debug(`metrics/compute/${e}/plugins > languages > processing ${t.user.repositories.nodes.length} repositories`);const s={colors:{},total:0,stats:{}};for(const r of t.user.repositories.nodes){if(o.includes(r.name.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > skipped repository ${r.name}`);continue}for(const{size:t,node:{color:n,name:o}}of Object.values(r.languages.edges)){if(a.includes(o.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > ignored language ${o}`);continue}s.stats[o]=(s.stats[o]??0)+t,s.colors[o]=n??"#ededed",s.total+=t}}console.debug(`metrics/compute/${e}/plugins > languages > computing stats`),Object.keys(s.stats).map(e=>s.stats[e]/=s.total),s.favorites=Object.entries(s.stats).sort(([e,t],[r,n])=>n-t).slice(0,8).map(([e,t])=>({name:e,value:t,color:s.colors[e],x:0}));for(let e=1;e<s.favorites.length;e++)s.favorites[e].x=s.favorites[e-1].x+s.favorites[e-1].value;return s}catch(e){throw{error:{message:"An error occured",instance:e}}}},lines:async function({login:e,data:t,imports:r,rest:n,q:a},{enabled:o=!1}={}){try{if(!o||!a.lines)return null;const i=t.user.repositories.nodes.map(({name:e})=>e)??[];console.debug(`metrics/compute/${e}/plugins > lines > querying api`);const s={added:0,deleted:0},l=await Promise.all(i.map(async t=>await n.repos.getContributorsStats({owner:e,repo:t})));return console.debug(`metrics/compute/${e}/plugins > lines > computing total diff`),l.map(({data:t})=>{if(Array.isArray(t)){const[r]=t.filter(({author:t})=>t.login===e);r&&r.weeks.forEach(({a:e,d:t})=>(s.added+=e,s.deleted+=t))}}),s.added=r.format(s.added),s.deleted=r.format(s.deleted),s}catch(e){throw{error:{message:"An error occured",instance:e}}}},music:a,pagespeed:async function({login:e,imports:t,data:r,q:n},{enabled:a=!1,token:o=null}={}){try{if(!a||!n.pagespeed||!r.user.websiteUrl)return null;let{"pagespeed.detailed":i=!1,"pagespeed.screenshot":s=!1}=n;i=!!i;let l=r.user.websiteUrl;/^https?:[/][/]/.test(l)||(l=`https://${l}`);const d={url:l,detailed:i,scores:[],metrics:{}};console.debug(`metrics/compute/${e}/plugins > pagespeed > querying api for ${l}`);const p=new Map;if(await Promise.all(["performance","accessibility","best-practices","seo"].map(async r=>{console.debug(`metrics/compute/${e}/plugins > pagespeed > performing audit ${r}`);const n=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${r}&url=${l}&key=${o}`);console.debug(n.data);const{score:a,title:i}=n.data.lighthouseResult.categories[r];p.set(r,{score:a,title:i}),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`),s&&"performance"===r&&(d.screenshot=n.data.lighthouseResult.audits["final-screenshot"].details.data,console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`))})),d.scores=[p.get("performance"),p.get("accessibility"),p.get("best-practices"),p.get("seo")],i){console.debug(`metrics/compute/${e}/plugins > pagespeed > performing detailed audit`);const r=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${l}&key=${o}`);console.debug(r.data),Object.assign(d.metrics,...r.data.lighthouseResult.audits.metrics.details.items),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed detailed audit (status code ${r.status})`)}return d}catch(e){let t="An error occured";if(e.isAxiosError){const r=e.response?.status,n=e.response?.data?.error?.message?.match(/Lighthouse returned error: (?<description>[A-Z_]+)/)?.groups?.description??null;t=`API returned ${r}${n?` (${n})`:""}`,e=e.response?.data??null}throw{error:{message:t,instance:e}}}},posts:async function({imports:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.posts)return null;const a=t.user.login;let{"posts.source":o="","posts.limit":i=4}=r;i=_Mathmax(1,_Mathmin(30,+i)),console.debug(`metrics/compute/${a}/plugins > posts > processing with source ${o}`);let s=null;switch(o){case"dev.to":{console.debug(`metrics/compute/${a}/plugins > posts > querying api`),s=(await e.axios.get(`https://dev.to/api/articles?username=${a}&state=fresh`)).data.map(({title:e,readable_publish_date:t})=>({title:e,date:t}));break}default:throw{error:{message:`Unsupported source "${o}"`}};}if(Array.isArray(s))return 0<i&&(console.debug(`metrics/compute/${a}/plugins > posts > keeping only ${i} posts`),s.splice(i)),{source:o,list:s};throw{error:{message:`An error occured (could not retLine truncated
|
|
||||||
query Sha {
|
|
||||||
repository(owner: "${t.context.repo.owner}", name: "${t.context.repo.repo}") {
|
|
||||||
object(expression: "${r}:${m}") { ... on Blob { oid } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);o=e}catch(e){console.debug(e)}console.log(`Previous render sha | ${o??"(none)"}`),await a.repos.createOrUpdateFileContents({...t.context.repo,path:m,message:`Update ${m} - [Skip GitHub Action]`,content:Buffer.from(E).toString("base64"),...(o?{sha:o}:{})}),console.log(`Commit to repo | ok`)}console.log(`Success, thanks for using metrics !`),process.exit(0)}catch(t){if(console.error(t),!i(e.getInput("debug")))for(const e of["_".repeat(64),"An error occured, logging debug message :",...s])console.log(e);e.setFailed(t.message),process.exit(1)}})().catch(()=>process.exit(1))},12541:function(e,t,r){"use strict";function n(e,t,r){const n=new p(e,t,r);process.stdout.write(n.toString()+s.EOL)}function a(e){return l.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function o(e){return l.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t};Object.defineProperty(t,"__esModule",{value:!0});const s=i(r(12087)),l=r(74332);t.issueCommand=n,t.issue=function(e,t=""){n(e,{},t)};const d="::";class p{constructor(e,t,r){e||(e="missing.command"),this.command=e,this.properties=t,this.message=r}toString(){let e=d+this.command;if(this.properties&&0<Object.keys(this.properties).length){e+=" ";let t=!0;for(const r in this.properties)if(this.properties.hasOwnProperty(r)){const n=this.properties[r];n&&(t?t=!1:e+=",",e+=`${r}=${o(n)}`)}}return e+=`${d}${a(this.message)}`,e}}},32882:function(e,t,r){"use strict";function n(e){process.exitCode=g.Failure,a(e)}function a(e){d.issue("error",e instanceof Error?e.toString():e)}function o(e){d.issue("group",e)}function i(){d.issue("endgroup")}var s=this&&this.__awaiter||function(e,t,r,n){function a(e){return e instanceof r?e:new r(function(t){t(e)})}return new(r||(r=Promise))(function(r,o){function i(e){try{l(n.next(e))}catch(t){o(t)}}function s(e){try{l(n["throw"](e))}catch(t){o(t)}}function l(e){e.done?r(e.value):a(e.value).then(i,s)}l((n=n.apply(e,t||[])).next())})},l=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t};Object.defineProperty(t,"__esModule",{value:!0});const d=r(12541),p=r(29582),c=r(74332),u=l(r(12087)),m=l(r(85622));var g;(function(e){e[e.Success=0]="Success",e[e.Failure=1]="Failure"})(g=t.ExitCode||(t.ExitCode={})),t.exportVariable=function(e,t){const r=c.toCommandValue(t);process.env[e]=r;const n=process.env.GITHUB_ENV||"";if(n){const t=`${e}<<${"_GitHubActionsFileCommandDelimeter_"}${u.EOL}${r}${u.EOL}${"_GitHubActionsFileCommandDelimeter_"}`;p.issueCommand("ENV",t)}else d.issueCommand("set-env",{name:e},r)},t.setSecret=function(e){d.issueCommand("add-mask",{},e)},t.addPath=function(e){const t=process.env.GITHUB_PATH||"";t?p.issueCommand("PATH",e):d.issueCommand("add-path",{},e),process.env.PATH=`${e}${m.delimiter}${process.env.PATH}`},t.getInput=function(e,t){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&t.required&&!r)throw new Error(`Input required and not supplied: ${e}`);return r.trim()},t.setOutput=function(e,t){d.issueCommand("set-output",{name:e},t)},t.setCommandEcho=function(e){d.issue("echo",e?"on":"off")},t.setFailed=n,t.isDebug=function(){return"1"===process.env.RUNNER_DEBUG},t.debug=function(e){d.issueCommand("debug",{},e)},t.error=a,t.warning=function(e){d.issue("warning",e instanceof Error?e.toString():e)},t.info=function(e){process.stdout.write(e+u.EOL)},t.startGroup=o,t.endGroup=i,t.group=function(e,t){return s(this,void 0,void 0,function*(){o(e);let r;try{r=yield t()}finally{i()}return r})},t.saveState=function(e,t){d.issueCommand("save-state",{name:e},t)},t.getState=function(e){return process.env[`STATE_${e}`]||""}},29582:function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t};Object.defineProperty(t,"__esModule",{value:!0});const a=n(r(35747)),o=n(r(12087)),i=r(74332);t.issueCommand=function(e,t){const r=process.env[`GITHUB_${e}`];if(!r)throw new Error(`Unable to find environment variable for file command ${e}`);if(!a.existsSync(r))throw new Error(`Missing file at path: ${r}`);a.appendFileSync(r,`${i.toCommandValue(t)}${o.EOL}`,{encoding:"utf8"})}},74332:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.toCommandValue=function(e){return null===e||void 0===e?"":"string"==typeof e||e instanceof String?e:JSON.stringify(e)}},84873:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Context=void 0;const n=r(35747),a=r(12087);class o{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(n.existsSync(process.e
Line truncated
|
|
||||||
* @file Embedded JavaScript templating engine. {@link http://ejs.co}
|
|
||||||
* @author Matthew Eernisse <mde@fleegix.org>
|
|
||||||
* @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
|
|
||||||
* @project EJS
|
|
||||||
* @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
|
|
||||||
*/function n(e,r){var n;if(r.some(function(r){return n=t.resolveInclude(e,r,!0),g.existsSync(n)}))return n}function a(e,r){var a=r.views,o=/^[A-Za-z]+:\\|^\//.exec(e),i,s;if(o&&o.length)e=e.replace(/^\/*/,""),i=Array.isArray(r.root)?n(e,r.root):t.resolveInclude(e,r.root||"/",!0);else if(r.filename&&(s=t.resolveInclude(e,r.filename),g.existsSync(s)&&(i=s)),!i&&Array.isArray(a)&&(i=n(e,a)),!i&&"function"!=typeof r.includer)throw new Error("Could not find the include file \""+r.escapeFunction(e)+"\"");return i}function i(e,r){var n=e.filename,a=1<arguments.length,o;if(e.cache){if(!n)throw new Error("cache option requires a filename");if(o=t.cache.get(n),o)return o;a||(r=l(n).toString().replace(x,""))}else if(!a){if(!n)throw new Error("Internal EJS error: no file name or template provided");r=l(n).toString().replace(x,"")}return o=t.compile(r,e),e.cache&&t.cache.set(n,o),o}function s(e,r,n){var a;if(!n){if("function"==typeof t.promiseImpl)return new t.promiseImpl(function(t,n){try{a=i(e)(r),t(a)}catch(e){n(e)}});throw new Error("Please provide a callback function")}else{try{a=i(e)(r)}catch(e){return n(e)}n(null,a)}}function l(e){return t.fileLoader(e)}function p(e,t){var r=h.shallowCopy({},t);if(r.filename=a(e,r),"function"==typeof t.includer){var n=t.includer(e,r.filename);if(n&&(n.filename&&(r.filename=n.filename),n.template))return i(r,n.template)}return i(r)}function c(e,t,r,n,a){var o=t.split("\n"),s=_Mathmax(n-3,0),l=_Mathmin(o.length,n+3),d=a(r),p=o.slice(s,l).map(function(e,t){var r=t+s+1;return(r==n?" >> ":" ")+r+"| "+e}).join("\n");throw e.path=d,e.message=(d||"ejs")+":"+n+"\n"+p+"\n\n"+e.message,e}function u(e){return e.replace(/;(\s*$)/,"$1")}function m(e,r){r=r||{};var n={};this.templateText=e,this.mode=null,this.truncate=!1,this.currentLine=1,this.source="",n.client=r.client||!1,n.escapeFunction=r.escape||r.escapeFunction||h.escapeXML,n.compileDebug=!1!==r.compileDebug,n.debug=!!r.debug,n.filename=r.filename,n.openDelimiter=r.openDelimiter||t.openDelimiter||"<",n.closeDelimiter=r.closeDelimiter||t.closeDelimiter||">",n.delimiter=r.delimiter||t.delimiter||"%",n.strict=r.strict||!1,n.context=r.context,n.cache=r.cache||!1,n.rmWhitespace=r.rmWhitespace,n.root=r.root,n.includer=r.includer,n.outputFunctionName=r.outputFunctionName,n.localsName=r.localsName||t.localsName||"locals",n.views=r.views,n.async=r.async,n.destructuredLocals=r.destructuredLocals,n.legacyInclude="undefined"==typeof r.legacyInclude||!!r.legacyInclude,n._with=!n.strict&&("undefined"==typeof r._with||r._with),this.opts=n,this.regex=this.createRegex()}var g=r(35747),o=r(85622),h=r(74998),f=!1,y=r(52021).i8,b=["delimiter","scope","context","debug","compileDebug","client","_with","rmWhitespace","strict","filename","async"],S=b.concat("cache"),x=/^\uFEFF/;t.cache=h.cache,t.fileLoader=g.readFileSync,t.localsName="locals",t.promiseImpl=new Function("return this;")().Promise,t.resolveInclude=function(e,t,r){var n=o.dirname,a=o.extname,i=o.resolve,s=i(r?t:n(t),e),l=a(e);return l||(s+=".ejs"),s},t.compile=function(e,t){var r;return t&&t.scope&&(!f&&(console.warn("`scope` option is deprecated and will be removed in EJS 3"),f=!0),!t.context&&(t.context=t.scope),delete t.scope),r=new m(e,t),r.compile()},t.render=function(e,t,r){var n=t||{},a=r||{};return 2==arguments.length&&h.shallowCopyFromList(a,n,b),i(a,e)(n)},t.renderFile=function(){var e=Array.prototype.slice.call(arguments),t=e.shift(),r={filename:t},n,a,o;return"function"==typeof arguments[arguments.length-1]&&(n=e.pop()),e.length?(a=e.shift(),e.length?h.shallowCopy(r,e.pop()):(a.settings&&(a.settings.views&&(r.views=a.settings.views),a.settings["view cache"]&&(r.cache=!0),o=a.settings["view options"],o&&h.shallowCopy(r,o)),h.shallowCopyFromList(r,a,S)),r.filename=t):a={},s(r,a,n)},t.Template=m,t.clearCache=function(){t.cache.reset()},m.modes={EVAL:"eval",ESCAPED:"escaped",RAW:"raw",COMMENT:"comment",LITERAL:"literal"},m.prototype={createRegex:function(){var e="(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)",t=h.escapeRegExpChars(this.opts.delimiter),r=h.escapeRegExpChars(this.opts.openDelimiter),n=h.escapeRegExpChars(this.opts.closeDelimiter);return e=e.replace(/%/g,t).replace(/</g,r).replace(/>/g,n),new RegExp(e)},compile:function(){var t=this.opts,r="",n="",a=t.escapeFunction,s,l,e;if(!this.source){if(this.generateSource(),r+=" var __output = \"\";\n function __append(s) { if (s !== undefined && s !== null) __output += s }\n",t.outputFunctionName&&(r+=" var "+t.outputFunctionName+" = __append;\n"),t.destructuredLocals&&t.destructuredLocals.length){for(var d=" var __locals = ("+t.localsName+" || {}),\n",u=0,m;u<t.destructuredLocals.length;u++)m=t.destructuredLocals[u],0<u&&(d+=",\n "),d+=m+" = __locals."+m;r+=d+";\n"}!1!==t._with&&(r+=" with ("+t.localsName+" || {}) {\n",n+=" }\n"),n+=" return __output;\n",this.source=r+this.source+n}s=t.compileDebug?"var __line = 1\n , __lines = "+JSON.stringify(this.templateText)+"\n , __filename = "+(t.filename?JSON.stringify(t.filename):"un
Line truncated
|
|
||||||
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/function r(e){return"[object Object]"===Object.prototype.toString.call(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.isPlainObject=function(e){var t,n;return!1!==r(e)&&((t=e.constructor,void 0===t)||(n=t.prototype,!1!==r(n)&&!1!==n.hasOwnProperty("isPrototypeOf")))}},31894:(e,t,r)=>{"use strict";var n=r(7158);e.exports=n},7158:(e,t,r)=>{"use strict";function n(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}var a=r(3434),o=r(86156);e.exports.Type=r(78099),e.exports.Schema=r(58126),e.exports.FAILSAFE_SCHEMA=r(21712),e.exports.JSON_SCHEMA=r(75698),e.exports.CORE_SCHEMA=r(11277),e.exports.DEFAULT_SAFE_SCHEMA=r(23713),e.exports.DEFAULT_FULL_SCHEMA=r(17028),e.exports.load=a.load,e.exports.loadAll=a.loadAll,e.exports.safeLoad=a.safeLoad,e.exports.safeLoadAll=a.safeLoadAll,e.exports.dump=o.dump,e.exports.safeDump=o.safeDump,e.exports.YAMLException=r(41030),e.exports.MINIMAL_SCHEMA=r(21712),e.exports.SAFE_SCHEMA=r(23713),e.exports.DEFAULT_SCHEMA=r(17028),e.exports.scan=n("scan"),e.exports.parse=n("parse"),e.exports.compose=n("compose"),e.exports.addConstructor=n("addConstructor")},39990:e=>{"use strict";function t(e){return"undefined"==typeof e||null===e}e.exports.isNothing=t,e.exports.isObject=function(e){return"object"==typeof e&&null!==e},e.exports.toArray=function(e){return Array.isArray(e)?e:t(e)?[]:[e]},e.exports.repeat=function(e,t){var r="",n;for(n=0;n<t;n+=1)r+=e;return r},e.exports.isNegativeZero=function(e){return 0===e&&_NumberNEGATIVE_INFINITY===1/e},e.exports.extend=function(e,t){var r,n,a,o;if(t)for(o=Object.keys(t),r=0,n=o.length;r<n;r+=1)a=o[r],e[a]=t[a];return e}},86156:(e,t,r)=>{"use strict";function n(e,t){var r,n,a,o,i,s,l;if(null===t)return{};for(r={},n=Object.keys(t),(a=0,o=n.length);a<o;a+=1)i=n[a],s=t[i]+"","!!"===i.slice(0,2)&&(i="tag:yaml.org,2002:"+i.slice(2)),l=e.compiledTypeMap.fallback[i],l&&q.call(l.styleAliases,s)&&(s=l.styleAliases[s]),r[i]=s;return r}function a(e){var t,r,n;if(t=e.toString(16).toUpperCase(),255>=e)r="x",n=2;else if(65535>=e)r="u",n=4;else if(4294967295>=e)r="U",n=8;else throw new R("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+r+z.repeat("0",n-t.length)+t}function o(e){this.schema=e.schema||I,this.indent=_Mathmax(1,e.indent||2),this.noArrayIndent=e.noArrayIndent||!1,this.skipInvalid=e.skipInvalid||!1,this.flowLevel=z.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=n(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.condenseFlow=e.condenseFlow||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function i(e,t){for(var r=z.repeat(" ",t),n=0,a=-1,o="",i=e.length,s;n<i;)a=e.indexOf("\n",n),-1===a?(s=e.slice(n),n=i):(s=e.slice(n,a+1),n=a+1),s.length&&"\n"!==s&&(o+=r),o+=s;return o}function s(e,t){return"\n"+z.repeat(" ",e.indent*t)}function l(e,t){var r,n,a;for(r=0,n=e.implicitTypes.length;r<n;r+=1)if(a=e.implicitTypes[r],a.resolve(t))return!0;return!1}function d(e){return 32===e||9===e}function p(e){return 32<=e&&126>=e||161<=e&&55295>=e&&8232!==e&&8233!==e||57344<=e&&65533>=e&&65279!==e||65536<=e&&1114111>=e}function u(e){return p(e)&&!d(e)&&65279!==e&&13!==e&&10!==e}function m(e,t){return p(e)&&65279!==e&&44!==e&&91!==e&&93!==e&&123!==e&&125!==e&&58!==e&&(35!==e||t&&u(t))}function g(e){return p(e)&&65279!==e&&!d(e)&&45!==e&&63!==e&&58!==e&&44!==e&&91!==e&&93!==e&&123!==e&&125!==e&&35!==e&&38!==e&&42!==e&&33!==e&&124!==e&&61!==e&&62!==e&&39!==e&&34!==e&&37!==e&&64!==e&&96!==e}function h(e){return /^\n* /.test(e)}function f(e,t,r,n,a){var o=!1,s=!1,l=-1!==n,c=-1,u=g(e.charCodeAt(0))&&!d(e.charCodeAt(e.length-1)),f,y,b;if(t)for(f=0;f<e.length;f++){if(y=e.charCodeAt(f),!p(y))return 5;b=0<f?e.charCodeAt(f-1):null,u=u&&m(y,b)}else{for(f=0;f<e.length;f++){if(y=e.charCodeAt(f),10===y)o=!0,l&&(s=s||f-c-1>n&&" "!==e[c+1],c=f);else if(!p(y))return 5;b=0<f?e.charCodeAt(f-1):null,u=u&&m(y,b)}s=s||l&&f-c-1>n&&" "!==e[c+1]}return o||s?9<r&&h(e)?5:s?4:3:u&&!a(e)?1:2}function y(e,t,r,n){e.dump=function(){function a(t){return l(e,t)}if(0===t.length)return"''";if(!e.noCompatMode&&-1!==N.indexOf(t))return"'"+t+"'";var o=e.indent*_Mathmax(1,r),s=-1===e.lineWidth?-1:_Mathmax(_Mathmin(e.lineWidth,40),e.lineWidth-o),d=n||-1<e.flowLevel&&r>=e.flowLevel;switch(f(t,d,e.indent,s,a)){case 1:return t;case 2:return"'"+t.replace(/'/g,"''")+"'";case 3:return"|"+b(t,e.indent)+S(i(t,o));case 4:return">"+b(t,e.indent)+S(i(x(t,s),o));case 5:return"\""+k(t,s)+"\"";default:throw new R("impossible error: invalid scalar style");}}()}function b(e,t){var r=h(e)?t+"":"",n="\n"===e[e.length-1],a=n&&("\n"===e[e.length-2]||"\n"===e),o=a?"+":n?"":"-";return r+o+"\n"}function S(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function x(e,t){for(var r=/(\n+)([^\n]*)/g,n=function(){var n=e.indexOf("\n");returnLine truncated
|
|
||||||
(() => {
|
|
||||||
${r}
|
|
||||||
const checkWaitForOptions = ${function(e,t,r){if(!e)return r;if(!t&&!r)return e;const n=e.nodeType===Node.TEXT_NODE?e.parentElement:e,a=window.getComputedStyle(n),o=a&&"hidden"!==a.visibility&&function(){const e=n.getBoundingClientRect();return!!(e.top||e.bottom||e.width||e.height)}();return t===o||r===!o?e:null}};
|
|
||||||
return (${e})(...args)
|
|
||||||
})() `},readProtocolStream:async function(e,t,r){if(!g.isNode&&r)throw new Error("Cannot write to a path outside of Node.js environment.");const n=g.isNode?await s():null;let a=!1,o;r&&n&&(o=await n.promises.open(r,"w"));const i=[];for(;!a;){const s=await e.send("IO.read",{handle:t});a=s.eof;const l=Buffer.from(s.data,s.base64Encoded?"base64":void 0);i.push(l),r&&n&&(await n.promises.writeFile(o,l))}r&&(await o.close()),await e.send("IO.close",{handle:t});let l=null;try{l=Buffer.concat(i)}finally{return l}},waitWithTimeout:async function(e,t,r){let n;const a=new c.TimeoutError(`waiting for ${t} failed: timeout ${r}ms exceeded`),o=new Promise((e,t)=>n=t);let i=null;r&&(i=setTimeout(()=>n(a),r));try{return await Promise.race([e,o])}finally{i&&clearTimeout(i)}},waitForEvent:async function(e,t,r,o,i){function s(){a([m]),clearTimeout(l)}let l,d,p;const u=new Promise((e,t)=>{d=e,p=t}),m=n(e,t,e=>{r(e)&&d(e)});o&&(l=setTimeout(()=>{p(new c.TimeoutError("Timeout exceeded while waiting for event"))},o));const g=await Promise.race([u,i]).then(e=>(s(),e),e=>{throw s(),e});if(g instanceof Error)throw g;return g},isString:o,isNumber:function(e){return"number"==typeof e||e instanceof Number},importFSModule:s,addEventListener:n,removeEventListeners:a,valueFromRemoteObject:function(e){if(m.assert(!e.objectId,"Cannot extract value when objectId is given"),e.unserializableValue){if("bigint"===e.type&&"undefined"!=typeof BigInt)return BigInt(e.unserializableValue.replace("n",""));switch(e.unserializableValue){case"-0":return-0;case"NaN":return NaN;case"Infinity":return 1/0;case"-Infinity":return-Infinity;default:throw new Error("Unsupported unserializable value: "+e.unserializableValue);}}return e.value},getExceptionMessage:function(e){if(e.exception)return e.exception.description||e.exception.value;let t=e.text;if(e.stackTrace)for(const r of e.stackTrace.callFrames){const e=r.url+":"+r.lineNumber+":"+r.columnNumber,n=r.functionName||"<anonymous>";t+=`\n at ${n} (${e})`}return t},releaseObject:async function(e,r){r.objectId&&(await e.send("Runtime.releaseObject",{objectId:r.objectId}).catch(e=>{t.debugError(e)}))}}},23222:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isNode=void 0,t.isNode=!!("undefined"!=typeof process&&process.version)},80527:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.initializePuppeteerNode=void 0;const a=r(9323),o=r(14148),i=n(r(10837));t.initializePuppeteerNode=e=>{const t=i.default.sync(__dirname);let r=o.PUPPETEER_REVISIONS.chromium;const n="puppeteer-core"===e,s=n?void 0:process.env.PUPPETEER_PRODUCT||process.env.npm_config_puppeteer_product||process.env.npm_package_config_puppeteer_product;return n||"firefox"!==s||(r=o.PUPPETEER_REVISIONS.firefox),new a.PuppeteerNode({projectRoot:t,preferredRevision:r,isPuppeteerCore:n,productName:s})}},90176:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=r(80527),a=r(23222);if(!a.isNode)throw new Error("Trying to run Puppeteer-Node in a web environment.");t.default=n.initializePuppeteerNode("puppeteer")},77463:function(e,t,r){"use strict";function n(e,t,r){if("chrome"===e){if("linux"===t)return"chrome-linux";if("mac"===t)return"chrome-mac";if("win32"===t||"win64"===t)return 591479<parseInt(r,10)?"chrome-win":"chrome-win32"}else if("firefox"===e)return t}function a(e,t,r,a){const o=x.format(R[e][t],r,a,n(e,t,a));return o}function o(){b.stat("/usr/bin/chromium-browser",function(e,t){if(void 0===t)throw console.error(`The chromium binary is not available for arm64: `),console.error(`If you are on Ubuntu, you can install with: `),console.error(`\n apt-get install chromium-browser\n`),new Error})}function i(e){return new Promise(t=>{b.access(e,e=>t(!e))})}function s(e,t){const r=S.basename(t),n=r.split("-");if(2!==n.length)return null;const[a,o]=n;return R[e][a]?{product:e,platform:a,revision:o}:null}function l(e,t,r){function n(e){a+=e.length,r(a,o)}z(`Downloading binary from ${e}`);let a=0,o=0,i,s;const l=new Promise((e,t)=>{i=e,s=t}),d=u(e,"GET",a=>{if(200!==a.statusCode){const t=new Error(`Download failed: server returned code ${a.statusCode}. URL: ${e}`);return a.resume(),void s(t)}const l=b.createWriteStream(t);l.on("finish",()=>i()),l.on("error",e=>s(e)),a.pipe(l),o=parseInt(a.headers["content-length"],10),r&&a.on("data",n)});return d.on("error",e=>s(e)),l}function d(e,t){if(z(`Installing ${e} to ${t}`),e.endsWith(".zip"))return _.default(e,{dir:t});if(e.endsWith(".tar.bz2"))return p(e,t);if(e.endsWith(".dmg"))return W(t).then(()=>c(e,t));throw new Error(`Unsupported archive format: ${e}`)}function p(e,t){const n=r(16974),a=r(1650);return new Promise((r,o)=>{const i=n.extract(t);i.on("error",o),i.on("finish",r);const s=b.createReadStream(e);s.pipe(a()).pipe(i)})}function c(e,t){function r(){if(n){const e=`hdiutil detach "${n}" -quiet`;z(`Unmounting ${n}`),v.exec(e,e=>{e&&console.
Line truncated
|
|
||||||
This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser.
|
|
||||||
Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed.
|
|
||||||
If you think this is a bug, please report it on the Puppeteer issue tracker.`}\nError cause: ${e.stack}`)}u.helper.removeEventListeners(this._listeners)}async setupConnection(e){const{usePipe:t,timeout:r,slowMo:a,preferredRevision:o}=e;if(!t){const e=await n(this.proc,r,o),t=await g.NodeWebSocketTransport.create(e);this.connection=new m.Connection(e,t,a)}else{const{3:e,4:t}=this.proc.stdio,r=new h.PipeTransport(e,t);this.connection=new m.Connection("",r,a)}return this.connection}}},93935:function(e,t,r){"use strict";function n(e){let t;if(!e._isPuppeteerCore){const e=process.env.PUPPETEER_EXECUTABLE_PATH||process.env.npm_config_puppeteer_executable_path||process.env.npm_package_config_puppeteer_executable_path;if(e){const t=d.existsSync(e)?null:"Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: "+e;return{executablePath:e,missingText:t}}t=process.env.PUPPETEER_DOWNLOAD_PATH||process.env.npm_config_puppeteer_download_path||process.env.npm_package_config_puppeteer_download_path}const r=new p.BrowserFetcher(e._projectRoot,{product:e.product,path:t});if(!e._isPuppeteerCore&&"chrome"===e.product){const e=process.env.PUPPETEER_CHROMIUM_REVISION;if(e){const t=r.revisionInfo(e),n=t.local?null:"Tried to use PUPPETEER_CHROMIUM_REVISION env variable to launch browser but did not find executable at: "+t.executablePath;return{executablePath:t.executablePath,missingText:n}}}const n=r.revisionInfo(e._preferredRevision),a=n.local?null:`Could not find browser revision ${e._preferredRevision}. Run "PUPPETEER_PRODUCT=firefox npm install" or "PUPPETEER_PRODUCT=firefox yarn install" to download a supported Firefox browser binary.`;return{executablePath:n.executablePath,missingText:a}}var a=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e["default"]=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!=r&&Object.hasOwnProperty.call(e,r)&&a(t,e,r);return o(t,e),t};Object.defineProperty(t,"__esModule",{value:!0});const s=i(r(12087)),l=i(r(85622)),d=i(r(35747)),p=r(77463),c=r(10487),u=r(15228),m=r(31669),g=m.promisify(d.mkdtemp),h=m.promisify(d.writeFile);class f{constructor(e,t,r){this._projectRoot=e,this._preferredRevision=t,this._isPuppeteerCore=r}async launch(e={}){const{ignoreDefaultArgs:t=!1,args:r=[],dumpio:a=!1,executablePath:o=null,pipe:i=!1,env:d=process.env,handleSIGINT:p=!0,handleSIGTERM:m=!0,handleSIGHUP:h=!0,ignoreHTTPSErrors:f=!1,defaultViewport:y={width:800,height:600},slowMo:b=0,timeout:S=3e4}=e,x=l.join(s.tmpdir(),"puppeteer_dev_chrome_profile-"),v=[];t?Array.isArray(t)?v.push(...this.defaultArgs(e).filter(e=>!t.includes(e))):v.push(...r):v.push(...this.defaultArgs(e));let k=null;v.some(e=>e.startsWith("--remote-debugging-"))||v.push(i?"--remote-debugging-pipe":"--remote-debugging-port=0"),v.some(e=>e.startsWith("--user-data-dir"))||(k=await g(x),v.push(`--user-data-dir=${k}`));let C=o;if("arm64"===s.arch())C="/usr/bin/chromium-browser";else if(!o){const{missingText:e,executablePath:t}=n(this);if(e)throw new Error(e);C=t}const _=v.includes("--remote-debugging-pipe"),w=new u.BrowserRunner(C,v,k);w.start({handleSIGHUP:h,handleSIGTERM:m,handleSIGINT:p,dumpio:a,env:d,pipe:_});try{const e=await w.setupConnection({usePipe:_,timeout:S,slowMo:b,preferredRevision:this._preferredRevision}),t=await c.Browser.create(e,[],f,y,w.proc,w.close.bind(w));return await t.waitForTarget(e=>"page"===e.type()),t}catch(e){throw w.kill(),e}}defaultArgs(e={}){const t=["--disable-background-networking","--enable-features=NetworkService,NetworkServiceInProcess","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-client-side-phishing-detection","--disable-component-extensions-with-background-pages","--disable-default-apps","--disable-dev-shm-usage","--disable-extensions","--disable-features=TranslateUI","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-popup-blocking","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-sync","--force-color-profile=srgb","--metrics-recording-only","--no-first-run","--enable-automation","--password-store=basic","--use-mock-keychain","--enable-blink-features=IdleDetection"],{devtools:r=!1,headless:n=!r,args:a=[],userDataDir:o=null}=e;return o&&t.push(`--user-data-dir=${l.resolve(o)}`),r&&t.push("--auto-open-devtools-for-tabs"),n&&t.push("--headless","--hide-scrollbars","--mute-audio"),a.every(e=>e.startsWith("-"))&&t.push("about:blank"),t.push(...a),t}executablePath(){return n(this).executablePath}get product(){return"chrome"}}class y{constructor(e,t,r){this._projectRoot=e,this._preferredRevision=t,this._isLine truncated
|
|
||||||
* SVGO is a Nodejs-based tool for optimizing SVG vector graphics files.
|
|
||||||
*
|
|
||||||
* @see https://github.com/svg/svgo
|
|
||||||
*
|
|
||||||
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet)
|
|
||||||
* @copyright © 2012 Kir Belevich
|
|
||||||
* @license MIT https://raw.githubusercontent.com/svg/svgo/master/LICENSE
|
|
||||||
*/var n=r(42342),a=r(3717),o=r(65994),i=r(71921),s=r(79736).By,l=r(58529),d=function(e){this.config=n(e)};d.prototype.optimize=function(e,t){return t=t||{},new Promise((r,n)=>{if(this.config.error)return void n(this.config.error);var a=this.config,o=a.multipass?10:1,i=0,l=_NumberPOSITIVE_INFINITY,d=e=>e.error?void n(e.error):void(t.multipassCount=i,++i<o&&e.data.length<l?(l=e.data.length,this._optimizeOnce(e.data,t,d)):(a.datauri&&(e.data=s(e.data,a.datauri)),t&&t.path&&(e.path=t.path),r(e)));this._optimizeOnce(e,t,d)})},d.prototype._optimizeOnce=function(e,t,r){var n=this.config;a(e,function(e){return e.error?void r(e):void(e=o(e,t,n.plugins),r(l(e,n.js2svg)))})},d.prototype.createContentItem=function(e){return new i(e)},d.Config=n,e.exports=d,e.exports.default=d},42342:(e,t,r)=>{function n(e){return"_collections.js"===e||"_collections"===e?r(76344):"_path.js"===e||"_path"===e?r(54870):"_transforms.js"===e||"_transforms"===e?r(22527):"addAttributesToSVGElement.js"===e||"addAttributesToSVGElement"===e?r(5519):"addClassesToSVGElement.js"===e||"addClassesToSVGElement"===e?r(75118):"cleanupAttrs.js"===e||"cleanupAttrs"===e?r(4106):"cleanupEnableBackground.js"===e||"cleanupEnableBackground"===e?r(26483):"cleanupIDs.js"===e||"cleanupIDs"===e?r(37762):"cleanupListOfValues.js"===e||"cleanupListOfValues"===e?r(92331):"cleanupNumericValues.js"===e||"cleanupNumericValues"===e?r(36296):"collapseGroups.js"===e||"collapseGroups"===e?r(59616):"convertColors.js"===e||"convertColors"===e?r(83254):"convertEllipseToCircle.js"===e||"convertEllipseToCircle"===e?r(56061):"convertPathData.js"===e||"convertPathData"===e?r(76307):"convertShapeToPath.js"===e||"convertShapeToPath"===e?r(24199):"convertStyleToAttrs.js"===e||"convertStyleToAttrs"===e?r(72446):"convertTransform.js"===e||"convertTransform"===e?r(72234):"inlineStyles.js"===e||"inlineStyles"===e?r(81862):"mergePaths.js"===e||"mergePaths"===e?r(46123):"minifyStyles.js"===e||"minifyStyles"===e?r(77686):"moveElemsAttrsToGroup.js"===e||"moveElemsAttrsToGroup"===e?r(42778):"moveGroupAttrsToElems.js"===e||"moveGroupAttrsToElems"===e?r(69078):"prefixIds.js"===e||"prefixIds"===e?r(33099):"removeAttributesBySelector.js"===e||"removeAttributesBySelector"===e?r(65731):"removeAttrs.js"===e||"removeAttrs"===e?r(91585):"removeComments.js"===e||"removeComments"===e?r(13383):"removeDesc.js"===e||"removeDesc"===e?r(81668):"removeDimensions.js"===e||"removeDimensions"===e?r(41690):"removeDoctype.js"===e||"removeDoctype"===e?r(42114):"removeEditorsNSData.js"===e||"removeEditorsNSData"===e?r(70325):"removeElementsByAttr.js"===e||"removeElementsByAttr"===e?r(70535):"removeEmptyAttrs.js"===e||"removeEmptyAttrs"===e?r(63151):"removeEmptyContainers.js"===e||"removeEmptyContainers"===e?r(41059):"removeEmptyText.js"===e||"removeEmptyText"===e?r(14156):"removeHiddenElems.js"===e||"removeHiddenElems"===e?r(1378):"removeMetadata.js"===e||"removeMetadata"===e?r(28873):"removeNonInheritableGroupAttrs.js"===e||"removeNonInheritableGroupAttrs"===e?r(67662):"removeOffCanvasPaths.js"===e||"removeOffCanvasPaths"===e?r(58267):"removeRasterImages.js"===e||"removeRasterImages"===e?r(99062):"removeScriptElement.js"===e||"removeScriptElement"===e?r(64186):"removeStyleElement.js"===e||"removeStyleElement"===e?r(99681):"removeTitle.js"===e||"removeTitle"===e?r(76087):"removeUnknownsAndDefaults.js"===e||"removeUnknownsAndDefaults"===e?r(8316):"removeUnusedNS.js"===e||"removeUnusedNS"===e?r(77926):"removeUselessDefs.js"===e||"removeUselessDefs"===e?r(1820):"removeUselessStrokeAndFill.js"===e||"removeUselessStrokeAndFill"===e?r(7519):"removeViewBox.js"===e||"removeViewBox"===e?r(81306):"removeXMLNS.js"===e||"removeXMLNS"===e?r(44987):"removeXMLProcInst.js"===e||"removeXMLProcInst"===e?r(97427):"reusePaths.js"===e||"reusePaths"===e?r(86607):"sortAttrs.js"===e||"sortAttrs"===e?r(17549):"sortDefsChildren.js"===e||"sortDefsChildren"===e?r(5681):void 0}function a(e,t){var r,n;return t.map(function(t){return"object"==typeof t?(n=Object.keys(t)[0],"object"==typeof t[n]&&t[n].fn&&"function"==typeof t[n].fn?r=i(n,t[n]):(r=l(d(e,n,t[n].path),t,n),r.name=n)):(r=d(e,t),r.name=t,"object"==typeof r.params&&(r.params=Object.assign({},r.params))),r})}function o(e,t){var r;return t.plugins&&t.plugins.forEach(function(n){"object"==typeof n&&(r=Object.keys(n)[0],null==n[r]&&console.error(`Error: '${r}' plugin is misconfigured! Have you padded its content in YML properly?\n`),"object"==typeof n[r]&&n[r].fn&&"function"==typeof n[r].fn?e.plugins.push(i(r,n[r])):"object"==typeof n[r]&&n[r].path?e.plugins.push(l(d(t,void 0,n[r].path),n,r)):e.plugins.forEach(function(e){e.name===r&&(e=l(e,n,r))}))}),e.multipass=t.multipass,t.svg2js&&(e.svg2js=t.svg2js),t.js2svg&&(e.js2svg=t.js2svg),e}function i(e,t){return t.active=!0,t.params=Object.assign({},t.params||{}),t.name=e,t}function s(e){var t;return e.reduce(function(e,r){return t&&r.type==t[0].type?t.push(r):e.push(t=[r]),e},[])}function l(e,t,r){return"object"==typeof t[r]?(e.params=Object.asLine truncated
|
|
||||||
* @license
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright © 2012–2016 Kir Belevich
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person
|
|
||||||
* obtaining a copy of this software and associated documentation
|
|
||||||
* files (the "Software"), to deal in the Software without
|
|
||||||
* restriction, including without limitation the rights to use,
|
|
||||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following
|
|
||||||
* conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
*
|
|
||||||
* Лицензия MIT
|
|
||||||
*
|
|
||||||
* Copyright © 2012–2016 Кир Белевич
|
|
||||||
*
|
|
||||||
* Данная лицензия разрешает лицам, получившим копию
|
|
||||||
* данного
|
|
||||||
* программного обеспечения и сопутствующей
|
|
||||||
* документации
|
|
||||||
* (в дальнейшем именуемыми «Программное Обеспечение»),
|
|
||||||
* безвозмездно
|
|
||||||
* использовать Программное Обеспечение без
|
|
||||||
* ограничений, включая
|
|
||||||
* неограниченное право на использование, копирование,
|
|
||||||
* изменение,
|
|
||||||
* добавление, публикацию, распространение,
|
|
||||||
* сублицензирование
|
|
||||||
* и/или продажу копий Программного Обеспечения, также
|
|
||||||
* как и лицам,
|
|
||||||
* которым предоставляется данное Программное
|
|
||||||
* Обеспечение,
|
|
||||||
* при соблюдении следующих условий:
|
|
||||||
*
|
|
||||||
* Указанное выше уведомление об авторском праве и
|
|
||||||
* данные условия
|
|
||||||
* должны быть включены во все копии или значимые части
|
|
||||||
* данного
|
|
||||||
* Программного Обеспечения.
|
|
||||||
*
|
|
||||||
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК
|
|
||||||
* ЕСТЬ»,
|
|
||||||
* БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ
|
|
||||||
* ПОДРАЗУМЕВАЕМЫХ,
|
|
||||||
* ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ
|
|
||||||
* ПРИГОДНОСТИ,
|
|
||||||
* СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И
|
|
||||||
* ОТСУТСТВИЯ НАРУШЕНИЙ
|
|
||||||
* ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ
|
|
||||||
* НЕСУТ
|
|
||||||
* ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ
|
|
||||||
* ИЛИ ДРУГИХ
|
|
||||||
* ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ
|
|
||||||
* ИНОМУ,
|
|
||||||
* ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С
|
|
||||||
* ПРОГРАММНЫМ
|
|
||||||
* ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО
|
|
||||||
* ОБЕСПЕЧЕНИЯ
|
|
||||||
* ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
|
|
||||||
*/function n(e,t){return e.renameElem("use"),e.removeAttr("d"),e.removeAttr("stroke"),e.removeAttr("fill"),e.addAttr({name:"xlink:href",local:"xlink:href",prefix:"none",value:"#"+t}),delete e.pathJS,e}function a(e,t){if(!e.isEmpty())for(let r of e.content)t(r),a(r,t)}var o=r(71921);t.type="full",t.active=!1,t.description="Finds <path> elements with the same d, fill, and stroke, and converts them to <use> elements referencing a single <path> def.",t.fn=function(e){const t=new Map;let r=0;const i=[];a(e,e=>{if(!e.isElem("path")||!e.hasAttr("d"))return;const a=e.attr("d").value,o=e.hasAttr("fill")&&e.attr("fill").value||"",s=e.hasAttr("stroke")&&e.attr("stroke").value||"",l=a+";s:"+s+";f:"+o,d=t.get(l);return d?void(!d.reused&&(d.reused=!0,!d.elem.hasAttr("id")&&d.elem.addAttr({name:"id",local:"id",prefix:"",value:"reuse-"+r++}),i.push(d.elem)),e=n(e,d.elem.attr("id").value)):void t.set(l,{elem:e,reused:!1})});const s=new o({elem:"defs",prefix:"",local:"defs",content:[],attrs:[]},e);e.content[0].spliceContent(0,0,s);for(let t of i){const e=t.style,r=t.class;delete t.style,delete t.class;const a=t.clone();t.style=e,t.class=r,a.removeAttr("transform"),s.spliceContent(0,0,a),t=n(t,a.attr("id").value),t.removeAttr("id")}return e}},17549:(e,t)=>{"use strict";t.type="perItem",t.active=!1,t.description="sorts element attributes (disabled by default)",t.params={order:["id","width","height","x","x1","x2","y","y1","y2","cx","cy","r","fill","stroke","marker","d","points"]},t.fn=function(e,t){var r=[],n={},o=t.order.length+1,i=t.xmlnsOrder||"front";e.elem&&(e.eachAttr(function(e){r.push(e)}),r.sort(function(e,r){if(e.prefix!=r.prefix){if("front"==i){if("xmlns"==e.prefix)return-1;if("xmlns"==r.prefix)return 1}return e.prefix<r.prefix?-1:1}for(var n=o,a=o,s=0;s<t.order.length;s++)e.name==t.order[s]?n=s:0===e.name.indexOf(t.order[s]+"-")&&(n=s+.5),r.name==t.order[s]?a=s:0===r.name.indexOf(t.order[s]+"-")&&(a=s+.5);return n==a?e.name<r.name?-1:1:n-a}),r.forEach(function(e){n[e.name]=e}),e.attrs=n)}},5681:(e,t)=>{"use strict";t.type="perItem",t.active=!0,t.description="Sorts children of <defs> to improve compression",t.fn=function(e){if(e.isElem("defs")){if(e.content){var t=e.content.reduce(function(e,t){return t.elem in e?e[t.elem]++:e[t.elem]=1,e},{});e.content.sort(function(e,r){var n=t[r.elem]-t[e.elem];if(0!=n)return n;var a=r.elem.length-e.elem.length;return 0==a?e.elem==r.elem?0:e.elem>r.elem?-1:1:a})}return!0}}},16974:(e,t,r)=>{function n(e,t,r,a){return t===r?a(null,!0):void e.lstat(t,function(o,i){return o&&"ENOENT"!==o.code?a(o):o||i.isDirectory()?n(e,p.join(t,".."),r,a):void a(null,!1)})}function a(e,t,r){l(e,{fs:t.fs},function(e,n){!e&&n&&t.own?o(n,t.uid,t.gid,r):r(e)})}var o=r(28729),i=r(15283),s=r(537),l=r(23607),d=r(35747),p=r(85622),c=r(12087),u="win32"===c.platform(),m=function(){},g=function(e){return e},h=u?function(e){return e.replace(/\\/g,"/").replace(/[:?<>|]/g,"_")}:g,f=function(e,t,r,n,a,o){var s=a||["."];return function(a){if(!s.length)return a();var l=s.shift(),d=p.join(r,l);t.call(e,d,function(t,c){return t?a(t):c.isDirectory()?void e.readdir(d,function(e,t){if(e)return a(e);o&&t.sort();for(var d=0;d<t.length;d++)n(p.join(r,l,t[d]))||s.push(p.join(l,t[d]));a(null,l,c)}):a(null,l,c)})}},y=function(e,t){return function(r){r.name=r.name.split("/").slice(t).join("/");var n=r.linkname;return n&&("link"===r.type||p.isAbsolute(n))&&(r.linkname=n.split("/").slice(t).join("/")),e(r)}};t.pack=function(e,t){e||(e="."),t||(t={});var r=t.fs||d,n=t.ignore||t.filter||m,a=t.map||m,o=t.mapStream||g,l=f(r,t.dereference?r.stat:r.lstat,e,n,t.entries,t.sort),c=!1!==t.strict,u="number"==typeof t.umask?~t.umask:~x(),b="number"==typeof t.dmode?t.dmode:0,S="number"==typeof t.fmode?t.fmode:0,v=t.pack||i.pack(),k=t.finish||m;t.strip&&(a=y(a,t.strip)),t.readable&&(b|=parseInt(555,8),S|=parseInt(444,8)),t.writable&&(b|=parseInt(333,8),S|=parseInt(222,8));var C=function(t,n){r.readlink(p.join(e,t),function(e,t){return e?v.destroy(e):void(n.linkname=h(t),v.entry(n,w))})},_=function(n,i,l){if(n)return v.destroy(n);if(!i)return!1!==t.finalize&&v.finalize(),k(v);if(l.isSocket())return w();var d={name:h(i),mode:(l.mode|(l.isDirectory()?b:S))&u,mtime:l.mtime,size:l.size,type:"file",uid:l.uid,gid:l.gid};if(l.isDirectory())return d.size=0,d.type="directory",d=a(d)||d,v.entry(d,w);if(l.isSymbolicLink())return d.size=0,d.type="symlink",d=a(d)||d,C(i,d);if(d=a(d)||d,!l.isFile())return c?v.destroy(new Error("unsupported type for "+i)):w();var m=v.entry(d,w);if(m){var g=o(r.createReadStream(p.join(e,i),{start:0,end:0<d.size?d.size-1:d.size}),d);g.on("error",function(e){m.destroy(e)}),s(g,m)}},w=function(e){return e?v.destroy(e):void l(_)};return w(),v};var b=function(e){return e.length?e[e.length-1]:null},S=function(){return process.getuid?process.getuid():-1},x=function(){return process.umask?process.umask():0};t.extract=function(e,t){e||(e="."),t||(t={});var r=t.fs||d,o=t.ignore||t.filter||m,l=t.map||m,c=t.mapStream||g,f=!1!==t.chown&&!Line truncated
|
|
||||||
+78
-71
@@ -1,13 +1,12 @@
|
|||||||
//Imports
|
//Imports
|
||||||
import * as _setup from "./../src/setup.mjs"
|
import setup from "./../src/setup.mjs"
|
||||||
import * as _metrics from "./../src/metrics.mjs"
|
import metrics from "./../src/metrics.mjs"
|
||||||
import * as _octokit from "@octokit/graphql"
|
import octokit from "@octokit/graphql"
|
||||||
import * as _core from "@actions/core"
|
import core from "@actions/core"
|
||||||
import * as _github from "@actions/github"
|
import github from "@actions/github"
|
||||||
|
import mocks from "./../src/mocks.mjs"
|
||||||
|
|
||||||
;((async function () {
|
;((async function () {
|
||||||
//Hack because ES modules are not correctly transpiled with ncc
|
|
||||||
const [core, github, octokit, setup, metrics] = [_core, _github, _octokit, _setup, _metrics].map(m => (m && m.default) ? m.default : m)
|
|
||||||
//Yaml boolean converter
|
//Yaml boolean converter
|
||||||
const bool = (value, defaulted = false) => typeof value === "string" ? /^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(value) : defaulted
|
const bool = (value, defaulted = false) => typeof value === "string" ? /^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(value) : defaulted
|
||||||
//Debug message buffer
|
//Debug message buffer
|
||||||
@@ -16,12 +15,11 @@
|
|||||||
try {
|
try {
|
||||||
//Initialization
|
//Initialization
|
||||||
console.log(`GitHub metrics`)
|
console.log(`GitHub metrics`)
|
||||||
console.log(`========================================================`)
|
console.log("─".repeat(64))
|
||||||
console.log(`Version | <#version>`)
|
|
||||||
process.on("unhandledRejection", error => { throw error })
|
process.on("unhandledRejection", error => { throw error })
|
||||||
|
|
||||||
//Skip process if needed
|
//Skip process if needed
|
||||||
if ((github.context.eventName === "push")&&(github.context.payload)&&(github.context.payload.head_commit)) {
|
if ((github.context.eventName === "push")&&(github.context.payload?.head_commit)) {
|
||||||
if (/\[Skip GitHub Action\]/.test(github.context.payload.head_commit.message)) {
|
if (/\[Skip GitHub Action\]/.test(github.context.payload.head_commit.message)) {
|
||||||
console.log(`Skipped because [Skip GitHub Action] is in commit message`)
|
console.log(`Skipped because [Skip GitHub Action] is in commit message`)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
@@ -30,30 +28,47 @@
|
|||||||
|
|
||||||
//Load configuration
|
//Load configuration
|
||||||
const conf = await setup({log:false})
|
const conf = await setup({log:false})
|
||||||
console.log(`Configuration | loaded`)
|
console.log(`Configuration │ loaded`)
|
||||||
|
console.log(`Version │ ${conf.package.version}`)
|
||||||
|
|
||||||
|
//Debug mode
|
||||||
|
const debug = bool(core.getInput("debug"))
|
||||||
|
if (!debug)
|
||||||
|
console.debug = message => debugged.push(message)
|
||||||
|
console.log(`Debug mode │ ${debug}`)
|
||||||
|
const dflags = (core.getInput("debug_flags") || "").split(" ").filter(flag => flag)
|
||||||
|
console.log(`Debug flags │ ${dflags.join(" ") || "(none)"}`)
|
||||||
|
|
||||||
//Load svg template, style, fonts and query
|
//Load svg template, style, fonts and query
|
||||||
const template = core.getInput("template") || "classic"
|
const template = core.getInput("template") || "classic"
|
||||||
console.log(`Template to use | ${template}`)
|
console.log(`Template to use │ ${template}`)
|
||||||
|
|
||||||
//Token for data gathering
|
//Token for data gathering
|
||||||
const token = core.getInput("token") || ""
|
const token = core.getInput("token") || ""
|
||||||
console.log(`Github token | ${token ? "provided" : "missing"}`)
|
console.log(`Github token │ ${/^MOCKED/.test(token) ? "(MOCKED)" : token ? "provided" : "missing"}`)
|
||||||
if (!token)
|
if (!token)
|
||||||
throw new Error("You must provide a valid GitHub token to gather your metrics")
|
throw new Error("You must provide a valid GitHub token to gather your metrics")
|
||||||
const graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
const api = {}
|
||||||
console.log(`Github GraphQL API | ok`)
|
api.graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
||||||
const rest = github.getOctokit(token)
|
console.log(`Github GraphQL API │ ok`)
|
||||||
console.log(`Github REST API | ok`)
|
api.rest = github.getOctokit(token)
|
||||||
|
console.log(`Github REST API │ ok`)
|
||||||
|
//Apply mocking if needed
|
||||||
|
if (bool(core.getInput("use_mocked_data"))) {
|
||||||
|
Object.assign(api, await mocks(api))
|
||||||
|
console.log(`Mocked Github API │ ok`)
|
||||||
|
}
|
||||||
|
//Extract octokits
|
||||||
|
const {graphql, rest} = api
|
||||||
|
|
||||||
//SVG output
|
//SVG output
|
||||||
const filename = core.getInput("filename") || "github-metrics.svg"
|
const filename = core.getInput("filename") || "github-metrics.svg"
|
||||||
console.log(`SVG output file | ${filename}`)
|
console.log(`SVG output file │ ${filename}`)
|
||||||
|
|
||||||
//SVG optimization
|
//SVG optimization
|
||||||
const optimize = bool(core.getInput("optimize"), true)
|
const optimize = bool(core.getInput("optimize"), true)
|
||||||
conf.optimize = optimize
|
conf.optimize = optimize
|
||||||
console.log(`SVG optimization | ${optimize}`)
|
console.log(`SVG optimization │ ${optimize}`)
|
||||||
|
|
||||||
//GitHub user
|
//GitHub user
|
||||||
let authenticated
|
let authenticated
|
||||||
@@ -64,28 +79,20 @@
|
|||||||
authenticated = github.context.repo.owner
|
authenticated = github.context.repo.owner
|
||||||
}
|
}
|
||||||
const user = core.getInput("user") || authenticated
|
const user = core.getInput("user") || authenticated
|
||||||
console.log(`GitHub user | ${user}`)
|
console.log(`GitHub user │ ${user}`)
|
||||||
|
|
||||||
//Debug mode
|
|
||||||
const debug = bool(core.getInput("debug"))
|
|
||||||
if (!debug)
|
|
||||||
console.debug = message => debugged.push(message)
|
|
||||||
console.log(`Debug mode | ${debug}`)
|
|
||||||
const dflags = (core.getInput("debug_flags") || "").split(" ").filter(flag => flag)
|
|
||||||
console.log(`Debug flags | ${dflags.join(" ") || "(none)"}`)
|
|
||||||
|
|
||||||
//Base elements
|
//Base elements
|
||||||
const base = {}
|
const base = {}
|
||||||
let parts = (core.getInput("base") || "").split(",").map(part => part.trim())
|
let parts = (core.getInput("base") || "").split(",").map(part => part.trim())
|
||||||
for (const part of conf.settings.plugins.base.parts)
|
for (const part of conf.settings.plugins.base.parts)
|
||||||
base[`base.${part}`] = parts.includes(part)
|
base[`base.${part}`] = parts.includes(part)
|
||||||
console.log(`Base parts | ${parts.join(", ") || "(none)"}`)
|
console.log(`Base parts │ ${parts.join(", ") || "(none)"}`)
|
||||||
|
|
||||||
//Config
|
//Config
|
||||||
const config = {
|
const config = {
|
||||||
"config.timezone":core.getInput("config_timezone") || ""
|
"config.timezone":core.getInput("config_timezone") || ""
|
||||||
}
|
}
|
||||||
console.log(`Timezone | ${config["config.timezone"] || "(system default)"}`)
|
console.log(`Timezone │ ${config["config.timezone"] || "(system default)"}`)
|
||||||
|
|
||||||
//Additional plugins
|
//Additional plugins
|
||||||
const plugins = {
|
const plugins = {
|
||||||
@@ -104,23 +111,23 @@
|
|||||||
tweets:{enabled:bool(core.getInput("plugin_tweets"))},
|
tweets:{enabled:bool(core.getInput("plugin_tweets"))},
|
||||||
}
|
}
|
||||||
let q = Object.fromEntries(Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => [key, true]))
|
let q = Object.fromEntries(Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => [key, true]))
|
||||||
console.log(`Plugins enabled | ${Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => key).join(", ")}`)
|
console.log(`Plugins enabled │ ${Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => key).join(", ")}`)
|
||||||
//Additional plugins options
|
//Additional plugins options
|
||||||
//Pagespeed
|
//Pagespeed
|
||||||
if (plugins.pagespeed.enabled) {
|
if (plugins.pagespeed.enabled) {
|
||||||
plugins.pagespeed.token = core.getInput("plugin_pagespeed_token") || ""
|
plugins.pagespeed.token = core.getInput("plugin_pagespeed_token") || ""
|
||||||
q[`pagespeed.detailed`] = bool(core.getInput(`plugin_pagespeed_detailed`))
|
q[`pagespeed.detailed`] = bool(core.getInput(`plugin_pagespeed_detailed`))
|
||||||
q[`pagespeed.screenshot`] = bool(core.getInput(`plugin_pagespeed_screenshot`))
|
q[`pagespeed.screenshot`] = bool(core.getInput(`plugin_pagespeed_screenshot`))
|
||||||
console.log(`Pagespeed token | ${plugins.pagespeed.token ? "provided" : "missing"}`)
|
console.log(`Pagespeed token │ ${/^MOCKED/.test(plugins.pagespeed.token) ? "(MOCKED)" : plugins.pagespeed.token ? "provided" : "missing"}`)
|
||||||
console.log(`Pagespeed detailed | ${q["pagespeed.detailed"]}`)
|
console.log(`Pagespeed detailed │ ${q["pagespeed.detailed"]}`)
|
||||||
console.log(`Pagespeed screenshot | ${q["pagespeed.screenshot"]}`)
|
console.log(`Pagespeed screenshot │ ${q["pagespeed.screenshot"]}`)
|
||||||
}
|
}
|
||||||
//Languages
|
//Languages
|
||||||
if (plugins.languages.enabled) {
|
if (plugins.languages.enabled) {
|
||||||
for (const option of ["ignored", "skipped"])
|
for (const option of ["ignored", "skipped"])
|
||||||
q[`languages.${option}`] = core.getInput(`plugin_languages_${option}`) || null
|
q[`languages.${option}`] = core.getInput(`plugin_languages_${option}`) || null
|
||||||
console.log(`Languages ignored | ${q["languages.ignored"] || "(none)"}`)
|
console.log(`Languages ignored │ ${q["languages.ignored"] || "(none)"}`)
|
||||||
console.log(`Languages skipped repos | ${q["languages.skipped"] || "(none)"}`)
|
console.log(`Languages skipped repos │ ${q["languages.skipped"] || "(none)"}`)
|
||||||
}
|
}
|
||||||
//Habits
|
//Habits
|
||||||
if (plugins.habits.enabled) {
|
if (plugins.habits.enabled) {
|
||||||
@@ -128,107 +135,107 @@
|
|||||||
q[`habits.${option}`] = core.getInput(`plugin_habits_${option}`) || null
|
q[`habits.${option}`] = core.getInput(`plugin_habits_${option}`) || null
|
||||||
q[`habits.facts`] = bool(core.getInput(`plugin_habits_facts`))
|
q[`habits.facts`] = bool(core.getInput(`plugin_habits_facts`))
|
||||||
q[`habits.charts`] = bool(core.getInput(`plugin_habits_charts`))
|
q[`habits.charts`] = bool(core.getInput(`plugin_habits_charts`))
|
||||||
console.log(`Habits facts | ${q["habits.facts"]}`)
|
console.log(`Habits facts │ ${q["habits.facts"]}`)
|
||||||
console.log(`Habits charts | ${q["habits.charts"]}`)
|
console.log(`Habits charts │ ${q["habits.charts"]}`)
|
||||||
console.log(`Habits events to use | ${q["habits.from"] || "(default)"}`)
|
console.log(`Habits events to use │ ${q["habits.from"] || "(default)"}`)
|
||||||
console.log(`Habits days to keep | ${q["habits.days"] || "(default)"}`)
|
console.log(`Habits days to keep │ ${q["habits.days"] || "(default)"}`)
|
||||||
}
|
}
|
||||||
//Music
|
//Music
|
||||||
if (plugins.music.enabled) {
|
if (plugins.music.enabled) {
|
||||||
plugins.music.token = core.getInput("plugin_music_token") || ""
|
plugins.music.token = core.getInput("plugin_music_token") || ""
|
||||||
for (const option of ["provider", "mode", "playlist", "limit"])
|
for (const option of ["provider", "mode", "playlist", "limit"])
|
||||||
q[`music.${option}`] = core.getInput(`plugin_music_${option}`) || null
|
q[`music.${option}`] = core.getInput(`plugin_music_${option}`) || null
|
||||||
console.log(`Music provider | ${q["music.provider"] || "(none)"}`)
|
console.log(`Music provider │ ${q["music.provider"] || "(none)"}`)
|
||||||
console.log(`Music plugin mode | ${q["music.mode"] || "(none)"}`)
|
console.log(`Music plugin mode │ ${q["music.mode"] || "(none)"}`)
|
||||||
console.log(`Music playlist | ${q["music.playlist"] || "(none)"}`)
|
console.log(`Music playlist │ ${q["music.playlist"] || "(none)"}`)
|
||||||
console.log(`Music tracks limit | ${q["music.limit"] || "(default)"}`)
|
console.log(`Music tracks limit │ ${q["music.limit"] || "(default)"}`)
|
||||||
console.log(`Music token | ${plugins.music.token ? "provided" : "missing"}`)
|
console.log(`Music token │ ${/^MOCKED/.test(plugins.music.token) ? "(MOCKED)" : plugins.music.token ? "provided" : "missing"}`)
|
||||||
}
|
}
|
||||||
//Posts
|
//Posts
|
||||||
if (plugins.posts.enabled) {
|
if (plugins.posts.enabled) {
|
||||||
for (const option of ["source", "limit"])
|
for (const option of ["source", "limit"])
|
||||||
q[`posts.${option}`] = core.getInput(`plugin_posts_${option}`) || null
|
q[`posts.${option}`] = core.getInput(`plugin_posts_${option}`) || null
|
||||||
console.log(`Posts source | ${q["posts.source"] || "(none)"}`)
|
console.log(`Posts source │ ${q["posts.source"] || "(none)"}`)
|
||||||
console.log(`Posts limit | ${q["posts.limit"] || "(default)"}`)
|
console.log(`Posts limit │ ${q["posts.limit"] || "(default)"}`)
|
||||||
}
|
}
|
||||||
//Isocalendar
|
//Isocalendar
|
||||||
if (plugins.isocalendar.enabled) {
|
if (plugins.isocalendar.enabled) {
|
||||||
q["isocalendar.duration"] = core.getInput("plugin_isocalendar_duration") || "half-year"
|
q["isocalendar.duration"] = core.getInput("plugin_isocalendar_duration") || "half-year"
|
||||||
console.log(`Isocalendar duration | ${q["isocalendar.duration"]}`)
|
console.log(`Isocalendar duration │ ${q["isocalendar.duration"]}`)
|
||||||
}
|
}
|
||||||
//Topics
|
//Topics
|
||||||
if (plugins.topics.enabled) {
|
if (plugins.topics.enabled) {
|
||||||
for (const option of ["mode", "sort", "limit"])
|
for (const option of ["mode", "sort", "limit"])
|
||||||
q[`topics.${option}`] = core.getInput(`plugin_topics_${option}`) || null
|
q[`topics.${option}`] = core.getInput(`plugin_topics_${option}`) || null
|
||||||
console.log(`Topics mode | ${q["topics.mode"] || "(default)"}`)
|
console.log(`Topics mode │ ${q["topics.mode"] || "(default)"}`)
|
||||||
console.log(`Topics sort mode | ${q["topics.sort"] || "(default)"}`)
|
console.log(`Topics sort mode │ ${q["topics.sort"] || "(default)"}`)
|
||||||
console.log(`Topics limit | ${q["topics.limit"] || "(default)"}`)
|
console.log(`Topics limit │ ${q["topics.limit"] || "(default)"}`)
|
||||||
}
|
}
|
||||||
//Projects
|
//Projects
|
||||||
if (plugins.projects.enabled) {
|
if (plugins.projects.enabled) {
|
||||||
for (const option of ["limit", "repositories"])
|
for (const option of ["limit", "repositories"])
|
||||||
q[`projects.${option}`] = core.getInput(`plugin_projects_${option}`) || null
|
q[`projects.${option}`] = core.getInput(`plugin_projects_${option}`) || null
|
||||||
console.log(`Projects limit | ${q["projects.limit"] || "(default)"}`)
|
console.log(`Projects limit │ ${q["projects.limit"] || "(default)"}`)
|
||||||
console.log(`Projects repositories | ${q["projects.repositories"] || "(none)"}`)
|
console.log(`Projects repositories │ ${q["projects.repositories"] || "(none)"}`)
|
||||||
}
|
}
|
||||||
//Tweets
|
//Tweets
|
||||||
if (plugins.tweets.enabled) {
|
if (plugins.tweets.enabled) {
|
||||||
plugins.tweets.token = core.getInput("plugin_tweets_token") || null
|
plugins.tweets.token = core.getInput("plugin_tweets_token") || null
|
||||||
for (const option of ["limit"])
|
for (const option of ["limit"])
|
||||||
q[`tweets.${option}`] = core.getInput(`plugin_tweets_${option}`) || null
|
q[`tweets.${option}`] = core.getInput(`plugin_tweets_${option}`) || null
|
||||||
console.log(`Twitter token | ${plugins.tweets.token ? "provided" : "missing"}`)
|
console.log(`Twitter token │ ${/^MOCKED/.test(plugins.tweets.token) ? "(MOCKED)" : plugins.tweets.token ? "provided" : "missing"}`)
|
||||||
console.log(`Tweets limit | ${q["tweets.limit"] || "(default)"}`)
|
console.log(`Tweets limit │ ${q["tweets.limit"] || "(default)"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Repositories to use
|
//Repositories to use
|
||||||
const repositories = Number(core.getInput("repositories")) || 100
|
const repositories = Number(core.getInput("repositories")) || 100
|
||||||
console.log(`Repositories to use | ${repositories}`)
|
console.log(`Repositories to use │ ${repositories}`)
|
||||||
|
|
||||||
//Die on plugins errors
|
//Die on plugins errors
|
||||||
const die = bool(core.getInput("plugins_errors_fatal"))
|
const die = bool(core.getInput("plugins_errors_fatal"))
|
||||||
console.log(`Plugin errors | ${die ? "die" : "warn"}`)
|
console.log(`Plugin errors │ ${die ? "die" : "warn"}`)
|
||||||
|
|
||||||
//Build query
|
//Build query
|
||||||
const query = JSON.parse(core.getInput("query") || "{}")
|
const query = JSON.parse(core.getInput("query") || "{}")
|
||||||
console.log(`Query additional params | ${JSON.stringify(query)}`)
|
console.log(`Query additional params │ ${JSON.stringify(query)}`)
|
||||||
q = {...query, ...q, base:false, ...base, ...config, repositories, template}
|
q = {...query, ...q, base:false, ...base, ...config, repositories, template}
|
||||||
|
|
||||||
//Render metrics
|
//Render metrics
|
||||||
const rendered = await metrics({login:user, q, dflags}, {graphql, rest, plugins, conf, die})
|
const rendered = await metrics({login:user, q, dflags}, {graphql, rest, plugins, conf, die})
|
||||||
console.log(`Render | complete`)
|
console.log(`Render │ complete`)
|
||||||
|
|
||||||
//Verify svg
|
//Verify svg
|
||||||
const verify = bool(core.getInput("verify"))
|
const verify = bool(core.getInput("verify"))
|
||||||
console.log(`Verify SVG | ${verify}`)
|
console.log(`Verify SVG │ ${verify}`)
|
||||||
if (verify) {
|
if (verify) {
|
||||||
const [libxmljs] = [await import("libxmljs")].map(m => (m && m.default) ? m.default : m)
|
const [libxmljs] = [await import("libxmljs")].map(m => (m && m.default) ? m.default : m)
|
||||||
const parsed = libxmljs.parseXml(rendered)
|
const parsed = libxmljs.parseXml(rendered)
|
||||||
if (parsed.errors.length)
|
if (parsed.errors.length)
|
||||||
throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`)
|
throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`)
|
||||||
console.log(`SVG valid | yes`)
|
console.log(`SVG valid │ yes`)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Commit to repository
|
//Commit to repository
|
||||||
const dryrun = bool(core.getInput("dryrun"))
|
const dryrun = bool(core.getInput("dryrun"))
|
||||||
if (dryrun)
|
if (dryrun)
|
||||||
console.log(`Dry-run | complete`)
|
console.log(`Dry-run │ complete`)
|
||||||
else {
|
else {
|
||||||
//Repository and branch
|
//Repository and branch
|
||||||
const branch = github.context.ref.replace(/^refs[/]heads[/]/, "")
|
const branch = github.context.ref.replace(/^refs[/]heads[/]/, "")
|
||||||
console.log(`Repository | ${github.context.repo.owner}/${github.context.repo.repo}`)
|
console.log(`Repository │ ${github.context.repo.owner}/${github.context.repo.repo}`)
|
||||||
console.log(`Branch | ${branch}`)
|
console.log(`Branch │ ${branch}`)
|
||||||
//Committer token
|
//Committer token
|
||||||
const token = core.getInput("committer_token") || core.getInput("token") || ""
|
const token = core.getInput("committer_token") || core.getInput("token") || ""
|
||||||
console.log(`Committer token | ${token ? "provided" : "missing"}`)
|
console.log(`Committer token │ ${/^MOCKED/.test(token) ? "(MOCKED)" : token ? "provided" : "missing"}`)
|
||||||
if (!token)
|
if (!token)
|
||||||
throw new Error("You must provide a valid GitHub token to commit your metrics")
|
throw new Error("You must provide a valid GitHub token to commit your metrics")
|
||||||
const rest = github.getOctokit(token)
|
const rest = github.getOctokit(token)
|
||||||
console.log(`Committer REST API | ok`)
|
console.log(`Committer REST API │ ok`)
|
||||||
try {
|
try {
|
||||||
console.log(`Committer | ${(await rest.users.getAuthenticated()).data.login}`)
|
console.log(`Committer │ ${(await rest.users.getAuthenticated()).data.login}`)
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
console.log(`Committer | (github-actions)`)
|
console.log(`Committer │ (github-actions)`)
|
||||||
}
|
}
|
||||||
//Retrieve previous render SHA to be able to update file content through API
|
//Retrieve previous render SHA to be able to update file content through API
|
||||||
let sha = null
|
let sha = null
|
||||||
@@ -243,14 +250,14 @@
|
|||||||
)
|
)
|
||||||
sha = oid
|
sha = oid
|
||||||
} catch (error) { console.debug(error) }
|
} catch (error) { console.debug(error) }
|
||||||
console.log(`Previous render sha | ${sha ?? "(none)"}`)
|
console.log(`Previous render sha │ ${sha ?? "(none)"}`)
|
||||||
//Update file content through API
|
//Update file content through API
|
||||||
await rest.repos.createOrUpdateFileContents({
|
await rest.repos.createOrUpdateFileContents({
|
||||||
...github.context.repo, path:filename, message:`Update ${filename} - [Skip GitHub Action]`,
|
...github.context.repo, path:filename, message:`Update ${filename} - [Skip GitHub Action]`,
|
||||||
content:Buffer.from(rendered).toString("base64"),
|
content:Buffer.from(rendered).toString("base64"),
|
||||||
...(sha ? {sha} : {})
|
...(sha ? {sha} : {})
|
||||||
})
|
})
|
||||||
console.log(`Commit to repo | ok`)
|
console.log(`Commit to repo │ ok`)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Success
|
//Success
|
||||||
@@ -262,7 +269,7 @@
|
|||||||
catch (error) {
|
catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
if (!bool(core.getInput("debug")))
|
if (!bool(core.getInput("debug")))
|
||||||
for (const log of ["_".repeat(64), "An error occured, logging debug message :", ...debugged])
|
for (const log of ["─".repeat(64), "An error occured, logging debug message :", ...debugged])
|
||||||
console.log(log)
|
console.log(log)
|
||||||
core.setFailed(error.message)
|
core.setFailed(error.message)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
|||||||
Generated
+5336
-415
File diff suppressed because it is too large.
Load diff
+4
-4
@@ -6,8 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.mjs",
|
"start": "node index.mjs",
|
||||||
"build": "node utils/build.mjs",
|
"build": "node utils/build.mjs",
|
||||||
"test": "node tests/metrics.mjs",
|
"test": "npx jest",
|
||||||
"upgrade": "npm install @actions/core@latest @actions/github@latest @octokit/graphql@latest @octokit/rest@latest axios@latest colors@latest compression@latest ejs@latest express@latest express-rate-limit@latest image-to-base64@latest memory-cache@latest prismjs@latest puppeteer@latest svgo@latest vue@latest vue-prism-component@latest @vercel/ncc@latest babel-minify@latest libxmljs@latest"
|
"upgrade": "npm install @actions/core@latest @actions/github@latest @octokit/graphql@latest @octokit/rest@latest axios@latest colors@latest compression@latest ejs@latest express@latest express-rate-limit@latest image-to-base64@latest memory-cache@latest prismjs@latest puppeteer@latest svgo@latest vue@latest vue-prism-component@latest jest@latest js-yaml@latest libxmljs@latest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -39,8 +39,8 @@
|
|||||||
"vue-prism-component": "^1.2.0"
|
"vue-prism-component": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.26.1",
|
"jest": "^26.6.3",
|
||||||
"babel-minify": "^0.5.1",
|
"js-yaml": "^3.14.1",
|
||||||
"libxmljs": "^0.19.7"
|
"libxmljs": "^0.19.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+765
@@ -0,0 +1,765 @@
|
|||||||
|
//Imports
|
||||||
|
import axios from "axios"
|
||||||
|
import urls from "url"
|
||||||
|
|
||||||
|
//Mocked state
|
||||||
|
let mocked = false
|
||||||
|
|
||||||
|
//Mocking
|
||||||
|
export default async function ({graphql, rest}) {
|
||||||
|
|
||||||
|
//Check if already mocked
|
||||||
|
if (mocked)
|
||||||
|
return {graphql, rest}
|
||||||
|
mocked = true
|
||||||
|
console.debug(`metrics/compute/mocks > mocking`)
|
||||||
|
|
||||||
|
//GraphQL API mocking
|
||||||
|
{
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api`)
|
||||||
|
const unmocked = graphql
|
||||||
|
graphql = new Proxy(unmocked, {
|
||||||
|
apply(target, that, args) {
|
||||||
|
//Arguments
|
||||||
|
const [query] = args
|
||||||
|
//Common query
|
||||||
|
if (/^query Metrics /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Metrics`)
|
||||||
|
return ({
|
||||||
|
user: {
|
||||||
|
databaseId:22963968,
|
||||||
|
name:"Simon Lecoq",
|
||||||
|
login:"lowlighter",
|
||||||
|
createdAt:"2016-10-20T16:49:29Z",
|
||||||
|
avatarUrl:"https://avatars0.githubusercontent.com/u/22963968?u=f5097de6f06ed2e31906f784163fc1e9fc84ed57&v=4",
|
||||||
|
websiteUrl:"https://simon.lecoq.io",
|
||||||
|
isHireable:false,
|
||||||
|
twitterUsername:"lecoqsimon",
|
||||||
|
repositories:{totalCount:Math.floor(Math.random()*100), totalDiskUsage:Math.floor(Math.random()*100000), nodes:[]},
|
||||||
|
packages:{totalCount:Math.floor(Math.random()*10)},
|
||||||
|
starredRepositories:{totalCount:Math.floor(Math.random()*1000)},
|
||||||
|
watching:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
sponsorshipsAsSponsor:{totalCount:Math.floor(Math.random()*5)},
|
||||||
|
sponsorshipsAsMaintainer:{totalCount:Math.floor(Math.random()*5)},
|
||||||
|
contributionsCollection:{
|
||||||
|
totalRepositoriesWithContributedCommits:Math.floor(Math.random()*30),
|
||||||
|
totalCommitContributions:Math.floor(Math.random()*1000),
|
||||||
|
restrictedContributionsCount:Math.floor(Math.random()*500),
|
||||||
|
totalIssueContributions:Math.floor(Math.random()*100),
|
||||||
|
totalPullRequestContributions:Math.floor(Math.random()*100),
|
||||||
|
totalPullRequestReviewContributions:Math.floor(Math.random()*100)
|
||||||
|
},
|
||||||
|
calendar:{
|
||||||
|
contributionCalendar:{
|
||||||
|
weeks:[
|
||||||
|
{
|
||||||
|
contributionDays:[
|
||||||
|
{color:"#40c463"},
|
||||||
|
{color:"#ebedf0"},
|
||||||
|
{color:"#9be9a8"},
|
||||||
|
{color:"#ebedf0"},
|
||||||
|
{color:"#ebedf0"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contributionDays:[
|
||||||
|
{color:"#30a14e"},
|
||||||
|
{color:"#9be9a8"},
|
||||||
|
{color:"#40c463"},
|
||||||
|
{color:"#9be9a8"},
|
||||||
|
{color:"#ebedf0"},
|
||||||
|
{color:"#ebedf0"},
|
||||||
|
{color:"#ebedf0"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contributionDays:[
|
||||||
|
{color:"#40c463"},
|
||||||
|
{color:"#216e39"},
|
||||||
|
{color:"#9be9a8"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
repositoriesContributedTo:{totalCount:Math.floor(Math.random()*10)},
|
||||||
|
followers:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
following:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
issueComments:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
organizations:{totalCount:Math.floor(Math.random()*5)}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Repositories query
|
||||||
|
if (/^query Repositories /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Repositories`)
|
||||||
|
return /after: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/m.test(query) ? ({
|
||||||
|
user:{
|
||||||
|
repositories:{
|
||||||
|
edges:[],
|
||||||
|
nodes:[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) : ({
|
||||||
|
user:{
|
||||||
|
repositories:{
|
||||||
|
edges:[
|
||||||
|
{
|
||||||
|
cursor:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nodes:[
|
||||||
|
{
|
||||||
|
name:"metrics",
|
||||||
|
watchers:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
stargazers:{totalCount:Math.floor(Math.random()*1000)},
|
||||||
|
languages:{
|
||||||
|
edges:[
|
||||||
|
{size:111733, node:{color:"#f1e05a", name:"JavaScript"}
|
||||||
|
},
|
||||||
|
{size:14398, node:{color:"#563d7c", name:"CSS"}},
|
||||||
|
{size:13223, node:{color:"#e34c26", name:"HTML"}},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
issues_open:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
issues_closed:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
pr_open:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
pr_merged:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
releases:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
forkCount:Math.floor(Math.random()*100),
|
||||||
|
licenseInfo:{spdxId:"MIT"}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Single repository query
|
||||||
|
if (/^query Repository /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Repository`)
|
||||||
|
return ({
|
||||||
|
user:{
|
||||||
|
repository:{
|
||||||
|
name:"metrics",
|
||||||
|
createdAt:new Date().toISOString(),
|
||||||
|
diskUsage:Math.floor(Math.random()*10000),
|
||||||
|
watchers:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
stargazers:{totalCount:Math.floor(Math.random()*1000)},
|
||||||
|
languages:{
|
||||||
|
edges:[
|
||||||
|
{size:111733, node:{color:"#f1e05a", name:"JavaScript"}
|
||||||
|
},
|
||||||
|
{size:14398, node:{color:"#563d7c", name:"CSS"}},
|
||||||
|
{size:13223, node:{color:"#e34c26", name:"HTML"}},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
issues_open:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
issues_closed:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
pr_open:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
pr_merged:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
releases:{totalCount:Math.floor(Math.random()*100)},
|
||||||
|
forkCount:Math.floor(Math.random()*100),
|
||||||
|
licenseInfo:{spdxId:"MIT"}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Calendar query
|
||||||
|
if (/^query Calendar /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Calendar`)
|
||||||
|
//Generate calendar
|
||||||
|
const date = new Date(query.match(/from: "(?<date>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z)"/)?.groups?.date)
|
||||||
|
const to = new Date(query.match(/to: "(?<date>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z)"/)?.groups?.date)
|
||||||
|
const weeks = []
|
||||||
|
let contributionDays = []
|
||||||
|
for (; date <= to; date.setDate(date.getDate()+1)) {
|
||||||
|
//Create new week on sunday
|
||||||
|
if (date.getDay() === 0) {
|
||||||
|
weeks.push({contributionDays})
|
||||||
|
contributionDays = []
|
||||||
|
}
|
||||||
|
//Random contributions
|
||||||
|
const contributionCount = Math.min(10, Math.max(0, Math.floor(Math.random()*14-4)))
|
||||||
|
contributionDays.push({
|
||||||
|
contributionCount,
|
||||||
|
color:["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"][Math.ceil(contributionCount/10/0.25)],
|
||||||
|
date:date.toISOString().substring(0, 10)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ({
|
||||||
|
user: {
|
||||||
|
calendar:{
|
||||||
|
contributionCalendar:{
|
||||||
|
weeks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Gists query
|
||||||
|
if (/^query Gists /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Projects`)
|
||||||
|
return ({
|
||||||
|
user:{
|
||||||
|
gists:{
|
||||||
|
totalCount:1,
|
||||||
|
nodes:[
|
||||||
|
{
|
||||||
|
stargazerCount:Math.floor(Math.random()*10),
|
||||||
|
isFork:false,
|
||||||
|
forks:{totalCount:Math.floor(Math.random()*10)},
|
||||||
|
files:[{name:"example"}],
|
||||||
|
comments:{totalCount:Math.floor(Math.random()*10)}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Projects query
|
||||||
|
if (/^query Projects /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > Projects`)
|
||||||
|
return ({
|
||||||
|
user:{
|
||||||
|
projects:{
|
||||||
|
totalCount:1,
|
||||||
|
nodes:[
|
||||||
|
{
|
||||||
|
name:"User-owned project",
|
||||||
|
updatedAt:new Date().toISOString(),
|
||||||
|
progress:{
|
||||||
|
doneCount:Math.floor(Math.random()*10),
|
||||||
|
inProgressCount:Math.floor(Math.random()*10),
|
||||||
|
todoCount:Math.floor(Math.random()*10),
|
||||||
|
enabled:true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Repository project query
|
||||||
|
if (/^query RepositoryProject /.test(query)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking graphql api result > RepositoryProject`)
|
||||||
|
return ({
|
||||||
|
user:{
|
||||||
|
repository:{
|
||||||
|
project:{
|
||||||
|
name:"Repository project example",
|
||||||
|
updatedAt:new Date().toISOString(),
|
||||||
|
progress:{
|
||||||
|
doneCount:Math.floor(Math.random()*10),
|
||||||
|
inProgressCount:Math.floor(Math.random()*10),
|
||||||
|
todoCount:Math.floor(Math.random()*10),
|
||||||
|
enabled:true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Unmocked call
|
||||||
|
return target(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rest API mocking
|
||||||
|
{
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api`)
|
||||||
|
const unmocked = {
|
||||||
|
request:rest.request,
|
||||||
|
rateLimit:rest.rateLimit.get,
|
||||||
|
listEventsForAuthenticatedUser:rest.activity.listEventsForAuthenticatedUser,
|
||||||
|
getViews:rest.repos.getViews,
|
||||||
|
getContributorsStats:rest.repos.getContributorsStats,
|
||||||
|
listCommits:rest.repos.listCommits,
|
||||||
|
}
|
||||||
|
|
||||||
|
//Raw request
|
||||||
|
rest.request = new Proxy(unmocked.request, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
//Arguments
|
||||||
|
const [url] = args
|
||||||
|
//Head request
|
||||||
|
if (/^HEAD .$/.test(url)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.request HEAD`)
|
||||||
|
return ({
|
||||||
|
status: 200,
|
||||||
|
url:"https://api.github.com/",
|
||||||
|
headers:{
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Commit content
|
||||||
|
if (/api.github.com.repos.lowlighter.metrics.commits.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/.test(url)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.request ${url}`)
|
||||||
|
return ({
|
||||||
|
status: 200,
|
||||||
|
url:"https://api.github.com/repos/lowlighter/metrics/commits/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
|
data:{
|
||||||
|
sha:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
|
commit:{
|
||||||
|
author:{
|
||||||
|
name:"lowlighter",
|
||||||
|
email:"22963968+lowlighter@users.noreply.github.com",
|
||||||
|
date:new Date().toISOString(),
|
||||||
|
},
|
||||||
|
committer:{
|
||||||
|
name:"lowlighter",
|
||||||
|
email:"22963968+lowlighter@users.noreply.github.com",
|
||||||
|
date:new Date().toISOString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author:{
|
||||||
|
login:"lowlighter",
|
||||||
|
id:22963968,
|
||||||
|
},
|
||||||
|
committer:{
|
||||||
|
login:"lowlighter",
|
||||||
|
id:22963968,
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
sha:"5ab8c4fb6a0be4c157419c3b9d7b522dca354b3f",
|
||||||
|
filename:"index.mjs",
|
||||||
|
patch:"@@ -0,0 +1,5 @@\n+//Imports\n+ import app from \"./src/app.mjs\"\n+\n+//Start app\n+ await app()\n\\ No newline at end of file"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return target(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Rate limit
|
||||||
|
rest.rateLimit.get = new Proxy(unmocked.rateLimit, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
return ({
|
||||||
|
status: 200,
|
||||||
|
url:"https://api.github.com/rate_limit",
|
||||||
|
headers:{
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:{
|
||||||
|
resources:{
|
||||||
|
core:{limit:5000, used:0, remaining:5000, reset:0 },
|
||||||
|
search:{limit:30, used:0, remaining:30, reset:0 },
|
||||||
|
graphql:{limit:5000, used:0, remaining:5000, reset:0 },
|
||||||
|
integration_manifest:{limit:5000, used:0, remaining:5000, reset:0 },
|
||||||
|
source_import:{limit:100, used:0, remaining:100, reset:0 },
|
||||||
|
code_scanning_upload:{limit:500, used:0, remaining:500, reset:0 },
|
||||||
|
},
|
||||||
|
rate:{limit:5000, used:0, remaining:"MOCKED", reset:0}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Events list
|
||||||
|
rest.activity.listEventsForAuthenticatedUser = new Proxy(unmocked.listEventsForAuthenticatedUser, {
|
||||||
|
apply:function(target, that, [{page, per_page}]) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.activity.listEventsForAuthenticatedUser`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
url:`https://api.github.com/users/lowlighter/events?per_page=${per_page}&page=${page}`,
|
||||||
|
headers:{
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:page < 1 ? new Array(10).fill(null).map(() =>
|
||||||
|
(false ? {
|
||||||
|
id:"10000000001",
|
||||||
|
type:"IssueCommentEvent",
|
||||||
|
} : {
|
||||||
|
id:"10000000000",
|
||||||
|
type:"PushEvent",
|
||||||
|
actor:{
|
||||||
|
id:22963968,
|
||||||
|
login:"lowlighter",
|
||||||
|
},
|
||||||
|
repo: {
|
||||||
|
id:293860197,
|
||||||
|
name:"lowlighter/metrics",
|
||||||
|
},
|
||||||
|
payload: {
|
||||||
|
ref:"refs/heads/master",
|
||||||
|
commits: [
|
||||||
|
{
|
||||||
|
url:"https://api.github.com/repos/lowlighter/metrics/commits/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString()
|
||||||
|
})
|
||||||
|
) : []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Repository traffic
|
||||||
|
rest.repos.getViews = new Proxy(unmocked.getViews, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.getViews`)
|
||||||
|
const count = Math.floor(Math.random()*1000)*2
|
||||||
|
const uniques = Math.floor(Math.random()*count)*2
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
url:"https://api.github.com/repos/lowlighter/metrics/traffic/views",
|
||||||
|
headers:{
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:{
|
||||||
|
count,
|
||||||
|
uniques,
|
||||||
|
views:[
|
||||||
|
{timestamp:new Date().toISOString(), count:count/2, uniques:uniques/2},
|
||||||
|
{timestamp:new Date().toISOString(), count:count/2, uniques:uniques/2},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Repository contributions
|
||||||
|
rest.repos.getContributorsStats = new Proxy(unmocked.getContributorsStats, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.getContributorsStats`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
url:"https://api.github.com/repos/lowlighter/metrics/stats/contributors",
|
||||||
|
headers: {
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:[
|
||||||
|
{
|
||||||
|
total:Math.floor(Math.random()*1000),
|
||||||
|
weeks:[
|
||||||
|
{w:1, a:Math.floor(Math.random()*10000), d:Math.floor(Math.random()*10000), c:Math.floor(Math.random()*10000)},
|
||||||
|
{w:2, a:Math.floor(Math.random()*10000), d:Math.floor(Math.random()*10000), c:Math.floor(Math.random()*10000)},
|
||||||
|
{w:3, a:Math.floor(Math.random()*10000), d:Math.floor(Math.random()*10000), c:Math.floor(Math.random()*10000)},
|
||||||
|
{w:4, a:Math.floor(Math.random()*10000), d:Math.floor(Math.random()*10000), c:Math.floor(Math.random()*10000)},
|
||||||
|
],
|
||||||
|
author: {
|
||||||
|
login:"lowlighter",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Repository contributions
|
||||||
|
rest.repos.listCommits = new Proxy(unmocked.listCommits, {
|
||||||
|
apply:function(target, that, [{page, per_page}]) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.listCommits`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
url:`https://api.github.com/repos/lowlighter/metrics/commits?per_page=${per_page}&page=${page}`,
|
||||||
|
headers: {
|
||||||
|
server:"GitHub.com",
|
||||||
|
status:"200 OK",
|
||||||
|
"x-oauth-scopes":"repo",
|
||||||
|
},
|
||||||
|
data:page < 2 ? new Array(per_page).fill(null).map(() =>
|
||||||
|
({
|
||||||
|
sha:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
|
commit:{
|
||||||
|
author:{
|
||||||
|
name:"lowlighter",
|
||||||
|
date:new Date(Date.now()-Math.floor(-Math.random()*14)*24*60*60*1000).toISOString()
|
||||||
|
},
|
||||||
|
committer:{
|
||||||
|
name:"lowlighter",
|
||||||
|
date:new Date(Date.now()-Math.floor(-Math.random()*14)*24*60*60*1000).toISOString()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
) : []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//Axios mocking
|
||||||
|
{
|
||||||
|
console.debug(`metrics/compute/mocks > mocking axios`)
|
||||||
|
const unmocked = {
|
||||||
|
get:axios.get,
|
||||||
|
post:axios.post,
|
||||||
|
}
|
||||||
|
|
||||||
|
//Post requests
|
||||||
|
axios.post = new Proxy(unmocked.post, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
//Arguments
|
||||||
|
const [url, body, options] = args
|
||||||
|
//Spotify api
|
||||||
|
if (/accounts.spotify.com.api.token/.test(url)) {
|
||||||
|
//Access token generator
|
||||||
|
const params = new urls.URLSearchParams(body)
|
||||||
|
if ((params.get("grant_type") === "refresh_token")&&(params.get("client_id") === "MOCKED_CLIENT_ID")&&(params.get("client_secret") === "MOCKED_CLIENT_SECRET")&&(params.get("refresh_token") === "MOCKED_REFRESH_TOKEN")) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
access_token:"MOCKED_TOKEN_ACCESS",
|
||||||
|
token_type:"Bearer",
|
||||||
|
expires_in:3600,
|
||||||
|
scope:"user-read-recently-played user-read-private",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Get requests
|
||||||
|
axios.get = new Proxy(unmocked.get, {
|
||||||
|
apply:function(target, that, args) {
|
||||||
|
//Arguments
|
||||||
|
const [url, options] = args
|
||||||
|
//Pagespeed api
|
||||||
|
if (/googleapis.com.pagespeedonline.v5/.test(url)) {
|
||||||
|
//Pagespeed result
|
||||||
|
if (/v5.runPagespeed.*&key=MOCKED_TOKEN/.test(url)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking pagespeed api result > ${url}`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
captchaResult:"CAPTCHA_NOT_NEEDED",
|
||||||
|
id:"https://simon.lecoq.io/",
|
||||||
|
lighthouseResult:{
|
||||||
|
requestedUrl:"https://simon.lecoq.io/",
|
||||||
|
finalUrl:"https://simon.lecoq.io/",
|
||||||
|
lighthouseVersion:"6.3.0",
|
||||||
|
audits:{
|
||||||
|
"final-screenshot":{
|
||||||
|
id:"final-screenshot",
|
||||||
|
title:"Final Screenshot",
|
||||||
|
score: null,
|
||||||
|
details:{
|
||||||
|
data:"data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
||||||
|
type:"screenshot",
|
||||||
|
timestamp:Date.now()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metrics:{
|
||||||
|
id:"metrics",
|
||||||
|
title:"Metrics",
|
||||||
|
score: null,
|
||||||
|
details:{
|
||||||
|
items:[
|
||||||
|
{
|
||||||
|
observedFirstContentfulPaint:283,
|
||||||
|
observedFirstVisualChangeTs:1789259909429,
|
||||||
|
observedFirstContentfulPaintTs:1789259857628,
|
||||||
|
firstContentfulPaint:370,
|
||||||
|
observedDomContentLoaded:251,
|
||||||
|
observedFirstMeaningfulPaint:642,
|
||||||
|
maxPotentialFID:203,
|
||||||
|
observedLoad:330,
|
||||||
|
firstMeaningfulPaint:370,
|
||||||
|
observedCumulativeLayoutShift:0.0028944855967078186,
|
||||||
|
observedSpeedIndex:711,
|
||||||
|
observedSpeedIndexTs:1789260285891,
|
||||||
|
observedTimeOriginTs:1789259574429,
|
||||||
|
observedLargestContentfulPaint:857,
|
||||||
|
cumulativeLayoutShift:0.0028944855967078186,
|
||||||
|
observedFirstPaintTs:1789259857628,
|
||||||
|
observedTraceEndTs:1789261300953,
|
||||||
|
largestContentfulPaint:1085,
|
||||||
|
observedTimeOrigin:0,
|
||||||
|
speedIndex:578,
|
||||||
|
observedTraceEnd:1727,
|
||||||
|
observedDomContentLoadedTs:1789259825567,
|
||||||
|
observedFirstPaint:283,
|
||||||
|
totalBlockingTime:133,
|
||||||
|
observedLastVisualChangeTs:1789260426429,
|
||||||
|
observedFirstVisualChange:335,
|
||||||
|
observedLargestContentfulPaintTs:1789260431554,
|
||||||
|
estimatedInputLatency:13,
|
||||||
|
observedLoadTs:1789259904916,
|
||||||
|
observedLastVisualChange:852,
|
||||||
|
firstCPUIdle:773,
|
||||||
|
interactive:953,
|
||||||
|
observedNavigationStartTs:1789259574429,
|
||||||
|
observedNavigationStart:0,
|
||||||
|
observedFirstMeaningfulPaintTs:1789260216895
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
categories:{
|
||||||
|
"best-practices":{
|
||||||
|
id:"best-practices",
|
||||||
|
title:"Best Practices",
|
||||||
|
score:Math.floor(Math.random()*100)/100,
|
||||||
|
},
|
||||||
|
seo:{
|
||||||
|
id:"seo",
|
||||||
|
title:"SEO",
|
||||||
|
score:Math.floor(Math.random()*100)/100,
|
||||||
|
},
|
||||||
|
accessibility:{
|
||||||
|
id:"accessibility",
|
||||||
|
title:"Accessibility",
|
||||||
|
score:Math.floor(Math.random()*100)/100,
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
id:"performance",
|
||||||
|
title:"Performance",
|
||||||
|
score:Math.floor(Math.random()*100)/100,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
analysisUTCTimestamp:new Date().toISOString()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Spotify api
|
||||||
|
if (/api.spotify.com/.test(url)) {
|
||||||
|
//Get recently played tracks
|
||||||
|
if (/me.player.recently-played/.test(url)&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN_ACCESS")) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
items:[
|
||||||
|
{
|
||||||
|
track:{
|
||||||
|
album:{
|
||||||
|
album_type:"single",
|
||||||
|
artists:[
|
||||||
|
{
|
||||||
|
name:"EGOIST",
|
||||||
|
type:"artist",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
images:[
|
||||||
|
{
|
||||||
|
height:640,
|
||||||
|
url:"https://i.scdn.co/image/ab67616d0000b27366371d0ad05c3f402d9cb2ae",
|
||||||
|
width:640
|
||||||
|
},
|
||||||
|
{
|
||||||
|
height:300,
|
||||||
|
url:"https://i.scdn.co/image/ab67616d00001e0266371d0ad05c3f402d9cb2ae",
|
||||||
|
width:300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
height:64,
|
||||||
|
url:"https://i.scdn.co/image/ab67616d0000485166371d0ad05c3f402d9cb2ae",
|
||||||
|
width:64
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name:"Fallen",
|
||||||
|
release_date:"2014-11-19",
|
||||||
|
type:"album",
|
||||||
|
},
|
||||||
|
artists:[
|
||||||
|
{
|
||||||
|
name:"EGOIST",
|
||||||
|
type:"artist",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name:"Fallen",
|
||||||
|
preview_url:"https://p.scdn.co/mp3-preview/f30eb6d1c55afa13ce754559a41ab683a1a76b02?cid=fa6ae353840041ee8af3bd1d21a66783",
|
||||||
|
type:"track",
|
||||||
|
},
|
||||||
|
played_at:new Date().toISOString(),
|
||||||
|
context:{
|
||||||
|
type:"album",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Twitter api
|
||||||
|
if (/api.twitter.com/.test(url)) {
|
||||||
|
//Get user profile
|
||||||
|
if ((/users.by.username/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
data:{
|
||||||
|
profile_image_url:"https://pbs.twimg.com/profile_images/1338344493234286592/C_ujKIUa_normal.png",
|
||||||
|
name:"GitHub",
|
||||||
|
verified:true,
|
||||||
|
id:"13334762",
|
||||||
|
username:"github",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//Get recent tweets
|
||||||
|
if ((/tweets.search.recent/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`)
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
data:[
|
||||||
|
{
|
||||||
|
id:"1000000000000000001",
|
||||||
|
created_at:new Date().toISOString(),
|
||||||
|
entities:{
|
||||||
|
mentions:[
|
||||||
|
{start:22, end:33, username:"lowlighter"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
text:"Checkout metrics from @lowlighter ! #GitHub",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:"1000000000000000000",
|
||||||
|
created_at:new Date().toISOString(),
|
||||||
|
text:"Hello world !",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
includes:{
|
||||||
|
users:[
|
||||||
|
{
|
||||||
|
id:"100000000000000000",
|
||||||
|
name:"lowlighter",
|
||||||
|
username:"lowlighter",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
meta:{
|
||||||
|
newest_id:"1000000000000000001",
|
||||||
|
oldest_id:"1000000000000000000",
|
||||||
|
result_count:2,
|
||||||
|
next_token:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return mocked elements
|
||||||
|
return {graphql, rest}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -131,9 +131,9 @@
|
|||||||
{headers:{"Content-Type":"application/x-www-form-urlencoded"}},
|
{headers:{"Content-Type":"application/x-www-form-urlencoded"}},
|
||||||
)
|
)
|
||||||
console.debug(`metrics/compute/${login}/plugins > music > got access token`)
|
console.debug(`metrics/compute/${login}/plugins > music > got access token`)
|
||||||
//Retriev tracks
|
//Retrieve tracks
|
||||||
console.debug(`metrics/compute/${login}/plugins > music > querying spotify api`)
|
console.debug(`metrics/compute/${login}/plugins > music > querying spotify api`)
|
||||||
tracks = (await imports.axios(`https://api.spotify.com/v1/me/player/recently-played?limit=${limit}&after=${timestamp}`, {headers:{
|
tracks = (await imports.axios.get(`https://api.spotify.com/v1/me/player/recently-played?limit=${limit}&after=${timestamp}`, {headers:{
|
||||||
"Accept":"application/json",
|
"Accept":"application/json",
|
||||||
"Content-Type":"application/json",
|
"Content-Type":"application/json",
|
||||||
"Authorization":`Bearer ${access}`}
|
"Authorization":`Bearer ${access}`}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
}
|
}
|
||||||
//Handle errors
|
//Handle errors
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
if (error.error?.message)
|
||||||
|
throw error
|
||||||
throw {error:{message:"An error occured", instance:error}}
|
throw {error:{message:"An error occured", instance:error}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,6 @@ query Metrics {
|
|||||||
websiteUrl
|
websiteUrl
|
||||||
isHireable
|
isHireable
|
||||||
twitterUsername
|
twitterUsername
|
||||||
gists {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
repositories(last: 0, isFork: false, ownerAffiliations: OWNER) {
|
repositories(last: 0, isFork: false, ownerAffiliations: OWNER) {
|
||||||
totalCount
|
totalCount
|
||||||
totalDiskUsage
|
totalDiskUsage
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
query Projects {
|
query RepositoryProject {
|
||||||
user(login: "$user") {
|
user(login: "$user") {
|
||||||
repository(name: "$repository") {
|
repository(name: "$repository") {
|
||||||
project(number: $id) {
|
project(number: $id) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
query Metrics {
|
query Repositories {
|
||||||
user(login: "$login") {
|
user(login: "$login") {
|
||||||
repositories($after first: $repositories, isFork: false, ownerAffiliations: OWNER, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
repositories($after first: $repositories, isFork: false, ownerAffiliations: OWNER, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
||||||
edges {
|
edges {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
query Metrics {
|
query Repository {
|
||||||
user(login: "$login") {
|
user(login: "$login") {
|
||||||
repository(name: "$repo") {
|
repository(name: "$repo") {
|
||||||
name
|
name
|
||||||
|
|||||||
+1
-18
@@ -37,17 +37,10 @@
|
|||||||
|
|
||||||
//Load package settings
|
//Load package settings
|
||||||
logger(`metrics/setup > load package.json`)
|
logger(`metrics/setup > load package.json`)
|
||||||
if (fs.existsSync(path.resolve("package.json"))) {
|
|
||||||
conf.package = JSON.parse(`${await fs.promises.readFile(path.resolve("package.json"))}`)
|
conf.package = JSON.parse(`${await fs.promises.readFile(path.resolve("package.json"))}`)
|
||||||
logger(`metrics/setup > load package.json > success`)
|
logger(`metrics/setup > load package.json > success`)
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger(`metrics/setup > load package.json > (missing)`)
|
|
||||||
conf.package = {version:"<#version>", author:"lowlighter"}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Load templates
|
//Load templates
|
||||||
if (fs.existsSync(path.resolve(templates))) {
|
|
||||||
for (const name of await fs.promises.readdir(templates)) {
|
for (const name of await fs.promises.readdir(templates)) {
|
||||||
//Cache templates
|
//Cache templates
|
||||||
if (/.*[.]mjs$/.test(name))
|
if (/.*[.]mjs$/.test(name))
|
||||||
@@ -73,14 +66,8 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger(`metrics/setup > load templates from build`)
|
|
||||||
conf.templates = JSON.parse(Buffer.from(`<#assets>`, "base64").toString("utf8"))
|
|
||||||
}
|
|
||||||
|
|
||||||
//Load queries
|
//Load queries
|
||||||
if (fs.existsSync(path.resolve(queries))) {
|
|
||||||
for (const query of await fs.promises.readdir(queries)) {
|
for (const query of await fs.promises.readdir(queries)) {
|
||||||
//Cache queries
|
//Cache queries
|
||||||
const name = query.replace(/[.]graphql$/, "")
|
const name = query.replace(/[.]graphql$/, "")
|
||||||
@@ -99,11 +86,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger(`metrics/setup > load queries from build`)
|
|
||||||
conf.queries = JSON.parse(Buffer.from(`<#queries>`, "base64").toString("utf8"))
|
|
||||||
}
|
|
||||||
//Create queries formatters
|
//Create queries formatters
|
||||||
Object.keys(conf.queries).map(name => conf.queries[name.substring(1)] = (vars = {}) => {
|
Object.keys(conf.queries).map(name => conf.queries[name.substring(1)] = (vars = {}) => {
|
||||||
let query = conf.queries[name]
|
let query = conf.queries[name]
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
//Imports
|
|
||||||
import build from "../utils/build.mjs"
|
|
||||||
import colors from "colors"
|
|
||||||
|
|
||||||
//Initialization
|
|
||||||
process.on("unhandledRejection", error => { throw error })
|
|
||||||
colors.enable()
|
|
||||||
|
|
||||||
/** Test function */
|
|
||||||
export default async function test() {
|
|
||||||
//Perform tests
|
|
||||||
await test.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Build test */
|
|
||||||
test.build = async function () {
|
|
||||||
//Ensure that code has been rebuild
|
|
||||||
console.log("TEST : build".cyan)
|
|
||||||
await build({actions:["check"]})
|
|
||||||
}
|
|
||||||
|
|
||||||
//Main
|
|
||||||
if (/metrics.mjs/.test(process.argv[1])) {
|
|
||||||
//Test
|
|
||||||
await test()
|
|
||||||
console.log("Test success !".green)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
//Imports
|
||||||
|
const processes = require("child_process")
|
||||||
|
const yaml = require("js-yaml")
|
||||||
|
const fs = require("fs")
|
||||||
|
|
||||||
|
//Github action
|
||||||
|
const action = yaml.safeLoad(fs.readFileSync("action.yml", "utf8"))
|
||||||
|
action.defaults = Object.fromEntries(Object.entries(action.inputs).map(([key, {default:value}]) => [key, /^(yes|no)$/.test(value) ? value === "yes" : value]))
|
||||||
|
action.input = vars => Object.fromEntries([...Object.entries(action.defaults), ...Object.entries(vars)].map(([key, value]) => [`INPUT_${key.toLocaleUpperCase()}`, value]))
|
||||||
|
action.run = async (vars) => await new Promise((solve, reject) => {
|
||||||
|
let [stdout, stderr] = ["", ""]
|
||||||
|
const env = {...process.env, ...action.input(vars), GITHUB_REPOSITORY:"lowlighter/metrics"}
|
||||||
|
const child = processes.spawn("node", ["action/index.mjs"], {env})
|
||||||
|
child.stdout.on("data", data => stdout += data)
|
||||||
|
child.stderr.on("data", data => stderr += data)
|
||||||
|
child.on("close", code => {
|
||||||
|
if (code === 0)
|
||||||
|
return solve(true)
|
||||||
|
console.log(stdout, stderr)
|
||||||
|
reject(stdout)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
//Tests run
|
||||||
|
describe.each([
|
||||||
|
["classic", {}],
|
||||||
|
["terminal", {}],
|
||||||
|
["repository", {repo:"metrics"}],
|
||||||
|
])("Template : %s", (template, query) => {
|
||||||
|
for (const [name, input, {skip = []} = {}] of [
|
||||||
|
["Base (header)", {
|
||||||
|
base:"header"
|
||||||
|
}],
|
||||||
|
["Base (activity", {
|
||||||
|
base:"activity"
|
||||||
|
}],
|
||||||
|
["Base (community)", {
|
||||||
|
base:"community"
|
||||||
|
}],
|
||||||
|
["Base (repositories)", {
|
||||||
|
base:"repositories"
|
||||||
|
}],
|
||||||
|
["Base (metadata)", {
|
||||||
|
base:"metadata"
|
||||||
|
}],
|
||||||
|
["Base (complete)", {
|
||||||
|
base:"header, activity, community, repositories, metadata"
|
||||||
|
}],
|
||||||
|
["PageSpeed plugin (default)", {
|
||||||
|
plugin_pagespeed:true,
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["PageSpeed plugin (detailed)", {
|
||||||
|
plugin_pagespeed:true,
|
||||||
|
plugin_pagespeed_detailed:true,
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["PageSpeed plugin (screenshot)", {
|
||||||
|
plugin_pagespeed:true,
|
||||||
|
plugin_pagespeed_screenshot:true,
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["PageSpeed plugin (complete)", {
|
||||||
|
plugin_pagespeed:true,
|
||||||
|
plugin_pagespeed_detailed:true,
|
||||||
|
plugin_pagespeed_screenshot:true,
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["Isocalendar plugin (default)", {
|
||||||
|
plugin_isocalendar: true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Isocalendar plugin (half-year)", {
|
||||||
|
plugin_isocalendar: true,
|
||||||
|
plugin_isocalendar_duration: "half-year",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Isocalendar plugin (full-year)", {
|
||||||
|
plugin_isocalendar: true,
|
||||||
|
plugin_isocalendar_duration: "full-year",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Music plugin (playlist - apple)", {
|
||||||
|
plugin_music:true,
|
||||||
|
plugin_music_playlist:"https://embed.music.apple.com/fr/playlist/usr-share/pl.u-V9D7m8Etjmjd0D",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Music plugin (playlist - spotify)", {
|
||||||
|
plugin_music:true,
|
||||||
|
plugin_music_playlist:"https://open.spotify.com/embed/playlist/3nfA87oeJw4LFVcUDjRcqi",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Music plugin (recent - spotify)", {
|
||||||
|
plugin_music:true,
|
||||||
|
plugin_music_provider: "spotify",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Language plugin (default)", {
|
||||||
|
plugin_languages:true,
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["Language plugin (ignored languages)", {
|
||||||
|
plugin_languages:true,
|
||||||
|
plugin_languages_ignored:"html, css, dockerfile",
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["Language plugin (skipped repositories)", {
|
||||||
|
plugin_languages:true,
|
||||||
|
plugin_languages_skipped:"metrics",
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["Language plugin (complete)", {
|
||||||
|
plugin_languages:true,
|
||||||
|
plugin_languages_ignored:"html, css, dockerfile",
|
||||||
|
plugin_languages_skipped:"metrics",
|
||||||
|
}, {skip:["repository"]}],
|
||||||
|
["Follow-up plugin (default)", {
|
||||||
|
plugin_followup:true,
|
||||||
|
}],
|
||||||
|
["Topics plugin (default)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (starred - starred sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"starred",
|
||||||
|
plugin_topics_sort:"starred",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (starred - activity sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"starred",
|
||||||
|
plugin_topics_sort:"activity",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (starred - stars sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"starred",
|
||||||
|
plugin_topics_sort:"stars",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (starred - random sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"starred",
|
||||||
|
plugin_topics_sort:"random",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (mastered - starred sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"mastered",
|
||||||
|
plugin_topics_sort:"starred",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (mastered - activity sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"mastered",
|
||||||
|
plugin_topics_sort:"activity",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (mastered - stars sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"mastered",
|
||||||
|
plugin_topics_sort:"stars",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Topics plugin (mastered - random sort)", {
|
||||||
|
plugin_topics:true,
|
||||||
|
plugin_topics_mode:"mastered",
|
||||||
|
plugin_topics_sort:"random",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Projects plugin (default)", {
|
||||||
|
plugin_projects:true,
|
||||||
|
}, {skip:["terminal"]}],
|
||||||
|
["Projects plugin (repositories)", {
|
||||||
|
plugin_projects:true,
|
||||||
|
plugin_projects_repositories:"lowlighter/metrics/projects/1",
|
||||||
|
plugin_projects_limit:0,
|
||||||
|
}, {skip:["terminal"]}],
|
||||||
|
["Lines plugin (default)", {
|
||||||
|
base:"repositories",
|
||||||
|
plugin_lines:true,
|
||||||
|
}],
|
||||||
|
["Traffic plugin (default)", {
|
||||||
|
base:"repositories",
|
||||||
|
plugin_traffic:true,
|
||||||
|
}],
|
||||||
|
["Tweets plugin (default)", {
|
||||||
|
plugin_tweets:true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Posts plugin (dev.to)", {
|
||||||
|
user:"lowlighter",
|
||||||
|
plugin_posts:true,
|
||||||
|
plugin_posts_source:"dev.to",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Habits plugin (default)", {
|
||||||
|
plugin_habits:true,
|
||||||
|
plugin_habits_from:5,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Habits plugin (charts)", {
|
||||||
|
plugin_habits:true,
|
||||||
|
plugin_habits_from:5,
|
||||||
|
plugin_habits_charts:true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Habits plugin (facts)", {
|
||||||
|
plugin_habits:true,
|
||||||
|
plugin_habits_from:5,
|
||||||
|
plugin_habits_facts:true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Habits plugin (complete)", {
|
||||||
|
plugin_habits:true,
|
||||||
|
plugin_habits_from:5,
|
||||||
|
plugin_habits_charts:true,
|
||||||
|
plugin_habits_charts:true,
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Gists plugin (default)", {
|
||||||
|
plugin_gists:true,
|
||||||
|
}, {skip:["terminal"]}],
|
||||||
|
])
|
||||||
|
if (skip.includes(template))
|
||||||
|
test.skip(name, () => null)
|
||||||
|
else
|
||||||
|
test(name, async () => expect(await action.run({
|
||||||
|
token:"MOCKED_TOKEN",
|
||||||
|
plugin_pagespeed_token:"MOCKED_TOKEN",
|
||||||
|
plugin_tweets_token:"MOCKED_TOKEN",
|
||||||
|
plugin_music_token:"MOCKED_CLIENT_ID, MOCKED_CLIENT_SECRET, MOCKED_REFRESH_TOKEN",
|
||||||
|
template, base:"", query:JSON.stringify(query),
|
||||||
|
config_timezone:"Europe/Paris",
|
||||||
|
plugins_errors_fatal:true, dryrun:true, use_mocked_data:true, verify:true,
|
||||||
|
...input
|
||||||
|
})).toBe(true), 60*1e3)
|
||||||
|
})
|
||||||
-117
@@ -2,20 +2,13 @@
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import url from "url"
|
import url from "url"
|
||||||
import ncc from "@vercel/ncc"
|
|
||||||
import minify from "babel-minify"
|
|
||||||
import colors from "colors"
|
import colors from "colors"
|
||||||
import ejs from "ejs"
|
|
||||||
|
|
||||||
//Initialization
|
//Initialization
|
||||||
const __dirname = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..")
|
const __dirname = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..")
|
||||||
const __action = path.join(__dirname, "action")
|
|
||||||
const __workflows = path.join(__dirname, ".github/workflows")
|
|
||||||
const __utils = path.join(__dirname, "utils")
|
|
||||||
const __src = path.join(__dirname, "src")
|
const __src = path.join(__dirname, "src")
|
||||||
const __plugins = path.join(__src, "plugins")
|
const __plugins = path.join(__src, "plugins")
|
||||||
const __templates = path.join(__src, "templates")
|
const __templates = path.join(__src, "templates")
|
||||||
const __queries = path.join(__src, "queries")
|
|
||||||
process.on("unhandledRejection", error => { throw error })
|
process.on("unhandledRejection", error => { throw error })
|
||||||
colors.enable()
|
colors.enable()
|
||||||
|
|
||||||
@@ -61,116 +54,6 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Workflow
|
|
||||||
{
|
|
||||||
//Build
|
|
||||||
const code = await ejs.renderFile(path.join(__utils, "workflow.yml"), {
|
|
||||||
releases:["master"],
|
|
||||||
templates:(await fs.promises.readdir(__templates)).filter(name => !/.*[.]mjs$/.test(name)).filter(name => !["repository"].includes(name)).sort(),
|
|
||||||
testcase(context = {}) {
|
|
||||||
return [`with:`, ...Object.entries({
|
|
||||||
token:"${{ secrets.METRICS_TOKEN }}",
|
|
||||||
dryrun:true,
|
|
||||||
repositories:0,
|
|
||||||
template:"${{ matrix.template }}",
|
|
||||||
base:"",
|
|
||||||
plugins_errors_fatal:true,
|
|
||||||
...context
|
|
||||||
}).map(([key, value]) => `${" ".repeat(5)}${key}: ${
|
|
||||||
typeof value === "boolean" ? (value ? "yes" : "no") :
|
|
||||||
typeof value === "string" ? (!value ? `""` : value) :
|
|
||||||
value
|
|
||||||
}`)].join("\n")
|
|
||||||
},
|
|
||||||
}, {async:true})
|
|
||||||
console.log(`Generated workflow`.grey)
|
|
||||||
|
|
||||||
//Save build
|
|
||||||
if (actions.includes("build")) {
|
|
||||||
fs.promises.writeFile(path.join(__workflows, "workflow.yml"), code)
|
|
||||||
console.log(`Generated workflow saved to ${path.join(__workflows, "dist/index.js")}`.green)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check build
|
|
||||||
if (actions.includes("check")) {
|
|
||||||
const status = `${await fs.promises.readFile(path.join(__workflows, "workflow.yml"))}` === code
|
|
||||||
if (status)
|
|
||||||
console.log(`Workflow is up-to-date`.grey)
|
|
||||||
else {
|
|
||||||
console.log(`Workflow is outdated`.red)
|
|
||||||
errors.push(`Workflow is outdated, run "npm run build" to fix it`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Action
|
|
||||||
{
|
|
||||||
//Build
|
|
||||||
let {code} = await ncc(`${__action}/index.mjs`, {sourceMap:false, sourceMapRegister:false})
|
|
||||||
console.log(`Generated action`.grey)
|
|
||||||
|
|
||||||
//Perform assets includes
|
|
||||||
{
|
|
||||||
const assets = {}
|
|
||||||
const templates = (await fs.promises.readdir(__templates)).filter(name => !/.*[.]mjs$/.test(name)).sort()
|
|
||||||
for (const name of templates) {
|
|
||||||
const files = [
|
|
||||||
`${__templates}/${name}/image.svg`,
|
|
||||||
`${__templates}/${name}/style.css`,
|
|
||||||
`${__templates}/${name}/fonts.css`,
|
|
||||||
].map(file => fs.existsSync(path.resolve(file)) ? file : file.replace(`${__templates}/${name}/`, `${__templates}/classic/`))
|
|
||||||
const [image, style, fonts] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
|
|
||||||
assets[name] = {image, style, fonts}
|
|
||||||
console.log(`Prepared template ${name}`.grey)
|
|
||||||
}
|
|
||||||
code = code.replace(/<#assets>/g, Buffer.from(JSON.stringify(assets)).toString("base64"))
|
|
||||||
console.log(`Included ${templates.length} templates to generated action`.grey)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Perform queries includes
|
|
||||||
{
|
|
||||||
const assets = {}
|
|
||||||
const queries = (await fs.promises.readdir(__queries)).sort()
|
|
||||||
for (const query of queries) {
|
|
||||||
const name = query.replace(/[.]graphql$/, "")
|
|
||||||
assets[`_${name}`] = `${await fs.promises.readFile(path.resolve(`${__queries}/${query}`))}`
|
|
||||||
console.log(`Prepared query ${name}`.grey)
|
|
||||||
}
|
|
||||||
code = code.replace(/<#queries>/g, Buffer.from(JSON.stringify(assets)).toString("base64"))
|
|
||||||
console.log(`Included ${queries.length} queries to generated action`.grey)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Perform version include
|
|
||||||
{
|
|
||||||
const version = JSON.parse(await fs.promises.readFile(path.join(__dirname, "package.json"))).version
|
|
||||||
code = code.replace(/<#version>/g, version)
|
|
||||||
console.log(`Included version number (${version}) to generated action`.grey)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Minify
|
|
||||||
code = minify(code).code
|
|
||||||
console.log(`Minified code`.grey)
|
|
||||||
if (!code)
|
|
||||||
throw new Error(`Failed to minify code`)
|
|
||||||
|
|
||||||
//Save build
|
|
||||||
if (actions.includes("build")) {
|
|
||||||
fs.promises.writeFile(path.join(__action, "dist/index.js"), code)
|
|
||||||
console.log(`Generated action saved to ${path.join(__action, "dist/index.js")}`.green)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check build
|
|
||||||
if (actions.includes("check")) {
|
|
||||||
const status = `${await fs.promises.readFile(path.join(__action, "dist/index.js"))}` === code
|
|
||||||
if (status)
|
|
||||||
console.log(`Action is up-to-date`.grey)
|
|
||||||
else {
|
|
||||||
console.log(`Action is outdated`.red)
|
|
||||||
errors.push(`Action is outdated, run "npm run build" to fix it`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Throw on errors
|
//Throw on errors
|
||||||
if (errors.length)
|
if (errors.length)
|
||||||
throw new Error(`${errors.length} errors occured :\n${errors.map(error => ` - ${error}`).join("\n")}`)
|
throw new Error(`${errors.length} errors occured :\n${errors.map(error => ` - ${error}`).join("\n")}`)
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Setup
|
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 15.x
|
|
||||||
- name: Install
|
|
||||||
run: npm ci
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
- name: Test
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
analyze:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: <%- JSON.stringify(releases.map(release => `test-${release}`)) %>
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Setup
|
|
||||||
uses: github/codeql-action/init@v1
|
|
||||||
with:
|
|
||||||
languages: javascript
|
|
||||||
config-file: ./.github/config/codeql.yml
|
|
||||||
- name: Analyze
|
|
||||||
uses: github/codeql-action/analyze@v1
|
|
||||||
|
|
||||||
# Tests cases below are auto generated through `npm run build`
|
|
||||||
# Edit utils/workflow.yml instead if you need to update workflow
|
|
||||||
<% for (const release of releases) { %>
|
|
||||||
test-<%- release %>:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
template: <%- JSON.stringify(templates) %>
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Base
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
base: "header, activity, community, repositories, metadata",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > PageSpeed
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_pagespeed: true,
|
|
||||||
plugin_pagespeed_token: "${{ secrets.PAGESPEED_TOKEN }}",
|
|
||||||
plugin_pagespeed_detailed: true,
|
|
||||||
plugin_pagespeed_screenshot: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (playlist - apple)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_music: true,
|
|
||||||
plugin_music_playlist: "${{ secrets.MUSIC_PLAYLIST_APPLE }}",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (playlist - spotify)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_music: true,
|
|
||||||
plugin_music_playlist: "${{ secrets.MUSIC_PLAYLIST_SPOTIFY }}",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Music (recent - spotify)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_music: true,
|
|
||||||
plugin_music_provider: "spotify",
|
|
||||||
plugin_music_token: "${{ secrets.SPOTIFY_TOKENS }}",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Posts (dev.to)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_posts: true,
|
|
||||||
plugin_posts_source: "dev.to",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Isocalendar
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_isocalendar: true,
|
|
||||||
plugin_isocalendar_duration: "full-year",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Habits
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_habits: true,
|
|
||||||
plugin_habits_from: 5,
|
|
||||||
plugin_habits_charts: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Languages
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_languages: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Follow-up
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_followup: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Lines and Traffic
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_lines: true,
|
|
||||||
plugin_traffic: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Gists
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_gists: true,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Topics (starred)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_topics: true,
|
|
||||||
plugin_topics_mode: "starred",
|
|
||||||
plugin_topics_sort: "random",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Topics (mastered)
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_topics: true,
|
|
||||||
plugin_topics_mode: "mastered",
|
|
||||||
plugin_topics_sort: "stars",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Projects
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_projects: true,
|
|
||||||
plugin_projects_repositories: "lowlighter/metrics/projects/1",
|
|
||||||
plugin_projects_limit: 2,
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
- name: ${{ matrix.template }} > Plugin > Tweets
|
|
||||||
uses: lowlighter/metrics@<%- release %>
|
|
||||||
<%- testcase({
|
|
||||||
plugin_tweets: true,
|
|
||||||
plugin_tweets_limit: 2,
|
|
||||||
plugin_tweets_token: "${{ secrets.TWITTER_TOKEN }}",
|
|
||||||
}) %>
|
|
||||||
|
|
||||||
<% } -%>
|
|
||||||
Reference in new issue
Block a user