From 8c4d0c68d1ea11efcc7c0fe3e9d15bdd4305ca98 Mon Sep 17 00:00:00 2001 From: George Rubaylo <90910967+GEREGUR@users.noreply.github.com> Date: Tue, 17 Feb 2026 04:41:32 +0300 Subject: [PATCH] fix: AST-based transformation for Solid docs hooks - Add solidTransform.ts module with regex-based transformation - Transform useQuery({...}) to useQuery(() => ({...})) for Solid - Skip broken string replacements in replaceContent - Apply transformation before string replacements --- package.json | 13 +- pnpm-lock.yaml | 223 +++++++++++++++++----------------- src/utils/documents.server.ts | 34 ++++-- src/utils/solidTransform.ts | 30 +++++ 4 files changed, 176 insertions(+), 124 deletions(-) create mode 100644 src/utils/solidTransform.ts diff --git a/package.json b/package.json index d39b80d1..fae40648 100644 --- a/package.json +++ b/package.json @@ -115,11 +115,17 @@ "zustand": "^4.5.2" }, "devDependencies": { + "@babel/generator": "^7.29.1", + "@babel/parser": "^7.29.0", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@content-collections/core": "^0.8.2", "@content-collections/vite": "^0.2.4", "@eslint/js": "^9.39.1", "@playwright/test": "^1.57.0", "@shikijs/transformers": "^1.10.3", + "@types/babel__generator": "^7.27.0", + "@types/babel__traverse": "^7.28.0", "@types/express": "^5.0.3", "@types/hast": "^3.0.4", "@types/node": "^24.3.0", @@ -159,6 +165,11 @@ "qs": ">=6.14.1", "js-yaml": "^3.14.2", "brace-expansion": ">=1.1.12" - } + }, + "ignoredBuiltDependencies": [ + "@sentry/cli", + "esbuild", + "msgpackr-extract" + ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6052fe7a..8d1dcb36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -279,6 +279,18 @@ importers: specifier: ^4.5.2 version: 4.5.2(@types/react@19.2.5)(react@19.2.0) devDependencies: + '@babel/generator': + specifier: ^7.29.1 + version: 7.29.1 + '@babel/parser': + specifier: ^7.29.0 + version: 7.29.0 + '@babel/traverse': + specifier: ^7.29.0 + version: 7.29.0 + '@babel/types': + specifier: ^7.29.0 + version: 7.29.0 '@content-collections/core': specifier: ^0.8.2 version: 0.8.2(typescript@5.9.2) @@ -294,6 +306,12 @@ importers: '@shikijs/transformers': specifier: ^1.10.3 version: 1.10.3 + '@types/babel__generator': + specifier: ^7.27.0 + version: 7.27.0 + '@types/babel__traverse': + specifier: ^7.28.0 + version: 7.28.0 '@types/express': specifier: ^5.0.3 version: 5.0.6 @@ -473,6 +491,10 @@ packages: resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.27.5': resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} engines: {node: '>=6.9.0'} @@ -481,8 +503,8 @@ packages: resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': @@ -539,10 +561,6 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} @@ -555,13 +573,8 @@ packages: resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.28.4': - resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true @@ -623,24 +636,20 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} '@babel/types@7.28.4': resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} '@braintree/sanitize-url@7.1.1': @@ -3330,14 +3339,14 @@ packages: '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -8609,7 +8618,7 @@ snapshots: '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 @@ -8618,21 +8627,26 @@ snapshots: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - optional: true + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 '@babel/compat-data@7.27.5': {} '@babel/core@7.28.4': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -8642,17 +8656,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.3': + '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -8670,7 +8684,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -8679,15 +8693,15 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -8695,14 +8709,14 @@ snapshots: dependencies: '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -8711,21 +8725,19 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} @@ -8733,15 +8745,11 @@ snapshots: '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/parser@7.28.3': + '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.28.2 - - '@babel/parser@7.28.4': - dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: @@ -8805,44 +8813,33 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 - '@babel/traverse@7.28.3': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 - '@babel/traverse@7.28.4': + '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@7.28.5': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 @@ -9465,7 +9462,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: @@ -9988,7 +9985,7 @@ snapshots: '@netlify/zip-it-and-ship-it@14.1.8(rollup@4.53.3)': dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@babel/types': 7.28.4 '@netlify/binary-info': 1.0.0 '@netlify/serverless-functions-api': 2.6.0 @@ -11338,8 +11335,8 @@ snapshots: dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@tanstack/router-utils': 1.141.0 babel-dead-code-elimination: 1.0.10 pathe: 2.0.3 @@ -11518,8 +11515,8 @@ snapshots: '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@tanstack/router-core': 1.141.8 '@tanstack/router-generator': 1.141.8 '@tanstack/router-utils': 1.141.0 @@ -11542,8 +11539,8 @@ snapshots: '@tanstack/router-utils@1.141.0': dependencies: '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/parser': 7.28.4 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) ansis: 4.1.0 diff: 8.0.2 @@ -11559,8 +11556,8 @@ snapshots: '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@tanstack/directive-functions-plugin': 1.141.0(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) babel-dead-code-elimination: 1.0.10 tiny-invariant: 1.3.3 @@ -11580,7 +11577,7 @@ snapshots: dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.28.4 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@rolldown/pluginutils': 1.0.0-beta.40 '@tanstack/router-core': 1.141.8 '@tanstack/router-generator': 1.141.8 @@ -11634,24 +11631,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.5 - '@types/babel__generator': 7.6.8 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 + '@types/babel__traverse': 7.28.0 - '@types/babel__generator@7.6.8': + '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 - '@types/babel__traverse@7.20.6': + '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/body-parser@1.19.6': dependencies: @@ -12094,7 +12091,7 @@ snapshots: '@vue/compiler-core@3.5.22': dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@vue/shared': 3.5.22 entities: 4.5.0 estree-walker: 2.0.2 @@ -12107,7 +12104,7 @@ snapshots: '@vue/compiler-sfc@3.5.22': dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@vue/compiler-core': 3.5.22 '@vue/compiler-dom': 3.5.22 '@vue/compiler-ssr': 3.5.22 @@ -12402,9 +12399,9 @@ snapshots: babel-dead-code-elimination@1.0.10: dependencies: '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -12427,7 +12424,7 @@ snapshots: better-ajv-errors@1.2.0(ajv@8.17.1): dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.28.6 '@humanwhocodes/momoa': 2.0.4 ajv: 8.17.1 chalk: 4.1.2 @@ -13613,7 +13610,7 @@ snapshots: eslint-plugin-react-hooks@7.0.1(eslint@9.39.1(jiti@2.6.0)): dependencies: '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 eslint: 9.39.1(jiti@2.6.0) hermes-parser: 0.25.1 zod: 4.3.5 @@ -15518,7 +15515,7 @@ snapshots: node-source-walk@7.0.1: dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 node-stream-zip@1.15.0: {} @@ -15735,7 +15732,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -15743,7 +15740,7 @@ snapshots: parse-json@8.3.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.28.6 index-to-position: 1.2.0 type-fest: 4.41.0 diff --git a/src/utils/documents.server.ts b/src/utils/documents.server.ts index 6e6c730f..94c4b5ec 100644 --- a/src/utils/documents.server.ts +++ b/src/utils/documents.server.ts @@ -2,19 +2,18 @@ import fs from 'node:fs' import fsp from 'node:fs/promises' import path from 'node:path' import * as graymatter from 'gray-matter' +import { transformSolidCodeBlocks } from './solidTransform' import { fetchCached } from '~/utils/cache.server' import { multiSortBy, removeLeadingSlash } from './utils' import { env } from './env' -export type Doc = { - filepath: string -} - -export type DocFrontMatter = { - title: string - published?: string - exerpt?: string -} +const SOLID_HOOKS_TO_TRANSFORM = [ + 'useQuery', + 'useMutation', + 'useQueries', + 'useInfiniteQuery', + 'useMutationState', +] /** * Return text content of file from remote location @@ -94,8 +93,23 @@ function replaceContent( let result = text const replace = frontmatter.data.replace as Record | undefined if (replace) { + const solidHookKeys = Object.keys(replace).filter((key) => + SOLID_HOOKS_TO_TRANSFORM.some((hook) => key.includes(hook)), + ) + + const hasSolidTransform = solidHookKeys.length > 0 + + // First: Apply AST transformation to valid code (before any string replacements) + if (hasSolidTransform) { + result = transformSolidCodeBlocks(result) + } + + // Then: Apply string replacements (skip all Solid hook replacements) Object.entries(replace).forEach(([key, value]) => { - result = result.replace(new RegExp(key, 'g'), value) + const isSolidHookReplacement = solidHookKeys.includes(key) + if (!isSolidHookReplacement) { + result = result.replace(new RegExp(key, 'g'), value) + } }) } diff --git a/src/utils/solidTransform.ts b/src/utils/solidTransform.ts new file mode 100644 index 00000000..8e579b68 --- /dev/null +++ b/src/utils/solidTransform.ts @@ -0,0 +1,30 @@ +const SOLID_HOOKS_TO_TRANSFORM = [ + 'useQuery', + 'useMutation', + 'useQueries', + 'useInfiniteQuery', + 'useMutationState', +] + +export function transformSolidHookCalls(code: string): string { + let result = code + + for (const hook of SOLID_HOOKS_TO_TRANSFORM) { + // Match hook({ ... }) and replace with hook(() => ({ ... })) + // This regex matches: hookName({ ... }) + // and replaces with: hookName(() => ({ ... })) + const regex = new RegExp(`${hook}\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, 'g') + result = result.replace(regex, `${hook}(() => ($1))`) + } + + return result +} + +export function transformSolidCodeBlocks(text: string): string { + const codeBlockRegex = /```(?:tsx|ts|js|jsx|javascript|typescript)\n([\s\S]*?)```/g + + return text.replace(codeBlockRegex, (_match, code) => { + const transformed = transformSolidHookCalls(code) + return `\`\`\`\n${transformed}\`\`\`` + }) +}