diff --git a/.github/actions/node-npm-setup/action.yml b/.github/actions/node-npm-setup/action.yml index c92092159111..0de78da57baa 100644 --- a/.github/actions/node-npm-setup/action.yml +++ b/.github/actions/node-npm-setup/action.yml @@ -7,9 +7,10 @@ runs: steps: - name: Cache node_modules uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 + id: cache-node_modules with: path: node_modules - key: ${{ runner.os }}-node_modules-${{ hashFiles('package*.json') }} + key: ${{ runner.os }}-node_modules-${{ hashFiles('package*.json') }}-${{ hashFiles('.github/actions/node-npm-setup/action.yml') }} - name: Setup Node.js uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 @@ -18,5 +19,6 @@ runs: cache: npm - name: Install dependencies + if: ${{ steps.cache-node_modules.outputs.cache-hit != 'true' }} shell: bash - run: npm install --prefer-offline --no-audit --ignore-scripts + run: npm ci diff --git a/assets/images/enterprise/2.22/repository/code-scanning-missing-analysis.png b/assets/images/enterprise/2.22/repository/code-scanning-missing-analysis.png deleted file mode 100644 index 6950cddd66a4..000000000000 Binary files a/assets/images/enterprise/2.22/repository/code-scanning-missing-analysis.png and /dev/null differ diff --git a/assets/images/enterprise/3.2/repository/code-scanning-missing-analysis.png b/assets/images/enterprise/3.2/repository/code-scanning-missing-analysis.png deleted file mode 100644 index 6950cddd66a4..000000000000 Binary files a/assets/images/enterprise/3.2/repository/code-scanning-missing-analysis.png and /dev/null differ diff --git a/assets/images/enterprise/3.2/repository/code-security-and-analysis-enable-ghas-3.2.png b/assets/images/enterprise/3.2/repository/code-security-and-analysis-enable-ghas-3.2.png deleted file mode 100644 index b67d3b125cd2..000000000000 Binary files a/assets/images/enterprise/3.2/repository/code-security-and-analysis-enable-ghas-3.2.png and /dev/null differ diff --git a/assets/images/enterprise/3.4/actions-access-settings.png b/assets/images/enterprise/3.4/actions-access-settings.png deleted file mode 100644 index a00945e914eb..000000000000 Binary files a/assets/images/enterprise/3.4/actions-access-settings.png and /dev/null differ diff --git a/assets/images/enterprise/maintenance/ip-exception-enabled.png b/assets/images/enterprise/maintenance/ip-exception-enabled.png deleted file mode 100644 index 597fea014fae..000000000000 Binary files a/assets/images/enterprise/maintenance/ip-exception-enabled.png and /dev/null differ diff --git a/assets/images/enterprise/management-console/sidebar-advanced-security.png b/assets/images/enterprise/management-console/sidebar-advanced-security.png deleted file mode 100644 index 3ca9bdcb2649..000000000000 Binary files a/assets/images/enterprise/management-console/sidebar-advanced-security.png and /dev/null differ diff --git a/assets/images/enterprise/repository/dependabot-alert-dismiss-drop-down.png b/assets/images/enterprise/repository/dependabot-alert-dismiss-drop-down.png deleted file mode 100644 index 630767708f40..000000000000 Binary files a/assets/images/enterprise/repository/dependabot-alert-dismiss-drop-down.png and /dev/null differ diff --git a/assets/images/enterprise/site-admin-settings/repository-creation-drop-down.png b/assets/images/enterprise/site-admin-settings/repository-creation-drop-down.png deleted file mode 100644 index 0fd96ea87004..000000000000 Binary files a/assets/images/enterprise/site-admin-settings/repository-creation-drop-down.png and /dev/null differ diff --git a/assets/images/help/2fa/totp-click-enter-code.png b/assets/images/help/2fa/totp-click-enter-code.png deleted file mode 100644 index cd1cebfb0b99..000000000000 Binary files a/assets/images/help/2fa/totp-click-enter-code.png and /dev/null differ diff --git a/assets/images/help/2fa/totp-enter-code.png b/assets/images/help/2fa/totp-enter-code.png deleted file mode 100644 index b0744855b84a..000000000000 Binary files a/assets/images/help/2fa/totp-enter-code.png and /dev/null differ diff --git a/assets/images/help/billing/actions-packages-report-download-org.png b/assets/images/help/billing/actions-packages-report-download-org.png deleted file mode 100644 index f1b677304b4e..000000000000 Binary files a/assets/images/help/billing/actions-packages-report-download-org.png and /dev/null differ diff --git a/assets/images/help/branches/branch-creation-popup-fork.png b/assets/images/help/branches/branch-creation-popup-fork.png deleted file mode 100644 index ae0f2b697497..000000000000 Binary files a/assets/images/help/branches/branch-creation-popup-fork.png and /dev/null differ diff --git a/assets/images/help/branches/branch-creation-popup.png b/assets/images/help/branches/branch-creation-popup.png deleted file mode 100644 index 4f92055b7b36..000000000000 Binary files a/assets/images/help/branches/branch-creation-popup.png and /dev/null differ diff --git a/assets/images/help/branches/branches-link.png b/assets/images/help/branches/branches-link.png deleted file mode 100644 index 39e652180a5b..000000000000 Binary files a/assets/images/help/branches/branches-link.png and /dev/null differ diff --git a/assets/images/help/business-accounts/outside-collaborators-tab-sidebar.png b/assets/images/help/business-accounts/outside-collaborators-tab-sidebar.png deleted file mode 100644 index 3d2f82c640e1..000000000000 Binary files a/assets/images/help/business-accounts/outside-collaborators-tab-sidebar.png and /dev/null differ diff --git a/assets/images/help/classroom/assignments-click-online-ide.png b/assets/images/help/classroom/assignments-click-online-ide.png deleted file mode 100644 index 1e33dc8da01a..000000000000 Binary files a/assets/images/help/classroom/assignments-click-online-ide.png and /dev/null differ diff --git a/assets/images/help/classroom/canvas-sync-roster.png b/assets/images/help/classroom/canvas-sync-roster.png deleted file mode 100644 index 67594c7a8eb1..000000000000 Binary files a/assets/images/help/classroom/canvas-sync-roster.png and /dev/null differ diff --git a/assets/images/help/classroom/click-import-from-a-learning-management-system-button.png b/assets/images/help/classroom/click-import-from-a-learning-management-system-button.png deleted file mode 100644 index 87972ddbb7eb..000000000000 Binary files a/assets/images/help/classroom/click-import-from-a-learning-management-system-button.png and /dev/null differ diff --git a/assets/images/help/classroom/sakai-sync-roster.png b/assets/images/help/classroom/sakai-sync-roster.png deleted file mode 100644 index 087d6521e1f2..000000000000 Binary files a/assets/images/help/classroom/sakai-sync-roster.png and /dev/null differ diff --git a/assets/images/help/desktop/pull-request-list-sync.png.png b/assets/images/help/desktop/pull-request-list-sync.png.png deleted file mode 100644 index 43fb71e2b5a4..000000000000 Binary files a/assets/images/help/desktop/pull-request-list-sync.png.png and /dev/null differ diff --git a/assets/images/help/desktop/repository-settings-remote-mac.png b/assets/images/help/desktop/repository-settings-remote-mac.png deleted file mode 100644 index ae7da9286f2d..000000000000 Binary files a/assets/images/help/desktop/repository-settings-remote-mac.png and /dev/null differ diff --git a/assets/images/help/desktop/repository-settings-remote-win.png b/assets/images/help/desktop/repository-settings-remote-win.png deleted file mode 100644 index 5fef55667a96..000000000000 Binary files a/assets/images/help/desktop/repository-settings-remote-win.png and /dev/null differ diff --git a/assets/images/help/desktop/repository-settings-save-mac.png b/assets/images/help/desktop/repository-settings-save-mac.png deleted file mode 100644 index 00bb3f6d2da1..000000000000 Binary files a/assets/images/help/desktop/repository-settings-save-mac.png and /dev/null differ diff --git a/assets/images/help/desktop/repository-settings-save-win.png b/assets/images/help/desktop/repository-settings-save-win.png deleted file mode 100644 index 9d0ff0f9c3b2..000000000000 Binary files a/assets/images/help/desktop/repository-settings-save-win.png and /dev/null differ diff --git a/assets/images/help/education/upload-image-link.png b/assets/images/help/education/upload-image-link.png deleted file mode 100644 index 2b2aa0842d86..000000000000 Binary files a/assets/images/help/education/upload-image-link.png and /dev/null differ diff --git a/assets/images/help/enterprises/administrators-pending.png b/assets/images/help/enterprises/administrators-pending.png deleted file mode 100644 index 6e4593592cdf..000000000000 Binary files a/assets/images/help/enterprises/administrators-pending.png and /dev/null differ diff --git a/assets/images/help/enterprises/audit-log-export-drop-down-menus.png b/assets/images/help/enterprises/audit-log-export-drop-down-menus.png deleted file mode 100644 index 2867aa53c654..000000000000 Binary files a/assets/images/help/enterprises/audit-log-export-drop-down-menus.png and /dev/null differ diff --git a/assets/images/help/enterprises/audit-stream-add-s3.png b/assets/images/help/enterprises/audit-stream-add-s3.png deleted file mode 100644 index 9fb73d2497f8..000000000000 Binary files a/assets/images/help/enterprises/audit-stream-add-s3.png and /dev/null differ diff --git a/assets/images/help/enterprises/members-pending.png b/assets/images/help/enterprises/members-pending.png deleted file mode 100644 index efe35676781e..000000000000 Binary files a/assets/images/help/enterprises/members-pending.png and /dev/null differ diff --git a/assets/images/help/images/overview-actions-result.png b/assets/images/help/images/overview-actions-result.png deleted file mode 100644 index 5e489fda9690..000000000000 Binary files a/assets/images/help/images/overview-actions-result.png and /dev/null differ diff --git a/assets/images/help/issues/add-issue-to-tasklist-button.png b/assets/images/help/issues/add-issue-to-tasklist-button.png deleted file mode 100644 index 59f704360258..000000000000 Binary files a/assets/images/help/issues/add-issue-to-tasklist-button.png and /dev/null differ diff --git a/assets/images/help/issues/add-issue-to-tasklist.png b/assets/images/help/issues/add-issue-to-tasklist.png deleted file mode 100644 index e625dc870a41..000000000000 Binary files a/assets/images/help/issues/add-issue-to-tasklist.png and /dev/null differ diff --git a/assets/images/help/issues/convert-checklist-to-tasklist.png b/assets/images/help/issues/convert-checklist-to-tasklist.png deleted file mode 100644 index 1506d3a8bb19..000000000000 Binary files a/assets/images/help/issues/convert-checklist-to-tasklist.png and /dev/null differ diff --git a/assets/images/help/issues/new_project_beta.png b/assets/images/help/issues/new_project_beta.png deleted file mode 100644 index d662c762ff64..000000000000 Binary files a/assets/images/help/issues/new_project_beta.png and /dev/null differ diff --git a/assets/images/help/issues/tasklist-add-tasklist-button.png b/assets/images/help/issues/tasklist-add-tasklist-button.png deleted file mode 100644 index 5cf8d5557687..000000000000 Binary files a/assets/images/help/issues/tasklist-add-tasklist-button.png and /dev/null differ diff --git a/assets/images/help/notifications-v2/watch-repository-options.png b/assets/images/help/notifications-v2/watch-repository-options.png deleted file mode 100644 index e5e879764bc9..000000000000 Binary files a/assets/images/help/notifications-v2/watch-repository-options.png and /dev/null differ diff --git a/assets/images/help/notifications-v2/watched-notifications.png b/assets/images/help/notifications-v2/watched-notifications.png deleted file mode 100644 index ac1a19866bf1..000000000000 Binary files a/assets/images/help/notifications-v2/watched-notifications.png and /dev/null differ diff --git a/assets/images/help/organizations/billing-settings.png b/assets/images/help/organizations/billing-settings.png deleted file mode 100644 index 19b32364a374..000000000000 Binary files a/assets/images/help/organizations/billing-settings.png and /dev/null differ diff --git a/assets/images/help/organizations/organization-projects-tab.png b/assets/images/help/organizations/organization-projects-tab.png deleted file mode 100644 index f2006594c59a..000000000000 Binary files a/assets/images/help/organizations/organization-projects-tab.png and /dev/null differ diff --git a/assets/images/help/organizations/repo-invitations-checkbox-old.png b/assets/images/help/organizations/repo-invitations-checkbox-old.png deleted file mode 100644 index a6c0e75c0665..000000000000 Binary files a/assets/images/help/organizations/repo-invitations-checkbox-old.png and /dev/null differ diff --git a/assets/images/help/organizations/secret-scanning-filter-alerts.png b/assets/images/help/organizations/secret-scanning-filter-alerts.png deleted file mode 100644 index 6f237afa8bb9..000000000000 Binary files a/assets/images/help/organizations/secret-scanning-filter-alerts.png and /dev/null differ diff --git a/assets/images/help/organizations/view-alert-subset.png b/assets/images/help/organizations/view-alert-subset.png deleted file mode 100644 index 4f0df8d248e3..000000000000 Binary files a/assets/images/help/organizations/view-alert-subset.png and /dev/null differ diff --git a/assets/images/help/package-registry/confirm-package-deletion.png b/assets/images/help/package-registry/confirm-package-deletion.png deleted file mode 100644 index dfa91422732d..000000000000 Binary files a/assets/images/help/package-registry/confirm-package-deletion.png and /dev/null differ diff --git a/assets/images/help/package-registry/delete-package-button.png b/assets/images/help/package-registry/delete-package-button.png deleted file mode 100644 index 3d7d98abfb4f..000000000000 Binary files a/assets/images/help/package-registry/delete-package-button.png and /dev/null differ diff --git a/assets/images/help/package-registry/manage-versions.png b/assets/images/help/package-registry/manage-versions.png deleted file mode 100644 index 3641199e6daf..000000000000 Binary files a/assets/images/help/package-registry/manage-versions.png and /dev/null differ diff --git a/assets/images/help/package-registry/select-pkg-cloud.png b/assets/images/help/package-registry/select-pkg-cloud.png deleted file mode 100644 index 304766ccd776..000000000000 Binary files a/assets/images/help/package-registry/select-pkg-cloud.png and /dev/null differ diff --git a/assets/images/help/pages/choose-theme.png b/assets/images/help/pages/choose-theme.png deleted file mode 100644 index 9433eecf3892..000000000000 Binary files a/assets/images/help/pages/choose-theme.png and /dev/null differ diff --git a/assets/images/help/personal_token_ghae.png b/assets/images/help/personal_token_ghae.png deleted file mode 100644 index 7d78513e6bdc..000000000000 Binary files a/assets/images/help/personal_token_ghae.png and /dev/null differ diff --git a/assets/images/help/projects-v2/view-menu-icon-roadmap.png b/assets/images/help/projects-v2/view-menu-icon-roadmap.png deleted file mode 100644 index e9307f06b778..000000000000 Binary files a/assets/images/help/projects-v2/view-menu-icon-roadmap.png and /dev/null differ diff --git a/assets/images/help/pull_requests/create-a-fork.png b/assets/images/help/pull_requests/create-a-fork.png deleted file mode 100644 index fcb36c50ee7d..000000000000 Binary files a/assets/images/help/pull_requests/create-a-fork.png and /dev/null differ diff --git a/assets/images/help/pull_requests/github-spoon-knife-fork.png b/assets/images/help/pull_requests/github-spoon-knife-fork.png deleted file mode 100644 index 7e6a384562aa..000000000000 Binary files a/assets/images/help/pull_requests/github-spoon-knife-fork.png and /dev/null differ diff --git a/assets/images/help/repository/file-tree-view-expand-directory.png b/assets/images/help/repository/file-tree-view-expand-directory.png deleted file mode 100644 index 597306a76b6d..000000000000 Binary files a/assets/images/help/repository/file-tree-view-expand-directory.png and /dev/null differ diff --git a/assets/images/help/repository/repo-code-scanning-filter-and-search.png b/assets/images/help/repository/repo-code-scanning-filter-and-search.png deleted file mode 100644 index 26a0677e25a1..000000000000 Binary files a/assets/images/help/repository/repo-code-scanning-filter-and-search.png and /dev/null differ diff --git a/assets/images/help/repository/repo-security-side-panel.png b/assets/images/help/repository/repo-security-side-panel.png deleted file mode 100644 index 50775f9ae8ec..000000000000 Binary files a/assets/images/help/repository/repo-security-side-panel.png and /dev/null differ diff --git a/assets/images/help/repository/repository-announcement-text-field.png b/assets/images/help/repository/repository-announcement-text-field.png deleted file mode 100644 index e0e19cd45cde..000000000000 Binary files a/assets/images/help/repository/repository-announcement-text-field.png and /dev/null differ diff --git a/assets/images/help/repository/secret-scanning-alerts-dismiss-alert-fpt.png b/assets/images/help/repository/secret-scanning-alerts-dismiss-alert-fpt.png deleted file mode 100644 index a0883a372262..000000000000 Binary files a/assets/images/help/repository/secret-scanning-alerts-dismiss-alert-fpt.png and /dev/null differ diff --git a/assets/images/help/repository/secret-scanning-dismiss-alert.png b/assets/images/help/repository/secret-scanning-dismiss-alert.png deleted file mode 100644 index eac0b1a0d175..000000000000 Binary files a/assets/images/help/repository/secret-scanning-dismiss-alert.png and /dev/null differ diff --git a/assets/images/help/repository/secret-scanning-resolve-alert.png b/assets/images/help/repository/secret-scanning-resolve-alert.png deleted file mode 100644 index 3f59dd4eb5af..000000000000 Binary files a/assets/images/help/repository/secret-scanning-resolve-alert.png and /dev/null differ diff --git a/assets/images/help/saml/okta-sign-on-tab.png b/assets/images/help/saml/okta-sign-on-tab.png deleted file mode 100644 index fbe90f62321a..000000000000 Binary files a/assets/images/help/saml/okta-sign-on-tab.png and /dev/null differ diff --git a/assets/images/help/security/ip-allow-list-config-for-github-apps-ghec.png b/assets/images/help/security/ip-allow-list-config-for-github-apps-ghec.png deleted file mode 100644 index eb4dc31f37ec..000000000000 Binary files a/assets/images/help/security/ip-allow-list-config-for-github-apps-ghec.png and /dev/null differ diff --git a/assets/images/help/security/ip-allow-list-configuration-github.png b/assets/images/help/security/ip-allow-list-configuration-github.png deleted file mode 100644 index c8bfcaa69ca3..000000000000 Binary files a/assets/images/help/security/ip-allow-list-configuration-github.png and /dev/null differ diff --git a/assets/images/help/security/ip-allowlist-dropdown-ghec.png b/assets/images/help/security/ip-allowlist-dropdown-ghec.png deleted file mode 100644 index b4faeab9f6e0..000000000000 Binary files a/assets/images/help/security/ip-allowlist-dropdown-ghec.png and /dev/null differ diff --git a/assets/images/help/server-statistics/enterprise-account-settings-tab.png b/assets/images/help/server-statistics/enterprise-account-settings-tab.png deleted file mode 100644 index 6490bf534a3b..000000000000 Binary files a/assets/images/help/server-statistics/enterprise-account-settings-tab.png and /dev/null differ diff --git a/assets/images/help/server-statistics/enterprise-settings.png b/assets/images/help/server-statistics/enterprise-settings.png deleted file mode 100644 index 8bab10a059a8..000000000000 Binary files a/assets/images/help/server-statistics/enterprise-settings.png and /dev/null differ diff --git a/assets/images/help/server-statistics/settings-github-connect-tab.png b/assets/images/help/server-statistics/settings-github-connect-tab.png deleted file mode 100644 index 54bfa26ff004..000000000000 Binary files a/assets/images/help/server-statistics/settings-github-connect-tab.png and /dev/null differ diff --git a/assets/images/help/settings/actions-access-settings.png b/assets/images/help/settings/actions-access-settings.png deleted file mode 100644 index 40db0684da98..000000000000 Binary files a/assets/images/help/settings/actions-access-settings.png and /dev/null differ diff --git a/assets/images/help/stars/star-a-project.png b/assets/images/help/stars/star-a-project.png deleted file mode 100644 index e2b354554b59..000000000000 Binary files a/assets/images/help/stars/star-a-project.png and /dev/null differ diff --git a/assets/images/personal_token.png b/assets/images/personal_token.png deleted file mode 100644 index 64fb14498879..000000000000 Binary files a/assets/images/personal_token.png and /dev/null differ diff --git a/lib/redirects/static/client-side-rest-api-redirects.json b/lib/redirects/static/client-side-rest-api-redirects.json index e4dae08b3b3d..905bb55f7a97 100644 --- a/lib/redirects/static/client-side-rest-api-redirects.json +++ b/lib/redirects/static/client-side-rest-api-redirects.json @@ -514,8 +514,11 @@ "/rest/issues#list-assignees": "/rest/issues/assignees#list-assignees", "/rest/issues#assignees": "/rest/issues/assignees", "/rest/issues#check-if-a-user-can-be-assigned": "/rest/issues/assignees#check-if-a-user-can-be-assigned", - "/restundefined": "/rest/repos/autolinks#undefined", + "/rest/repos/autolinks#list-all-autolinks-of-a-repository": "/rest/repos/autolinks#list-all-autolinks-of-a-repository", "/rest/repos#autolinks": "/rest/repos/autolinks", + "/rest/repos/autolinks#create-an-autolink-reference-for-a-repository": "/rest/repos/autolinks#create-an-autolink-reference-for-a-repository", + "/rest/repos/autolinks#get-an-autolink-reference-of-a-repository": "/rest/repos/autolinks#get-an-autolink-reference-of-a-repository", + "/rest/repos/autolinks#delete-an-autolink-reference-from-a-repository": "/rest/repos/autolinks#delete-an-autolink-reference-from-a-repository", "/rest/repos#enable-automated-security-fixes": "/rest/repos/repos#enable-automated-security-fixes", "/rest/repos#disable-automated-security-fixes": "/rest/repos/repos#disable-automated-security-fixes", "/rest/branches/branches#list-branches": "/rest/branches/branches#list-branches", diff --git a/lib/webhooks/static/decorated/api.github.com.json b/lib/webhooks/static/decorated/api.github.com.json index 53de694f8825..165d20f4e743 100644 --- a/lib/webhooks/static/decorated/api.github.com.json +++ b/lib/webhooks/static/decorated/api.github.com.json @@ -32463,7 +32463,7 @@ "installation": { "created": { "descriptionHtml": "
Someone installed a GitHub App on a user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32680,7 +32680,7 @@ }, "deleted": { "descriptionHtml": "Someone uninstalled a GitHub App from their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32783,7 +32783,7 @@ }, "new_permissions_accepted": { "descriptionHtml": "Someone granted new permissions to a GitHub App.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32886,7 +32886,7 @@ }, "suspend": { "descriptionHtml": "Someone blocked access by a GitHub App to their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32989,7 +32989,7 @@ }, "unsuspend": { "descriptionHtml": "A GitHub App that was blocked from accessing a user or organization account was given access the account again.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33094,7 +33094,7 @@ "installation_repositories": { "added": { "descriptionHtml": "A GitHub App installation was granted access to one or more repositories.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33358,7 +33358,7 @@ }, "removed": { "descriptionHtml": "Access to one or more repositories was revoked for a GitHub App installation.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", diff --git a/lib/webhooks/static/decorated/ghec.json b/lib/webhooks/static/decorated/ghec.json index b68d7632ca2b..7c7371af9d46 100644 --- a/lib/webhooks/static/decorated/ghec.json +++ b/lib/webhooks/static/decorated/ghec.json @@ -32463,7 +32463,7 @@ "installation": { "created": { "descriptionHtml": "Someone installed a GitHub App on a user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32680,7 +32680,7 @@ }, "deleted": { "descriptionHtml": "Someone uninstalled a GitHub App from their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32783,7 +32783,7 @@ }, "new_permissions_accepted": { "descriptionHtml": "Someone granted new permissions to a GitHub App.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32886,7 +32886,7 @@ }, "suspend": { "descriptionHtml": "Someone blocked access by a GitHub App to their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32989,7 +32989,7 @@ }, "unsuspend": { "descriptionHtml": "A GitHub App that was blocked from accessing a user or organization account was given access the account again.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33094,7 +33094,7 @@ "installation_repositories": { "added": { "descriptionHtml": "A GitHub App installation was granted access to one or more repositories.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33358,7 +33358,7 @@ }, "removed": { "descriptionHtml": "Access to one or more repositories was revoked for a GitHub App installation.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", diff --git a/lib/webhooks/static/decorated/ghes-3.7.json b/lib/webhooks/static/decorated/ghes-3.7.json index b007c33c4727..7b68d6d75af7 100644 --- a/lib/webhooks/static/decorated/ghes-3.7.json +++ b/lib/webhooks/static/decorated/ghes-3.7.json @@ -32243,7 +32243,7 @@ "installation": { "created": { "descriptionHtml": "Someone installed a GitHub App on a user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32460,7 +32460,7 @@ }, "deleted": { "descriptionHtml": "Someone uninstalled a GitHub App from their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32563,7 +32563,7 @@ }, "new_permissions_accepted": { "descriptionHtml": "Someone granted new permissions to a GitHub App.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32666,7 +32666,7 @@ }, "suspend": { "descriptionHtml": "Someone blocked access by a GitHub App to their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32769,7 +32769,7 @@ }, "unsuspend": { "descriptionHtml": "A GitHub App that was blocked from accessing a user or organization account was given access the account again.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32874,7 +32874,7 @@ "installation_repositories": { "added": { "descriptionHtml": "A GitHub App installation was granted access to one or more repositories.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33138,7 +33138,7 @@ }, "removed": { "descriptionHtml": "Access to one or more repositories was revoked for a GitHub App installation.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", diff --git a/lib/webhooks/static/decorated/github.ae.json b/lib/webhooks/static/decorated/github.ae.json index 86b36d9c951d..de5932426997 100644 --- a/lib/webhooks/static/decorated/github.ae.json +++ b/lib/webhooks/static/decorated/github.ae.json @@ -32243,7 +32243,7 @@ "installation": { "created": { "descriptionHtml": "Someone installed a GitHub App on a user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32460,7 +32460,7 @@ }, "deleted": { "descriptionHtml": "Someone uninstalled a GitHub App from their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32563,7 +32563,7 @@ }, "new_permissions_accepted": { "descriptionHtml": "Someone granted new permissions to a GitHub App.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32666,7 +32666,7 @@ }, "suspend": { "descriptionHtml": "Someone blocked access by a GitHub App to their user or organization account.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32769,7 +32769,7 @@ }, "unsuspend": { "descriptionHtml": "A GitHub App that was blocked from accessing a user or organization account was given access the account again.
", - "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to a GitHub App installation. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -32874,7 +32874,7 @@ "installation_repositories": { "added": { "descriptionHtml": "A GitHub App installation was granted access to one or more repositories.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", @@ -33138,7 +33138,7 @@ }, "removed": { "descriptionHtml": "Access to one or more repositories was revoked for a GitHub App installation.
", - "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. For more information, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", + "summaryHtml": "This event occurs when there is activity relating to which repositories a GitHub App installation can access. All GitHub Apps receive this event by default. You cannot manually subscribe to this event.
\nFor more information about GitHub Apps, see \"About apps.\" For information about the APIs to manage GitHub Apps, see the GraphQL API documentation or \"Apps\" in the REST API documentation.
", "bodyParameters": [ { "type": "string", diff --git a/middleware/dynamic-assets.js b/middleware/dynamic-assets.js new file mode 100644 index 000000000000..5f24eea23b85 --- /dev/null +++ b/middleware/dynamic-assets.js @@ -0,0 +1,84 @@ +import fs from 'fs/promises' + +import sharp from 'sharp' + +import { assetCacheControl, defaultCacheControl } from './cache-control.js' +import { setFastlySurrogateKey, SURROGATE_ENUMS } from './set-fastly-surrogate-key.js' + +export default async function dynamicAssets(req, res, next) { + if (!req.url.startsWith('/assets/')) return next() + + if (!(req.method === 'GET' || req.method === 'HEAD')) { + return res.status(405).type('text/plain').send('Method Not Allowed') + } + + if (req.path.endsWith('.webp')) { + // From PNG (if it exists) to WEBP + try { + const originalBuffer = await fs.readFile(req.path.slice(1).replace(/\.webp$/, '.png')) + const buffer = await sharp(originalBuffer) + // Note that by default, sharp will use a lossy compression. + // (i.e. `{lossless: false}` in the options) + // The difference is that a lossless image is slightly crisper + // but becomes on average 1.8x larger. + // Given how we serve images, no human would be able to tell the + // difference simply by looking at the image as it appears as an + // image tag in the web page. + // Also given that rendering-for-viewing is the "end of the line" + // for the image meaning it just ends up being viewed and not + // resaved as a source file. If we had intention to overwrite all + // original PNG source files to WEBP, we should consier lossless + // to preserve as much quality as possible at the source level. + // The default quality is 80% which, combined with `lossless:false` + // makes our images 2.8x smaller than the average PNG. + .webp() + .toBuffer() + assetCacheControl(res) + return res.type('image/webp').send(buffer) + } catch (error) { + if (error.code !== 'ENOENT') { + throw error + } + } + } + + if (req.path.endsWith('.avif')) { + // From PNG (if it exists) to AVIF + try { + const originalBuffer = await fs.readFile(req.path.slice(1).replace(/\.avif$/, '.png')) + const buffer = await sharp(originalBuffer) + .avif({ + // The default is 4 (max is 9). Because this is a dynamic thing + // and AVIF encoding is slow for large images, go for a smaller + // effort to be sure it can't take too long on a busy server. + effort: 2, + }) + .toBuffer() + assetCacheControl(res) + return res.type('image/avif').send(buffer) + } catch (error) { + if (error.code !== 'ENOENT') { + throw error + } + } + } + + // Cache the 404 so it won't be re-attempted over and over + defaultCacheControl(res) + + // There's a preceeding middleware that sets the Surrogate-Key to + // "manual-purge" based on the URL possibly having the `/cb-xxxxx/` + // checksum in it. But, if it failed, we don't want that. So + // undo that if it was set. + // It's handy too to not overly cache 404s in the CDN because + // it could be that the next prod deployment fixes the missing image. + // For example, a PR landed that introduced the *reference* to the image + // but forgot to check in the new image, then a follow-up PR adds the image. + setFastlySurrogateKey(res, SURROGATE_ENUMS.DEFAULT) + + // Don't use something like `next(404)` because we don't want a fancy + // HTML "Page not found" page response because a failed asset lookup + // is impossibly a typo in the browser address bar or an accidentally + // broken link, like it might be to a regular HTML page. + res.status(404).type('text/plain').send('Asset not found') +} diff --git a/middleware/index.js b/middleware/index.js index 6b329a2f1a8e..34f1d5e4a587 100644 --- a/middleware/index.js +++ b/middleware/index.js @@ -61,6 +61,7 @@ import fastHead from './fast-head.js' import fastlyCacheTest from './fastly-cache-test.js' import trailingSlashes from './trailing-slashes.js' import fastlyBehavior from './fastly-behavior.js' +import dynamicAssets from './dynamic-assets.js' const { DEPLOYMENT_ENV, NODE_ENV } = process.env const isTest = NODE_ENV === 'test' || process.env.GITHUB_ACTIONS === 'true' @@ -155,12 +156,11 @@ export default function (app) { // URLs with a cache busting prefix. maxAge: '7 days', immutable: process.env.NODE_ENV !== 'development', - // This means, that if you request a file that starts with /assets/ - // any file doesn't exist, don't bother (NextJS) rendering a - // pretty HTML error page. - fallthrough: false, + // The next middleware will try its luck and send the 404 if must. + fallthrough: true, }) ) + app.use(asyncMiddleware(instrument(dynamicAssets, './dynamic-assets'))) app.use( '/public/', express.static('data/graphql', { diff --git a/package-lock.json b/package-lock.json index b3ae08381a19..32a58f87527c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,6 +79,7 @@ "rss-parser": "^3.12.0", "scroll-anchoring": "^0.1.0", "semver": "^7.3.7", + "sharp": "0.31.3", "slash": "^5.0.0", "strip-html-comments": "^1.0.0", "styled-components": "^5.3.5", @@ -6362,8 +6363,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "optional": true + ] }, "node_modules/basic-auth": { "version": "2.0.1", @@ -6400,7 +6400,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -6677,7 +6676,6 @@ "url": "https://feross.org/support" } ], - "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -7000,8 +6998,7 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chrome-trace-event": { "version": "1.0.3", @@ -7202,9 +7199,20 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", - "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -7215,9 +7223,17 @@ }, "node_modules/color-name": { "version": "1.1.4", - "devOptional": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color2k": { "version": "1.2.4", "license": "MIT" @@ -7658,7 +7674,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "engines": { "node": ">=4.0.0" } @@ -7726,6 +7741,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8940,6 +8963,14 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/expand-tilde": { "version": "1.2.2", "devOptional": true, @@ -9678,8 +9709,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "optional": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-exists-sync": { "version": "0.1.0", @@ -9931,6 +9961,11 @@ "node": ">=4" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -10902,7 +10937,6 @@ }, "node_modules/ini": { "version": "1.3.8", - "devOptional": true, "license": "ISC" }, "node_modules/inline-style-parser": { @@ -15528,7 +15562,6 @@ }, "node_modules/minimist": { "version": "1.2.6", - "devOptional": true, "license": "MIT" }, "node_modules/minimist-options": { @@ -15582,8 +15615,7 @@ "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "optional": true + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/mockdate": { "version": "3.0.5", @@ -15688,6 +15720,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -15790,6 +15827,22 @@ "node": ">= 10.13" } }, + "node_modules/node-abi": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", + "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node_modules/node-fetch": { "version": "2.6.7", "devOptional": true, @@ -16599,6 +16652,31 @@ "version": "4.1.0", "license": "MIT" }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -17011,7 +17089,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -17026,7 +17103,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -18187,9 +18263,9 @@ "integrity": "sha512-ZQruFgZnIWH+WyO9t5rWt4ZEGqCKPwhiw+YbzTwpmT9elgLrLcfuyUiSnwwjUiVy9r4VM3urtbNF1xmEh9IL2w==" }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -18392,6 +18468,28 @@ "version": "1.1.0", "license": "MIT" }, + "node_modules/sharp": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -18496,6 +18594,62 @@ "devOptional": true, "license": "ISC" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/simple-update-notifier": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", @@ -19138,7 +19292,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "optional": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -19150,7 +19303,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "optional": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -19516,6 +19668,17 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -25437,8 +25600,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "optional": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "basic-auth": { "version": "2.0.1", @@ -25461,7 +25623,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -25650,7 +25811,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "optional": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -25861,8 +26021,7 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "chrome-trace-event": { "version": "1.0.3", @@ -26002,16 +26161,32 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + } + }, "color-convert": { "version": "2.0.1", - "devOptional": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.4", - "devOptional": true + "version": "1.1.4" + }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "color2k": { "version": "1.2.4" @@ -26298,8 +26473,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.4" @@ -26336,6 +26510,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -27153,6 +27332,11 @@ "version": "0.1.2", "devOptional": true }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "expand-tilde": { "version": "1.2.2", "devOptional": true, @@ -27680,8 +27864,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "optional": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-exists-sync": { "version": "0.1.0", @@ -27847,6 +28030,11 @@ } } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -28496,8 +28684,7 @@ "version": "2.0.4" }, "ini": { - "version": "1.3.8", - "devOptional": true + "version": "1.3.8" }, "inline-style-parser": { "version": "0.1.1" @@ -31717,8 +31904,7 @@ } }, "minimist": { - "version": "1.2.6", - "devOptional": true + "version": "1.2.6" }, "minimist-options": { "version": "4.1.0", @@ -31752,8 +31938,7 @@ "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "optional": true + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "mockdate": { "version": "3.0.5", @@ -31836,6 +32021,11 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "dev": true @@ -31904,6 +32094,19 @@ "propagate": "^2.0.0" } }, + "node-abi": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", + "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "requires": { + "semver": "^7.3.5" + } + }, + "node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node-fetch": { "version": "2.6.7", "devOptional": true, @@ -32423,6 +32626,25 @@ "postcss-value-parser": { "version": "4.1.0" }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "dev": true @@ -32703,7 +32925,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -32714,8 +32935,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" } } }, @@ -33471,9 +33691,9 @@ "integrity": "sha512-ZQruFgZnIWH+WyO9t5rWt4ZEGqCKPwhiw+YbzTwpmT9elgLrLcfuyUiSnwwjUiVy9r4VM3urtbNF1xmEh9IL2w==" }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } @@ -33633,6 +33853,21 @@ "shallowequal": { "version": "1.1.0" }, + "sharp": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", + "requires": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + } + }, "shebang-command": { "version": "2.0.0", "dev": true, @@ -33702,6 +33937,36 @@ "version": "3.0.7", "devOptional": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "simple-update-notifier": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", @@ -34118,7 +34383,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "optional": true, "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -34130,7 +34394,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "optional": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -34384,6 +34647,14 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "type-check": { "version": "0.4.0", "dev": true, diff --git a/package.json b/package.json index f36a39069889..a79071577e5d 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "rss-parser": "^3.12.0", "scroll-anchoring": "^0.1.0", "semver": "^7.3.7", + "sharp": "0.31.3", "slash": "^5.0.0", "strip-html-comments": "^1.0.0", "styled-components": "^5.3.5", diff --git a/tests/rendering/dynamic-assets.js b/tests/rendering/dynamic-assets.js new file mode 100644 index 000000000000..a433eeb241f9 --- /dev/null +++ b/tests/rendering/dynamic-assets.js @@ -0,0 +1,47 @@ +import { jest } from '@jest/globals' + +import { SURROGATE_ENUMS } from '../../middleware/set-fastly-surrogate-key.js' +import { get, head } from '../helpers/e2etest.js' + +const POSSIBLE_EXTENSIONS = ['webp', 'avif'] + +const EXPECTED_MIMETYPES = { + webp: 'image/webp', + avif: 'image/avif', +} + +describe('dynamic assets', () => { + jest.setTimeout(3 * 60 * 1000) + + test.each(POSSIBLE_EXTENSIONS)('GET logo PNG as a %s', async (extension) => { + const res = await get(`/assets/images/site/logo.${extension}`) + expect(res.statusCode).toBe(200) + expect(res.headers['content-type']).toBe(EXPECTED_MIMETYPES[extension]) + }) + + test.each(POSSIBLE_EXTENSIONS)('HEAD logo PNG as a %s', async (extension) => { + const res = await head(`/assets/images/site/logo.${extension}`) + expect(res.statusCode).toBe(200) + expect(res.headers['content-type']).toBe(EXPECTED_MIMETYPES[extension]) + }) + + test.each(POSSIBLE_EXTENSIONS)('get PNG as a %s with cache busting prefix', async (extension) => { + const res = await get(`/assets/cb-12345/images/site/logo.${extension}`) + expect(res.statusCode).toBe(200) + expect(res.headers['cache-control']).toContain('public') + expect(res.headers['cache-control']).toMatch(/max-age=[1-9]/) + expect(res.headers['surrogate-key']).toBe(SURROGATE_ENUMS.MANUAL) + }) + + test('unrecognized extensions get a 404', async () => { + const res = await get('/assets/images/site/logo.xxx') + expect(res.statusCode).toBe(404) + expect(res.headers['content-type']).toMatch(/text\/plain/) + }) + + test('unrecognized as source PNG get a 404', async () => { + const res = await get('/assets/images/site/loooogo.png') + expect(res.statusCode).toBe(404) + expect(res.headers['content-type']).toMatch(/text\/plain/) + }) +})