From 083531e5c935c4b4f4dca5423eb999d2a0cc2124 Mon Sep 17 00:00:00 2001 From: andrewwallacespeckle <139135120+andrewwallacespeckle@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:58:31 +0100 Subject: [PATCH] refactor(fe2): Use webflow api for dashboard stories (#3342) * Initial work * fallback image * Update api name * Add read time * Filter out newly updated stories * Update webflow.ts * Add NuxtImg * Update webflow.ts * Update Card.vue * Rename to Webflow Items * Helm changes * Rename webflow to blog * useAsyncData * Throw error if no API --- packages/frontend-2/.env.example | 2 + .../components/dashboard/Blog/Card.vue | 49 +++ .../components/dashboard/Blog/Wrapper.vue | 31 ++ .../components/dashboard/TutorialCard.vue | 41 -- .../frontend-2/lib/dashboard/helpers/types.ts | 14 +- packages/frontend-2/nuxt.config.ts | 2 + packages/frontend-2/package.json | 1 + packages/frontend-2/pages/index.vue | 42 +- packages/frontend-2/server/api/webflow.ts | 97 ++++ .../templates/frontend_2/deployment.yml | 6 +- utils/helm/speckle-server/values.schema.json | 4 +- utils/helm/speckle-server/values.yaml | 4 +- yarn.lock | 415 +++++++++++++++++- 13 files changed, 609 insertions(+), 99 deletions(-) create mode 100644 packages/frontend-2/components/dashboard/Blog/Card.vue create mode 100644 packages/frontend-2/components/dashboard/Blog/Wrapper.vue delete mode 100644 packages/frontend-2/components/dashboard/TutorialCard.vue create mode 100644 packages/frontend-2/server/api/webflow.ts diff --git a/packages/frontend-2/.env.example b/packages/frontend-2/.env.example index 02cf1c290..17cfbc107 100644 --- a/packages/frontend-2/.env.example +++ b/packages/frontend-2/.env.example @@ -42,3 +42,5 @@ NUXT_PUBLIC_ENABLE_DIRECT_PREVIEWS=true # Ghost API NUXT_PUBLIC_GHOST_API_KEY= + +NUXT_WEBFLOW_API_TOKEN=8c9bea4c120742a21ff308cda0bea73f13e89ffe26dcc886990bba353549b652 \ No newline at end of file diff --git a/packages/frontend-2/components/dashboard/Blog/Card.vue b/packages/frontend-2/components/dashboard/Blog/Card.vue new file mode 100644 index 000000000..2268e1b41 --- /dev/null +++ b/packages/frontend-2/components/dashboard/Blog/Card.vue @@ -0,0 +1,49 @@ + + + diff --git a/packages/frontend-2/components/dashboard/Blog/Wrapper.vue b/packages/frontend-2/components/dashboard/Blog/Wrapper.vue new file mode 100644 index 000000000..2434cbebf --- /dev/null +++ b/packages/frontend-2/components/dashboard/Blog/Wrapper.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/frontend-2/components/dashboard/TutorialCard.vue b/packages/frontend-2/components/dashboard/TutorialCard.vue deleted file mode 100644 index 097ffd52b..000000000 --- a/packages/frontend-2/components/dashboard/TutorialCard.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/packages/frontend-2/lib/dashboard/helpers/types.ts b/packages/frontend-2/lib/dashboard/helpers/types.ts index 5867d4b90..7a3258b1a 100644 --- a/packages/frontend-2/lib/dashboard/helpers/types.ts +++ b/packages/frontend-2/lib/dashboard/helpers/types.ts @@ -1,13 +1,13 @@ -import type { Nullable } from '@speckle/shared' import { type LayoutDialogButton } from '@speckle/ui-components' -export type TutorialItem = { +export type WebflowItem = { id: string - readingTime?: number - publishedAt?: Nullable - url?: string - title?: string - featureImage?: Nullable + title: string + createdOn: string + lastPublished: string + featureImageUrl?: string + url: string + readTime?: number } export type QuickStartItem = { diff --git a/packages/frontend-2/nuxt.config.ts b/packages/frontend-2/nuxt.config.ts index 013d07a9a..6044d9140 100644 --- a/packages/frontend-2/nuxt.config.ts +++ b/packages/frontend-2/nuxt.config.ts @@ -33,6 +33,7 @@ export default defineNuxtConfig({ modules: [ '@nuxt/eslint', '@nuxt/devtools', + '@nuxt/image', '@nuxtjs/tailwindcss', [ '~/lib/core/nuxt-modules/apollo/module.ts', @@ -47,6 +48,7 @@ export default defineNuxtConfig({ ], runtimeConfig: { redisUrl: '', + webflowApiToken: '', public: { ...featureFlags, apiOrigin: 'UNDEFINED', diff --git a/packages/frontend-2/package.json b/packages/frontend-2/package.json index 624312ed6..d9b1f91d0 100644 --- a/packages/frontend-2/package.json +++ b/packages/frontend-2/package.json @@ -96,6 +96,7 @@ "@graphql-codegen/visitor-plugin-common": "5.3.1", "@nuxt/devtools": "^1.3.9", "@nuxt/eslint": "^0.3.13", + "@nuxt/image": "^1.8.1", "@nuxtjs/tailwindcss": "^6.3.0", "@parcel/watcher": "^2.4.1", "@speckle/tailwind-theme": "workspace:^", diff --git a/packages/frontend-2/pages/index.vue b/packages/frontend-2/pages/index.vue index 689d58bd4..94686064e 100644 --- a/packages/frontend-2/pages/index.vue +++ b/packages/frontend-2/pages/index.vue @@ -53,16 +53,7 @@ -
-

News & tutorials

-
- -
-
+ @@ -74,10 +65,8 @@ import { dashboardProjectsPageWorkspacesQuery } from '~~/lib/dashboard/graphql/queries' import type { QuickStartItem } from '~~/lib/dashboard/helpers/types' -import { getResizedGhostImage } from '~~/lib/dashboard/helpers/utils' import { useQuery } from '@vue/apollo-composable' import { useMixpanel } from '~~/lib/core/composables/mp' -import GhostContentAPI from '@tryghost/content-api' import { docsPageUrl, forumPageUrl, @@ -97,7 +86,6 @@ definePageMeta({ alias: ['/profile', '/dashboard'] }) -const config = useRuntimeConfig() const mixpanel = useMixpanel() const isWorkspacesEnabled = useIsWorkspacesEnabled() const { result: projectsResult } = useQuery(dashboardProjectsPageQuery) @@ -109,20 +97,11 @@ const { result: workspacesResult } = useQuery( }) ) const { triggerNotification } = useGlobalToast() -const { data: tutorials } = await useLazyAsyncData('tutorials', fetchTutorials, { - server: false -}) const { isGuest } = useActiveUser() const router = useRouter() const openNewProject = ref(false) -const ghostContentApi = new GhostContentAPI({ - url: 'https://v1.speckle.systems', - key: config.public.ghostApiKey, - version: 'v5.0' -}) - const quickStartItems = shallowRef([ { title: 'Install Speckle manager', @@ -171,25 +150,6 @@ const createProjectButton = shallowRef([ const projects = computed(() => projectsResult.value?.activeUser?.projects.items) const hasProjects = computed(() => (projects.value ? projects.value.length > 0 : false)) -async function fetchTutorials() { - const posts = await ghostContentApi.posts.browse({ - limit: 8, - filter: 'visibility:public' - }) - - return posts - .filter((post) => post.url) - .map((post) => ({ - id: post.id, - readingTime: post.reading_time, - publishedAt: post.published_at, - // Temporary replacement until we swap to WebFlow API - url: post.url?.replace('https://v1.speckle.systems', 'https://speckle.systems'), - title: post.title, - featureImage: getResizedGhostImage({ url: post.feature_image, width: 600 }) - })) -} - const onDownloadManager = (extension: ManagerExtension) => { try { downloadManager(extension) diff --git a/packages/frontend-2/server/api/webflow.ts b/packages/frontend-2/server/api/webflow.ts new file mode 100644 index 000000000..dbc2770ef --- /dev/null +++ b/packages/frontend-2/server/api/webflow.ts @@ -0,0 +1,97 @@ +import { ensureError } from '@speckle/shared' +import type { WebflowItem } from '~/lib/dashboard/helpers/types' + +type WebflowApiResponse = { + items: Array<{ + id: string + lastPublished: string + createdOn: string + fieldData: { + name: string + slug: string + 'feature-image'?: { + url: string + } + html?: string + } + }> +} + +const calculateReadTime = (content: string): number => { + const wordsPerMinute = 280 + const wordCount = content.trim().split(/\s+/).length + return Math.ceil(wordCount / wordsPerMinute) +} + +// Used to filter to last 6 months' articles to prevent old, +// recently edited posts from appearing at the top +const getSixMonthsAgo = (): Date => { + const date = new Date() + date.setMonth(date.getMonth() - 6) + return date +} + +export default defineEventHandler(async (): Promise<{ items: WebflowItem[] }> => { + const { webflowApiToken } = useRuntimeConfig() + + if (!webflowApiToken) { + throw createError({ + statusCode: 500, + fatal: true, + message: 'Webflow API token is not set' + }) + } + + const url = + 'https://api.webflow.com/v2/collections/66d822d3199be6f73a6c3c2c/items?limit=16&sortBy=lastPublished&sortOrder=desc' + + try { + const response = await fetch(url, { + headers: { + Authorization: `Bearer ${webflowApiToken}`, + 'accept-version': '2.0.0' + } + }) + + if (!response.ok) { + const errMsg = `Webflow API Error: ${response.status} ${response.statusText}` + throw createError({ + statusCode: response.status, + fatal: true, + message: errMsg + }) + } + + const data = (await response.json()) as WebflowApiResponse + + const sixMonthsAgo = getSixMonthsAgo() + + const filteredItems = data.items + .filter((item) => new Date(item.createdOn) > sixMonthsAgo) + .sort((a, b) => new Date(b.createdOn).getTime() - new Date(a.createdOn).getTime()) + .slice(0, 8) // Take only the first 8 items after filtering and sorting + + return { + items: filteredItems.map( + (item): WebflowItem => ({ + id: item.id, + title: item.fieldData.name, + createdOn: item.createdOn, + lastPublished: item.lastPublished, + featureImageUrl: item.fieldData['feature-image']?.url, + url: `https://speckle.systems/blog/${item.fieldData.slug}`, + readTime: item.fieldData.html + ? calculateReadTime(item.fieldData.html) + : undefined + }) + ) + } + } catch (e) { + const errMsg = ensureError(e).message + throw createError({ + statusCode: 500, + fatal: true, + message: `Error fetching webflow items: ${errMsg}` + }) + } +}) diff --git a/utils/helm/speckle-server/templates/frontend_2/deployment.yml b/utils/helm/speckle-server/templates/frontend_2/deployment.yml index 0171b0917..4080a9bb9 100644 --- a/utils/helm/speckle-server/templates/frontend_2/deployment.yml +++ b/utils/helm/speckle-server/templates/frontend_2/deployment.yml @@ -91,9 +91,9 @@ spec: secretKeyRef: name: {{ default .Values.secretName .Values.redis.connectionString.secretName }} key: {{ default "redis_url" .Values.redis.connectionString.secretKey }} - {{- if .Values.frontend_2.ghostApiKey }} - - name: NUXT_PUBLIC_GHOST_API_KEY - value: {{ .Values.frontend_2.ghostApiKey | quote }} + {{- if .Values.frontend_2.webflowApiKey }} + - name: NUXT_PUBLIC_WEBFLOW_API_KEY + value: {{ .Values.frontend_2.webflowApiKey | quote }} {{- end }} {{- if .Values.analytics.datadog_app_id }} - name: NUXT_PUBLIC_DATADOG_APP_ID diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 48bd23ece..647394a5e 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -1684,9 +1684,9 @@ "description": "The Docker image to be used for the Speckle Frontend 2 component. If blank, defaults to speckle/speckle-frontend-2:{{ .Values.docker_image_tag }}. If provided, this value should be the full path including tag. The docker_image_tag value will be ignored.", "default": "" }, - "ghostApiKey": { + "webflowApiKey": { "type": "string", - "description": "API Key for Ghost, which provides the blog content for the new web application frontend.", + "description": "API Key for Webflow, which provides the blog content for the new web application frontend.", "default": "" }, "logClientApiToken": { diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index 2a14ef13b..dbfc0aef5 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -1009,9 +1009,9 @@ frontend_2: ## @param frontend_2.image The Docker image to be used for the Speckle Frontend 2 component. If blank, defaults to speckle/speckle-frontend-2:{{ .Values.docker_image_tag }}. If provided, this value should be the full path including tag. The docker_image_tag value will be ignored. ## image: '' - ## @param frontend_2.ghostApiKey API Key for Ghost, which provides the blog content for the new web application frontend. + ## @param frontend_2.webflowApiKey API Key for Webflow, which provides the blog content for the new web application frontend. ## - ghostApiKey: '' + webflowApiKey: '' ## @param frontend_2.logClientApiToken SEQ API token ## logClientApiToken: '' diff --git a/yarn.lock b/yarn.lock index aed081971..e2b42a75d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10597,6 +10597,13 @@ __metadata: languageName: node linkType: hard +"@fastify/accept-negotiator@npm:^1.1.0": + version: 1.1.0 + resolution: "@fastify/accept-negotiator@npm:1.1.0" + checksum: 10/5c8f263680af0aece8c1fdea4d4c094a7f82cc5ed90b709357eb52a01e3388d1ac74a17e5a1d5d53f2d3ca93ae50d283ee451a6435b2cbe1b9847fff4d7d0732 + languageName: node + linkType: hard + "@fastify/busboy@npm:^2.0.0": version: 2.1.1 resolution: "@fastify/busboy@npm:2.1.1" @@ -12817,6 +12824,28 @@ __metadata: languageName: node linkType: hard +"@nuxt/image@npm:^1.8.1": + version: 1.8.1 + resolution: "@nuxt/image@npm:1.8.1" + dependencies: + "@nuxt/kit": "npm:^3.13.2" + consola: "npm:^3.2.3" + defu: "npm:^6.1.4" + h3: "npm:^1.12.0" + image-meta: "npm:^0.2.1" + ipx: "npm:^2.1.0" + node-fetch-native: "npm:^1.6.4" + ohash: "npm:^1.1.4" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + ufo: "npm:^1.5.4" + dependenciesMeta: + ipx: + optional: true + checksum: 10/63efc91906870d00403a07999f5d6ab588bef68f18f7dcca30ebb7b68ad91bfdb8fb42a8af358280653a4f0c042dd9a45f348da827b98134012b44bd668817bc + languageName: node + linkType: hard + "@nuxt/kit@npm:3.12.2": version: 3.12.2 resolution: "@nuxt/kit@npm:3.12.2" @@ -12950,6 +12979,34 @@ __metadata: languageName: node linkType: hard +"@nuxt/kit@npm:^3.13.2": + version: 3.13.2 + resolution: "@nuxt/kit@npm:3.13.2" + dependencies: + "@nuxt/schema": "npm:3.13.2" + c12: "npm:^1.11.2" + consola: "npm:^3.2.3" + defu: "npm:^6.1.4" + destr: "npm:^2.0.3" + globby: "npm:^14.0.2" + hash-sum: "npm:^2.0.0" + ignore: "npm:^5.3.2" + jiti: "npm:^1.21.6" + klona: "npm:^2.0.6" + knitwork: "npm:^1.1.0" + mlly: "npm:^1.7.1" + pathe: "npm:^1.1.2" + pkg-types: "npm:^1.2.0" + scule: "npm:^1.3.0" + semver: "npm:^7.6.3" + ufo: "npm:^1.5.4" + unctx: "npm:^2.3.1" + unimport: "npm:^3.12.0" + untyped: "npm:^1.4.2" + checksum: 10/0c8a67cb1b42841e0f7a297eefc703398674e220565b5aa56056646b1aa29f08482ff8db2e778f85f2e4059d1c9a6fb97a204a70904dd8ce66aaa0a70d403c98 + languageName: node + linkType: hard + "@nuxt/kit@npm:^3.4.3": version: 3.5.0 resolution: "@nuxt/kit@npm:3.5.0" @@ -13149,6 +13206,26 @@ __metadata: languageName: node linkType: hard +"@nuxt/schema@npm:3.13.2": + version: 3.13.2 + resolution: "@nuxt/schema@npm:3.13.2" + dependencies: + compatx: "npm:^0.1.8" + consola: "npm:^3.2.3" + defu: "npm:^6.1.4" + hookable: "npm:^5.5.3" + pathe: "npm:^1.1.2" + pkg-types: "npm:^1.2.0" + scule: "npm:^1.3.0" + std-env: "npm:^3.7.0" + ufo: "npm:^1.5.4" + uncrypto: "npm:^0.1.3" + unimport: "npm:^3.12.0" + untyped: "npm:^1.4.2" + checksum: 10/698520eb9095f7ab40f9308a9f8153578f506cf6b27635493a04e0e363d7f9d43e2174f718adc8fc948205d5300e0b1d1097f044d0615515c9374455f192a3ab + languageName: node + linkType: hard + "@nuxt/schema@npm:3.5.0": version: 3.5.0 resolution: "@nuxt/schema@npm:3.5.0" @@ -14585,6 +14662,22 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^5.1.2": + version: 5.1.2 + resolution: "@rollup/pluginutils@npm:5.1.2" + dependencies: + "@types/estree": "npm:^1.0.0" + estree-walker: "npm:^2.0.2" + picomatch: "npm:^2.3.1" + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 10/cc1fe3285ab48915a6535ab2f0c90dc511bd3e63143f8e9994bb036c6c5071fd14d641cff6c89a7fde6a4faa85227d4e2cf46ee36b7d962099e0b9e4c9b8a4b0 + languageName: node + linkType: hard + "@rollup/rollup-android-arm-eabi@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.13.0" @@ -16267,6 +16360,7 @@ __metadata: "@jsonforms/vue-vanilla": "npm:^3.3.0" "@nuxt/devtools": "npm:^1.3.9" "@nuxt/eslint": "npm:^0.3.13" + "@nuxt/image": "npm:^1.8.1" "@nuxtjs/tailwindcss": "npm:^6.3.0" "@parcel/watcher": "npm:^2.4.1" "@speckle/shared": "workspace:^" @@ -25644,6 +25738,31 @@ __metadata: languageName: node linkType: hard +"c12@npm:^1.11.2": + version: 1.11.2 + resolution: "c12@npm:1.11.2" + dependencies: + chokidar: "npm:^3.6.0" + confbox: "npm:^0.1.7" + defu: "npm:^6.1.4" + dotenv: "npm:^16.4.5" + giget: "npm:^1.2.3" + jiti: "npm:^1.21.6" + mlly: "npm:^1.7.1" + ohash: "npm:^1.1.3" + pathe: "npm:^1.1.2" + perfect-debounce: "npm:^1.0.0" + pkg-types: "npm:^1.2.0" + rc9: "npm:^2.1.2" + peerDependencies: + magicast: ^0.3.4 + peerDependenciesMeta: + magicast: + optional: true + checksum: 10/ba568cac969692a3324135e6d292e2e7d414a0394753c3afdefcb1fb799cd26dda05f8258e58b22c95253db7ec0cd29788780d291b6c6f60ddf88d5ba414d325 + languageName: node + linkType: hard + "c12@npm:^1.4.1": version: 1.4.1 resolution: "c12@npm:1.4.1" @@ -26754,7 +26873,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.19.0, commander@npm:^2.20.0": +"commander@npm:^2.19.0, commander@npm:^2.20.0, commander@npm:^2.20.3": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: 10/90c5b6898610cd075984c58c4f88418a4fb44af08c1b1415e9854c03171bec31b336b7f3e4cefe33de994b3f12b03c5e2d638da4316df83593b9e82554e7e95b @@ -27045,6 +27164,13 @@ __metadata: languageName: node linkType: hard +"confbox@npm:^0.1.8": + version: 0.1.8 + resolution: "confbox@npm:0.1.8" + checksum: 10/4ebcfb1c6a3b25276734ec5722e88768eb61fc02f98e11960b845c5c62bc27fd05f493d2a8244d9675b24ef95afe4c0d511cdcad02c72f5eeea463cc26687999 + languageName: node + linkType: hard + "config-chain@npm:^1.1.13": version: 1.1.13 resolution: "config-chain@npm:1.1.13" @@ -27194,6 +27320,13 @@ __metadata: languageName: node linkType: hard +"cookie-es@npm:^1.2.2": + version: 1.2.2 + resolution: "cookie-es@npm:1.2.2" + checksum: 10/0fd742c11caa185928e450543f84df62d4b2c1fc7b5041196b57b7db04e1c6ac6585fb40e4f579a2819efefd2d6a9cbb4d17f71240d05f4dcd8f74ae81341a20 + languageName: node + linkType: hard + "cookie-parser@npm:^1.4.6, cookie-parser@npm:~1.4.4": version: 1.4.6 resolution: "cookie-parser@npm:1.4.6" @@ -27598,6 +27731,15 @@ __metadata: languageName: node linkType: hard +"crossws@npm:>=0.2.0 <0.4.0": + version: 0.3.1 + resolution: "crossws@npm:0.3.1" + dependencies: + uncrypto: "npm:^0.1.3" + checksum: 10/d358a58b364b3314a0e42ee66b1432c01d416128e53eda983eb121abdad5ff39831a1f1ea3e90e80157ceaa0fc925f5193c151b156aa62af9e0c9bcb2fb2a15a + languageName: node + linkType: hard + "crossws@npm:^0.2.0, crossws@npm:^0.2.2, crossws@npm:^0.2.4": version: 0.2.4 resolution: "crossws@npm:0.2.4" @@ -27791,6 +27933,13 @@ __metadata: languageName: node linkType: hard +"cssfilter@npm:0.0.10": + version: 0.0.10 + resolution: "cssfilter@npm:0.0.10" + checksum: 10/1e45182f42de848f092f50a313113c28a88e4ac98333bf1603ee1c3b200384a3bc83c12e35cd61135e3b0f218295f600d51120ca1f926b7958b2d3262d711214 + languageName: node + linkType: hard + "cssnano-preset-default@npm:^6.0.1": version: 6.0.1 resolution: "cssnano-preset-default@npm:6.0.1" @@ -28833,7 +28982,7 @@ __metadata: languageName: node linkType: hard -"destr@npm:^2.0.3": +"destr@npm:^2.0.2, destr@npm:^2.0.3": version: 2.0.3 resolution: "destr@npm:2.0.3" checksum: 10/dbb756baa876810ec0ca4bcb702d86cc3b480ed14f36bf5747718ed211f96bca5520b63a4109eb181ad940ee2a645677d9a63d4a0ed11a7510619dae97317201 @@ -33251,6 +33400,24 @@ __metadata: languageName: node linkType: hard +"h3@npm:^1.10.0, h3@npm:^1.12.0": + version: 1.13.0 + resolution: "h3@npm:1.13.0" + dependencies: + cookie-es: "npm:^1.2.2" + crossws: "npm:>=0.2.0 <0.4.0" + defu: "npm:^6.1.4" + destr: "npm:^2.0.3" + iron-webcrypto: "npm:^1.2.1" + ohash: "npm:^1.1.4" + radix3: "npm:^1.1.2" + ufo: "npm:^1.5.4" + uncrypto: "npm:^0.1.3" + unenv: "npm:^1.10.0" + checksum: 10/ecdbe3cdddc767ea6f9be9939b14192dd296eb434641bbecc5b665f7210de8c03910ae40931668788395b5de6cd517afaa628d7b5ce0fb60786fce1ad6e81bcb + languageName: node + linkType: hard + "h3@npm:^1.10.2, h3@npm:^1.11.1": version: 1.11.1 resolution: "h3@npm:1.11.1" @@ -34173,6 +34340,13 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.3.2": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 + languageName: node + linkType: hard + "image-meta@npm:^0.2.0": version: 0.2.0 resolution: "image-meta@npm:0.2.0" @@ -34180,6 +34354,13 @@ __metadata: languageName: node linkType: hard +"image-meta@npm:^0.2.1": + version: 0.2.1 + resolution: "image-meta@npm:0.2.1" + checksum: 10/b8cb692727aaf47821b845714cbae5b2423a34802355bfcd815ad11610c051c10bd5b70b1634b2a5b7eb807801479983930f000e192eb956ef79c0660e7589a0 + languageName: node + linkType: hard + "immediate@npm:~3.0.5": version: 3.0.6 resolution: "immediate@npm:3.0.6" @@ -34506,6 +34687,32 @@ __metadata: languageName: node linkType: hard +"ipx@npm:^2.1.0": + version: 2.1.0 + resolution: "ipx@npm:2.1.0" + dependencies: + "@fastify/accept-negotiator": "npm:^1.1.0" + citty: "npm:^0.1.5" + consola: "npm:^3.2.3" + defu: "npm:^6.1.4" + destr: "npm:^2.0.2" + etag: "npm:^1.8.1" + h3: "npm:^1.10.0" + image-meta: "npm:^0.2.0" + listhen: "npm:^1.5.6" + ofetch: "npm:^1.3.3" + pathe: "npm:^1.1.2" + sharp: "npm:^0.32.6" + svgo: "npm:^3.2.0" + ufo: "npm:^1.3.2" + unstorage: "npm:^1.10.1" + xss: "npm:^1.0.14" + bin: + ipx: bin/ipx.mjs + checksum: 10/e91e5bb702fabf9f7e3bf866028e1b356be1f1d425bb2544d0ad60b6d8925c866259fb717a7d2ab4e805d338fc352ddcfb834582f50b1974428719c754660259 + languageName: node + linkType: hard + "iron-webcrypto@npm:^0.7.0": version: 0.7.0 resolution: "iron-webcrypto@npm:0.7.0" @@ -34520,6 +34727,13 @@ __metadata: languageName: node linkType: hard +"iron-webcrypto@npm:^1.2.1": + version: 1.2.1 + resolution: "iron-webcrypto@npm:1.2.1" + checksum: 10/c1f52ccfe2780efa5438c134538ee4b26c96a87d22f351d896781219efbce25b4fe716d1cb7f248e02da96881760541135acbcc7c0622ffedf71cb0e227bebf9 + languageName: node + linkType: hard + "is-absolute-url@npm:^4.0.0": version: 4.0.1 resolution: "is-absolute-url@npm:4.0.1" @@ -36168,6 +36382,15 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^2.1.2": + version: 2.3.3 + resolution: "jiti@npm:2.3.3" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10/21d1e89d909101c702769537e75ad87b433f980bc6938a6f64a90d1fbe7cb1510a0d4b82d4020b3093b47cebff5568af5e39d883e26aa4413564ced43b8cfd84 + languageName: node + linkType: hard + "jju@npm:~1.4.0": version: 1.4.0 resolution: "jju@npm:1.4.0" @@ -37224,6 +37447,35 @@ __metadata: languageName: node linkType: hard +"listhen@npm:^1.5.6": + version: 1.9.0 + resolution: "listhen@npm:1.9.0" + dependencies: + "@parcel/watcher": "npm:^2.4.1" + "@parcel/watcher-wasm": "npm:^2.4.1" + citty: "npm:^0.1.6" + clipboardy: "npm:^4.0.0" + consola: "npm:^3.2.3" + crossws: "npm:>=0.2.0 <0.4.0" + defu: "npm:^6.1.4" + get-port-please: "npm:^3.1.2" + h3: "npm:^1.12.0" + http-shutdown: "npm:^1.2.2" + jiti: "npm:^2.1.2" + mlly: "npm:^1.7.1" + node-forge: "npm:^1.3.1" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + ufo: "npm:^1.5.4" + untun: "npm:^0.1.3" + uqr: "npm:^0.1.2" + bin: + listen: bin/listhen.mjs + listhen: bin/listhen.mjs + checksum: 10/72b869c8604301352c5d5825a7737705f0df2ce1795af8e779b6f956ba71302e13b12b2d35142687fb4e1e8ccc2747e2be3c9cbf20f7f96b73f897881aa3c384 + languageName: node + linkType: hard + "listhen@npm:^1.7.2": version: 1.7.2 resolution: "listhen@npm:1.7.2" @@ -37830,6 +38082,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.4.3": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a + languageName: node + linkType: hard + "lru-cache@npm:^4.1.5": version: 4.1.5 resolution: "lru-cache@npm:4.1.5" @@ -39756,6 +40015,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.7.2": + version: 1.7.2 + resolution: "mlly@npm:1.7.2" + dependencies: + acorn: "npm:^8.12.1" + pathe: "npm:^1.1.2" + pkg-types: "npm:^1.2.0" + ufo: "npm:^1.5.4" + checksum: 10/c28e9f32cfc7b204e4d089a9af01b6af30547f39dd97244486fe208523c1453828b694430ebfa2d06297116861d464f150d3273040bf5e11ef5a357958f142d5 + languageName: node + linkType: hard + "mocha-junit-reporter@npm:^2.0.2": version: 2.0.2 resolution: "mocha-junit-reporter@npm:2.0.2" @@ -41355,6 +41626,13 @@ __metadata: languageName: node linkType: hard +"ohash@npm:^1.1.4": + version: 1.1.4 + resolution: "ohash@npm:1.1.4" + checksum: 10/b11445234e59c9c2b00f357f8f00b6ba00e14c84fc0a232cdc14eb1d80066479b09d27af0201631e84b7a15ba7c4a1939f4cc47f2030e9bf83c9e8afc3ff7dfd + languageName: node + linkType: hard + "oidc-token-hash@npm:^5.0.3": version: 5.0.3 resolution: "oidc-token-hash@npm:5.0.3" @@ -42767,6 +43045,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.2.0": + version: 1.2.1 + resolution: "pkg-types@npm:1.2.1" + dependencies: + confbox: "npm:^0.1.8" + mlly: "npm:^1.7.2" + pathe: "npm:^1.1.2" + checksum: 10/d61f4b7a2351b55b22f1d08f5f9b4236928d5660886131cc0e11576362e2b3bfcb54084bb4a0ba79147b707a27dcae87444a86e731113e152ffd3b6155ce5a5a + languageName: node + linkType: hard + "playwright-core@npm:1.27.1, playwright-core@npm:>=1.2.0": version: 1.27.1 resolution: "playwright-core@npm:1.27.1" @@ -48785,7 +49074,7 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^3.3.2": +"svgo@npm:^3.2.0, svgo@npm:^3.3.2": version: 3.3.2 resolution: "svgo@npm:3.3.2" dependencies: @@ -50303,6 +50592,19 @@ __metadata: languageName: node linkType: hard +"unenv@npm:^1.10.0": + version: 1.10.0 + resolution: "unenv@npm:1.10.0" + dependencies: + consola: "npm:^3.2.3" + defu: "npm:^6.1.4" + mime: "npm:^3.0.0" + node-fetch-native: "npm:^1.6.4" + pathe: "npm:^1.1.2" + checksum: 10/23198e150fd3b4db4d7abe444b75ee05a0d36768bd6d94a6aaf5dca830db82e707ccc0f6cca22671327b62c5cd85ada08d4665bf7652afec9de0bdc7a4546249 + languageName: node + linkType: hard + "unenv@npm:^1.5.1": version: 1.5.2 resolution: "unenv@npm:1.5.2" @@ -50455,6 +50757,27 @@ __metadata: languageName: node linkType: hard +"unimport@npm:^3.12.0": + version: 3.13.1 + resolution: "unimport@npm:3.13.1" + dependencies: + "@rollup/pluginutils": "npm:^5.1.2" + acorn: "npm:^8.12.1" + escape-string-regexp: "npm:^5.0.0" + estree-walker: "npm:^3.0.3" + fast-glob: "npm:^3.3.2" + local-pkg: "npm:^0.5.0" + magic-string: "npm:^0.30.11" + mlly: "npm:^1.7.1" + pathe: "npm:^1.1.2" + pkg-types: "npm:^1.2.0" + scule: "npm:^1.3.0" + strip-literal: "npm:^2.1.0" + unplugin: "npm:^1.14.1" + checksum: 10/e8ec260915ebec7641f4bf545a6f272188235d1fe25876646465c954b163ac661b769918fac7a4351f2ae3170aae9e34a8739a270c2ad284461d399cb8413e0e + languageName: node + linkType: hard + "unimport@npm:^3.5.0": version: 3.6.0 resolution: "unimport@npm:3.6.0" @@ -50867,6 +51190,21 @@ __metadata: languageName: node linkType: hard +"unplugin@npm:^1.14.1": + version: 1.14.1 + resolution: "unplugin@npm:1.14.1" + dependencies: + acorn: "npm:^8.12.1" + webpack-virtual-modules: "npm:^0.6.2" + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + checksum: 10/ad82ec5b8de5ae4fb7d24f8ed7d71071e15855d335365d7ab6f2e074d5d666589dd52e9f2a16017da19d7c43f60e50e09bc529420bf9f29ac7c90cc3cf13ef28 + languageName: node + linkType: hard + "unplugin@npm:^1.3.1": version: 1.3.1 resolution: "unplugin@npm:1.3.1" @@ -50903,6 +51241,65 @@ __metadata: languageName: node linkType: hard +"unstorage@npm:^1.10.1": + version: 1.12.0 + resolution: "unstorage@npm:1.12.0" + dependencies: + anymatch: "npm:^3.1.3" + chokidar: "npm:^3.6.0" + destr: "npm:^2.0.3" + h3: "npm:^1.12.0" + listhen: "npm:^1.7.2" + lru-cache: "npm:^10.4.3" + mri: "npm:^1.2.0" + node-fetch-native: "npm:^1.6.4" + ofetch: "npm:^1.3.4" + ufo: "npm:^1.5.4" + peerDependencies: + "@azure/app-configuration": ^1.7.0 + "@azure/cosmos": ^4.1.1 + "@azure/data-tables": ^13.2.2 + "@azure/identity": ^4.4.1 + "@azure/keyvault-secrets": ^4.8.0 + "@azure/storage-blob": ^12.24.0 + "@capacitor/preferences": ^6.0.2 + "@netlify/blobs": ^6.5.0 || ^7.0.0 + "@planetscale/database": ^1.19.0 + "@upstash/redis": ^1.34.0 + "@vercel/kv": ^1.0.1 + idb-keyval: ^6.2.1 + ioredis: ^5.4.1 + peerDependenciesMeta: + "@azure/app-configuration": + optional: true + "@azure/cosmos": + optional: true + "@azure/data-tables": + optional: true + "@azure/identity": + optional: true + "@azure/keyvault-secrets": + optional: true + "@azure/storage-blob": + optional: true + "@capacitor/preferences": + optional: true + "@netlify/blobs": + optional: true + "@planetscale/database": + optional: true + "@upstash/redis": + optional: true + "@vercel/kv": + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + checksum: 10/b648d79e9913a87152228a080355d9ccf780900eb78bd32f8dab9cc55eb66ab45876e9fc1ed49f1c7a4171600e78c33430e2527740d991df9d071872409b9c37 + languageName: node + linkType: hard + "unstorage@npm:^1.10.2": version: 1.10.2 resolution: "unstorage@npm:1.10.2" @@ -53443,6 +53840,18 @@ __metadata: languageName: node linkType: hard +"xss@npm:^1.0.14": + version: 1.0.15 + resolution: "xss@npm:1.0.15" + dependencies: + commander: "npm:^2.20.3" + cssfilter: "npm:0.0.10" + bin: + xss: bin/xss + checksum: 10/074ad54babac9dd5107466dbf30d3b871dbedae1f8e7b8f4e3b76d60da8b92bd0f66f18ccd26b8524545444ef784b78c526cee089a907aa904f83c8b8d7958f6 + languageName: node + linkType: hard + "xtend@npm:^2.2.0": version: 2.2.0 resolution: "xtend@npm:2.2.0"