diff --git a/source/app/web/instance.mjs b/source/app/web/instance.mjs index 4e5552ae..2c6f0011 100644 --- a/source/app/web/instance.mjs +++ b/source/app/web/instance.mjs @@ -81,7 +81,7 @@ export default async function({mock, nosettings} = {}) { const limiter = ratelimit({max:debug ? Number.MAX_SAFE_INTEGER : 60, windowMs:60 * 1000, headers:false}) const metadata = Object.fromEntries( Object.entries(conf.metadata.plugins) - .map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "category", "web", "supports"].includes(key)))]) + .map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "category", "web", "supports", "scopes"].includes(key)))]) .map(([key, value]) => [key, key === "core" ? {...value, web:Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value]))} : value]), ) const enabled = Object.entries(metadata).filter(([_name, {category}]) => category !== "core").map(([name]) => ({name, enabled:plugins[name]?.enabled ?? false})) diff --git a/source/app/web/statics/app.js b/source/app/web/statics/app.js index ce068a22..e3707e7b 100644 --- a/source/app/web/statics/app.js +++ b/source/app/web/statics/app.js @@ -174,6 +174,13 @@ embed() { return `![Metrics](${this.url})` }, + //Token scopes + scopes() { + return new Set([ + ...Object.entries(this.plugins.enabled).filter(([key, value]) => (key !== "base") && (value)).flatMap(([key]) => metadata[key].scopes), + ...(Object.entries(this.plugins.enabled.base).filter(([key, value]) => value).length ? metadata.base.scopes : []) + ]) + }, //GitHub action auto-generated code action() { return [ @@ -191,8 +198,18 @@ ` steps:`, ` - uses: lowlighter/metrics@latest`, ` with:`, + ...(this.scopes.size ? [ ` # Your GitHub token`, - ` token: ${"$"}{{ secrets.METRICS_TOKEN }}`, + ` # The following scopes are required:`, + ...[...this.scopes].map(scope => ` # - ${scope}${scope === "public_access" ? " (default scope)" : ""}`), + ` # The following additional scopes may be required:`, + ` # - read:org (for organization related metrics)`, + ` # - read:user (for user related data)`, + ` # - repo (optional, if you want to include private repositories)` + ] : [ + ` # Current configuration doesn't require a GitHub token`, + ]), + ` token: ${this.scopes.size ? `${"$"}{{ secrets.METRICS_TOKEN }}` : "NOT_NEEDED"}`, ``, ` # Options`, ` user: ${this.user}`, @@ -230,8 +247,18 @@ }, //Methods methods: { + //Refresh computed properties + async refresh() { + const keys = {action:["scopes", "action"], markdown:["url", "embed"]}[this.tab] + if (keys) { + for (const key of keys) + this._computedWatchers[key]?.run() + this.$forceUpdate() + } + }, //Load and render placeholder image async mock({ timeout = 600 } = {}) { + this.refresh() clearTimeout(this.templates.placeholder.timeout) this.templates.placeholder.timeout = setTimeout(async () => { this.templates.placeholder.image = await placeholder(this)