From eea82596f4db93d2ce56d48e15a7e64ec547752b Mon Sep 17 00:00:00 2001 From: Jean-Charles FAUCHET Date: Thu, 31 Oct 2024 00:15:56 +0100 Subject: [PATCH 01/11] feat(ecosystem): add flowbite-qwik --- packages/docs/public/ecosystem/logo.svg | 49 +++++++++++++++++++ .../src/routes/(ecosystem)/ecosystem.json | 8 +++ 2 files changed, 57 insertions(+) create mode 100644 packages/docs/public/ecosystem/logo.svg diff --git a/packages/docs/public/ecosystem/logo.svg b/packages/docs/public/ecosystem/logo.svg new file mode 100644 index 00000000000..95d8e48daad --- /dev/null +++ b/packages/docs/public/ecosystem/logo.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/src/routes/(ecosystem)/ecosystem.json b/packages/docs/src/routes/(ecosystem)/ecosystem.json index 2df59ae86ed..207c0198c35 100644 --- a/packages/docs/src/routes/(ecosystem)/ecosystem.json +++ b/packages/docs/src/routes/(ecosystem)/ecosystem.json @@ -225,6 +225,14 @@ "width": 231, "height": 90, "description": "UI library that helps developers create storefronts" + }, + { + "title": "flowbite-qwik", + "github": "https://flowbite-qwik.com/", + "imgSrc": "/ecosystem/flowbite.svg", + "width": 90, + "height": 90, + "description": "UI component Library based on the utility-first Tailwind CSS." } ], "communities": [ From 3e66bb762dc72304479c3fee184d6e8e48ac4ba3 Mon Sep 17 00:00:00 2001 From: Jean-Charles Fct Date: Thu, 31 Oct 2024 13:28:58 +0100 Subject: [PATCH 02/11] fix(ecosystem): rename flowbite icon name (#7024) --- packages/docs/public/ecosystem/{logo.svg => flowbite.svg} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/docs/public/ecosystem/{logo.svg => flowbite.svg} (100%) diff --git a/packages/docs/public/ecosystem/logo.svg b/packages/docs/public/ecosystem/flowbite.svg similarity index 100% rename from packages/docs/public/ecosystem/logo.svg rename to packages/docs/public/ecosystem/flowbite.svg From e08879fc9c9cf8bedc6e1d40cee17767b15cb22d Mon Sep 17 00:00:00 2001 From: Shai Reznik Date: Thu, 31 Oct 2024 19:40:25 +0200 Subject: [PATCH 03/11] reduce the fear level of the warning of useComputed async --- packages/qwik/src/core/use/use-task.ts | 48 +++++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/qwik/src/core/use/use-task.ts b/packages/qwik/src/core/use/use-task.ts index a7e54faaa9a..c0b2607e78b 100644 --- a/packages/qwik/src/core/use/use-task.ts +++ b/packages/qwik/src/core/use/use-task.ts @@ -1,17 +1,10 @@ -import { newInvokeContext, invoke, waitAndRun, untrack, useInvokeContext } from './use-core'; -import { logError, logErrorAndStop, logOnceWarn } from '../util/log'; -import { delay, safeCall, maybeThen, isPromise } from '../util/promises'; -import { isFunction, isObject, type ValueOrPromise } from '../util/types'; -import { isServerPlatform } from '../platform/platform'; -import { implicit$FirstArg } from '../util/implicit_dollar'; +import { type ContainerState, intToStr, type MustGetObjID, strToInt } from '../container/container'; import { assertDefined, assertEqual } from '../error/assert'; -import type { QRL } from '../qrl/qrl.public'; -import { assertQrl, assertSignal, createQRL, type QRLInternal } from '../qrl/qrl-class'; import { codeToText, QError_trackUseStore } from '../error/error'; -import { useOn, useOnDocument } from './use-on'; -import { type ContainerState, intToStr, type MustGetObjID, strToInt } from '../container/container'; -import { notifyTask, _hW } from '../render/dom/notify-render'; -import { useSequentialScope } from './use-sequential-scope'; +import { isServerPlatform } from '../platform/platform'; +import { assertQrl, assertSignal, createQRL, type QRLInternal } from '../qrl/qrl-class'; +import type { QRL } from '../qrl/qrl.public'; +import { _hW, notifyTask } from '../render/dom/notify-render'; import type { QwikElement } from '../render/dom/virtual-element'; import { handleError } from '../render/error-handling'; import type { RenderContext } from '../render/types'; @@ -21,19 +14,26 @@ import { type NoSerialize, unwrapProxy, } from '../state/common'; +import { QObjectManagerSymbol } from '../state/constants'; +import { getContext } from '../state/context'; import { + _createSignal, isSignal, QObjectSignalFlags, + type ReadonlySignal, type Signal, - type SignalInternal, SIGNAL_IMMUTABLE, SIGNAL_UNASSIGNED, - _createSignal, - type ReadonlySignal, + type SignalInternal, } from '../state/signal'; -import { QObjectManagerSymbol } from '../state/constants'; +import { implicit$FirstArg } from '../util/implicit_dollar'; +import { logError, logErrorAndStop, logOnceWarn } from '../util/log'; import { ComputedEvent, TaskEvent } from '../util/markers'; -import { getContext } from '../state/context'; +import { delay, isPromise, maybeThen, safeCall } from '../util/promises'; +import { isFunction, isObject, type ValueOrPromise } from '../util/types'; +import { invoke, newInvokeContext, untrack, useInvokeContext, waitAndRun } from './use-core'; +import { useOn, useOnDocument } from './use-on'; +import { useSequentialScope } from './use-sequential-scope'; import { useConstant } from './use-signal'; export const TaskFlagsIsVisibleTask = 1 << 0; @@ -760,10 +760,16 @@ export const runComputed = ( try { const result = taskFn(); if (isPromise(result)) { - const stack = new Error( - 'useComputed$: Async functions in computed tasks are deprecated and will stop working in v2. Use useTask$ or useResource$ instead.' - ).stack; - logOnceWarn(stack); + const warningMessage = + 'useComputed$: Async functions in computed tasks are deprecated and will stop working in v2. Use useTask$ or useResource$ instead.'; + const stack = new Error(warningMessage).stack; + if (!stack) { + logOnceWarn(warningMessage); + } else { + const lessScaryStack = stack.replace(/^Error:\s*/, ''); + logOnceWarn(lessScaryStack); + } + return result.then(ok, fail); } else { ok(result); From e7418fa84d89d5d9c1f8c3fe11c9a8e23d40b9fd Mon Sep 17 00:00:00 2001 From: Wout Mertens Date: Fri, 1 Nov 2024 10:02:23 +0100 Subject: [PATCH 04/11] fix(computed): don't warn on qrl load --- packages/qwik/src/core/use/use-task.ts | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/qwik/src/core/use/use-task.ts b/packages/qwik/src/core/use/use-task.ts index c0b2607e78b..d61897a25ad 100644 --- a/packages/qwik/src/core/use/use-task.ts +++ b/packages/qwik/src/core/use/use-task.ts @@ -758,22 +758,24 @@ export const runComputed = ( handleError(reason, hostElement, rCtx); }; try { - const result = taskFn(); - if (isPromise(result)) { - const warningMessage = - 'useComputed$: Async functions in computed tasks are deprecated and will stop working in v2. Use useTask$ or useResource$ instead.'; - const stack = new Error(warningMessage).stack; - if (!stack) { - logOnceWarn(warningMessage); + return maybeThen(task.$qrl$.$resolveLazy$(containerState.$containerEl$), () => { + const result = taskFn(); + if (isPromise(result)) { + const warningMessage = + 'useComputed$: Async functions in computed tasks are deprecated and will stop working in v2. Use useTask$ or useResource$ instead.'; + const stack = new Error(warningMessage).stack; + if (!stack) { + logOnceWarn(warningMessage); + } else { + const lessScaryStack = stack.replace(/^Error:\s*/, ''); + logOnceWarn(lessScaryStack); + } + + return result.then(ok, fail); } else { - const lessScaryStack = stack.replace(/^Error:\s*/, ''); - logOnceWarn(lessScaryStack); + ok(result); } - - return result.then(ok, fail); - } else { - ok(result); - } + }); } catch (reason) { fail(reason); } From bb14ad9dd759801eaf5de64a231bd8fee20ed719 Mon Sep 17 00:00:00 2001 From: Wout Mertens Date: Fri, 1 Nov 2024 10:28:36 +0100 Subject: [PATCH 05/11] fix(eslint-plugin): specify the runtime dependency --- .changeset/rude-camels-hang.md | 5 + packages/eslint-plugin-qwik/package.json | 4 +- pnpm-lock.yaml | 297 ++++++++++++++++++----- 3 files changed, 237 insertions(+), 69 deletions(-) create mode 100644 .changeset/rude-camels-hang.md diff --git a/.changeset/rude-camels-hang.md b/.changeset/rude-camels-hang.md new file mode 100644 index 00000000000..51e1d5836d8 --- /dev/null +++ b/.changeset/rude-camels-hang.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-qwik': patch +--- + +FIX: the @typescript-eslint/utils dependency is upgraded and made explicit in the package diff --git a/packages/eslint-plugin-qwik/package.json b/packages/eslint-plugin-qwik/package.json index 0c204125e80..39f8639d05f 100644 --- a/packages/eslint-plugin-qwik/package.json +++ b/packages/eslint-plugin-qwik/package.json @@ -5,7 +5,8 @@ "author": "Builder Team", "bugs": "https://github.com/QwikDev/qwik/issues", "dependencies": { - "jsx-ast-utils": "^3.3.5" + "jsx-ast-utils": "^3.3.5", + "@typescript-eslint/utils": "^8.12.2" }, "devDependencies": { "@builder.io/qwik": "workspace:^", @@ -13,7 +14,6 @@ "@types/eslint": "8.56.10", "@types/estree": "1.0.5", "@typescript-eslint/rule-tester": "7.8.0", - "@typescript-eslint/utils": "7.8.0", "redent": "4.0.0" }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43455b567df..f9852ac1851 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -421,6 +421,9 @@ importers: packages/eslint-plugin-qwik: dependencies: + '@typescript-eslint/utils': + specifier: ^8.12.2 + version: 8.12.2(eslint@8.57.0)(typescript@5.4.5) jsx-ast-utils: specifier: ^3.3.5 version: 3.3.5 @@ -440,9 +443,6 @@ importers: '@typescript-eslint/rule-tester': specifier: 7.8.0 version: 7.8.0(@eslint/eslintrc@3.1.0)(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': - specifier: 7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@5.4.5) redent: specifier: 4.0.0 version: 4.0.0 @@ -2297,6 +2297,12 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.11.1': resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -3576,6 +3582,10 @@ packages: resolution: {integrity: sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.12.2': + resolution: {integrity: sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/type-utils@7.16.1': resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -3598,6 +3608,10 @@ packages: resolution: {integrity: sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.12.2': + resolution: {integrity: sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@5.62.0': resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3625,6 +3639,15 @@ packages: typescript: optional: true + '@typescript-eslint/typescript-estree@8.12.2': + resolution: {integrity: sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/utils@7.16.1': resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -3637,6 +3660,12 @@ packages: peerDependencies: eslint: ^8.56.0 + '@typescript-eslint/utils@8.12.2': + resolution: {integrity: sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@5.62.0': resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3649,6 +3678,10 @@ packages: resolution: {integrity: sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.12.2': + resolution: {integrity: sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/analyze-trace@0.10.1': resolution: {integrity: sha512-RnlSOPh14QbopGCApgkSx5UBgGda5MX1cHqp2fsqfiDyCwGL/m1jaeB9fzu7didVS81LQqGZZuxFBcg8YU8EVw==} hasBin: true @@ -3945,8 +3978,8 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - array-includes@3.1.7: - resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} array-timsort@1.0.3: @@ -4651,6 +4684,18 @@ packages: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} @@ -5075,8 +5120,8 @@ packages: error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - es-abstract@1.22.4: - resolution: {integrity: sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} es-define-property@1.0.0: @@ -5090,6 +5135,10 @@ packages: es-module-lexer@1.4.1: resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + es-set-tostringtag@2.0.3: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} @@ -5911,8 +5960,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} globby@11.1.0: @@ -6014,6 +6063,10 @@ packages: resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} engines: {node: '>= 0.4'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + hast-util-from-html@2.0.1: resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} @@ -6314,6 +6367,10 @@ packages: is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} @@ -7258,6 +7315,10 @@ packages: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -7536,6 +7597,10 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -7544,8 +7609,8 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - object.values@1.1.7: - resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} ofetch@1.3.3: @@ -8330,8 +8395,8 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} registry-auth-token@5.0.2: @@ -8514,8 +8579,8 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - safe-array-concat@1.1.0: - resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} safe-buffer@5.1.2: @@ -8613,8 +8678,8 @@ packages: set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} set-function-name@2.0.2: @@ -8876,15 +8941,16 @@ packages: resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} engines: {node: '>=18'} - string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -9209,6 +9275,12 @@ packages: peerDependencies: typescript: 5.4.5 + ts-api-utils@1.4.0: + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: 5.4.5 + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -9318,8 +9390,8 @@ packages: resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} - typed-array-length@1.0.5: - resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} typedarray-to-buffer@3.1.5: @@ -9754,8 +9826,8 @@ packages: resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} engines: {node: '>=8.15'} - which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} which@1.3.1: @@ -11081,6 +11153,11 @@ snapshots: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.1(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.11.1': {} '@eslint/eslintrc@2.1.4': @@ -12634,6 +12711,11 @@ snapshots: '@typescript-eslint/types': 7.8.0 '@typescript-eslint/visitor-keys': 7.8.0 + '@typescript-eslint/scope-manager@8.12.2': + dependencies: + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/visitor-keys': 8.12.2 + '@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.4.5) @@ -12652,6 +12734,8 @@ snapshots: '@typescript-eslint/types@7.8.0': {} + '@typescript-eslint/types@8.12.2': {} + '@typescript-eslint/typescript-estree@5.62.0(supports-color@9.4.0)(typescript@5.4.5)': dependencies: '@typescript-eslint/types': 5.62.0 @@ -12688,9 +12772,24 @@ snapshots: debug: 4.3.7(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.4 + minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.4.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.12.2(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/visitor-keys': 8.12.2 + debug: 4.3.7(supports-color@9.4.0) + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.4.0(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -12709,7 +12808,7 @@ snapshots: '@typescript-eslint/utils@7.8.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 7.8.0 @@ -12721,6 +12820,17 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@8.12.2(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.0) + '@typescript-eslint/scope-manager': 8.12.2 + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.4.5) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -12736,6 +12846,11 @@ snapshots: '@typescript-eslint/types': 7.8.0 eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.12.2': + dependencies: + '@typescript-eslint/types': 8.12.2 + eslint-visitor-keys: 3.4.3 + '@typescript/analyze-trace@0.10.1': dependencies: chalk: 4.1.2 @@ -13121,11 +13236,12 @@ snapshots: array-flatten@1.1.1: {} - array-includes@3.1.7: + array-includes@3.1.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 is-string: 1.0.7 @@ -13137,7 +13253,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 arraybuffer.prototype.slice@1.0.3: @@ -13145,7 +13261,7 @@ snapshots: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 es-errors: 1.3.0 get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 @@ -13425,7 +13541,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - set-function-length: 1.2.1 + set-function-length: 1.2.2 callsite@1.0.0: {} @@ -13892,6 +14008,24 @@ snapshots: data-uri-to-buffer@6.0.2: {} + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dataloader@1.4.0: {} date-fns@1.30.1: {} @@ -14218,49 +14352,54 @@ snapshots: dependencies: stackframe: 1.3.4 - es-abstract@1.22.4: + es-abstract@1.23.3: dependencies: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 available-typed-arrays: 1.0.7 call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 es-define-property: 1.0.0 es-errors: 1.3.0 + es-object-atoms: 1.0.0 es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 - globalthis: 1.0.3 + globalthis: 1.0.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.1 + hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 + is-data-view: 1.0.1 is-negative-zero: 2.0.3 is-regex: 1.1.4 is-shared-array-buffer: 1.0.3 is-string: 1.0.7 is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.1 + object-inspect: 1.13.2 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.0 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.5 + typed-array-length: 1.0.6 unbox-primitive: 1.0.2 - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 es-define-property@1.0.0: dependencies: @@ -14270,15 +14409,19 @@ snapshots: es-module-lexer@1.4.1: {} + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + es-set-tostringtag@2.0.3: dependencies: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 - hasown: 2.0.1 + hasown: 2.0.2 es-shim-unscopables@1.0.2: dependencies: - hasown: 2.0.1 + hasown: 2.0.2 es-to-primitive@1.2.1: dependencies: @@ -15239,7 +15382,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 functions-have-names: 1.2.3 functions-have-names@1.2.3: {} @@ -15389,9 +15532,10 @@ snapshots: globals@14.0.0: {} - globalthis@1.0.3: + globalthis@1.0.4: dependencies: define-properties: 1.2.1 + gopd: 1.0.1 globby@11.1.0: dependencies: @@ -15518,6 +15662,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + hast-util-from-html@2.0.1: dependencies: '@types/hast': 3.0.4 @@ -15858,7 +16006,7 @@ snapshots: internal-slot@1.0.7: dependencies: es-errors: 1.3.0 - hasown: 2.0.1 + hasown: 2.0.2 side-channel: 1.0.6 ioredis@5.3.2: @@ -15956,6 +16104,10 @@ snapshots: dependencies: hasown: 2.0.1 + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + is-date-object@1.0.5: dependencies: has-tostringtag: 1.0.2 @@ -16083,7 +16235,7 @@ snapshots: is-typed-array@1.1.13: dependencies: - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 is-typedarray@1.0.0: {} @@ -16244,10 +16396,10 @@ snapshots: jsx-ast-utils@3.3.5: dependencies: - array-includes: 3.1.7 + array-includes: 3.1.8 array.prototype.flat: 1.3.2 object.assign: 4.1.5 - object.values: 1.1.7 + object.values: 1.2.0 junk@4.0.1: {} @@ -17135,6 +17287,10 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + minimist@1.2.8: {} minipass@3.3.6: @@ -17571,6 +17727,8 @@ snapshots: object-inspect@1.13.1: {} + object-inspect@1.13.2: {} + object-keys@1.1.1: {} object.assign@4.1.5: @@ -17580,11 +17738,11 @@ snapshots: has-symbols: 1.0.3 object-keys: 1.1.1 - object.values@1.1.7: + object.values@1.2.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-object-atoms: 1.0.0 ofetch@1.3.3: dependencies: @@ -18380,7 +18538,7 @@ snapshots: regenerator-runtime@0.14.1: {} - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -18611,7 +18769,7 @@ snapshots: dependencies: mri: 1.2.0 - safe-array-concat@1.1.0: + safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 @@ -18736,7 +18894,7 @@ snapshots: set-cookie-parser@2.6.0: {} - set-function-length@1.2.1: + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 @@ -19023,23 +19181,24 @@ snapshots: get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 - string.prototype.trim@1.2.8: + string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - string.prototype.trimend@1.0.7: + string.prototype.trimend@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-object-atoms: 1.0.0 - string.prototype.trimstart@1.0.7: + string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-object-atoms: 1.0.0 string_decoder@1.1.1: dependencies: @@ -19395,6 +19554,10 @@ snapshots: dependencies: typescript: 5.4.5 + ts-api-utils@1.4.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + ts-interface-checker@0.1.13: {} ts-node@10.9.2(@types/node@20.14.11)(typescript@5.4.5): @@ -19495,7 +19658,7 @@ snapshots: has-proto: 1.0.3 is-typed-array: 1.1.13 - typed-array-length@1.0.5: + typed-array-length@1.0.6: dependencies: call-bind: 1.0.7 for-each: 0.3.3 @@ -19964,7 +20127,7 @@ snapshots: load-yaml-file: 0.2.0 path-exists: 4.0.0 - which-typed-array@1.1.14: + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 From 259d3a10a82746a827cfa105ebefb68957ebe349 Mon Sep 17 00:00:00 2001 From: Wout Mertens Date: Sun, 3 Nov 2024 19:57:20 +0100 Subject: [PATCH 06/11] fix(dev): let vite do all dev url handling we now take the verbatim parent url to build the qrls, and let vite decode it. This makes it work in windows and with the different relative/absolute urls that vite generates. --- .changeset/late-bugs-visit.md | 5 + packages/qwik/src/optimizer/core/src/lib.rs | 12 +- packages/qwik/src/optimizer/core/src/parse.rs | 4 +- ...wik_core__test__example_noop_dev_mode.snap | 16 +- packages/qwik/src/optimizer/core/src/test.rs | 10 ++ .../qwik/src/optimizer/core/src/transform.rs | 33 +++- .../qwik/src/optimizer/src/plugins/plugin.ts | 151 +++++++++--------- .../optimizer/src/plugins/vite-dev-server.ts | 31 +--- packages/qwik/src/optimizer/src/types.ts | 1 + 9 files changed, 139 insertions(+), 124 deletions(-) create mode 100644 .changeset/late-bugs-visit.md diff --git a/.changeset/late-bugs-visit.md b/.changeset/late-bugs-visit.md new file mode 100644 index 00000000000..b115e5db433 --- /dev/null +++ b/.changeset/late-bugs-visit.md @@ -0,0 +1,5 @@ +--- +'@builder.io/qwik': patch +--- + +FIX: dev-mode QRL paths are now handled by Vite so they are the same as the parent paths. You can see this in the Sources section of the browser devtools, where the segments are now always next to their parents (when the parent is loaded). diff --git a/packages/qwik/src/optimizer/core/src/lib.rs b/packages/qwik/src/optimizer/core/src/lib.rs index 7c551ddbaa4..dd1b6b97be0 100644 --- a/packages/qwik/src/optimizer/core/src/lib.rs +++ b/packages/qwik/src/optimizer/core/src/lib.rs @@ -82,6 +82,7 @@ pub struct TransformFsOptions { #[serde(rename_all = "camelCase")] pub struct TransformModuleInput { pub path: String, + pub dev_path: Option, pub code: String, } @@ -137,6 +138,7 @@ pub fn transform_fs(config: TransformFsOptions) -> Result Result Result { + + let iterator = iterator.map(|input| -> Result { transform_code(TransformCodeOptions { src_dir, root_dir, - relative_path: &path.path, - code: &path.code, + relative_path: &input.path, + dev_path: input.dev_path.as_deref(), + code: &input.code, minify: config.minify, source_maps: config.source_maps, transpile_ts: config.transpile_ts, diff --git a/packages/qwik/src/optimizer/core/src/parse.rs b/packages/qwik/src/optimizer/core/src/parse.rs index d154fd14d4a..3e1b40a2083 100644 --- a/packages/qwik/src/optimizer/core/src/parse.rs +++ b/packages/qwik/src/optimizer/core/src/parse.rs @@ -73,6 +73,7 @@ pub enum EmitMode { pub struct TransformCodeOptions<'a> { pub relative_path: &'a str, + pub dev_path: Option<&'a str>, pub src_dir: &'a Path, pub root_dir: Option<&'a Path>, pub source_maps: bool, @@ -227,7 +228,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result { @@ -321,6 +322,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result { import { componentQrl } from "@builder.io/qwik"; import { qrlDEV } from "@builder.io/qwik"; export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0", { - file: "/user/qwik/src/test.tsx", + file: "/hello/from/dev/test.tsx", lo: 107, hi: 569, displayName: "test.tsx_App_component" @@ -53,7 +53,7 @@ import { useStore } from "@builder.io/qwik"; export const App_component_ckEPmXZlub0 = ()=>{ const stuff = useStore(); serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_component_serverStuff_ebyHaP15ytQ", { - file: "/user/qwik/src/test.tsx", + file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, displayName: "test.tsx_App_component_serverStuff" @@ -61,7 +61,7 @@ export const App_component_ckEPmXZlub0 = ()=>{ stuff ])); serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_component_serverStuff_1_PQCqO0ANabY", { - file: "/user/qwik/src/test.tsx", + file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, displayName: "test.tsx_App_component_serverStuff_1" @@ -70,7 +70,7 @@ export const App_component_ckEPmXZlub0 = ()=>{ children: /*#__PURE__*/ _jsxQ("p", null, { class: "stuff", shouldRemove$: /*#__PURE__*/ _noopQrlDEV("App_component_Cmp_p_shouldRemove_uU0MG0jvQD4", { - file: "/user/qwik/src/test.tsx", + file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, displayName: "test.tsx_App_component_Cmp_p_shouldRemove" @@ -78,18 +78,18 @@ export const App_component_ckEPmXZlub0 = ()=>{ stuff ]), onClick$: /*#__PURE__*/ _noopQrlDEV("App_component_Cmp_p_onClick_vuXzfUTkpto", { - file: "/user/qwik/src/test.tsx", + file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, displayName: "test.tsx_App_component_Cmp_p_onClick" }) }, "Hello Qwik", 3, null, { - fileName: "test.tsx", + fileName: "/hello/from/dev/test.tsx", lineNumber: 16, columnNumber: 13 }) }, 3, "u6_0", { - fileName: "test.tsx", + fileName: "/hello/from/dev/test.tsx", lineNumber: 15, columnNumber: 9 }); diff --git a/packages/qwik/src/optimizer/core/src/test.rs b/packages/qwik/src/optimizer/core/src/test.rs index 336e5f672d3..09dc728492d 100644 --- a/packages/qwik/src/optimizer/core/src/test.rs +++ b/packages/qwik/src/optimizer/core/src/test.rs @@ -65,6 +65,7 @@ fn test_input_fn(input: TestInput) -> Result { input: vec![TransformModuleInput { code: input.code.clone(), path: input.filename, + dev_path: input.dev_path, }], source_maps: true, minify: input.minify, @@ -3276,10 +3277,12 @@ export const Local = component$(() => { TransformModuleInput { code: dep.into(), path: "../../node_modules/dep/dist/lib.mjs".into(), + dev_path: None, }, TransformModuleInput { code: code.into(), path: "components/main.tsx".into(), + dev_path: None, }, ], source_maps: true, @@ -3355,10 +3358,12 @@ export const Greeter = component$(() => { TransformModuleInput { code: code.into(), path: "main.tsx".into(), + dev_path: None, }, TransformModuleInput { code: code.into(), path: "components/main.tsx".into(), + dev_path: None, }, ], source_maps: true, @@ -3393,10 +3398,12 @@ export const Greeter = component$(() => { TransformModuleInput { code: code.into(), path: "main.tsx".into(), + dev_path: None, }, TransformModuleInput { code: code.into(), path: "components/main.tsx".into(), + dev_path: None, }, ], root_dir: None, @@ -3528,6 +3535,7 @@ export const App = component$(() => { "# .to_string(), mode: EmitMode::Dev, + dev_path: Some("/hello/from/dev/test.tsx".into()), transpile_ts: true, transpile_jsx: true, strip_event_handlers: true, @@ -3621,6 +3629,7 @@ fn get_hash(name: &str) -> String { struct TestInput { pub code: String, pub filename: String, + pub dev_path: Option, pub src_dir: String, pub root_dir: Option, pub manual_chunks: Option>, @@ -3645,6 +3654,7 @@ impl TestInput { pub fn default() -> Self { Self { filename: "test.tsx".to_string(), + dev_path: None, src_dir: "/user/qwik/src/".to_string(), root_dir: None, code: "/user/qwik/src/".to_string(), diff --git a/packages/qwik/src/optimizer/core/src/transform.rs b/packages/qwik/src/optimizer/core/src/transform.rs index 6777947fa19..177318602fe 100644 --- a/packages/qwik/src/optimizer/core/src/transform.rs +++ b/packages/qwik/src/optimizer/core/src/transform.rs @@ -18,7 +18,6 @@ use std::fmt::Write as _; use std::hash::Hash; use std::hash::Hasher; // import without risk of name clashing use std::iter; -use std::path::Path; use std::str; use swc_atoms::{js_word, JsWord}; use swc_common::comments::{Comments, SingleThreadedComments}; @@ -118,6 +117,7 @@ pub struct QwikTransform<'a> { pub struct QwikTransformOptions<'a> { pub path_data: &'a PathData, + pub dev_path: Option<&'a str>, pub entry_policy: &'a dyn EntryPolicy, pub extension: JsWord, pub core_module: JsWord, @@ -265,7 +265,11 @@ impl<'a> QwikTransform<'a> { fn get_dev_location(&self, span: Span) -> ast::ExprOrSpread { let loc = self.options.cm.lookup_char_pos(span.lo); - let file_name = self.options.path_data.rel_path.to_slash_lossy().to_string(); + let file_name = self + .options + .dev_path + .map(|p| p.to_string()) + .unwrap_or_else(|| self.options.path_data.rel_path.to_slash_lossy().to_string()); ast::ExprOrSpread { spread: None, expr: Box::new(ast::Expr::Object(ast::ObjectLit { @@ -952,7 +956,12 @@ impl<'a> QwikTransform<'a> { ]; let fn_callee = if self.options.mode == EmitMode::Dev { args.push(get_qrl_dev_obj( - &self.options.path_data.abs_path, + JsWord::from( + self.options + .dev_path + .as_deref() + .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), + ), segment_data, span, )); @@ -1020,7 +1029,12 @@ impl<'a> QwikTransform<'a> { let fn_callee = if self.options.mode == EmitMode::Dev { args.push(get_qrl_dev_obj( - &self.options.path_data.abs_path, + JsWord::from( + self.options + .dev_path + .as_deref() + .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), + ), &segment_data, &span, )); @@ -1668,7 +1682,12 @@ impl<'a> QwikTransform<'a> { let mut fn_name: &JsWord = &_NOOP_QRL; if self.options.mode == EmitMode::Dev { args.push(get_qrl_dev_obj( - &self.options.path_data.abs_path, + JsWord::from( + self.options + .dev_path + .as_deref() + .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), + ), &segment_data, &DUMMY_SP, )); @@ -2339,7 +2358,7 @@ fn parse_symbol_name( (s_n, display_name.into(), hash.into()) } -fn get_qrl_dev_obj(abs_path: &Path, segment: &SegmentData, span: &Span) -> ast::Expr { +fn get_qrl_dev_obj(abs_path: JsWord, segment: &SegmentData, span: &Span) -> ast::Expr { ast::Expr::Object(ast::ObjectLit { span: DUMMY_SP, props: vec![ @@ -2347,7 +2366,7 @@ fn get_qrl_dev_obj(abs_path: &Path, segment: &SegmentData, span: &Span) -> ast:: key: ast::PropName::Ident(ast::IdentName::new(js_word!("file"), DUMMY_SP)), value: Box::new(ast::Expr::Lit(ast::Lit::Str(ast::Str { span: DUMMY_SP, - value: abs_path.to_str().unwrap().into(), + value: abs_path, raw: None, }))), }))), diff --git a/packages/qwik/src/optimizer/src/plugins/plugin.ts b/packages/qwik/src/optimizer/src/plugins/plugin.ts index b2949a073bf..4e2832b1441 100644 --- a/packages/qwik/src/optimizer/src/plugins/plugin.ts +++ b/packages/qwik/src/optimizer/src/plugins/plugin.ts @@ -82,7 +82,6 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { const clientResults = new Map(); const clientTransformedOutputs = new Map(); - const serverResults = new Map(); const serverTransformedOutputs = new Map(); const parentIds = new Map(); @@ -408,8 +407,13 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { /** * This resolves virtual names and QRL segments/entries. All the rest falls through. We must * always return a value for QRL segments because they don't exist on disk. + * + * Note: During development, the QRL filenames will be of the form + * `${parentUrl}_${name}_${hash}.js`, and we might get requests for QRLs from the client before + * the parent was built. That means we need to recover the parent from the URL and then in the + * `load()` phase ensure it is built first. */ - const resolveId = ( + const resolveId = async ( ctx: Rollup.PluginContext, id: string, importerId: string | undefined, @@ -422,44 +426,16 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { const isServer = getIsServer(resolveOpts); debug(`resolveId(${count})`, `begin ${id} | ${isServer ? 'server' : 'client'} | ${importerId}`); - /** - * During development, the QRL filenames will be of the form `${parentId}_${name}_${hash}.js`, - * and we might get requests for QRLs from the client before the parent was built. - * - * Furthermore, the client requests come in via HTTP and they are encoded in a lossy way. - * - * So, first we need to recover the real requested id, then we need to make it an absolute path, - * and then we can start matching. - */ const parsedImporterId = importerId && parseId(importerId); importerId = parsedImporterId && normalizePath(parsedImporterId.pathId); - const path = getPath(); - const importerDir = parsedImporterId && path.dirname(parsedImporterId.pathId); - - /** - * A request possibly from the browser. It could be our own QRLs requests, which we uri encode, - * or an import generated by vite. So we have to be careful. - */ - if (devServer && id.startsWith('/') && importerId?.endsWith('.html')) { - const maybeQrl = decodeURIComponent(id); - // We encode absolute paths like this, due to e.g. pnpm linking - if (maybeQrl.startsWith('/@fs/')) { - id = maybeQrl.slice(5); - } else { - /** - * This path could still be absolute, when encoded by Vite. If the first path segment is the - * same as that of the importer dir, we assume it's absolute. - */ - if (!maybeQrl.startsWith(importerDir!.slice(0, importerDir!.indexOf('/', 1)))) { - id = path.join(importerDir!, maybeQrl); - } - } - // Now we hopefully removed the influence of the http encoding - } // Relative paths must be resolved vs the importer - if (id.startsWith('.') && importerDir) { - id = path.resolve(importerDir, id); + if (id.startsWith('.') && parsedImporterId) { + const path = getPath(); + const importerDir = path.dirname(parsedImporterId.pathId); + if (importerDir) { + id = path.resolve(importerDir, id); + } } // Split query, remove windows path encoding etc @@ -470,11 +446,13 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { /** At this point, the request has been normalized. */ - /** - * Check if we know the QRL. During regular builds, we'll encounter and build parents before - * their QRLs, so this will always match. - */ - if (parentIds.get(pathId)) { + if ( + /** + * Check if we know the QRL. During regular builds, we'll encounter and build parents before + * their QRLs, so this will always match. + */ + parentIds.get(pathId) + ) { debug(`resolveId(${count}) Resolved already known ${pathId}`); result = { id: pathId + parsedId.query, @@ -486,45 +464,53 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { * been transformed yet. */ - // We test with endsWith because the dev server might add a / + // We test with endsWith because the dev server adds the base pathname pathId.endsWith(QWIK_BUILD_ID) ) { if (opts.resolveQwikBuild) { debug(`resolveId(${count})`, 'Resolved', QWIK_BUILD_ID); result = { - // We use / because \0 gives errors - id: `/${QWIK_BUILD_ID}`, + id: QWIK_BUILD_ID, moduleSideEffects: false, }; } } else if (pathId.endsWith(QWIK_CLIENT_MANIFEST_ID)) { debug(`resolveId(${count})`, 'Resolved', QWIK_CLIENT_MANIFEST_ID); result = { - id: `/${QWIK_CLIENT_MANIFEST_ID}`, + id: QWIK_CLIENT_MANIFEST_ID, moduleSideEffects: false, }; } else { + const qrlMatch = /^(?.*\.[mc]?[jt]sx?)_(?[^/]+)\.js(?$|\?.*$)/.exec(id) + ?.groups as { parent: string; name: string; query: string } | undefined; + /** * If this looks like a dev qrl filename, it doesn't matter who imports, we have the parentId * embedded. */ - const match = /^(.*\.[mc]?[jt]sx?)_([^/]+)\.js($|\?)/.exec(pathId); - if (match) { - const [, parentId, name] = match; - return ctx.resolve(parentId, importerId, { skipSelf: true }).then((resolved) => { - if (resolved) { - debug(`resolveId(${count})`, `resolved to QRL ${name} of ${parentId}`); - // Save for quick lookup - parentIds.set(pathId, resolved.id); - return { - id: pathId + parsedId.query, - // QRL segments can't have side effects. Probably never useful, but it's here for consistency - moduleSideEffects: false, - }; - } else { - debug(`resolveId(${count})`, `${parentId} does not exist`); - } - }); + if (qrlMatch) { + const { parent, name, query } = qrlMatch; + + const resolvedParent = await ctx.resolve(parent, importerId, { skipSelf: true }); + if (resolvedParent) { + /** + * A request possibly from the browser. It could be our own QRL request or an import URL + * generated by vite. In any case, only Vite fully knows how to resolve it. Therefore, we + * must recombine the resolved parent path with the QRL name. + */ + const isDevUrl = devServer && importerId?.endsWith('.html'); + const resolvedId = isDevUrl ? `${resolvedParent.id}_${name}.js` : pathId; + debug(`resolveId(${count})`, `resolved to QRL ${name} of ${resolvedParent.id}`); + // Save for lookup by load() + parentIds.set(resolvedId, resolvedParent.id); + result = { + id: resolvedId + query, + // QRL segments can't have side effects. Probably never useful, but it's here for consistency + moduleSideEffects: false, + }; + } else { + console.error(`resolveId(${count})`, `QRL parent ${parent} does not exist!`); + } } else if (importerId) { /** * When we get here it's neither a virtual module nor a QRL segment. However, Rollup can ask @@ -536,7 +522,7 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { */ const importerParentId = parentIds.get(importerId); if (importerParentId) { - debug(`resolveId(${count})`, `resolving via ${importerParentId}`); + debug(`resolveId(${count}) end`, `resolving via ${importerParentId}`); // This returns a promise that we can't await because of deadlocking return ctx.resolve(id, importerParentId, { skipSelf: true }); } @@ -560,14 +546,14 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { const isServer = getIsServer(loadOpts); // Virtual modules - if (opts.resolveQwikBuild && id === `/${QWIK_BUILD_ID}`) { + if (opts.resolveQwikBuild && id === QWIK_BUILD_ID) { debug(`load(${count})`, QWIK_BUILD_ID, opts.buildMode); return { moduleSideEffects: false, code: getQwikBuildModule(isServer, opts.target), }; } - if (id === `/${QWIK_CLIENT_MANIFEST_ID}`) { + if (id === QWIK_CLIENT_MANIFEST_ID) { debug(`load(${count})`, QWIK_CLIENT_MANIFEST_ID, opts.buildMode); return { moduleSideEffects: false, @@ -583,14 +569,19 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { // in dev mode, it could be that the id is a QRL segment that wasn't transformed yet const parentId = parentIds.get(id); if (parentId) { - // building here via ctx.load doesn't seem to work (no transform), instead we use the devserver directly - debug(`load(${count})`, 'transforming QRL parent', parentId); - // We need to encode it as an absolute path - await devServer.transformRequest(`/@fs${parentId}`); - // The QRL segment should exist now - if (!outputs.has(id)) { - debug(`load(${count})`, `QRL segment ${id} not found in ${parentId}`); - return null; + const parentModule = devServer.moduleGraph.getModuleById(parentId); + if (parentModule) { + // building here via ctx.load doesn't seem to work (no transform), instead we use the devserver directly + debug(`load(${count})`, 'transforming QRL parent', parentId); + // We need to encode it as an absolute path + await devServer.transformRequest(parentModule.url); + // The QRL segment should exist now + if (!outputs.has(id)) { + debug(`load(${count})`, `QRL segment ${id} not found in ${parentId}`); + return null; + } + } else { + console.error(`load(${count})`, `${parentModule} does not exist!`); } } } @@ -636,7 +627,6 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { if (ext in TRANSFORM_EXTS || TRANSFORM_REGEX.test(pathId)) { /** Strip client|server code from qwik server|client, but not in lib/test */ const strip = opts.target === 'client' || opts.target === 'ssr'; - const normalizedID = normalizePath(pathId); debug( `transform(${count})`, `Transforming ${id} (for: ${isServer ? 'server' : 'client'}${strip ? ', strip' : ''})` @@ -662,8 +652,12 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { filePath = normalizePath(filePath); const srcDir = opts.srcDir ? opts.srcDir : normalizePath(dir); const entryStrategy: EntryStrategy = opts.entryStrategy; + let devPath: string | undefined; + if (devServer) { + devPath = devServer.moduleGraph.getModuleById(pathId)?.url; + } const transformOpts: TransformModulesOptions = { - input: [{ code, path: filePath }], + input: [{ code, path: filePath, devPath }], entryStrategy: isServer ? { type: 'hoist' } : entryStrategy, minify: 'simplify', // Always enable sourcemaps in dev for click-to-source @@ -690,20 +684,20 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { } } + // TODO use a worker pool or make this async const newOutput = optimizer.transformModulesSync(transformOpts); const module = newOutput.modules.find((mod) => !isAdditionalFile(mod))!; // uncomment to show transform results - // debug({ isServer, strip }, transformOpts, newOutput); + debug({ isServer, strip }, transformOpts, newOutput); diagnosticsCallback(newOutput.diagnostics, optimizer, srcDir); if (isServer) { if (newOutput.diagnostics.length === 0 && linter) { linter.lint(ctx, code, id); } - serverResults.set(normalizedID, newOutput); } else { - clientResults.set(normalizedID, newOutput); + clientResults.set(id, newOutput); } const deps = new Set(); for (const mod of newOutput.modules) { @@ -857,7 +851,6 @@ export const manifest = ${JSON.stringify(manifest)};\n`; const { id } = mod; if (id) { debug('handleHotUpdate()', `invalidate ${id}`); - serverResults.delete(id); clientResults.delete(id); for (const outputs of [clientTransformedOutputs, serverTransformedOutputs]) { for (const [key, [_, parentId]] of outputs) { diff --git a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts index f844f244295..82517fec9f7 100644 --- a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts +++ b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts @@ -27,22 +27,7 @@ function getOrigin(req: IncomingMessage) { return `${protocol}://${host}`; } -// We must encode the chunk so that e.g. + doesn't get converted to space etc -const encode = (url: string) => - encodeURIComponent(url) - .replaceAll('%2F', '/') - .replaceAll('%40', '@') - .replaceAll('%3A', ':') - .replaceAll('%5B', '[') - .replaceAll('%5D', ']') - .replaceAll('%2C', ','); -function createSymbolMapper( - base: string, - opts: NormalizedQwikPluginOptions, - path: Path, - sys: OptimizerSystem -): SymbolMapperFn { - const normalizePath = makeNormalizePath(sys); +function createSymbolMapper(base: string): SymbolMapperFn { return ( symbolName: string, _mapper: SymbolMapper | undefined, @@ -58,14 +43,10 @@ function createSymbolMapper( ); return [symbolName, `${base}${symbolName}.js`]; } - // on windows, absolute paths don't start with a slash - const parentPath = normalizePath(path.dirname(parent)); - const parentFile = path.basename(parent); - const qrlPath = parentPath.startsWith(opts.rootDir) - ? normalizePath(path.relative(opts.rootDir, parentPath)) - : `@fs/${parentPath}`; - const qrlFile = encode(`${qrlPath}/${parentFile}_${symbolName}.js`); - return [symbolName, `${base}${qrlFile}`]; + // In dev mode, the `parent` is the Vite URL for the parent, not the real absolute path. + // It always has a starting slash. + const qrlFile = `${base}${parent.slice(1)}_${symbolName}.js`; + return [symbolName, qrlFile]; }; } @@ -96,7 +77,7 @@ export async function configureDevServer( clientDevInput: string | undefined, devSsrServer: boolean ) { - symbolMapper = lazySymbolMapper = createSymbolMapper(base, opts, path, sys); + symbolMapper = lazySymbolMapper = createSymbolMapper(base); if (!devSsrServer) { // we just needed the symbolMapper return; diff --git a/packages/qwik/src/optimizer/src/types.ts b/packages/qwik/src/optimizer/src/types.ts index 5ca142320e7..1b1febb7620 100644 --- a/packages/qwik/src/optimizer/src/types.ts +++ b/packages/qwik/src/optimizer/src/types.ts @@ -83,6 +83,7 @@ export interface TransformFsOptions extends TransformOptions { /** @public */ export interface TransformModuleInput { path: string; + devPath?: string; code: string; } From 4a22dd18624d963baf17ea7385590a2150dac39a Mon Sep 17 00:00:00 2001 From: Shai Reznik Date: Sun, 3 Nov 2024 21:32:09 +0200 Subject: [PATCH 07/11] fix linting error --- .../docs/src/routes/api/qwik-optimizer/api.json | 2 +- .../docs/src/routes/api/qwik-optimizer/index.md | 15 +++++++++++++++ packages/docs/src/routes/api/qwik/api.json | 6 +++--- packages/docs/src/routes/api/qwik/index.md | 14 +++++++++++--- packages/qwik/src/optimizer/src/api.md | 2 ++ .../src/optimizer/src/plugins/vite-dev-server.ts | 16 ++++++++-------- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/packages/docs/src/routes/api/qwik-optimizer/api.json b/packages/docs/src/routes/api/qwik-optimizer/api.json index 1ce05405480..e12f43ae489 100644 --- a/packages/docs/src/routes/api/qwik-optimizer/api.json +++ b/packages/docs/src/routes/api/qwik-optimizer/api.json @@ -796,7 +796,7 @@ } ], "kind": "Interface", - "content": "```typescript\nexport interface TransformModuleInput \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[code](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[path](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
", + "content": "```typescript\nexport interface TransformModuleInput \n```\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[code](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[devPath?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[path](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts", "mdFile": "qwik.transformmoduleinput.md" }, diff --git a/packages/docs/src/routes/api/qwik-optimizer/index.md b/packages/docs/src/routes/api/qwik-optimizer/index.md index 68f01c9fa21..d2fe9605443 100644 --- a/packages/docs/src/routes/api/qwik-optimizer/index.md +++ b/packages/docs/src/routes/api/qwik-optimizer/index.md @@ -3149,6 +3149,21 @@ string +[devPath?](#) + + + + + +string + + + +_(Optional)_ + + + + [path](#) diff --git a/packages/docs/src/routes/api/qwik/api.json b/packages/docs/src/routes/api/qwik/api.json index 72c5a93de0c..7b1503a4698 100644 --- a/packages/docs/src/routes/api/qwik/api.json +++ b/packages/docs/src/routes/api/qwik/api.json @@ -1760,7 +1760,7 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXNode<\"script\">\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to the q:base value `/build/`. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<\"script\">", + "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXNode<\"script\">\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to the q:base value `/build/`. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n
\n**Returns:**\n\nJSXNode<\"script\">", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts", "mdFile": "qwik.prefetchgraph.md" }, @@ -1774,7 +1774,7 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker `import.meta.env.BASE_URL` or `/`. Default is `import.meta.env.BASE_URL` - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`.\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<'script'>", + "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker `import.meta.env.BASE_URL` or `/`. Default is `import.meta.env.BASE_URL` - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`.\n\n\n
\n**Returns:**\n\nJSXNode<'script'>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts", "mdFile": "qwik.prefetchserviceworker.md" }, @@ -3034,7 +3034,7 @@ } ], "kind": "Function", - "content": "Hook that returns a read-only signal that updates when signals used in the `ComputedFn` change.\n\n\n```typescript\nuseComputed$: (qrl: ComputedFn) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[ComputedFn](#computedfn)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", + "content": "Returns a computed signal which is calculated from the given function. A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated, and if the result changed, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered.\n\nThe function must be synchronous and must not have any side effects.\n\nAsync functions are deprecated because:\n\n- When calculating the first time, it will see it's a promise and it will restart the render function. - Qwik can't track used signals after the first await, which leads to subtle bugs. - Both `useTask$` and `useResource$` are available, without these problems.\n\nIn v2, async functions won't work.\n\n\n```typescript\nuseComputed$: (qrl: ComputedFn) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[ComputedFn](#computedfn)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", "mdFile": "qwik.usecomputed_.md" }, diff --git a/packages/docs/src/routes/api/qwik/index.md b/packages/docs/src/routes/api/qwik/index.md index 69a948f1463..7e7b14311f9 100644 --- a/packages/docs/src/routes/api/qwik/index.md +++ b/packages/docs/src/routes/api/qwik/index.md @@ -3625,7 +3625,7 @@ _(Optional)_ Options for the loading prefetch graph. **Returns:** -[JSXNode](#jsxnode)<"script"> +JSXNode<"script"> [Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts) @@ -3679,7 +3679,7 @@ Options for the prefetch service worker. **Returns:** -[JSXNode](#jsxnode)<'script'> +JSXNode<'script'> [Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts) @@ -10160,7 +10160,15 @@ T ## useComputed$ -Hook that returns a read-only signal that updates when signals used in the `ComputedFn` change. +Returns a computed signal which is calculated from the given function. A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated, and if the result changed, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered. + +The function must be synchronous and must not have any side effects. + +Async functions are deprecated because: + +- When calculating the first time, it will see it's a promise and it will restart the render function. - Qwik can't track used signals after the first await, which leads to subtle bugs. - Both `useTask$` and `useResource$` are available, without these problems. + +In v2, async functions won't work. ```typescript useComputed$: (qrl: ComputedFn) => Signal>; diff --git a/packages/qwik/src/optimizer/src/api.md b/packages/qwik/src/optimizer/src/api.md index df24882b4fe..5dc12594d81 100644 --- a/packages/qwik/src/optimizer/src/api.md +++ b/packages/qwik/src/optimizer/src/api.md @@ -432,6 +432,8 @@ export interface TransformModuleInput { // (undocumented) code: string; // (undocumented) + devPath?: string; + // (undocumented) path: string; } diff --git a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts index 82517fec9f7..e6a06c05930 100644 --- a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts +++ b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts @@ -1,19 +1,19 @@ /* eslint-disable no-console */ import type { Render, RenderToStreamOptions } from '@builder.io/qwik/server'; -import { magenta } from 'kleur/colors'; import type { IncomingMessage, ServerResponse } from 'http'; +import { magenta } from 'kleur/colors'; import type { Connect, ViteDevServer } from 'vite'; +import { SYNC_QRL } from '../../../core/qrl/qrl-class'; import type { OptimizerSystem, Path, QwikManifest, SymbolMapper, SymbolMapperFn } from '../types'; -import { type NormalizedQwikPluginOptions, parseId, makeNormalizePath } from './plugin'; -import type { QwikViteDevResponse } from './vite'; -import { formatError } from './vite-utils'; -import { VITE_ERROR_OVERLAY_STYLES } from './vite-error'; -import imageDevTools from './image-size-runtime.html?raw'; import clickToComponent from './click-to-component.html?raw'; -import perfWarning from './perf-warning.html?raw'; import errorHost from './error-host.html?raw'; -import { SYNC_QRL } from '../../../core/qrl/qrl-class'; +import imageDevTools from './image-size-runtime.html?raw'; +import perfWarning from './perf-warning.html?raw'; +import { parseId, type NormalizedQwikPluginOptions } from './plugin'; +import type { QwikViteDevResponse } from './vite'; +import { VITE_ERROR_OVERLAY_STYLES } from './vite-error'; +import { formatError } from './vite-utils'; function getOrigin(req: IncomingMessage) { const { PROTOCOL_HEADER, HOST_HEADER } = process.env; From da725e952910972b8684c36e68e39a4c89e0e18a Mon Sep 17 00:00:00 2001 From: Jerry_wu <409187100@qq.com> Date: Mon, 4 Nov 2024 22:19:08 +0800 Subject: [PATCH 08/11] 6799 fix route (#6970) Co-authored-by: wuls --- .changeset/twenty-radios-camp.md | 5 ++++ .../buildtime/build-pages-rewrited.unit.ts | 29 +++++++++++++++++++ packages/qwik-city/src/buildtime/build.ts | 10 ++++++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .changeset/twenty-radios-camp.md diff --git a/.changeset/twenty-radios-camp.md b/.changeset/twenty-radios-camp.md new file mode 100644 index 00000000000..e00bf88178a --- /dev/null +++ b/.changeset/twenty-radios-camp.md @@ -0,0 +1,5 @@ +--- +'@builder.io/qwik-city': patch +--- + +fix: Multiple rewrite routes pointing to the same route is no longer an error. diff --git a/packages/qwik-city/src/buildtime/build-pages-rewrited.unit.ts b/packages/qwik-city/src/buildtime/build-pages-rewrited.unit.ts index 8f6875f5bed..8ae32d63361 100644 --- a/packages/qwik-city/src/buildtime/build-pages-rewrited.unit.ts +++ b/packages/qwik-city/src/buildtime/build-pages-rewrited.unit.ts @@ -228,3 +228,32 @@ testWithDuplicatedRoutes( assert.equal(r.pathname, '/produkt/'); } ); + +const testSameRoutes = testAppSuite('Same route with undefined prefixes', { + rewriteRoutes: [ + { + prefix: undefined, + paths: {}, + }, + { + prefix: undefined, + paths: { + produkt: 'produkt', + }, + }, + { + prefix: undefined, + paths: { + produkt: 'produkt', + }, + }, + ], +}); + +testSameRoutes( + 'Issue #6799: Bug while using rewrite routes pointing to the same file', + ({ assertRoute }) => { + const r = assertRoute('/produkt/'); + assert.equal(r.pathname, '/produkt/'); + } +); diff --git a/packages/qwik-city/src/buildtime/build.ts b/packages/qwik-city/src/buildtime/build.ts index 03951fa8789..16e450a20c7 100644 --- a/packages/qwik-city/src/buildtime/build.ts +++ b/packages/qwik-city/src/buildtime/build.ts @@ -78,7 +78,15 @@ function rewriteRoutes(ctx: BuildContext, resolvedFiles: ReturnType + item.pathname === routeToPush.pathname && item.routeName === routeToPush.routeName + ) + ) { + translatedRoutes.push(routeToPush); + } }); } }); From 546d3b08c9a3ed85d49080fe931a3fbc9bb1ef60 Mon Sep 17 00:00:00 2001 From: Wout Mertens Date: Sun, 3 Nov 2024 23:00:23 +0100 Subject: [PATCH 09/11] lint: rust/optimizer plugin --- .../qwik/src/optimizer/core/src/transform.rs | 3 --- .../qwik/src/optimizer/src/plugins/plugin.ts | 10 +++++---- .../src/optimizer/src/plugins/plugin.unit.ts | 22 +++++++++++-------- .../optimizer/src/plugins/vite-dev-server.ts | 4 ++-- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/qwik/src/optimizer/core/src/transform.rs b/packages/qwik/src/optimizer/core/src/transform.rs index 177318602fe..03f02bdb6ea 100644 --- a/packages/qwik/src/optimizer/core/src/transform.rs +++ b/packages/qwik/src/optimizer/core/src/transform.rs @@ -959,7 +959,6 @@ impl<'a> QwikTransform<'a> { JsWord::from( self.options .dev_path - .as_deref() .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), ), segment_data, @@ -1032,7 +1031,6 @@ impl<'a> QwikTransform<'a> { JsWord::from( self.options .dev_path - .as_deref() .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), ), &segment_data, @@ -1685,7 +1683,6 @@ impl<'a> QwikTransform<'a> { JsWord::from( self.options .dev_path - .as_deref() .unwrap_or(&self.options.path_data.abs_path.to_slash_lossy()), ), &segment_data, diff --git a/packages/qwik/src/optimizer/src/plugins/plugin.ts b/packages/qwik/src/optimizer/src/plugins/plugin.ts index 4e2832b1441..02e9acddee4 100644 --- a/packages/qwik/src/optimizer/src/plugins/plugin.ts +++ b/packages/qwik/src/optimizer/src/plugins/plugin.ts @@ -493,16 +493,18 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { const resolvedParent = await ctx.resolve(parent, importerId, { skipSelf: true }); if (resolvedParent) { + // Vite likes to add ?v=1234... to the end of the id + const parentId = resolvedParent.id.split('?')[0]; /** * A request possibly from the browser. It could be our own QRL request or an import URL * generated by vite. In any case, only Vite fully knows how to resolve it. Therefore, we * must recombine the resolved parent path with the QRL name. */ const isDevUrl = devServer && importerId?.endsWith('.html'); - const resolvedId = isDevUrl ? `${resolvedParent.id}_${name}.js` : pathId; - debug(`resolveId(${count})`, `resolved to QRL ${name} of ${resolvedParent.id}`); + const resolvedId = isDevUrl ? `${parentId}_${name}.js` : pathId; + debug(`resolveId(${count})`, `resolved to QRL ${name} of ${parentId}`); // Save for lookup by load() - parentIds.set(resolvedId, resolvedParent.id); + parentIds.set(resolvedId, parentId); result = { id: resolvedId + query, // QRL segments can't have side effects. Probably never useful, but it's here for consistency @@ -689,7 +691,7 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) { const module = newOutput.modules.find((mod) => !isAdditionalFile(mod))!; // uncomment to show transform results - debug({ isServer, strip }, transformOpts, newOutput); + // debug({ isServer, strip }, transformOpts, newOutput); diagnosticsCallback(newOutput.diagnostics, optimizer, srcDir); if (isServer) { diff --git a/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts b/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts index 1547bbb06fe..df83c878b4d 100644 --- a/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts +++ b/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts @@ -221,7 +221,7 @@ test('experimental[]', async () => { describe('resolveId', () => { test('qrls', async () => { const plugin = await mockPlugin(); - expect(plugin.resolveId(null!, 'foo', undefined)).toBeFalsy(); + expect(await plugin.resolveId(null!, 'foo', undefined)).toBeFalsy(); const ctx = { resolve: async () => ({ id: 'Yey' }) } as any; await expect( plugin.resolveId( @@ -236,7 +236,7 @@ describe('resolveId', () => { expect( await plugin.resolveId(ctx, '/root/src/routes/layout.tsx_s_7xk04rim0vu.js', undefined) ).toHaveProperty('id', '/root/src/routes/layout.tsx_s_7xk04rim0vu.js'); - expect(plugin.resolveId(null!, './foo', '/root/src/routes/layout.tsx')).toBeFalsy(); + expect(await plugin.resolveId(null!, './foo', '/root/src/routes/layout.tsx')).toBeFalsy(); expect( await plugin.resolveId( ctx, @@ -263,7 +263,11 @@ describe('resolveId', () => { const plugin = await mockPlugin('win32'); expect( await plugin.resolveId( - { resolve: async () => 'Yey' } as any, + { + resolve: async () => ({ + id: 'Yey', + }), + } as any, 'C:\\src\\routes\\layout.tsx_s_7xk04rim0vu.js', undefined ) @@ -271,17 +275,17 @@ describe('resolveId', () => { }); test('libs', async () => { const plugin = await mockPlugin(); - expect(plugin.resolveId(null!, '@builder.io/qwik/build', undefined)).toHaveProperty( + expect(await plugin.resolveId(null!, '@builder.io/qwik/build', undefined)).toHaveProperty( 'id', - '/@builder.io/qwik/build' + '@builder.io/qwik/build' ); - expect(plugin.resolveId(null!, '/@builder.io/qwik/build', undefined)).toHaveProperty( + expect(await plugin.resolveId(null!, '/@builder.io/qwik/build', undefined)).toHaveProperty( 'id', - '/@builder.io/qwik/build' + '@builder.io/qwik/build' ); - expect(plugin.resolveId(null!, '@qwik-client-manifest', '/foo/bar')).toHaveProperty( + expect(await plugin.resolveId(null!, '@qwik-client-manifest', '/foo/bar')).toHaveProperty( 'id', - '/@qwik-client-manifest' + '@qwik-client-manifest' ); }); }); diff --git a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts index e6a06c05930..e8289c54da7 100644 --- a/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts +++ b/packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts @@ -44,8 +44,8 @@ function createSymbolMapper(base: string): SymbolMapperFn { return [symbolName, `${base}${symbolName}.js`]; } // In dev mode, the `parent` is the Vite URL for the parent, not the real absolute path. - // It always has a starting slash. - const qrlFile = `${base}${parent.slice(1)}_${symbolName}.js`; + // It is always absolute but when on Windows that's without a / + const qrlFile = `${base}${parent.startsWith('/') ? parent.slice(1) : parent}_${symbolName}.js`; return [symbolName, qrlFile]; }; } From f229c3b5e4f6ed5780a9a068f3f2a31f5a6896cb Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Tue, 5 Nov 2024 19:14:19 +0200 Subject: [PATCH 10/11] docs: update middleware sources references (#7046) --- .../docs/src/routes/docs/deployments/cloudflare-pages/index.mdx | 2 +- .../docs/src/routes/docs/deployments/netlify-edge/index.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs/src/routes/docs/deployments/cloudflare-pages/index.mdx b/packages/docs/src/routes/docs/deployments/cloudflare-pages/index.mdx index 580ddeb79c7..8fa40decc68 100644 --- a/packages/docs/src/routes/docs/deployments/cloudflare-pages/index.mdx +++ b/packages/docs/src/routes/docs/deployments/cloudflare-pages/index.mdx @@ -221,7 +221,7 @@ import { fetch } from "../server/entry.cloudflare-pages"; export default { fetch }; ``` -- [Cloudflare Pages Middleware Source](https://github.com/QwikDev/qwik/tree/main/packages/qwik-city/middleware/cloudflare-pages/index.ts) +- [Cloudflare Pages Middleware Source](https://github.com/QwikDev/qwik/tree/main/packages/qwik-city/src/middleware/cloudflare-pages/index.ts) - [Cloudflare Pages Advanced Mode](https://developers.cloudflare.com/pages/platform/functions/advanced-mode/) - [Function Invocation Route Config](https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes) diff --git a/packages/docs/src/routes/docs/deployments/netlify-edge/index.mdx b/packages/docs/src/routes/docs/deployments/netlify-edge/index.mdx index 988b776c755..77cba8e4f50 100644 --- a/packages/docs/src/routes/docs/deployments/netlify-edge/index.mdx +++ b/packages/docs/src/routes/docs/deployments/netlify-edge/index.mdx @@ -173,4 +173,4 @@ export const onRequest = async ({ env }) => { ``` - [Netlify Environment Variables](https://docs.netlify.com/environment-variables/overview/#environment-variable-options) -- [Netlify Edge Middleware Source](https://github.com/QwikDev/qwik/blob/main/packages/qwik-city/middleware/netlify-edge/index.ts) +- [Netlify Edge Middleware Source](https://github.com/QwikDev/qwik/blob/main/packages/qwik-city/src/middleware/netlify-edge/index.ts) From dea36bed50552391c49e521ccb4550b6a1c2ffbf Mon Sep 17 00:00:00 2001 From: Nelson Sousa Date: Wed, 6 Nov 2024 06:24:49 +0000 Subject: [PATCH 11/11] fix: solve issue with Cache-Control header deletion (#6991) --- .changeset/moaning-master-chief.md | 5 +++++ .../src/middleware/request-handler/request-event.ts | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .changeset/moaning-master-chief.md diff --git a/.changeset/moaning-master-chief.md b/.changeset/moaning-master-chief.md new file mode 100644 index 00000000000..962242ed53b --- /dev/null +++ b/.changeset/moaning-master-chief.md @@ -0,0 +1,5 @@ +--- +'@builder.io/qwik-city': patch +--- + +fix: Redirect, error, and fail request events no longer forcefully delete user-defined Cache-Control HTTP header value. diff --git a/packages/qwik-city/src/middleware/request-handler/request-event.ts b/packages/qwik-city/src/middleware/request-handler/request-event.ts index 506387b5530..2def677b08a 100644 --- a/packages/qwik-city/src/middleware/request-handler/request-event.ts +++ b/packages/qwik-city/src/middleware/request-handler/request-event.ts @@ -194,7 +194,6 @@ export function createRequestEvent( error: (statusCode: number, message: string) => { status = statusCode; - headers.delete('Cache-Control'); return new ErrorResponse(statusCode, message); }, @@ -208,8 +207,8 @@ export function createRequestEvent( } headers.set('Location', fixedURL); } - headers.delete('Cache-Control'); - if (statusCode > 301) { + // Fallback to 'no-store' when end user is not managing Cache-Control header + if (statusCode > 301 && !headers.get('Cache-Control')) { headers.set('Cache-Control', 'no-store'); } exit(); @@ -223,7 +222,6 @@ export function createRequestEvent( fail: >(statusCode: number, data: T): FailReturn => { check(); status = statusCode; - headers.delete('Cache-Control'); return { failed: true, ...data,