diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 640bd06..9c4e112 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,7 +11,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 with: - node-version: "20" + node-version: "20.10.0" - uses: actions/checkout@v4 - uses: cloudflare/wrangler-action@v3 with: diff --git a/.github/workflows/jest-testing.yml b/.github/workflows/jest-testing.yml index a982775..fc594c5 100644 --- a/.github/workflows/jest-testing.yml +++ b/.github/workflows/jest-testing.yml @@ -1,10 +1,7 @@ name: Run Jest testing suite on: workflow_dispatch: - workflow_run: - workflows: ["Knip"] - types: - - completed + pull_request: env: NODE_ENV: "test" @@ -24,10 +21,9 @@ jobs: with: fetch-depth: 0 - - name: Jest With Coverage Comment - # Ensures this step is run even on previous step failure (e.g. test failed) + - name: Jest With Coverage + run: yarn install --immutable --immutable-cache --check-cache && yarn test + + - name: Add Jest Report to Summary if: always() - uses: ArtiomTr/jest-coverage-report-action@v2 - with: - package-manager: yarn - prnumber: ${{ github.event.pull_request.number || github.event.workflow_run.pull_requests[0].number }} + run: echo "$(cat test-dashboard.md)" >> $GITHUB_STEP_SUMMARY diff --git a/README.md b/README.md index 6fa6f90..b01f60d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # @ubiquibot/user-activity-watcher Watches user activity on issues, sends reminders on deadlines, and eventually unassigns inactive user to ensure that -tasks don't stall, and applies malus XP. +tasks don't stall, and subtracts XP. ## Setup ```shell @@ -52,6 +52,6 @@ yarn test - plugin: ubiquibot/user-activity-watcher type: github with: - unassignUserThreshold: 7 - sendRemindersThreshold: 3.5 + disqualification: "7 days" + warning: "3.5 days" ``` diff --git a/jest.config.json b/jest.config.json index b4ebbc9..2796b3f 100644 --- a/jest.config.json +++ b/jest.config.json @@ -5,7 +5,7 @@ "coveragePathIgnorePatterns": ["node_modules", "mocks"], "collectCoverage": true, "coverageReporters": ["json", "lcov", "text", "clover", "json-summary"], - "reporters": ["default", "jest-junit"], + "reporters": ["default", "jest-junit", "jest-md-dashboard"], "coverageDirectory": "coverage", "setupFiles": ["dotenv/config"] } diff --git a/package.json b/package.json index 23a693c..4a12dce 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "husky": "9.0.11", "jest": "29.7.0", "jest-junit": "16.0.0", + "jest-md-dashboard": "0.8.0", "knip": "5.17.3", "lint-staged": "15.2.5", "msw": "2.3.1", diff --git a/src/handlers/collect-linked-pulls.ts b/src/handlers/collect-linked-pulls.ts new file mode 100644 index 0000000..37bb276 --- /dev/null +++ b/src/handlers/collect-linked-pulls.ts @@ -0,0 +1,78 @@ +import { parseGitHubUrl } from "../helpers/github-url"; +import { Context } from "../types/context"; +import { GitHubLinkEvent, GitHubTimelineEvent, isGitHubLinkEvent } from "../types/github-types"; + +export type IssueParams = ReturnType; + +export async function collectLinkedPullRequests(context: Context, issue: IssueParams) { + const onlyPullRequests = await collectLinkedPulls(context, issue); + return onlyPullRequests.filter((event) => { + if (!event.source.issue.body) { + return false; + } + // Matches all keywords according to the docs: + // https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword + // Works on multiple linked issues, and matches # or URL patterns + const linkedIssueRegex = + /\b(?:Close(?:s|d)?|Fix(?:es|ed)?|Resolve(?:s|d)?):?\s+(?:#(\d+)|https?:\/\/(?:www\.)?github\.com\/(?:[^/\s]+\/[^/\s]+\/(?:issues|pull)\/(\d+)))\b/gi; + const linkedPrUrls = event.source.issue.body.match(linkedIssueRegex); + if (!linkedPrUrls) { + return false; + } + let isClosingPr = false; + for (let i = 0; i < linkedPrUrls.length && !isClosingPr; ++i) { + const idx = linkedPrUrls[i].indexOf("#"); + if (idx !== -1) { + isClosingPr = Number(linkedPrUrls[i].slice(idx + 1)) === issue.issue_number; + } else { + const url = linkedPrUrls[i].match(/https.+/)?.[0]; + if (url) { + const linkedRepo = parseGitHubUrl(url); + isClosingPr = linkedRepo.issue_number === issue.issue_number && linkedRepo.repo === issue.repo && linkedRepo.owner === issue.owner; + } + } + } + return isGitHubLinkEvent(event) && event.source.issue.pull_request?.merged_at === null && isClosingPr; + }); +} + +export async function collectLinkedPulls(context: Context, issue: IssueParams) { + const issueLinkEvents = await getLinkedEvents(context, issue); + const onlyConnected = eliminateDisconnects(issueLinkEvents); + return onlyConnected.filter((event) => isGitHubLinkEvent(event) && event.source.issue.pull_request); +} + +function eliminateDisconnects(issueLinkEvents: GitHubLinkEvent[]) { + // Track connections and disconnections + const connections = new Map(); // Use issue/pr number as key for easy access + const disconnections = new Map(); // Track disconnections + + issueLinkEvents.forEach((issueEvent: GitHubLinkEvent) => { + const issueNumber = issueEvent.source.issue.number as number; + + if (issueEvent.event === "connected" || issueEvent.event === "cross-referenced") { + // Only add to connections if there is no corresponding disconnected event + if (!disconnections.has(issueNumber)) { + connections.set(issueNumber, issueEvent); + } + } else if (issueEvent.event === "disconnected") { + disconnections.set(issueNumber, issueEvent); + // If a disconnected event is found, remove the corresponding connected event + if (connections.has(issueNumber)) { + connections.delete(issueNumber); + } + } + }); + + return Array.from(connections.values()); +} + +async function getLinkedEvents(context: Context, params: IssueParams): Promise { + const issueEvents = await getAllTimelineEvents(context, params); + return issueEvents.filter(isGitHubLinkEvent); +} + +export async function getAllTimelineEvents({ octokit }: Context, issueParams: IssueParams): Promise { + const options = octokit.issues.listEventsForTimeline.endpoint.merge(issueParams); + return await octokit.paginate(options); +} diff --git a/src/helpers/update-tasks.ts b/src/helpers/update-tasks.ts index 4da70ef..3ec9e59 100644 --- a/src/helpers/update-tasks.ts +++ b/src/helpers/update-tasks.ts @@ -1,4 +1,5 @@ import { DateTime } from "luxon"; +import { collectLinkedPullRequests } from "../handlers/collect-linked-pulls"; import { Context } from "../types/context"; import { Database } from "../types/database"; import { getGithubIssue } from "./get-env"; @@ -11,7 +12,7 @@ async function unassignUserFromIssue(context: Context, issue: Database["public"] config, } = context; - if (config.unassignUserThreshold <= 0) { + if (config.disqualification <= 0) { logger.info("The unassign threshold is <= 0, won't unassign users."); } else { logger.info(`Passed the deadline on ${issue.url} and no activity is detected, removing assignees.`); @@ -30,7 +31,7 @@ async function remindAssigneesForIssue(context: Context, issue: Database["public const now = DateTime.now(); const deadline = DateTime.fromISO(issue.deadline); - if (config.sendRemindersThreshold <= 0) { + if (config.warning <= 0) { logger.info("The reminder threshold is <= 0, won't send any reminder."); } else { const lastReminder = issue.last_reminder; @@ -59,8 +60,8 @@ async function updateReminders(context: Context, issue: Database["public"]["Tabl payload.issue?.assignees?.find((assignee) => assignee?.login === o.actor.login) && DateTime.fromISO(o.created_at) >= DateTime.fromISO(issue.last_check) ); const deadline = DateTime.fromISO(issue.deadline); - const deadlineWithThreshold = deadline.plus({ day: config.unassignUserThreshold }); - const reminderWithThreshold = deadline.plus({ day: config.sendRemindersThreshold }); + const deadlineWithThreshold = deadline.plus({ milliseconds: config.disqualification }); + const reminderWithThreshold = deadline.plus({ milliseconds: config.warning }); if (activity?.length) { const lastCheck = DateTime.fromISO(issue.last_check); @@ -100,14 +101,29 @@ export async function updateTasks(context: Context) { return true; } -async function getAssigneesActivityForIssue({ octokit }: Context, issue: Database["public"]["Tables"]["issues"]["Row"]) { - const { repo, owner, issue_number } = parseGitHubUrl(issue.url); - return octokit.paginate(octokit.rest.issues.listEvents, { - owner, - repo, - issue_number, +/** + * Retrieves all the activity for users that are assigned to the issue. Also takes into account linked pull requests. + */ +async function getAssigneesActivityForIssue(context: Context, issue: Database["public"]["Tables"]["issues"]["Row"]) { + const gitHubUrl = parseGitHubUrl(issue.url); + const issueEvents = await context.octokit.paginate(context.octokit.rest.issues.listEvents, { + owner: gitHubUrl.owner, + repo: gitHubUrl.repo, + issue_number: gitHubUrl.issue_number, per_page: 100, }); + const linkedPullRequests = await collectLinkedPullRequests(context, gitHubUrl); + for (const linkedPullRequest of linkedPullRequests) { + const { owner, repo, issue_number } = parseGitHubUrl(linkedPullRequest.source.issue.html_url); + const events = await context.octokit.paginate(context.octokit.rest.issues.listEvents, { + owner, + repo, + issue_number, + per_page: 100, + }); + issueEvents.push(...events); + } + return issueEvents; } async function remindAssignees(context: Context, issue: Database["public"]["Tables"]["issues"]["Row"]) { diff --git a/src/parser/payload.ts b/src/parser/payload.ts index df73d98..19b2150 100644 --- a/src/parser/payload.ts +++ b/src/parser/payload.ts @@ -1,17 +1,20 @@ import * as github from "@actions/github"; +import { Value } from "@sinclair/typebox/value"; import { config } from "dotenv"; -import { PluginInputs } from "../types/plugin-inputs"; +import { PluginInputs, userActivityWatcherSettingsSchema } from "../types/plugin-inputs"; config(); const webhookPayload = github.context.payload.inputs; +const settings = Value.Decode(userActivityWatcherSettingsSchema, Value.Default(userActivityWatcherSettingsSchema, JSON.parse(webhookPayload.settings))); + const program: PluginInputs = { stateId: webhookPayload.stateId, eventName: webhookPayload.eventName, authToken: webhookPayload.authToken, ref: webhookPayload.ref, eventPayload: JSON.parse(webhookPayload.eventPayload), - settings: JSON.parse(webhookPayload.settings), + settings, }; export default program; diff --git a/src/types/database.ts b/src/types/database.ts index a2f645e..c50f91b 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -1,31 +1,6 @@ export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]; export type Database = { - graphql_public: { - Tables: { - [_ in never]: never; - }; - Views: { - [_ in never]: never; - }; - Functions: { - graphql: { - Args: { - operationName?: string; - query?: string; - variables?: Json; - extensions?: Json; - }; - Returns: Json; - }; - }; - Enums: { - [_ in never]: never; - }; - CompositeTypes: { - [_ in never]: never; - }; - }; public: { Tables: { issues: { @@ -69,311 +44,6 @@ export type Database = { [_ in never]: never; }; }; - storage: { - Tables: { - buckets: { - Row: { - allowed_mime_types: string[] | null; - avif_autodetection: boolean | null; - created_at: string | null; - file_size_limit: number | null; - id: string; - name: string; - owner: string | null; - owner_id: string | null; - public: boolean | null; - updated_at: string | null; - }; - Insert: { - allowed_mime_types?: string[] | null; - avif_autodetection?: boolean | null; - created_at?: string | null; - file_size_limit?: number | null; - id: string; - name: string; - owner?: string | null; - owner_id?: string | null; - public?: boolean | null; - updated_at?: string | null; - }; - Update: { - allowed_mime_types?: string[] | null; - avif_autodetection?: boolean | null; - created_at?: string | null; - file_size_limit?: number | null; - id?: string; - name?: string; - owner?: string | null; - owner_id?: string | null; - public?: boolean | null; - updated_at?: string | null; - }; - Relationships: []; - }; - migrations: { - Row: { - executed_at: string | null; - hash: string; - id: number; - name: string; - }; - Insert: { - executed_at?: string | null; - hash: string; - id: number; - name: string; - }; - Update: { - executed_at?: string | null; - hash?: string; - id?: number; - name?: string; - }; - Relationships: []; - }; - objects: { - Row: { - bucket_id: string | null; - created_at: string | null; - id: string; - last_accessed_at: string | null; - metadata: Json | null; - name: string | null; - owner: string | null; - owner_id: string | null; - path_tokens: string[] | null; - updated_at: string | null; - version: string | null; - }; - Insert: { - bucket_id?: string | null; - created_at?: string | null; - id?: string; - last_accessed_at?: string | null; - metadata?: Json | null; - name?: string | null; - owner?: string | null; - owner_id?: string | null; - path_tokens?: string[] | null; - updated_at?: string | null; - version?: string | null; - }; - Update: { - bucket_id?: string | null; - created_at?: string | null; - id?: string; - last_accessed_at?: string | null; - metadata?: Json | null; - name?: string | null; - owner?: string | null; - owner_id?: string | null; - path_tokens?: string[] | null; - updated_at?: string | null; - version?: string | null; - }; - Relationships: [ - { - foreignKeyName: "objects_bucketId_fkey"; - columns: ["bucket_id"]; - isOneToOne: false; - referencedRelation: "buckets"; - referencedColumns: ["id"]; - }, - ]; - }; - s3_multipart_uploads: { - Row: { - bucket_id: string; - created_at: string; - id: string; - in_progress_size: number; - key: string; - owner_id: string | null; - upload_signature: string; - version: string; - }; - Insert: { - bucket_id: string; - created_at?: string; - id: string; - in_progress_size?: number; - key: string; - owner_id?: string | null; - upload_signature: string; - version: string; - }; - Update: { - bucket_id?: string; - created_at?: string; - id?: string; - in_progress_size?: number; - key?: string; - owner_id?: string | null; - upload_signature?: string; - version?: string; - }; - Relationships: [ - { - foreignKeyName: "s3_multipart_uploads_bucket_id_fkey"; - columns: ["bucket_id"]; - isOneToOne: false; - referencedRelation: "buckets"; - referencedColumns: ["id"]; - }, - ]; - }; - s3_multipart_uploads_parts: { - Row: { - bucket_id: string; - created_at: string; - etag: string; - id: string; - key: string; - owner_id: string | null; - part_number: number; - size: number; - upload_id: string; - version: string; - }; - Insert: { - bucket_id: string; - created_at?: string; - etag: string; - id?: string; - key: string; - owner_id?: string | null; - part_number: number; - size?: number; - upload_id: string; - version: string; - }; - Update: { - bucket_id?: string; - created_at?: string; - etag?: string; - id?: string; - key?: string; - owner_id?: string | null; - part_number?: number; - size?: number; - upload_id?: string; - version?: string; - }; - Relationships: [ - { - foreignKeyName: "s3_multipart_uploads_parts_bucket_id_fkey"; - columns: ["bucket_id"]; - isOneToOne: false; - referencedRelation: "buckets"; - referencedColumns: ["id"]; - }, - { - foreignKeyName: "s3_multipart_uploads_parts_upload_id_fkey"; - columns: ["upload_id"]; - isOneToOne: false; - referencedRelation: "s3_multipart_uploads"; - referencedColumns: ["id"]; - }, - ]; - }; - }; - Views: { - [_ in never]: never; - }; - Functions: { - can_insert_object: { - Args: { - bucketid: string; - name: string; - owner: string; - metadata: Json; - }; - Returns: undefined; - }; - extension: { - Args: { - name: string; - }; - Returns: string; - }; - filename: { - Args: { - name: string; - }; - Returns: string; - }; - foldername: { - Args: { - name: string; - }; - Returns: string[]; - }; - get_size_by_bucket: { - Args: Record; - Returns: { - size: number; - bucket_id: string; - }[]; - }; - list_multipart_uploads_with_delimiter: { - Args: { - bucket_id: string; - prefix_param: string; - delimiter_param: string; - max_keys?: number; - next_key_token?: string; - next_upload_token?: string; - }; - Returns: { - key: string; - id: string; - created_at: string; - }[]; - }; - list_objects_with_delimiter: { - Args: { - bucket_id: string; - prefix_param: string; - delimiter_param: string; - max_keys?: number; - start_after?: string; - next_token?: string; - }; - Returns: { - name: string; - id: string; - metadata: Json; - updated_at: string; - }[]; - }; - search: { - Args: { - prefix: string; - bucketname: string; - limits?: number; - levels?: number; - offsets?: number; - search?: string; - sortcolumn?: string; - sortorder?: string; - }; - Returns: { - name: string; - id: string; - updated_at: string; - created_at: string; - last_accessed_at: string; - metadata: Json; - }[]; - }; - }; - Enums: { - [_ in never]: never; - }; - CompositeTypes: { - [_ in never]: never; - }; - }; }; type PublicSchema = Database[Extract]; diff --git a/src/types/github-types.ts b/src/types/github-types.ts new file mode 100644 index 0000000..add634d --- /dev/null +++ b/src/types/github-types.ts @@ -0,0 +1,24 @@ +import { RestEndpointMethodTypes } from "@octokit/rest"; + +export type GitHubIssue = RestEndpointMethodTypes["issues"]["get"]["response"]["data"]; +export type GitHubPullRequest = RestEndpointMethodTypes["pulls"]["get"]["response"]["data"]; +export type GitHubTimelineEvent = RestEndpointMethodTypes["issues"]["listEventsForTimeline"]["response"]["data"][0]; +export type GitHubRepository = RestEndpointMethodTypes["repos"]["get"]["response"]["data"]; + +type LinkPullRequestDetail = { + url: string; + html_url: string; + diff_url: string; + patch_url: string; + merged_at: string; +}; + +type SourceIssueWithPullRequest = GitHubIssue | ((GitHubPullRequest & { pull_request: LinkPullRequestDetail }) & { repository: GitHubRepository }); + +export type GitHubLinkEvent = RestEndpointMethodTypes["issues"]["listEventsForTimeline"]["response"]["data"][0] & { + event: "connected" | "disconnected" | "cross-referenced"; + source: { issue: SourceIssueWithPullRequest }; +}; +export function isGitHubLinkEvent(event: GitHubTimelineEvent): event is GitHubLinkEvent { + return "source" in event; +} diff --git a/src/types/plugin-inputs.ts b/src/types/plugin-inputs.ts index a41c120..cd5f714 100644 --- a/src/types/plugin-inputs.ts +++ b/src/types/plugin-inputs.ts @@ -1,5 +1,6 @@ import { EmitterWebhookEvent as WebhookEvent, EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks"; -import { StaticDecode, Type as T } from "@sinclair/typebox"; +import { StaticDecode, StringOptions, Type as T, TypeBoxError } from "@sinclair/typebox"; +import ms from "ms"; export type SupportedEvents = "issues.closed" | "issues.assigned" | "issues.unassigned"; @@ -12,18 +13,34 @@ export interface PluginInputs { ref: string; } +function thresholdType(options?: StringOptions) { + return T.Transform(T.String(options)) + .Decode((value) => { + const milliseconds = ms(value); + if (milliseconds === undefined) { + throw new TypeBoxError(`Invalid threshold value: [${value}]`); + } + return milliseconds; + }) + .Encode((value) => { + const textThreshold = ms(value, { long: true }); + if (textThreshold === undefined) { + throw new TypeBoxError(`Invalid threshold value: [${value}]`); + } + return textThreshold; + }); +} + export const userActivityWatcherSettingsSchema = T.Object({ /** * Delay to send reminders. 0 means disabled. Any other value is counted in days, e.g. 1,5 days */ - sendRemindersThreshold: T.Number({ - default: 3.5, - }), + warning: thresholdType({ default: "3.5 days" }), /** * Delay to unassign users. 0 means disabled. Any other value is counted in days, e.g. 7 days */ - unassignUserThreshold: T.Number({ - default: 7, + disqualification: thresholdType({ + default: "7 days", }), }); diff --git a/tests/__mocks__/handlers.ts b/tests/__mocks__/handlers.ts index cef791a..4250d54 100644 --- a/tests/__mocks__/handlers.ts +++ b/tests/__mocks__/handlers.ts @@ -2,6 +2,7 @@ import { http, HttpResponse } from "msw"; import { db } from "./db"; import issueEventsGet from "./routes/get-events.json"; import issuesLabelsGet from "./routes/get-labels.json"; +import issueTimeline from "./routes/get-timeline.json"; /** * Intercepts the routes and returns a custom payload @@ -29,4 +30,7 @@ export const handlers = [ http.get("https://api.github.com/repos/:owner/:repo/issues/:id/labels", () => { return HttpResponse.json(issuesLabelsGet); }), + http.get("https://api.github.com/repos/:owner/:repo/issues/:id/timeline", () => { + return HttpResponse.json(issueTimeline); + }), ]; diff --git a/tests/__mocks__/results/valid-configuration.json b/tests/__mocks__/results/valid-configuration.json index 9a64ae2..3cc6d25 100644 --- a/tests/__mocks__/results/valid-configuration.json +++ b/tests/__mocks__/results/valid-configuration.json @@ -1,4 +1,4 @@ { - "sendRemindersThreshold": 3.5, - "unassignUserThreshold": 7 + "warning": "3.5 days", + "disqualification": "7 days" } diff --git a/tests/__mocks__/routes/get-timeline.json b/tests/__mocks__/routes/get-timeline.json new file mode 100644 index 0000000..a54a40c --- /dev/null +++ b/tests/__mocks__/routes/get-timeline.json @@ -0,0 +1,1052 @@ +[ + { + "sha": "2c3f0741a2e82cc78e347f5b41aec92c3dc68801", + "node_id": "C_kwDOMDzQsNoAKDJjM2YwNzQxYTJlODJjYzc4ZTM0N2Y1YjQxYWVjOTJjM2RjNjg4MDE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/2c3f0741a2e82cc78e347f5b41aec92c3dc68801", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/2c3f0741a2e82cc78e347f5b41aec92c3dc68801", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T09:59:51Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T09:59:51Z" + }, + "tree": { + "sha": "1d32a660fc6e8bac21961be105370d8ae08b6858", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/1d32a660fc6e8bac21961be105370d8ae08b6858" + }, + "message": "chore: added base content", + "parents": [ + { + "sha": "77252bb09215cdab4f954b7c141885777df92679", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/77252bb09215cdab4f954b7c141885777df92679", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/77252bb09215cdab4f954b7c141885777df92679" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "561ebf525573ce65d70c7f8fb0214ed1342c1032", + "node_id": "C_kwDOMDzQsNoAKDU2MWViZjUyNTU3M2NlNjVkNzBjN2Y4ZmIwMjE0ZWQxMzQyYzEwMzI", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/561ebf525573ce65d70c7f8fb0214ed1342c1032", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/561ebf525573ce65d70c7f8fb0214ed1342c1032", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T16:54:41Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T16:54:41Z" + }, + "tree": { + "sha": "0ebc47dcfbb3c8ef3cce4d82e96038d6f7bc34a1", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/0ebc47dcfbb3c8ef3cce4d82e96038d6f7bc34a1" + }, + "message": "chore: added more base content", + "parents": [ + { + "sha": "2c3f0741a2e82cc78e347f5b41aec92c3dc68801", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/2c3f0741a2e82cc78e347f5b41aec92c3dc68801", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/2c3f0741a2e82cc78e347f5b41aec92c3dc68801" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "141a332505336b39c0d902027e49ce57ff98429d", + "node_id": "C_kwDOMDzQsNoAKDE0MWEzMzI1MDUzMzZiMzljMGQ5MDIwMjdlNDljZTU3ZmY5ODQyOWQ", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/141a332505336b39c0d902027e49ce57ff98429d", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/141a332505336b39c0d902027e49ce57ff98429d", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T17:25:48Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-02T17:25:48Z" + }, + "tree": { + "sha": "212ec39fcb81c168ec15e8e77a86d4a48ab97bb3", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/212ec39fcb81c168ec15e8e77a86d4a48ab97bb3" + }, + "message": "chore: added github action", + "parents": [ + { + "sha": "561ebf525573ce65d70c7f8fb0214ed1342c1032", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/561ebf525573ce65d70c7f8fb0214ed1342c1032", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/561ebf525573ce65d70c7f8fb0214ed1342c1032" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "499d25491a0781b900556adb5f8ddb5e61338c09", + "node_id": "C_kwDOMDzQsNoAKDQ5OWQyNTQ5MWEwNzgxYjkwMDU1NmFkYjVmOGRkYjVlNjEzMzhjMDk", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/499d25491a0781b900556adb5f8ddb5e61338c09", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/499d25491a0781b900556adb5f8ddb5e61338c09", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T04:06:15Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T04:06:15Z" + }, + "tree": { + "sha": "ffae61b0b57523432e3e7fb8f5b8a3cccbe48716", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/ffae61b0b57523432e3e7fb8f5b8a3cccbe48716" + }, + "message": "chore: added env parsing", + "parents": [ + { + "sha": "141a332505336b39c0d902027e49ce57ff98429d", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/141a332505336b39c0d902027e49ce57ff98429d", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/141a332505336b39c0d902027e49ce57ff98429d" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "83d1e7794823d168189a6ecb99d45d9a8b88b76c", + "node_id": "C_kwDOMDzQsNoAKDgzZDFlNzc5NDgyM2QxNjgxODlhNmVjYjk5ZDQ1ZDlhOGI4OGI3NmM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/83d1e7794823d168189a6ecb99d45d9a8b88b76c", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/83d1e7794823d168189a6ecb99d45d9a8b88b76c", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T06:45:45Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T06:45:45Z" + }, + "tree": { + "sha": "5d8cbd61e49a89c0c40bd3b25af9e927b965d34a", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/5d8cbd61e49a89c0c40bd3b25af9e927b965d34a" + }, + "message": "chore: fixed workflows", + "parents": [ + { + "sha": "499d25491a0781b900556adb5f8ddb5e61338c09", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/499d25491a0781b900556adb5f8ddb5e61338c09", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/499d25491a0781b900556adb5f8ddb5e61338c09" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "037f7f3eaa2d25a2f5034537e46e16c63c03da8b", + "node_id": "C_kwDOMDzQsNoAKDAzN2Y3ZjNlYWEyZDI1YTJmNTAzNDUzN2U0NmUxNmM2M2MwM2RhOGI", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/037f7f3eaa2d25a2f5034537e46e16c63c03da8b", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/037f7f3eaa2d25a2f5034537e46e16c63c03da8b", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T07:58:47Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T07:58:47Z" + }, + "tree": { + "sha": "8731fa8eca21f200e3adbbb446ca7b32b8630860", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/8731fa8eca21f200e3adbbb446ca7b32b8630860" + }, + "message": "chore: callback proxy", + "parents": [ + { + "sha": "83d1e7794823d168189a6ecb99d45d9a8b88b76c", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/83d1e7794823d168189a6ecb99d45d9a8b88b76c", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/83d1e7794823d168189a6ecb99d45d9a8b88b76c" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "417b2784352e983469c995e38833f950dc198af5", + "node_id": "C_kwDOMDzQsNoAKDQxN2IyNzg0MzUyZTk4MzQ2OWM5OTVlMzg4MzNmOTUwZGMxOThhZjU", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/417b2784352e983469c995e38833f950dc198af5", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/417b2784352e983469c995e38833f950dc198af5", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T08:28:19Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T08:28:19Z" + }, + "tree": { + "sha": "2a614a52e182b51e975eb2734fe0dafeef2152ef", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/2a614a52e182b51e975eb2734fe0dafeef2152ef" + }, + "message": "chore: added handlers", + "parents": [ + { + "sha": "037f7f3eaa2d25a2f5034537e46e16c63c03da8b", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/037f7f3eaa2d25a2f5034537e46e16c63c03da8b", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/037f7f3eaa2d25a2f5034537e46e16c63c03da8b" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "f6a065fc93025b4f60cfb179f33c4c4654d5df8b", + "node_id": "C_kwDOMDzQsNoAKGY2YTA2NWZjOTMwMjViNGY2MGNmYjE3OWYzM2M0YzQ2NTRkNWRmOGI", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f6a065fc93025b4f60cfb179f33c4c4654d5df8b", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f6a065fc93025b4f60cfb179f33c4c4654d5df8b", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T09:44:35Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T09:44:35Z" + }, + "tree": { + "sha": "74c0b4263d0dc0df9bc99b84f6d7e29ab8fc163d", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/74c0b4263d0dc0df9bc99b84f6d7e29ab8fc163d" + }, + "message": "chore: added adapters", + "parents": [ + { + "sha": "417b2784352e983469c995e38833f950dc198af5", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/417b2784352e983469c995e38833f950dc198af5", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/417b2784352e983469c995e38833f950dc198af5" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "fb4be189de5c07794d05099acc9b61991f9813bf", + "node_id": "C_kwDOMDzQsNoAKGZiNGJlMTg5ZGU1YzA3Nzk0ZDA1MDk5YWNjOWI2MTk5MWY5ODEzYmY", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/fb4be189de5c07794d05099acc9b61991f9813bf", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/fb4be189de5c07794d05099acc9b61991f9813bf", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:08:22Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:08:22Z" + }, + "tree": { + "sha": "982d3140b75c4aa041c10201ea4b9cb1b56f6a9b", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/982d3140b75c4aa041c10201ea4b9cb1b56f6a9b" + }, + "message": "feat: database generation script", + "parents": [ + { + "sha": "f6a065fc93025b4f60cfb179f33c4c4654d5df8b", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f6a065fc93025b4f60cfb179f33c4c4654d5df8b", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f6a065fc93025b4f60cfb179f33c4c4654d5df8b" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac", + "node_id": "C_kwDOMDzQsNoAKDZmMTlkNGQwNzIyZGJjZmQ0ZTNiNTljZTFkZGRiOTRhNTUwYTIwYWM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:35:30Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:35:30Z" + }, + "tree": { + "sha": "e0ee1a513d4daae2d3759e6c5d157f0a59458c6a", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/e0ee1a513d4daae2d3759e6c5d157f0a59458c6a" + }, + "message": "feat: database generation script", + "parents": [ + { + "sha": "fb4be189de5c07794d05099acc9b61991f9813bf", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/fb4be189de5c07794d05099acc9b61991f9813bf", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/fb4be189de5c07794d05099acc9b61991f9813bf" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "2b1aaee984aee68973f4fb387465ca9b0807766a", + "node_id": "C_kwDOMDzQsNoAKDJiMWFhZWU5ODRhZWU2ODk3M2Y0ZmIzODc0NjVjYTliMDgwNzc2NmE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/2b1aaee984aee68973f4fb387465ca9b0807766a", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/2b1aaee984aee68973f4fb387465ca9b0807766a", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:40:47Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:40:47Z" + }, + "tree": { + "sha": "595a1a8fee5eb827d2a71764e22bd8da3a2be112", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/595a1a8fee5eb827d2a71764e22bd8da3a2be112" + }, + "message": "chore: fix workflow", + "parents": [ + { + "sha": "6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/6f19d4d0722dbcfd4e3b59ce1dddb94a550a20ac" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3", + "node_id": "C_kwDOMDzQsNoAKGQ1ODI0ZTVlMmU2ZmQ1ZDg3ZGVhMjE2NTE4OTY1NGNjMWVmM2ZmZDM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:42:34Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:42:34Z" + }, + "tree": { + "sha": "59325d33f0e7bde77bd3e3d1d1f53b3005b27535", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/59325d33f0e7bde77bd3e3d1d1f53b3005b27535" + }, + "message": "chore: fix workflow", + "parents": [ + { + "sha": "2b1aaee984aee68973f4fb387465ca9b0807766a", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/2b1aaee984aee68973f4fb387465ca9b0807766a", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/2b1aaee984aee68973f4fb387465ca9b0807766a" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "f256464e5c7fe5aff9275af1dc8d123b43a3a2bc", + "node_id": "C_kwDOMDzQsNoAKGYyNTY0NjRlNWM3ZmU1YWZmOTI3NWFmMWRjOGQxMjNiNDNhM2EyYmM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f256464e5c7fe5aff9275af1dc8d123b43a3a2bc", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f256464e5c7fe5aff9275af1dc8d123b43a3a2bc", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:55:04Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:55:04Z" + }, + "tree": { + "sha": "aae17b6d373d6a28620c7b353fdea66e1f506e4a", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/aae17b6d373d6a28620c7b353fdea66e1f506e4a" + }, + "message": "chore: fix commit name", + "parents": [ + { + "sha": "d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/d5824e5e2e6fd5d87dea2165189654cc1ef3ffd3" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "a1f914df8a63d77a9e808b5a9224c0dcb5f86baa", + "node_id": "C_kwDOMDzQsNoAKGExZjkxNGRmOGE2M2Q3N2E5ZTgwOGI1YTkyMjRjMGRjYjVmODZiYWE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/a1f914df8a63d77a9e808b5a9224c0dcb5f86baa", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/a1f914df8a63d77a9e808b5a9224c0dcb5f86baa", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:59:03Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T10:59:03Z" + }, + "tree": { + "sha": "d5df3d95d5edb619553e92bebe72c4384ccf299d", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/d5df3d95d5edb619553e92bebe72c4384ccf299d" + }, + "message": "chore: content write permission", + "parents": [ + { + "sha": "f256464e5c7fe5aff9275af1dc8d123b43a3a2bc", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f256464e5c7fe5aff9275af1dc8d123b43a3a2bc", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f256464e5c7fe5aff9275af1dc8d123b43a3a2bc" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "bb6a38644d22f86009b9142e56a2e4d2b33b8eff", + "node_id": "C_kwDOMDzQsNoAKGJiNmEzODY0NGQyMmY4NjAwOWI5MTQyZTU2YTJlNGQyYjMzYjhlZmY", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/bb6a38644d22f86009b9142e56a2e4d2b33b8eff", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/bb6a38644d22f86009b9142e56a2e4d2b33b8eff", + "author": { + "name": "github-actions[bot]", + "email": "github-actions[bot]@users.noreply.github.com", + "date": "2024-06-03T11:00:26Z" + }, + "committer": { + "name": "github-actions[bot]", + "email": "github-actions[bot]@users.noreply.github.com", + "date": "2024-06-03T11:00:26Z" + }, + "tree": { + "sha": "5d6e909f2ee2a0da31f2d956702241587e92a637", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/5d6e909f2ee2a0da31f2d956702241587e92a637" + }, + "message": "chore: updated generated Supabase types", + "parents": [ + { + "sha": "a1f914df8a63d77a9e808b5a9224c0dcb5f86baa", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/a1f914df8a63d77a9e808b5a9224c0dcb5f86baa", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/a1f914df8a63d77a9e808b5a9224c0dcb5f86baa" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa", + "node_id": "C_kwDOMDzQsNoAKDg2ZDZhZWUxYjI4ZjlmYjhmOWE5YjdjODcxYzE4ODBjZDM3NmU5ZmE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:05:55Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:06:05Z" + }, + "tree": { + "sha": "c4d46f983e24babfba4884914e03bb0d0b506890", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/c4d46f983e24babfba4884914e03bb0d0b506890" + }, + "message": "chore: db migration", + "parents": [ + { + "sha": "bb6a38644d22f86009b9142e56a2e4d2b33b8eff", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/bb6a38644d22f86009b9142e56a2e4d2b33b8eff", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/bb6a38644d22f86009b9142e56a2e4d2b33b8eff" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "d8bab65d4f721339bed9918be06bd3bcbf8cc80d", + "node_id": "C_kwDOMDzQsNoAKGQ4YmFiNjVkNGY3MjEzMzliZWQ5OTE4YmUwNmJkM2JjYmY4Y2M4MGQ", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/d8bab65d4f721339bed9918be06bd3bcbf8cc80d", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/d8bab65d4f721339bed9918be06bd3bcbf8cc80d", + "author": { + "name": "github-actions[bot]", + "email": "github-actions[bot]@users.noreply.github.com", + "date": "2024-06-03T11:07:28Z" + }, + "committer": { + "name": "github-actions[bot]", + "email": "github-actions[bot]@users.noreply.github.com", + "date": "2024-06-03T11:07:28Z" + }, + "tree": { + "sha": "70236ec10d0db32b0129f8d7bd7b2c1be52fe99b", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/70236ec10d0db32b0129f8d7bd7b2c1be52fe99b" + }, + "message": "chore: updated generated Supabase types", + "parents": [ + { + "sha": "86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/86d6aee1b28f9fb8f9a9b7c871c1880cd376e9fa" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "0f257468779dca54f9da5c15c66f6d5a56cedc14", + "node_id": "C_kwDOMDzQsNoAKDBmMjU3NDY4Nzc5ZGNhNTRmOWRhNWMxNWM2NmY2ZDVhNTZjZWRjMTQ", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/0f257468779dca54f9da5c15c66f6d5a56cedc14", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/0f257468779dca54f9da5c15c66f6d5a56cedc14", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:07:30Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:11:45Z" + }, + "tree": { + "sha": "f9206a07f2c88910c97576e11195a0d9b1298563", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/f9206a07f2c88910c97576e11195a0d9b1298563" + }, + "message": "chore: cspell ignore path", + "parents": [ + { + "sha": "d8bab65d4f721339bed9918be06bd3bcbf8cc80d", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/d8bab65d4f721339bed9918be06bd3bcbf8cc80d", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/d8bab65d4f721339bed9918be06bd3bcbf8cc80d" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "dce9745932f9adc27b7f8004e0352b2d62f600bb", + "node_id": "C_kwDOMDzQsNoAKGRjZTk3NDU5MzJmOWFkYzI3YjdmODAwNGUwMzUyYjJkNjJmNjAwYmI", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/dce9745932f9adc27b7f8004e0352b2d62f600bb", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/dce9745932f9adc27b7f8004e0352b2d62f600bb", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:14:18Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:14:18Z" + }, + "tree": { + "sha": "191b6d73a1157c72d92dd636f837a79e10983c91", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/191b6d73a1157c72d92dd636f837a79e10983c91" + }, + "message": "chore: cspell ignore path for migrations", + "parents": [ + { + "sha": "0f257468779dca54f9da5c15c66f6d5a56cedc14", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/0f257468779dca54f9da5c15c66f6d5a56cedc14", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/0f257468779dca54f9da5c15c66f6d5a56cedc14" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "68c72e35f80eea8fa7319ebf2e68e536fb41dc33", + "node_id": "C_kwDOMDzQsNoAKDY4YzcyZTM1ZjgwZWVhOGZhNzMxOWViZjJlNjhlNTM2ZmI0MWRjMzM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/68c72e35f80eea8fa7319ebf2e68e536fb41dc33", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/68c72e35f80eea8fa7319ebf2e68e536fb41dc33", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:17:22Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T11:17:22Z" + }, + "tree": { + "sha": "d036dba05a97649363af5733d253d46a379b00fb", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/d036dba05a97649363af5733d253d46a379b00fb" + }, + "message": "chore: check for empty commits", + "parents": [ + { + "sha": "dce9745932f9adc27b7f8004e0352b2d62f600bb", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/dce9745932f9adc27b7f8004e0352b2d62f600bb", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/dce9745932f9adc27b7f8004e0352b2d62f600bb" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "b1c379a1792a93f2ebd2112039790a45c5eab1f6", + "node_id": "C_kwDOMDzQsNoAKGIxYzM3OWExNzkyYTkzZjJlYmQyMTEyMDM5NzkwYTQ1YzVlYWIxZjY", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/b1c379a1792a93f2ebd2112039790a45c5eab1f6", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/b1c379a1792a93f2ebd2112039790a45c5eab1f6", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T14:48:12Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T14:48:12Z" + }, + "tree": { + "sha": "5429f4c1fda7a5f45f58b767af9e6759b25f7dcf", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/5429f4c1fda7a5f45f58b767af9e6759b25f7dcf" + }, + "message": "chore: fix lint stage", + "parents": [ + { + "sha": "68c72e35f80eea8fa7319ebf2e68e536fb41dc33", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/68c72e35f80eea8fa7319ebf2e68e536fb41dc33", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/68c72e35f80eea8fa7319ebf2e68e536fb41dc33" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "4014c0b6ac7a5a6c6a421542758d68b13171a27c", + "node_id": "C_kwDOMDzQsNoAKDQwMTRjMGI2YWM3YTVhNmM2YTQyMTU0Mjc1OGQ2OGIxMzE3MWEyN2M", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/4014c0b6ac7a5a6c6a421542758d68b13171a27c", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/4014c0b6ac7a5a6c6a421542758d68b13171a27c", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T15:49:12Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T15:49:12Z" + }, + "tree": { + "sha": "0cbe3cd7a6b8885dd0d7537bb25ca1b8768f3637", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/0cbe3cd7a6b8885dd0d7537bb25ca1b8768f3637" + }, + "message": "chore: time estimate calculation", + "parents": [ + { + "sha": "b1c379a1792a93f2ebd2112039790a45c5eab1f6", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/b1c379a1792a93f2ebd2112039790a45c5eab1f6", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/b1c379a1792a93f2ebd2112039790a45c5eab1f6" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "aeba8b437baa5f7178c44cfae09a565d1335e3bf", + "node_id": "C_kwDOMDzQsNoAKGFlYmE4YjQzN2JhYTVmNzE3OGM0NGNmYWUwOWE1NjVkMTMzNWUzYmY", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/aeba8b437baa5f7178c44cfae09a565d1335e3bf", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/aeba8b437baa5f7178c44cfae09a565d1335e3bf", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T15:59:27Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T15:59:27Z" + }, + "tree": { + "sha": "37bfc73ee3c797e3763c013ec7427ad25ebb3cea", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/37bfc73ee3c797e3763c013ec7427ad25ebb3cea" + }, + "message": "chore: added missing action file", + "parents": [ + { + "sha": "4014c0b6ac7a5a6c6a421542758d68b13171a27c", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/4014c0b6ac7a5a6c6a421542758d68b13171a27c", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/4014c0b6ac7a5a6c6a421542758d68b13171a27c" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "47b64a93175c4b452059e50568c9427507dd92ac", + "node_id": "C_kwDOMDzQsNoAKDQ3YjY0YTkzMTc1YzRiNDUyMDU5ZTUwNTY4Yzk0Mjc1MDdkZDkyYWM", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/47b64a93175c4b452059e50568c9427507dd92ac", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/47b64a93175c4b452059e50568c9427507dd92ac", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:02:47Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:02:47Z" + }, + "tree": { + "sha": "765598bb1b29c2e1a7966e54b8f5910b76882724", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/765598bb1b29c2e1a7966e54b8f5910b76882724" + }, + "message": "chore: added missing start command", + "parents": [ + { + "sha": "aeba8b437baa5f7178c44cfae09a565d1335e3bf", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/aeba8b437baa5f7178c44cfae09a565d1335e3bf", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/aeba8b437baa5f7178c44cfae09a565d1335e3bf" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "7deda8b1d00b6e6c3b003be0fd7490fe7dac3992", + "node_id": "C_kwDOMDzQsNoAKDdkZWRhOGIxZDAwYjZlNmMzYjAwM2JlMGZkNzQ5MGZlN2RhYzM5OTI", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/7deda8b1d00b6e6c3b003be0fd7490fe7dac3992", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/7deda8b1d00b6e6c3b003be0fd7490fe7dac3992", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:07:17Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:07:17Z" + }, + "tree": { + "sha": "ef028b0aeb79ce46782d56a3358552072eab2f6f", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/ef028b0aeb79ce46782d56a3358552072eab2f6f" + }, + "message": "chore: added missing package tsx", + "parents": [ + { + "sha": "47b64a93175c4b452059e50568c9427507dd92ac", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/47b64a93175c4b452059e50568c9427507dd92ac", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/47b64a93175c4b452059e50568c9427507dd92ac" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "c2fbb92c9f02679766efecfb5f801559e9b1e5ba", + "node_id": "C_kwDOMDzQsNoAKGMyZmJiOTJjOWYwMjY3OTc2NmVmZWNmYjVmODAxNTU5ZTliMWU1YmE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/c2fbb92c9f02679766efecfb5f801559e9b1e5ba", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/c2fbb92c9f02679766efecfb5f801559e9b1e5ba", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:11:35Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:11:35Z" + }, + "tree": { + "sha": "bfd3ab1d5c16db49485c988ef22e3f0f6b9bed28", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/bfd3ab1d5c16db49485c988ef22e3f0f6b9bed28" + }, + "message": "chore: moved tsx to deps", + "parents": [ + { + "sha": "7deda8b1d00b6e6c3b003be0fd7490fe7dac3992", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/7deda8b1d00b6e6c3b003be0fd7490fe7dac3992", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/7deda8b1d00b6e6c3b003be0fd7490fe7dac3992" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "f97acec24cff4bcc60487c6d06c0e66c65059dba", + "node_id": "C_kwDOMDzQsNoAKGY5N2FjZWMyNGNmZjRiY2M2MDQ4N2M2ZDA2YzBlNjZjNjUwNTlkYmE", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f97acec24cff4bcc60487c6d06c0e66c65059dba", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f97acec24cff4bcc60487c6d06c0e66c65059dba", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:21:54Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:21:54Z" + }, + "tree": { + "sha": "94d18557ddb611a46dee3205d53bf2dbda4b4ddf", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/94d18557ddb611a46dee3205d53bf2dbda4b4ddf" + }, + "message": "chore: fixed proxy", + "parents": [ + { + "sha": "c2fbb92c9f02679766efecfb5f801559e9b1e5ba", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/c2fbb92c9f02679766efecfb5f801559e9b1e5ba", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/c2fbb92c9f02679766efecfb5f801559e9b1e5ba" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "1eb4e1aab67a2946d5fcdd517f248523ef62e5af", + "node_id": "C_kwDOMDzQsNoAKDFlYjRlMWFhYjY3YTI5NDZkNWZjZGQ1MTdmMjQ4NTIzZWY2MmU1YWY", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/1eb4e1aab67a2946d5fcdd517f248523ef62e5af", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/1eb4e1aab67a2946d5fcdd517f248523ef62e5af", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:29:25Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T16:29:25Z" + }, + "tree": { + "sha": "f6189a18acce37429560f6d28e91d0fed0c1f75f", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/f6189a18acce37429560f6d28e91d0fed0c1f75f" + }, + "message": "chore: fixed label fetch", + "parents": [ + { + "sha": "f97acec24cff4bcc60487c6d06c0e66c65059dba", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/f97acec24cff4bcc60487c6d06c0e66c65059dba", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/f97acec24cff4bcc60487c6d06c0e66c65059dba" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "e191bb71302a0612a541e8059b34b24ccef277a5", + "node_id": "C_kwDOMDzQsNoAKGUxOTFiYjcxMzAyYTA2MTJhNTQxZTgwNTliMzRiMjRjY2VmMjc3YTU", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/e191bb71302a0612a541e8059b34b24ccef277a5", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/e191bb71302a0612a541e8059b34b24ccef277a5", + "author": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T23:59:14Z" + }, + "committer": { + "name": "ubiquibot", + "email": "ubiquibot@ubq.fi", + "date": "2024-06-03T23:59:14Z" + }, + "tree": { + "sha": "2c981f61e41e57a7290d5311c61872e3e495816a", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/2c981f61e41e57a7290d5311c61872e3e495816a" + }, + "message": "chore: added worker", + "parents": [ + { + "sha": "1eb4e1aab67a2946d5fcdd517f248523ef62e5af", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/1eb4e1aab67a2946d5fcdd517f248523ef62e5af", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/1eb4e1aab67a2946d5fcdd517f248523ef62e5af" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "event": "committed" + }, + { + "sha": "be21381a33d906f1cb04e216dcf70a119a35ef7a", + "node_id": "C_kwDOMDzQsNoAKGJlMjEzODFhMzNkOTA2ZjFjYjA0ZTIxNmRjZjcwYTExOWEzNWVmN2E", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/be21381a33d906f1cb04e216dcf70a119a35ef7a", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/be21381a33d906f1cb04e216dcf70a119a35ef7a", + "author": { + "name": "github-actions[bot]", + "email": "41898282+github-actions[bot]@users.noreply.github.com", + "date": "2024-06-04T00:00:15Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-06-04T00:00:15Z" + }, + "tree": { + "sha": "76e639aa66bc0a51fcc0a149dbe16eac3bfff79c", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/trees/76e639aa66bc0a51fcc0a149dbe16eac3bfff79c" + }, + "message": "chore(main): release 1.0.0", + "parents": [ + { + "sha": "e191bb71302a0612a541e8059b34b24ccef277a5", + "url": "https://api.github.com/repos/ubiquibot/user-activity-watcher/git/commits/e191bb71302a0612a541e8059b34b24ccef277a5", + "html_url": "https://github.com/ubiquibot/user-activity-watcher/commit/e191bb71302a0612a541e8059b34b24ccef277a5" + } + ], + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJmXlkPCRC1aQ7uu5UhlAAAh0YQAFV1gc8M2QWmvmR9TK6zhDlM\ni9Yjk9q92ZyyauNcTv4nv1tCm9FRbG+HcomH8mxDiysY1GvPGhNoiKXYeIyueQY6\nGA8dOd6S/OBbLTOKyor7iXyJTz8iaW1GuCPKvoEt9CKcc5rHgx9QX/Q9+VM9SH5d\npgIMOCaCgwxHXtVXURic+zY1FSRSr83b30OmLxRIQkWQx3QtS+eQzxWls4DaRtuz\nJxc+V1igl90s/fAO/5zrVAFSrl/4loFXmGC3VBEdDB/kLSfdJqdevLC3bcdK0NEr\ntJ4RppK2QRf+wl6VNUgmTisfcmPoIH9WhALdcbzHzyAcP9qgM+yPXeyYKMPXuMbw\nZgFkpRtGWJ8YsGwHLAYtGvRmTfKrzntSy1UlWD8bNOR7IkVvOG8iECN6tTm8YIUw\nXS33KxNeurNhdEgVJtwIvCmz4866nkAm3jV8rcGANrM+EdzuclFeA4qNLoump4S0\nr8lz1syX/pf2HUL5uaLJfLRJvNTo+T8obF6Qpaj2AnPfMJMdZkSDZcvhKc5l1T+w\n50NvAj389LWhgxixlr3caYzlt+EpqT2u/TIL3ZyLKrVJ/Qojt/m813inQDdYdUUp\naCIF5nUP+E04F4vRMyg9+gODAeVnN4j82+Qv22v/hwPOqpGxUKCHmbh4YnAhqDjY\nAJTCJ320ZROttEPNXJEE\n=rj+7\n-----END PGP SIGNATURE-----\n", + "payload": "tree 76e639aa66bc0a51fcc0a149dbe16eac3bfff79c\nparent e191bb71302a0612a541e8059b34b24ccef277a5\nauthor github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 1717459215 +0000\ncommitter GitHub 1717459215 +0000\n\nchore(main): release 1.0.0" + }, + "event": "committed" + } +] diff --git a/tests/main.test.ts b/tests/main.test.ts index 57c38f0..cc4f687 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -1,14 +1,16 @@ import { drop } from "@mswjs/data"; -import { Value } from "@sinclair/typebox/value"; +import { TransformDecodeError, Value } from "@sinclair/typebox/value"; import { ValidationException } from "typebox-validators"; import { getEnv } from "../src/helpers/get-env"; import { parseDurationString } from "../src/helpers/time"; import program from "../src/parser/payload"; import { run } from "../src/run"; import envConfigSchema from "../src/types/env-type"; +import { userActivityWatcherSettingsSchema } from "../src/types/plugin-inputs"; import { db as mockDb } from "./__mocks__/db"; import dbSeed from "./__mocks__/db-seed.json"; import { server } from "./__mocks__/node"; +import cfg from "./__mocks__/results/valid-configuration.json"; beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); @@ -52,6 +54,19 @@ describe("Run tests", () => { await expect(getEnv()).rejects.toEqual(new ValidationException("The environment is" + " invalid.")); process.env = oldEnv; }); + it("Should parse thresholds", async () => { + const settings = Value.Decode(userActivityWatcherSettingsSchema, Value.Default(userActivityWatcherSettingsSchema, cfg)); + expect(settings).toEqual({ warning: 302400000, disqualification: 604800000 }); + expect(() => + Value.Decode( + userActivityWatcherSettingsSchema, + Value.Default(userActivityWatcherSettingsSchema, { + warning: "12 foobars", + disqualification: "2 days", + }) + ) + ).toThrow(TransformDecodeError); + }); it("Should run", async () => { const result = await run(program, Value.Decode(envConfigSchema, process.env)); expect(JSON.parse(result)).toEqual({ status: "ok" }); diff --git a/yarn.lock b/yarn.lock index c78ee20..09e854e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2209,6 +2209,11 @@ as-table@^1.0.36: dependencies: printable-characters "^1.0.42" +async-lock@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.1.tgz#56b8718915a9b68b10fce2f2a9a3dddf765ef53f" + integrity sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ== + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2452,6 +2457,11 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== +clean-git-ref@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/clean-git-ref/-/clean-git-ref-2.0.1.tgz#dcc0ca093b90e527e67adb5a5e55b1af6816dcd9" + integrity sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2652,6 +2662,11 @@ cosmiconfig@^9.0.0: js-yaml "^4.1.0" parse-json "^5.2.0" +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + create-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" @@ -2826,6 +2841,13 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, d dependencies: ms "2.1.2" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^1.0.0: version "1.5.3" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" @@ -2868,6 +2890,11 @@ diff-sequences@^29.6.3: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== +diff3@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/diff3/-/diff3-0.0.3.tgz#d4e5c3a4cdf4e5fe1211ab42e693fcb4321580fc" + integrity sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g== + dot-prop@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -3566,7 +3593,7 @@ identity-function@^1.0.0: resolved "https://registry.yarnpkg.com/identity-function/-/identity-function-1.0.0.tgz#bea1159f0985239be3ca348edf40ce2f0dd2c21d" integrity sha512-kNrgUK0qI+9qLTBidsH85HjDLpZfrrS0ElquKKe/fJFdB3D7VeKdXXEvOPDUHSHOzdZKCAAaQIWWyp0l2yq6pw== -ignore@^5.1.8, ignore@^5.2.0: +ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -3615,7 +3642,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.1, inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3735,6 +3762,23 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isomorphic-git@^1.25.6: + version "1.25.10" + resolved "https://registry.yarnpkg.com/isomorphic-git/-/isomorphic-git-1.25.10.tgz#59ff7af88773b126f2b273ef3c536c08308b6d36" + integrity sha512-IxGiaKBwAdcgBXwIcxJU6rHLk+NrzYaaPKXXQffcA0GW3IUrQXdUPDXDo+hkGVcYruuz/7JlGBiuaeTCgIgivQ== + dependencies: + async-lock "^1.4.1" + clean-git-ref "^2.0.1" + crc-32 "^1.2.0" + diff3 "0.0.3" + ignore "^5.1.4" + minimisted "^2.0.0" + pako "^1.0.10" + pify "^4.0.1" + readable-stream "^3.4.0" + sha.js "^2.4.9" + simple-get "^4.0.1" + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -3974,6 +4018,13 @@ jest-matcher-utils@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" +jest-md-dashboard@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/jest-md-dashboard/-/jest-md-dashboard-0.8.0.tgz#024eeaf2192cf93f3c6f7dad8fec1dc94e2b05e1" + integrity sha512-CaxG69pKBA9UauMHBxmsxNbbPMe3kcdTY17BUBM1hj3ZKyZSnKDnOqtnjMti4t9XKuf6Hc3Vn1pXBfll3bWn6A== + dependencies: + isomorphic-git "^1.25.6" + jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -4516,6 +4567,11 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + miniflare@3.20240524.1: version "3.20240524.1" resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-3.20240524.1.tgz#38477cce5123d05ae87ac68e9addf0d0d30534d2" @@ -4548,11 +4604,18 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@1.2.8, minimist@^1.2.6, minimist@^1.2.8: +minimist@1.2.8, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minimisted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minimisted/-/minimisted-2.0.1.tgz#d059fb905beecf0774bc3b308468699709805cb1" + integrity sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA== + dependencies: + minimist "^1.2.5" + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4, minipass@^7.1.0, minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" @@ -4692,7 +4755,7 @@ object-values@^1.0.0: resolved "https://registry.yarnpkg.com/object-values/-/object-values-1.0.0.tgz#72af839630119e5b98c3b02bb8c27e3237158105" integrity sha512-+8hwcz/JnQ9EpLIXzN0Rs7DLsBpJNT/xYehtB/jU93tHYr5BFEO8E+JGQNOSqE7opVzz5cGksKFHt7uUJVLSjQ== -once@^1.3.0, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -4784,6 +4847,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pako@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -4881,6 +4949,11 @@ pidtree@~0.6.0: resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + pirates@^4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" @@ -4969,6 +5042,15 @@ read-cmd-shim@^4.0.0: resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== +readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -5092,6 +5174,11 @@ run-parallel@^1.1.9, run-parallel@^1.2.0: dependencies: queue-microtask "^1.2.2" +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + selfsigned@^2.0.1: version "2.4.1" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" @@ -5110,6 +5197,14 @@ semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== +sha.js@^2.4.9: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -5137,6 +5232,20 @@ signal-exit@^4.0.1, signal-exit@^4.1.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -5280,6 +5389,13 @@ string.fromcodepoint@^0.2.1: resolved "https://registry.yarnpkg.com/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz#8d978333c0bc92538f50f383e4888f3e5619d653" integrity sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -5562,6 +5678,11 @@ uri-js@^4.2.2, uri-js@^4.4.1: dependencies: punycode "^2.1.0" +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + uuid@^8.3.1, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"