From 913e8f08093ab4a0a61357670b4471fcd908fdf9 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Sun, 5 Oct 2025 21:03:08 +0300 Subject: [PATCH 01/20] feat: add React on Rails Pro with RSC support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add react_on_rails_pro gem (local path for development) - Add react-on-rails-rsc npm package (v19.0.2) - Link @shakacode-tools/react-on-rails-pro-node-renderer locally - Add .claude/ to .gitignore This enables React Server Components support for the demo app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 3 +++ Gemfile | 3 +++ Gemfile.lock | 15 +++++++++++++++ package-lock.json | 29 +++++++++++++++++++++++++++++ package.json | 1 + 5 files changed, 51 insertions(+) diff --git a/.gitignore b/.gitignore index 47c710c..4b5c88f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ yarn-debug.log* # Generated React on Rails packs **/generated/** + +# Claude Code configuration +.claude/ diff --git a/Gemfile b/Gemfile index 62187ab..31a6284 100644 --- a/Gemfile +++ b/Gemfile @@ -57,3 +57,6 @@ group :test do end gem "shakapacker", "~> 8.3" gem "react_on_rails", "~> 16.1.1" + +# Using local path for development - change to GitHub packages for production +gem "react_on_rails_pro", path: "/home/ihab/ihab/work/shakacode/react_on_rails/react_on_rails_pro" diff --git a/Gemfile.lock b/Gemfile.lock index 5328ad6..bc84edd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,14 @@ +PATH + remote: /home/ihab/ihab/work/shakacode/react_on_rails/react_on_rails_pro + specs: + react_on_rails_pro (4.0.0) + addressable + connection_pool + execjs (~> 2.9) + httpx (~> 1.5) + rainbow + react_on_rails (>= 16.0.0) + GEM remote: https://rubygems.org/ specs: @@ -116,6 +127,9 @@ GEM raabro (~> 1.4) globalid (1.3.0) activesupport (>= 6.1) + http-2 (1.1.1) + httpx (1.6.2) + http-2 (>= 1.0.0) i18n (1.14.7) concurrent-ruby (~> 1.0) io-console (0.8.1) @@ -391,6 +405,7 @@ DEPENDENCIES puma (>= 5.0) rails (~> 8.0.2, >= 8.0.2.1) react_on_rails (~> 16.1.1) + react_on_rails_pro! rubocop-rails-omakase selenium-webdriver shakapacker (~> 8.3) diff --git a/package-lock.json b/package-lock.json index 5de9143..8a26aee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "react-dom": "^19.1.1", "react-markdown": "^10.1.0", "react-on-rails": "^16.1.1", + "react-on-rails-rsc": "^19.0.2", "remark-gfm": "^4.0.1", "shakapacker": "8.4.0", "style-loader": "^4.0.0", @@ -2193,6 +2194,18 @@ "acorn": "^8.14.0" } }, + "node_modules/acorn-loose": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz", + "integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -7215,6 +7228,22 @@ } } }, + "node_modules/react-on-rails-rsc": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/react-on-rails-rsc/-/react-on-rails-rsc-19.0.2.tgz", + "integrity": "sha512-0q26jcWcr6v9nfYfB4wxtAdTwEC4PCDSb/5U7TPperP4Ac9U2K7nt3uLOSVh7BX4bacX3PrpDeI1C30cIkBPog==", + "license": "MIT", + "dependencies": { + "acorn-loose": "^8.3.0", + "neo-async": "^2.6.1", + "webpack-sources": "^3.2.0" + }, + "peerDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "webpack": "^5.59.0" + } + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", diff --git a/package.json b/package.json index b1cee67..b02c8d9 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react-dom": "^19.1.1", "react-markdown": "^10.1.0", "react-on-rails": "^16.1.1", + "react-on-rails-rsc": "^19.0.2", "remark-gfm": "^4.0.1", "shakapacker": "8.4.0", "style-loader": "^4.0.0", From d23eba9e2254df453ca41f4f7aa3b0288c9c7579 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Sun, 5 Oct 2025 21:24:24 +0300 Subject: [PATCH 02/20] feat: configure webpack and Rails for RSC bundle generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configure complete RSC infrastructure following React on Rails Pro documentation: **Webpack Configuration:** - Create rscWebpackConfig.js with RSC loader before babel-loader - Add react-server condition to resolve config - Add RSCWebpackPlugin to client and server webpack configs - Update generateWebpackConfigs to include RSC bundle in default build - Support RSC_BUNDLE_ONLY environment variable **Rails Configuration:** - Add rsc_bundle_js_file = "rsc-bundle.js" to react_on_rails initializer - Create react_on_rails_pro initializer with enable_rsc_support = true - Add rsc_payload_route to routes for RSC payload handling **Development Workflow:** - Add wp-rsc process to Procfile.dev for RSC bundle watch mode This sets up the foundation for implementing RSC components with proper bundle splitting and server-side component execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Procfile.dev | 1 + config/initializers/react_on_rails.rb | 3 ++ config/initializers/react_on_rails_pro.rb | 9 ++++ config/routes.rb | 3 ++ config/webpack/clientWebpackConfig.js | 6 ++- config/webpack/generateWebpackConfigs.js | 10 +++- config/webpack/rscWebpackConfig.js | 56 +++++++++++++++++++++++ config/webpack/serverWebpackConfig.js | 4 ++ 8 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 config/initializers/react_on_rails_pro.rb create mode 100644 config/webpack/rscWebpackConfig.js diff --git a/Procfile.dev b/Procfile.dev index 650af5e..29b85f7 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -3,3 +3,4 @@ rails: bundle exec rails s -p 3000 wp-client: WEBPACK_SERVE=true bin/shakapacker-dev-server wp-server: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch +wp-rsc: HMR=true RSC_BUNDLE_ONLY=yes bin/shakapacker --watch diff --git a/config/initializers/react_on_rails.rb b/config/initializers/react_on_rails.rb index 2ae1d45..8b178ed 100644 --- a/config/initializers/react_on_rails.rb +++ b/config/initializers/react_on_rails.rb @@ -49,6 +49,9 @@ # config.server_bundle_js_file = "server-bundle.js" + # React Server Components bundle file + config.rsc_bundle_js_file = "rsc-bundle.js" + ################################################################################ ################################################################################ # FILE SYSTEM BASED COMPONENT REGISTRY diff --git a/config/initializers/react_on_rails_pro.rb b/config/initializers/react_on_rails_pro.rb new file mode 100644 index 0000000..a729d07 --- /dev/null +++ b/config/initializers/react_on_rails_pro.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# React on Rails Pro configuration +# See https://www.shakacode.com/react-on-rails-pro/docs/configuration/ + +ReactOnRailsPro.configure do |config| + # Enable React Server Components support + config.enable_rsc_support = true +end diff --git a/config/routes.rb b/config/routes.rb index 5417043..5557a3a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,9 @@ # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker + # React Server Components payload route + rsc_payload_route + # React on Rails demo routes root "hello_world#index" get "hello_world", to: "hello_world#index" diff --git a/config/webpack/clientWebpackConfig.js b/config/webpack/clientWebpackConfig.js index fe705c6..c5040d6 100644 --- a/config/webpack/clientWebpackConfig.js +++ b/config/webpack/clientWebpackConfig.js @@ -1,7 +1,8 @@ -// The source code including full typescript support is available at: +// The source code including full typescript support is available at: // https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/clientWebpackConfig.js const commonWebpackConfig = require('./commonWebpackConfig'); +const { RSCWebpackPlugin } = require('react-on-rails-rsc/WebpackPlugin'); const configureClient = () => { const clientConfig = commonWebpackConfig(); @@ -12,6 +13,9 @@ const configureClient = () => { // client config is going to try to load chunks. delete clientConfig.entry['server-bundle']; + // Add React Server Components plugin for client bundle + clientConfig.plugins.push(new RSCWebpackPlugin({ isServer: false })); + return clientConfig; }; diff --git a/config/webpack/generateWebpackConfigs.js b/config/webpack/generateWebpackConfigs.js index 17a118b..0a1b841 100644 --- a/config/webpack/generateWebpackConfigs.js +++ b/config/webpack/generateWebpackConfigs.js @@ -3,10 +3,12 @@ const clientWebpackConfig = require('./clientWebpackConfig'); const serverWebpackConfig = require('./serverWebpackConfig'); +const rscWebpackConfig = require('./rscWebpackConfig'); const generateWebpackConfigs = (envSpecific) => { const clientConfig = clientWebpackConfig(); const serverConfig = serverWebpackConfig(); + const rscConfig = rscWebpackConfig(); if (envSpecific) { envSpecific(clientConfig, serverConfig); @@ -22,11 +24,15 @@ const generateWebpackConfigs = (envSpecific) => { // eslint-disable-next-line no-console console.log('[React on Rails] Creating only the server bundle.'); result = serverConfig; + } else if (process.env.RSC_BUNDLE_ONLY) { + // eslint-disable-next-line no-console + console.log('[React on Rails] Creating only the RSC bundle.'); + result = rscConfig; } else { // default is the standard client and server build // eslint-disable-next-line no-console - console.log('[React on Rails] Creating both client and server bundles.'); - result = [clientConfig, serverConfig]; + console.log('[React on Rails] Creating client, server, and RSC bundles.'); + result = [clientConfig, serverConfig, rscConfig]; } // To debug, uncomment next line and inspect "result" diff --git a/config/webpack/rscWebpackConfig.js b/config/webpack/rscWebpackConfig.js new file mode 100644 index 0000000..bc9b9b2 --- /dev/null +++ b/config/webpack/rscWebpackConfig.js @@ -0,0 +1,56 @@ +// use the same config as serverWebpackConfig.js but add the RSC loader +const serverWebpackConfig = require('./serverWebpackConfig'); + +// Function that extracts a specific loader from a webpack rule +function extractLoader(rule, loaderName) { + return rule.use.find((item) => { + let testValue; + + if (typeof item === 'string') { + testValue = item; + } else if (typeof item.loader === 'string') { + testValue = item.loader; + } + + return testValue.includes(loaderName); + }); +} + +const configureRsc = () => { + const rscConfig = serverWebpackConfig(); + + // Update the entry name to be `rsc-bundle` instead of `server-bundle` + const rscEntry = { + 'rsc-bundle': rscConfig.entry['server-bundle'], + }; + rscConfig.entry = rscEntry; + + // Add the RSC loader before the babel loader + const rules = rscConfig.module.rules; + rules.forEach((rule) => { + if (Array.isArray(rule.use)) { + // Ensure this loader runs before the JS loader (Babel loader in this case) to properly exclude client components from the RSC bundle. + // If your project uses a different JS loader, insert it before that loader instead. + const babelLoader = extractLoader(rule, 'babel-loader'); + if (babelLoader) { + rule.use.push({ + loader: 'react-on-rails-rsc/WebpackLoader', + }); + } + } + }); + + // Add the `react-server` condition to the resolve config + // This condition is used by React and React on Rails to know that this bundle is a React Server Component bundle + // The `...` tells webpack to retain the default Webpack conditions (In this case will keep the `node` condition because the bundle targets node) + rscConfig.resolve = { + ...rscConfig.resolve, + conditionNames: ['react-server', '...'], + }; + + // Update the output bundle name to be `rsc-bundle.js` instead of `server-bundle.js` + rscConfig.output.filename = 'rsc-bundle.js'; + return rscConfig; +}; + +module.exports = configureRsc; diff --git a/config/webpack/serverWebpackConfig.js b/config/webpack/serverWebpackConfig.js index 8d4b18c..1ece6e9 100644 --- a/config/webpack/serverWebpackConfig.js +++ b/config/webpack/serverWebpackConfig.js @@ -5,6 +5,7 @@ const { merge, config } = require('shakapacker'); const commonWebpackConfig = require('./commonWebpackConfig'); const webpack = require('webpack'); +const { RSCWebpackPlugin } = require('react-on-rails-rsc/WebpackPlugin'); const configureServer = () => { // We need to use "merge" because the clientConfigObject, EVEN after running @@ -112,6 +113,9 @@ const configureServer = () => { // If using the React on Rails Pro node server renderer, uncomment the next line // serverWebpackConfig.target = 'node' + // Add React Server Components plugin for server bundle + serverWebpackConfig.plugins.push(new RSCWebpackPlugin({ isServer: true })); + return serverWebpackConfig; }; From a3ecc1bbdb125ec3bbd6a9efc2875d3be27dadd7 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Sun, 5 Oct 2025 21:31:47 +0300 Subject: [PATCH 03/20] feat: implement RSC markdown page with shared component pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Demonstrate React Server Components with a shared viewer pattern: **Shared MarkdownViewer Component:** - Lightweight display component with no markdown processing dependencies - Accepts pre-processed HTML as prop - Reusable by both server and client components - Minimal bundle impact (~2KB) **RSCMarkdownPage Server Component:** - Processes markdown server-side using 'marked' library - Heavy markdown library stays on server, never ships to client - Uses async/await for server-side data fetching - Renders using shared MarkdownViewer component **Rails Integration:** - Created RscMarkdownPageController with ReactOnRailsPro::Stream - Uses stream_view_containing_react_components for streaming SSR - View uses stream_react_component helper for RSC rendering - Added route at /rsc_markdown_page **Dependencies:** - Added 'marked' npm package for server-side markdown processing This demonstrates the key RSC benefit: markdown processing happens entirely on the server, keeping client bundles minimal while providing full markdown rendering capabilities. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../rsc_markdown_page_controller.rb | 15 ++ .../ror_components/MarkdownViewer.jsx | 25 +++ .../ror_components/MarkdownViewer.module.css | 92 ++++++++++ .../ror_components/RSCMarkdownPage.jsx | 161 ++++++++++++++++++ .../ror_components/RSCMarkdownPage.module.css | 131 ++++++++++++++ app/views/rsc_markdown_page/index.html.erb | 3 + config/routes.rb | 1 + package-lock.json | 13 ++ package.json | 1 + 9 files changed, 442 insertions(+) create mode 100644 app/controllers/rsc_markdown_page_controller.rb create mode 100644 app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.jsx create mode 100644 app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.module.css create mode 100644 app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.jsx create mode 100644 app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.module.css create mode 100644 app/views/rsc_markdown_page/index.html.erb diff --git a/app/controllers/rsc_markdown_page_controller.rb b/app/controllers/rsc_markdown_page_controller.rb new file mode 100644 index 0000000..edf8da4 --- /dev/null +++ b/app/controllers/rsc_markdown_page_controller.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class RscMarkdownPageController < ApplicationController + include ReactOnRailsPro::Stream + + def index + @rsc_markdown_page_props = { + title: "React Server Components Demo", + author: "Demo System", + lastModified: Time.current + } + + stream_view_containing_react_components(template: "rsc_markdown_page/index") + end +end diff --git a/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.jsx b/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.jsx new file mode 100644 index 0000000..5c8ca41 --- /dev/null +++ b/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import * as style from './MarkdownViewer.module.css'; + +/** + * Lightweight shared markdown viewer component + * + * This component is deliberately lightweight - it only displays pre-processed HTML. + * No markdown libraries are imported here, keeping the bundle size minimal. + * + * Processing happens in the consuming components: + * - Server component: processes markdown server-side (heavy libs stay on server) + * - Client component: processes markdown client-side (heavy libs go to client) + * + * This pattern ensures the viewer itself has minimal bundle impact. + */ +const MarkdownViewer = ({ processedHtml, className }) => { + return ( +
+ ); +}; + +export default MarkdownViewer; diff --git a/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.module.css b/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.module.css new file mode 100644 index 0000000..c68ec3e --- /dev/null +++ b/app/javascript/src/MarkdownViewer/ror_components/MarkdownViewer.module.css @@ -0,0 +1,92 @@ +/* Lightweight markdown content styling for the shared viewer component */ +.markdownContent { + line-height: 1.6; +} + +/* Headings */ +.markdownContent h1, +.markdownContent h2, +.markdownContent h3, +.markdownContent h4, +.markdownContent h5, +.markdownContent h6 { + color: #2c3e50; + margin-top: 1.5rem; + margin-bottom: 0.5rem; +} + +.markdownContent h1 { + border-bottom: 2px solid #e67e22; + padding-bottom: 0.3rem; +} + +/* Code and pre */ +.markdownContent code { + background-color: #f1c40f; + padding: 2px 4px; + border-radius: 3px; + font-size: 0.9em; + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; +} + +.markdownContent pre { + background-color: #2c3e50; + color: #ecf0f1; + padding: 1rem; + border-radius: 4px; + overflow-x: auto; +} + +.markdownContent pre code { + background: none; + color: inherit; + padding: 0; +} + +/* Tables */ +.markdownContent table { + border-collapse: collapse; + width: 100%; + margin: 1rem 0; +} + +.markdownContent th, +.markdownContent td { + border: 1px solid #bdc3c7; + padding: 0.5rem; + text-align: left; +} + +.markdownContent th { + background-color: #ecf0f1; + font-weight: bold; +} + +/* Lists */ +.markdownContent ul li[data-task] { + list-style: none; + margin-left: -1rem; +} + +/* Blockquotes */ +.markdownContent blockquote { + border-left: 4px solid #e67e22; + margin: 1rem 0; + padding-left: 1rem; + color: #7f8c8d; +} + +/* Links */ +.markdownContent a { + color: #3498db; + text-decoration: none; +} + +.markdownContent a:hover { + text-decoration: underline; +} + +/* Paragraphs */ +.markdownContent p { + margin-bottom: 1rem; +} diff --git a/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.jsx b/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.jsx new file mode 100644 index 0000000..e019cb8 --- /dev/null +++ b/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.jsx @@ -0,0 +1,161 @@ +import React from 'react'; +import { marked } from 'marked'; +import MarkdownViewer from '../../MarkdownViewer/ror_components/MarkdownViewer'; +import * as style from './RSCMarkdownPage.module.css'; + +/** + * RSC (React Server Component) version of markdown display + * + * This component demonstrates Bob's shared component pattern: + * - Heavy markdown processing (via 'marked' library) happens server-side + * - The 'marked' library NEVER ships to the client + * - Only the processed HTML is sent to the browser + * - Uses the lightweight shared MarkdownViewer component for display + * + * Key benefits: + * - Zero client-side JavaScript for markdown processing + * - Faster initial page load + * - Smaller client bundle size + * - Server can access files, databases, etc. + */ +async function RSCMarkdownPage({ initialText, title, author, lastModified }) { + // Default markdown content + const defaultMarkdown = `# React Server Components Demo + +## What's Happening Here? + +This markdown is being **processed on the server** using the \`marked\` library. + +The heavy markdown library (\`marked\`) is imported in this server component, +which means it: +- ✅ Runs only on the server +- ✅ Never ships to the client +- ✅ Keeps the client bundle size minimal + +Compare this to the **HeavyMarkdownEditor** which processes markdown client-side +for live preview functionality. + +## Shared Component Pattern + +Both this RSC component and the HeavyMarkdownEditor use the same lightweight +\`MarkdownViewer\` component to display the processed HTML. + +\`\`\` +Server Component (RSC) Client Component (Editor) + | | + |--[imports marked] |--[imports react-markdown] + |--[processes MD] |--[processes MD] + | | + +------[MarkdownViewer]--------+ + (lightweight, no deps) +\`\`\` + +## Features Demonstrated + +### GitHub Flavored Markdown + +- [x] Task lists +- [x] Tables +- [x] Code blocks +- [ ] More features to come + +### Code Highlighting + +\`\`\`javascript +const serverComponent = async () => { + // Heavy processing on server + const html = await marked(markdown); + return ; +}; +\`\`\` + +### Tables + +| Feature | Client-Side | Server-Side (RSC) | +|---------|-------------|-------------------| +| Bundle Size | Large (~1.1MB) | Minimal (~12KB) | +| Processing | Client | Server | +| Interactivity | High | Static | +| SEO | Good (after hydration) | Excellent (immediate) | + +### Quotes + +> "React Server Components represent a paradigm shift in how we think about +> bundle splitting and server/client boundaries." - React Team + +## Try It Out! + +1. Check the network tab - notice no markdown library is downloaded +2. View page source - the HTML is already rendered +3. Compare bundle sizes: this page vs HeavyMarkdownEditor +`; + + const markdown = initialText || defaultMarkdown; + + // Server-side markdown processing using 'marked' + // This heavy library stays on the server and never ships to client + const processedHtml = await marked(markdown, { + gfm: true, // GitHub Flavored Markdown + breaks: true, + }); + + return ( +
+
+

RSC Markdown Page

+

+ Server-rendered markdown - processing happens on the server, zero client-side JS for markdown! +

+
+ +
+
+

📄 Document Info

+
+ {title && ( +
+ Title: {title} +
+ )} + {author && ( +
+ Author: {author} +
+ )} + {lastModified && ( +
+ Last Modified:{' '} + {new Date(lastModified).toLocaleDateString()} +
+ )} +
+ Rendered: Server-side (RSC) +
+
+
+ +
+

📖 Content

+
+ +
+
+
+ +
+ + ← Back to Lightweight HelloWorld + + + View Client-Side Editor → + +
+ Bundle Impact: Minimal - markdown processing stays on server! + The 'marked' library ({'>'}120KB) never ships to the client. +
+
+
+ ); +} + +export default RSCMarkdownPage; diff --git a/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.module.css b/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.module.css new file mode 100644 index 0000000..bcb4fd9 --- /dev/null +++ b/app/javascript/src/RSCMarkdownPage/ror_components/RSCMarkdownPage.module.css @@ -0,0 +1,131 @@ +.container { + padding: 1.5rem; + width: 1200px; + max-width: calc(100vw - 2rem); + margin: 0 auto; + background-color: #f8f9fa; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +.header { + text-align: center; + margin-bottom: 1.5rem; +} + +.title { + color: #2c3e50; + font-size: 1.8rem; + margin-bottom: 0.3rem; + border-bottom: 3px solid #9b59b6; + padding-bottom: 0.3rem; +} + +.subtitle { + color: #7f8c8d; + font-size: 0.95rem; + margin: 0; + background-color: #e8daef; + padding: 0.6rem; + border-radius: 4px; + border-left: 4px solid #8e44ad; +} + +.content { + display: grid; + grid-template-columns: 300px 1fr; + gap: 1rem; + margin-bottom: 1.5rem; +} + +.metadataPanel, +.markdownPanel { + background-color: #fff; + border-radius: 6px; + padding: 0.8rem; + border: 1px solid #ddd; +} + +.panelTitle { + color: #2c3e50; + font-size: 1.1rem; + margin-bottom: 0.8rem; + border-bottom: 2px solid #ecf0f1; + padding-bottom: 0.4rem; +} + +.metadata { + display: flex; + flex-direction: column; + gap: 0.8rem; +} + +.metadataItem { + font-size: 0.9rem; + color: #34495e; + padding: 0.5rem; + background-color: #f8f9fa; + border-radius: 4px; + border-left: 3px solid #9b59b6; +} + +.metadataItem strong { + color: #8e44ad; + display: block; + margin-bottom: 0.2rem; +} + +.viewerWrapper { + padding: 1rem; + background-color: #fafafa; + border: 1px solid #ecf0f1; + border-radius: 4px; + max-height: 600px; + overflow-y: auto; +} + +.navigation { + text-align: center; + padding-top: 1rem; + border-top: 2px solid #ecf0f1; + display: flex; + flex-direction: column; + gap: 0.8rem; + align-items: center; +} + +.link { + display: inline-block; + background-color: #9b59b6; + color: white; + padding: 0.75rem 1.5rem; + text-decoration: none; + border-radius: 4px; + font-weight: bold; + transition: background-color 0.3s ease, transform 0.2s ease; +} + +.link:hover { + background-color: #8e44ad; + transform: translateY(-1px); +} + +.bundleInfo { + color: #8e44ad; + font-size: 0.9rem; + background-color: #f4ecf7; + padding: 0.5rem 1rem; + border-radius: 4px; + border: 1px solid #9b59b6; + max-width: 600px; +} + +@media (max-width: 768px) { + .content { + grid-template-columns: 1fr; + } + + .container { + padding: 1rem; + } +} diff --git a/app/views/rsc_markdown_page/index.html.erb b/app/views/rsc_markdown_page/index.html.erb new file mode 100644 index 0000000..c810728 --- /dev/null +++ b/app/views/rsc_markdown_page/index.html.erb @@ -0,0 +1,3 @@ +<%= stream_react_component("RSCMarkdownPage", + props: @rsc_markdown_page_props, + id: "rsc-markdown-page-0") %> diff --git a/config/routes.rb b/config/routes.rb index 5557a3a..ea319a4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,4 +16,5 @@ root "hello_world#index" get "hello_world", to: "hello_world#index" get "heavy_markdown_editor", to: "heavy_markdown_editor#index" + get "rsc_markdown_page", to: "rsc_markdown_page#index" end diff --git a/package-lock.json b/package-lock.json index 8a26aee..6c57800 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "compression-webpack-plugin": "^9.2.0", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.2", + "marked": "^16.3.0", "mini-css-extract-plugin": "^2.9.4", "prop-types": "^15.8.1", "react": "^19.1.1", @@ -5009,6 +5010,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.3.0.tgz", + "integrity": "sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "license": "MIT", diff --git a/package.json b/package.json index b02c8d9..f018bf2 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "compression-webpack-plugin": "^9.2.0", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.2", + "marked": "^16.3.0", "mini-css-extract-plugin": "^2.9.4", "prop-types": "^15.8.1", "react": "^19.1.1", From a88a9031cf6dfe384585f2cf2faae3ccef252668 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Sun, 5 Oct 2025 22:10:22 +0300 Subject: [PATCH 04/20] feat: configure Node renderer with GitHub packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set up .gitignore to exclude .npmrc credentials - Install react-on-rails-pro-node-renderer from GitHub packages - Add client/node-renderer.js configuration file - Update Procfile.dev to run node-renderer process - Configure Node renderer in react_on_rails_pro.rb initializer This switches from local npm link to published packages, resolving dependency issues with fastify and other packages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 3 + Procfile.dev | 1 + client/node-renderer.js | 35 + config/initializers/react_on_rails_pro.rb | 9 + package-lock.json | 2085 ++++++++++++++++++++- package.json | 1 + 6 files changed, 2049 insertions(+), 85 deletions(-) create mode 100644 client/node-renderer.js diff --git a/.gitignore b/.gitignore index 4b5c88f..4e6321b 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,6 @@ yarn-debug.log* # Claude Code configuration .claude/ + +# npm credentials +.npmrc diff --git a/Procfile.dev b/Procfile.dev index 29b85f7..4092598 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -4,3 +4,4 @@ rails: bundle exec rails s -p 3000 wp-client: WEBPACK_SERVE=true bin/shakapacker-dev-server wp-server: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch wp-rsc: HMR=true RSC_BUNDLE_ONLY=yes bin/shakapacker --watch +node-renderer: RENDERER_LOG_LEVEL=debug RENDERER_PORT=3800 node client/node-renderer.js diff --git a/client/node-renderer.js b/client/node-renderer.js new file mode 100644 index 0000000..29672e4 --- /dev/null +++ b/client/node-renderer.js @@ -0,0 +1,35 @@ +const path = require('path'); + +const { reactOnRailsProNodeRenderer } = require('@shakacode-tools/react-on-rails-pro-node-renderer'); + +const { env } = process; + +const config = { + // Bundle path where webpack outputs the bundles + bundlePath: path.resolve(__dirname, '../public/packs'), + + // Listen at RENDERER_PORT env value or default port 3800 + port: env.RENDERER_PORT || 3800, + + // Log level + logLevel: env.RENDERER_LOG_LEVEL || 'info', + + // Password should match the one in config/initializers/react_on_rails_pro.rb + // In production, use ENV variable + password: env.RENDERER_PASSWORD || 'devPassword', + + // Enable support for NodeJS modules in server bundle + // Required for React Server Components + supportModules: true, + + // Additional context for VM + additionalContext: { URL, AbortController }, + + // Required to use setTimeout, setInterval, & clearTimeout during server rendering + stubTimers: false, + + // Replay console logs from async server operations + replayServerAsyncOperationLogs: true, +}; + +reactOnRailsProNodeRenderer(config); diff --git a/config/initializers/react_on_rails_pro.rb b/config/initializers/react_on_rails_pro.rb index a729d07..75a03bc 100644 --- a/config/initializers/react_on_rails_pro.rb +++ b/config/initializers/react_on_rails_pro.rb @@ -6,4 +6,13 @@ ReactOnRailsPro.configure do |config| # Enable React Server Components support config.enable_rsc_support = true + + # Use Node renderer for streaming RSC + config.server_renderer = "NodeRenderer" + + # Node renderer URL (uses localhost:3800 by default if not set) + config.renderer_url = ENV.fetch("REACT_RENDERER_URL", "http://localhost:3800") + + # Password for node renderer (should match client/node-renderer.js) + config.renderer_password = ENV.fetch("RENDERER_PASSWORD", "devPassword") end diff --git a/package-lock.json b/package-lock.json index 6c57800..fec89a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@babel/preset-env": "^7.28.3", "@babel/preset-react": "^7.27.1", "@babel/runtime": "^7.28.4", + "@shakacode-tools/react-on-rails-pro-node-renderer": "^4.0.0", "@types/babel__core": "^7.20.5", "@types/webpack": "^5.28.5", "babel-loader": "^8.4.1", @@ -1469,6 +1470,248 @@ "node": ">=10.0.0" } }, + "node_modules/@fastify/ajv-compiler": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.2.tgz", + "integrity": "sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/@fastify/busboy": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", + "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", + "license": "MIT" + }, + "node_modules/@fastify/deepmerge": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-3.1.0.tgz", + "integrity": "sha512-lCVONBQINyNhM6LLezB6+2afusgEYR4G8xenMsfe+AT+iZ7Ca6upM5Ha8UkZuYSnuMw3GWl/BiPXnLMi/gSxuQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/error": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz", + "integrity": "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.0.3.tgz", + "integrity": "sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^6.0.0" + } + }, + "node_modules/@fastify/formbody": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@fastify/formbody/-/formbody-8.0.2.tgz", + "integrity": "sha512-84v5J2KrkXzjgBpYnaNRPqwgMsmY7ZDjuj0YVuMR3NXCJRCgKEZy/taSP1wUYGn0onfxJpLyRGDLa+NMaDJtnA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-querystring": "^1.1.2", + "fastify-plugin": "^5.0.0" + } + }, + "node_modules/@fastify/forwarded": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.1.tgz", + "integrity": "sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", + "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@fastify/multipart": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-9.2.1.tgz", + "integrity": "sha512-U4221XDMfzCUtfzsyV1/PkR4MNgKI0158vUUyn/oF2Tl6RxMc+N7XYLr5fZXQiEC+Fmw5zFaTjxsTGTgtDtK+g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@fastify/deepmerge": "^3.0.0", + "@fastify/error": "^4.0.0", + "fastify-plugin": "^5.0.0", + "secure-json-parse": "^4.0.0" + } + }, + "node_modules/@fastify/proxy-addr": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.0.tgz", + "integrity": "sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/forwarded": "^3.0.0", + "ipaddr.js": "^2.1.0" + } + }, + "node_modules/@honeybadger-io/core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@honeybadger-io/core/-/core-6.7.2.tgz", + "integrity": "sha512-4+hyrFI0S/Eni2cBgO40Lqyft5hyNXjgnuh1EbeH457kty8g4YatJYuHBffmrjwLiZHgFbWXRGv7SlG+NehC5Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "json-nd": "^1.0.0", + "stacktrace-parser": "^0.1.10" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@honeybadger-io/js": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/@honeybadger-io/js/-/js-6.12.2.tgz", + "integrity": "sha512-nT8PmmGcMi8C9OVCPcevurD3810DIq49RyTWNCiWezC1lB6En4+xhMMEzMMxBVOjAVCahwh+vMhkCcjeB6aR7A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@honeybadger-io/core": "^6.7.2", + "@types/aws-lambda": "^8.10.89", + "@types/express": "^5.0.3" + }, + "bin": { + "honeybadger-checkins-sync": "scripts/check-ins-sync-bin.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@honeybadger-io/js/node_modules/@types/express": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", + "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1545,115 +1788,1027 @@ "version": "2.0.5", "license": "MIT" }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.6.1.tgz", - "integrity": "sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "anser": "^2.1.1", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "html-entities": "^2.1.0", - "schema-utils": "^4.2.0", - "source-map": "^0.7.3" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": ">=18.12" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" }, "peerDependencies": { - "@types/webpack": "5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": "^5.0.0", - "webpack-dev-server": "^4.8.0 || 5.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "1.x" + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "peer": true, "engines": { - "node": ">= 12" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.46.1.tgz", + "integrity": "sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.43.0.tgz", + "integrity": "sha512-Q57JGpH6T4dkYHo9tKXONgLtxzsh1ZEW5M9A/OwKrZFyEpLqWgjhcZ3hIuVvDlhb426iDF1f9FPToV/mi5rpeA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.36" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.16.0.tgz", + "integrity": "sha512-88+qCHZC02up8PwKHk0UQKLLqGGURzS3hFQBZC7PnGwReuoKjHXS1o29H58S+QkXJpkTr2GACbx8j6mUoGjNPA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.47.0.tgz", + "integrity": "sha512-XFWVx6k0XlU8lu6cBlCa29ONtVt6ADEjmxtyAyeF2+rifk8uBJbk1La0yIVfI0DoKURGbaEDTNelaXG9l/lNNQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.44.1.tgz", + "integrity": "sha512-RoVeMGKcNttNfXMSl6W4fsYoCAYP1vi6ZAWIGhBY+o7R9Y0afA7f9JJL0j8LHbyb0P0QhSYk+6O56OwI2k4iRQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.19.0.tgz", + "integrity": "sha512-JGwmHhBkRT2G/BYNV1aGI+bBjJu4fJUD/5/Jat0EWZa2ftrLV3YE8z84Fiij/wK32oMZ88eS8DI4ecLGZhpqsQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.43.0.tgz", + "integrity": "sha512-at8GceTtNxD1NfFKGAuwtqM41ot/TpcLh+YsGe4dhf7gvv1HW/ZWdq6nfRtS6UjIvZJOokViqLPJ3GVtZItAnQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.47.0.tgz", + "integrity": "sha512-Cc8SMf+nLqp0fi8oAnooNEfwZWFnzMiBHCGmDFYqmgjPylyLmi83b+NiTns/rKGwlErpW0AGPt0sMpkbNlzn8w==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.45.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.45.1.tgz", + "integrity": "sha512-VH6mU3YqAKTePPfUPwfq4/xr049774qWtfTuJqVHoVspCLiT3bW+fCQ1toZxt6cxRPYASoYaBsMA3CWo8B8rcw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.1.tgz", + "integrity": "sha512-ThLmzAQDs7b/tdKI3BV2+yawuF09jF111OFsovqT1Qj3D8vjwKBwhi/rDE5xethwn4tSXtZcJ9hBsVAlWFQZ7g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "0.57.1", + "@opentelemetry/semantic-conventions": "1.28.0", + "forwarded-parse": "2.1.2", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/api-logs": { + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.1.tgz", + "integrity": "sha512-I4PHczeujhQAQv6ZBzqHYEUiggZL4IdSMixtVD3EYqbdrjujE7kRfI5QohjlPoJm8BvenoW5YaTMWRrbpot6tg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.1.tgz", + "integrity": "sha512-SgHEKXoVxOjc20ZYusPG3Fh+RLIZTSa4x8QtD3NfgAUDyqdFFS9W1F2ZVbZkqDCdyMcQG02Ok4duUGLHJXHgbA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api-logs": "0.57.1", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.47.0.tgz", + "integrity": "sha512-4HqP9IBC8e7pW9p90P3q4ox0XlbLGme65YTrA3UTLvqvo4Z6b0puqZQP203YFu8m9rE/luLfaG7/xrwwqMUpJw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.7.0.tgz", + "integrity": "sha512-LB+3xiNzc034zHfCtgs4ITWhq6Xvdo8bsq7amR058jZlf2aXXDrN9SV4si4z2ya9QX4tz6r4eZJwDkXOp14/AQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.44.0.tgz", + "integrity": "sha512-SlT0+bLA0Lg3VthGje+bSZatlGHw/vwgQywx0R/5u9QC59FddTQSPJeWNw29M6f8ScORMeUOOTwihlQAn4GkJQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.47.0.tgz", + "integrity": "sha512-HFdvqf2+w8sWOuwtEXayGzdZ2vWpCKEQv5F7+2DSA74Te/Cv4rvb2E5So5/lh+ok4/RAIPuvCbCb/SHQFzMmbw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.44.0.tgz", + "integrity": "sha512-Tn7emHAlvYDFik3vGU0mdwvWJDwtITtkJ+5eT2cUquct6nIs+H8M47sqMJkCpyPe5QIBJoTOHxmc6mj9lz6zDw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.51.0.tgz", + "integrity": "sha512-cMKASxCX4aFxesoj3WK8uoQ0YUrRvnfxaO72QWI2xLu5ZtgX/QvdGBlU3Ehdond5eb74c2s1cqRQUIptBnKz1g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.0.tgz", + "integrity": "sha512-mtVv6UeaaSaWTeZtLo4cx4P5/ING2obSqfWGItIFSunQBrYROfhuVe7wdIrFUs2RH1tn2YYpAJyMaRe/bnTTIQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.0.tgz", + "integrity": "sha512-tWWyymgwYcTwZ4t8/rLDfPYbOTF3oYB8SxnYMtIQ1zEf5uDm90Ku3i6U/vhaMyfHNlIHvDhvJh+qx5Nc4Z3Acg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.26" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.45.0.tgz", + "integrity": "sha512-qLslv/EPuLj0IXFvcE3b0EqhWI8LKmrgRPIa4gUd8DllbBpqJAvLNJSv3cC6vWwovpbSI3bagNO/3Q2SuXv2xA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-nestjs-core": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.44.0.tgz", + "integrity": "sha512-t16pQ7A4WYu1yyQJZhRKIfUNvl5PAaF2pEteLvgJb/BWdd1oNuU1rOYt4S825kMy+0q4ngiX281Ss9qiwHfxFQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.50.0.tgz", + "integrity": "sha512-TtLxDdYZmBhFswm8UIsrDjh/HFBeDXd4BLmE8h2MxirNHewLJ0VS9UUddKKEverb5Sm2qFVjqRjcU+8Iw4FJ3w==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.26.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "1.27.0", + "@opentelemetry/sql-common": "^0.40.1", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz", + "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.46.0.tgz", + "integrity": "sha512-aTUWbzbFMFeRODn3720TZO0tsh/49T8H3h8vVnVKJ+yE36AeW38Uj/8zykQ/9nO8Vrtjr5yKuX3uMiG/W8FKNw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.18.0.tgz", + "integrity": "sha512-9zhjDpUDOtD+coeADnYEJQ0IeLVCj7w/hqzIutdp5NqS1VqTAanaEfsEcSypyvYv5DX3YOsTUoF+nr2wDXPETA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.10.0.tgz", + "integrity": "sha512-vm+V255NGw9gaSsPD6CP0oGo8L55BffBc8KnxqsMuc6XiAD1L8SFNzsW0RHhxJFqy9CJaJh+YiJ5EHXuZ5rZBw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", + "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.37.0.tgz", + "integrity": "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", + "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.6.1.tgz", + "integrity": "sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "anser": "^2.1.1", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "html-entities": "^2.1.0", + "schema-utils": "^4.2.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "@types/webpack": "5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": "^5.0.0", + "webpack-dev-server": "^4.8.0 || 5.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@prisma/instrumentation": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-5.22.0.tgz", + "integrity": "sha512-LxccF392NN37ISGxIurUljZSh1YWnphO34V5a0+T7FVQG2u9bhAXRTJpgmQ3483woVhkraQZFF7cbRrpbw/F4Q==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api": "^1.8", + "@opentelemetry/instrumentation": "^0.49 || ^0.50 || ^0.51 || ^0.52.0 || ^0.53.0", + "@opentelemetry/sdk-trace-base": "^1.22" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz", + "integrity": "sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.53.0.tgz", + "integrity": "sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/api-logs": "0.53.0", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@prisma/instrumentation/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.10.8", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.8.tgz", + "integrity": "sha512-f02QYEnBDE0p8cteNoPYHHjbDuwyfbe4cCIVlNi8/MRicIxFW4w4CfgU0LNgWEID6s06P+hRJ1qjpBLMhPRCiQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.1", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.2", + "tar-fs": "^3.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry-internal/tracing": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.4.tgz", + "integrity": "sha512-Fz5+4XCg3akeoFK+K7g+d7HqGMjmnLoY2eJlpONJmaeT9pXY7yfUyXKZMmMajdE2LxxKJgQ2YKvSCaGVamTjHw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@sentry/core": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry-internal/tracing/node_modules/@sentry/core": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.4.tgz", + "integrity": "sha512-TXu3Q5kKiq8db9OXGkWyXUbIxMMuttB5vJ031yolOl5T/B69JRyAoKuojLBjRv1XX583gS1rSSoX8YXX7ATFGA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/core": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.55.0.tgz", + "integrity": "sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/node": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-8.55.0.tgz", + "integrity": "sha512-h10LJLDTRAzYgay60Oy7moMookqqSZSviCWkkmHZyaDn+4WURnPp5SKhhfrzPRQcXKrweiOwDSHBgn1tweDssg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/instrumentation-amqplib": "^0.46.0", + "@opentelemetry/instrumentation-connect": "0.43.0", + "@opentelemetry/instrumentation-dataloader": "0.16.0", + "@opentelemetry/instrumentation-express": "0.47.0", + "@opentelemetry/instrumentation-fastify": "0.44.1", + "@opentelemetry/instrumentation-fs": "0.19.0", + "@opentelemetry/instrumentation-generic-pool": "0.43.0", + "@opentelemetry/instrumentation-graphql": "0.47.0", + "@opentelemetry/instrumentation-hapi": "0.45.1", + "@opentelemetry/instrumentation-http": "0.57.1", + "@opentelemetry/instrumentation-ioredis": "0.47.0", + "@opentelemetry/instrumentation-kafkajs": "0.7.0", + "@opentelemetry/instrumentation-knex": "0.44.0", + "@opentelemetry/instrumentation-koa": "0.47.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.44.0", + "@opentelemetry/instrumentation-mongodb": "0.51.0", + "@opentelemetry/instrumentation-mongoose": "0.46.0", + "@opentelemetry/instrumentation-mysql": "0.45.0", + "@opentelemetry/instrumentation-mysql2": "0.45.0", + "@opentelemetry/instrumentation-nestjs-core": "0.44.0", + "@opentelemetry/instrumentation-pg": "0.50.0", + "@opentelemetry/instrumentation-redis-4": "0.46.0", + "@opentelemetry/instrumentation-tedious": "0.18.0", + "@opentelemetry/instrumentation-undici": "0.10.0", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.28.0", + "@prisma/instrumentation": "5.22.0", + "@sentry/core": "8.55.0", + "@sentry/opentelemetry": "8.55.0", + "import-in-the-middle": "^1.11.2" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.55.0.tgz", + "integrity": "sha512-UvatdmSr3Xf+4PLBzJNLZ2JjG1yAPWGe/VrJlJAqyTJ2gKeTzgXJJw8rp4pbvNZO8NaTGEYhhO+scLUj0UtLAQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@sentry/core": "8.55.0" + }, + "engines": { + "node": ">=14.18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.28.0" } }, - "node_modules/@puppeteer/browsers": { - "version": "2.10.8", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.8.tgz", - "integrity": "sha512-f02QYEnBDE0p8cteNoPYHHjbDuwyfbe4cCIVlNi8/MRicIxFW4w4CfgU0LNgWEID6s06P+hRJ1qjpBLMhPRCiQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@sentry/tracing": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.120.4.tgz", + "integrity": "sha512-cAtpLh23qW3hoqZJ6c36EvFki5NhFWUSK71ALHefqDXEocMlfDc9I+IGn3B/ola2D2TDEDamCy3x32vctKqOag==", + "license": "MIT", + "peer": true, "dependencies": { - "debug": "^4.4.1", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.2", - "tar-fs": "^3.1.0", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@sentry-internal/tracing": "7.120.4" }, "engines": { - "node": ">=18" + "node": ">=8" } }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, + "node_modules/@sentry/types": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.4.tgz", + "integrity": "sha512-cUq2hSSe6/qrU6oZsEP4InMI5VVdD86aypE+ENrQ6eZEVLTCYm1w6XhW1NvIu3UuWh7gZec4a9J7AFpYxki88Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/utils": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.4.tgz", + "integrity": "sha512-zCKpyDIWKHwtervNK2ZlaK8mMV7gVUijAgFeJStH+CU/imcdquizV3pFLlSQYRswG+Lbyd6CT/LGRh3IbtkCFw==", "license": "MIT", + "peer": true, "dependencies": { - "ms": "^2.1.3" + "@sentry/types": "7.120.4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", + "node_modules/@shakacode-tools/react-on-rails-pro-node-renderer": { + "version": "4.0.0", + "resolved": "https://npm.pkg.github.com/download/@shakacode-tools/react-on-rails-pro-node-renderer/4.0.0/fb2d53528d82488d8ded444208bb9c7c920cd13d", + "integrity": "sha512-0hp7p+qBvM8/7vtHQ4QfPlwvmAO06R3kmvk+vmgYZnLJEoUMLuUhPwo+f/Ttiw0deeVotDkesRKm+F7Nrm10LQ==", + "hasInstallScript": true, + "license": "UNLICENSED", + "dependencies": { + "@fastify/formbody": "^7.4.0 || ^8.0.2", + "@fastify/multipart": "^8.3.1 || ^9.0.3", + "fastify": "^4.29.0 || ^5.2.1", + "fs-extra": "^11.2.0", + "lockfile": "^1.0.4" + }, "bin": { - "semver": "bin/semver.js" + "react-on-rails-pro-node-renderer": "packages/node-renderer/dist/default-node-renderer.js" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@honeybadger-io/js": ">=4.0.0", + "@sentry/node": ">=5.0.0 <9.0.0", + "@sentry/tracing": ">=5.0.0" } }, "node_modules/@sinclair/typebox": { @@ -1669,6 +2824,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/aws-lambda": { + "version": "8.10.155", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.155.tgz", + "integrity": "sha512-wd1XgoL0gy/ybo7WozUKQBd+IOgUkdfG6uUGI0fQOTEq06FBFdO7tmPDSxgjkFkl8GlfApvk5TvqZlAl0g+Lbg==", + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "license": "MIT", @@ -1867,6 +3029,16 @@ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, + "node_modules/@types/mysql": { + "version": "2.15.26", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", + "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "24.3.1", "license": "MIT", @@ -1887,6 +3059,28 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/qs": { "version": "6.14.0", "license": "MIT" @@ -1942,6 +3136,13 @@ "@types/send": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "license": "MIT", + "peer": true + }, "node_modules/@types/sockjs": { "version": "0.3.36", "license": "MIT", @@ -1949,6 +3150,16 @@ "@types/node": "*" } }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -2157,6 +3368,12 @@ "version": "4.2.2", "license": "Apache-2.0" }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, "node_modules/accepts": { "version": "1.3.8", "license": "MIT", @@ -2185,6 +3402,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-import-phases": { "version": "1.0.4", "license": "MIT", @@ -2231,6 +3458,45 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/ajv-keywords": { "version": "3.5.2", "license": "MIT", @@ -2310,6 +3576,25 @@ "node": ">=4" } }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.1.0.tgz", + "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==", + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "fastq": "^1.17.1" + } + }, "node_modules/b4a": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", @@ -2817,6 +4102,13 @@ "node": ">=8" } }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT", + "peer": true + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3932,6 +5224,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "license": "MIT" @@ -3947,6 +5245,61 @@ "version": "2.1.0", "license": "MIT" }, + "node_modules/fast-json-stringify": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.1.1.tgz", + "integrity": "sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0", + "json-schema-ref-resolver": "^3.0.0", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, "node_modules/fast-uri": { "version": "3.1.0", "funding": [ @@ -3968,6 +5321,76 @@ "node": ">= 4.9.1" } }, + "node_modules/fastify": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.6.1.tgz", + "integrity": "sha512-WjjlOciBF0K8pDUPZoGPhqhKrQJ02I8DKaDIfO51EL0kbSMwQFl85cRwhOvmSDWoukNOdTo27gLN549pLCcH7Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^4.0.0", + "@fastify/error": "^4.0.0", + "@fastify/fast-json-stringify-compiler": "^5.0.0", + "@fastify/proxy-addr": "^5.0.0", + "abstract-logging": "^2.0.1", + "avvio": "^9.0.0", + "fast-json-stringify": "^6.0.0", + "find-my-way": "^9.0.0", + "light-my-request": "^6.0.0", + "pino": "^9.0.0", + "process-warning": "^5.0.0", + "rfdc": "^1.3.1", + "secure-json-parse": "^4.0.0", + "semver": "^7.6.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastify/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "license": "Apache-2.0", @@ -4029,6 +5452,20 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-my-way": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz", + "integrity": "sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/find-up": { "version": "4.1.0", "license": "MIT", @@ -4072,6 +5509,13 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT", + "peer": true + }, "node_modules/fresh": { "version": "0.5.2", "license": "MIT", @@ -4079,6 +5523,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fs-monkey": { "version": "1.1.0", "license": "Unlicense" @@ -4547,6 +6005,19 @@ "node": ">=4" } }, + "node_modules/import-in-the-middle": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.4.tgz", + "integrity": "sha512-eWjxh735SJLFJJDs5X82JQ2405OdJeAHDBnaoFCfdr5GVc7AWc9xU7KbrF+3Xd5F2ccP1aQFKtY+65X6EfKZ7A==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.2.0", "license": "MIT", @@ -4847,10 +6318,36 @@ "node": ">=6" } }, + "node_modules/json-nd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-nd/-/json-nd-1.0.0.tgz", + "integrity": "sha512-8TIp0HZAY0VVrwRQJJPb4+nOTSPoOWZeEKBTLizUfQO4oym5Fc/MKqN8vEbLCxcyxDf2vwNxOQ1q84O49GWPyQ==", + "license": "BSD-3-Clause", + "peer": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "license": "MIT" }, + "node_modules/json-schema-ref-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", + "integrity": "sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "license": "MIT" @@ -4865,6 +6362,18 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/kind-of": { "version": "6.0.3", "license": "MIT", @@ -4880,6 +6389,52 @@ "shell-quote": "^1.8.3" } }, + "node_modules/light-my-request": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.6.0.tgz", + "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^1.0.1", + "process-warning": "^4.0.0", + "set-cookie-parser": "^2.6.0" + } + }, + "node_modules/light-my-request/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/light-my-request/node_modules/process-warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", + "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -6006,6 +7561,13 @@ "dev": true, "license": "MIT" }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT", + "peer": true + }, "node_modules/ms": { "version": "2.1.3", "license": "MIT" @@ -6123,6 +7685,15 @@ "version": "1.1.2", "license": "MIT" }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "license": "MIT", @@ -6378,6 +7949,40 @@ "dev": true, "license": "MIT" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT", + "peer": true + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "peer": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "license": "ISC" @@ -6392,6 +7997,43 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pino": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.13.1.tgz", + "integrity": "sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "slow-redact": "^0.3.0", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "license": "MIT" + }, "node_modules/pkg-dir": { "version": "4.2.0", "license": "MIT", @@ -6919,10 +8561,69 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "license": "MIT" }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -7143,6 +8844,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, "node_modules/randombytes": { "version": "2.1.0", "license": "MIT", @@ -7289,6 +8996,15 @@ "node": ">=8.10.0" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/rechoir": { "version": "0.7.1", "license": "MIT", @@ -7435,6 +9151,39 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/requires-port": { "version": "1.0.0", "license": "MIT" @@ -7474,6 +9223,15 @@ "node": ">=8" } }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/retry": { "version": "0.13.1", "license": "MIT", @@ -7481,6 +9239,22 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rimraf": { "version": "3.0.2", "license": "ISC", @@ -7512,6 +9286,34 @@ ], "license": "MIT" }, + "node_modules/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "license": "MIT" @@ -7588,6 +9390,22 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/select-hose": { "version": "2.0.0", "license": "MIT" @@ -7710,6 +9528,12 @@ "node": ">= 0.8.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "license": "ISC" @@ -7793,6 +9617,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "license": "BSD-2-Clause", + "peer": true + }, "node_modules/side-channel": { "version": "1.1.0", "license": "MIT", @@ -7861,6 +9692,12 @@ "version": "3.0.7", "license": "ISC" }, + "node_modules/slow-redact": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/slow-redact/-/slow-redact-0.3.1.tgz", + "integrity": "sha512-NvFvl1GuLZNW4U046Tfi8b26zXo8aBzgCAS2f7yVJR/fArN93mOqSA99cB9uITm92ajSz01bsu1K7SCVVjIMpQ==", + "license": "MIT" + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -7929,6 +9766,15 @@ } } }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "license": "BSD-3-Clause", @@ -8019,6 +9865,15 @@ } } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -8026,6 +9881,29 @@ "dev": true, "license": "MIT" }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "license": "MIT", + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "license": "(MIT OR CC0-1.0)", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/statuses": { "version": "2.0.1", "license": "MIT", @@ -8307,6 +10185,15 @@ "b4a": "^1.6.4" } }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/thunky": { "version": "1.1.0", "license": "MIT" @@ -8321,6 +10208,15 @@ "node": ">=8.0" } }, + "node_modules/toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "license": "MIT", @@ -8508,6 +10404,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "license": "MIT", @@ -8921,6 +10826,16 @@ } } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index f018bf2..3e182f7 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@babel/preset-env": "^7.28.3", "@babel/preset-react": "^7.27.1", "@babel/runtime": "^7.28.4", + "@shakacode-tools/react-on-rails-pro-node-renderer": "^4.0.0", "@types/babel__core": "^7.20.5", "@types/webpack": "^5.28.5", "babel-loader": "^8.4.1", From db4e465a705a83e7a2a802356387c5e3634974bf Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:49:41 +0300 Subject: [PATCH 05/20] chore: add gitignore entries for RSC bundles and audit file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ignore /ssr-generated directory containing server-side webpack bundles - Ignore RSC_CONFIG_AUDIT.md analysis file 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 4e6321b..202edd5 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,9 @@ /public/packs /public/packs-test /node_modules + +# Server-side bundles generated by webpack +/ssr-generated /yarn-error.log yarn-debug.log* .yarn-integrity @@ -52,3 +55,6 @@ yarn-debug.log* # npm credentials .npmrc + +# Audit and analysis files +RSC_CONFIG_AUDIT.md From 0c542769b548f4203e874f15d0b6bbbad983704e Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:49:56 +0300 Subject: [PATCH 06/20] feat: configure Rails for RSC bundle paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set server_bundle_output_path to "ssr-generated" - Enable enforce_private_server_bundles to prevent fallback to public/packs - Required for React on Rails Pro node renderer to locate bundles 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- config/initializers/react_on_rails.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/initializers/react_on_rails.rb b/config/initializers/react_on_rails.rb index 8b178ed..4499f4c 100644 --- a/config/initializers/react_on_rails.rb +++ b/config/initializers/react_on_rails.rb @@ -52,6 +52,12 @@ # React Server Components bundle file config.rsc_bundle_js_file = "rsc-bundle.js" + # Server bundle output directory + config.server_bundle_output_path = "ssr-generated" + + # Enforce private server bundles (prevents fallback to public/packs) + config.enforce_private_server_bundles = true + ################################################################################ ################################################################################ # FILE SYSTEM BASED COMPONENT REGISTRY From ba16eec05a07551bbfdc5a037515a6a2f3851b8a Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:50:04 +0300 Subject: [PATCH 07/20] feat: configure node renderer to use ssr-generated bundles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update bundlePath from public/packs to ssr-generated - Aligns with Rails configuration for private server bundles 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- client/node-renderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/node-renderer.js b/client/node-renderer.js index 29672e4..62ab832 100644 --- a/client/node-renderer.js +++ b/client/node-renderer.js @@ -6,7 +6,7 @@ const { env } = process; const config = { // Bundle path where webpack outputs the bundles - bundlePath: path.resolve(__dirname, '../public/packs'), + bundlePath: path.resolve(__dirname, '../ssr-generated'), // Listen at RENDERER_PORT env value or default port 3800 port: env.RENDERER_PORT || 3800, From 75a416f06aa9eb5b872438a3e5299eed610a6acb Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:50:13 +0300 Subject: [PATCH 08/20] feat: configure server webpack bundle for node renderer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enable target: 'node' for Node.js runtime compatibility - Enable libraryTarget: 'commonjs2' for module export format - Add babel-loader SSR caller flag for proper React transforms - Output to ssr-generated directory instead of public/packs - Remove publicPath as server bundles are not web-served Required for React on Rails Pro node renderer to execute server bundles. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- config/webpack/serverWebpackConfig.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/config/webpack/serverWebpackConfig.js b/config/webpack/serverWebpackConfig.js index 1ece6e9..e6dfaac 100644 --- a/config/webpack/serverWebpackConfig.js +++ b/config/webpack/serverWebpackConfig.js @@ -3,6 +3,7 @@ const { merge, config } = require('shakapacker'); const commonWebpackConfig = require('./commonWebpackConfig'); +const path = require('path'); const webpack = require('webpack'); const { RSCWebpackPlugin } = require('react-on-rails-rsc/WebpackPlugin'); @@ -50,9 +51,9 @@ const configureServer = () => { filename: 'server-bundle.js', globalObject: 'this', // If using the React on Rails Pro node server renderer, uncomment the next line - // libraryTarget: 'commonjs2', - path: config.outputPath, - publicPath: config.publicPath, + libraryTarget: 'commonjs2', + path: path.resolve(__dirname, '../../ssr-generated'), + // No publicPath needed since server bundles are not served via web // https://webpack.js.org/configuration/output/#outputglobalobject }; @@ -97,6 +98,21 @@ const configureServer = () => { cssLoader.options.modules = { exportOnlyLocals: true }; } + const babelLoader = rule.use.find((item) => { + let testValue; + + if (typeof item === 'string') { + testValue = item; + } else if (typeof item.loader === 'string') { + testValue = item.loader; + } + + return testValue.includes('babel-loader'); + }); + if (babelLoader && babelLoader.options) { + babelLoader.options.caller = { ssr: true }; + } + // Skip writing image files during SSR by setting emitFile to false } else if (rule.use && (rule.use.loader === 'url-loader' || rule.use.loader === 'file-loader')) { rule.use.options.emitFile = false; @@ -111,7 +127,7 @@ const configureServer = () => { // If using the default 'web', then libraries like Emotion and loadable-components // break with SSR. The fix is to use a node renderer and change the target. // If using the React on Rails Pro node server renderer, uncomment the next line - // serverWebpackConfig.target = 'node' + serverWebpackConfig.target = 'node'; // Add React Server Components plugin for server bundle serverWebpackConfig.plugins.push(new RSCWebpackPlugin({ isServer: true })); From b5ee8a542ff9ca47eec98f8443f1dd71c0e29b8e Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:50:25 +0300 Subject: [PATCH 09/20] feat: add react-dom/server alias to RSC webpack config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Alias react-dom/server to false in RSC bundle - Prevents runtime errors from unused server rendering imports - RSC payload generation uses react-on-rails-rsc instead 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- config/webpack/rscWebpackConfig.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/webpack/rscWebpackConfig.js b/config/webpack/rscWebpackConfig.js index bc9b9b2..48daf26 100644 --- a/config/webpack/rscWebpackConfig.js +++ b/config/webpack/rscWebpackConfig.js @@ -46,6 +46,13 @@ const configureRsc = () => { rscConfig.resolve = { ...rscConfig.resolve, conditionNames: ['react-server', '...'], + alias: { + ...rscConfig.resolve?.alias, + // Ignore import of react-dom/server in rsc bundle + // This module is not needed to generate the rsc payload, it's rendered using `react-on-rails-rsc` + // Not removing it will cause a runtime error + 'react-dom/server': false, + }, }; // Update the output bundle name to be `rsc-bundle.js` instead of `server-bundle.js` From f141a1f57a8741ab637064a203d7dc1327217fa1 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:50:36 +0300 Subject: [PATCH 10/20] fix: add "use client" directives to client components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add directive to HelloWorld for SSR registration - Add directive to HeavyMarkdownEditor for client-side rendering Auto-bundler uses "use client" to determine component registration: - WITH directive → ReactOnRails.register() (SSR/client components) - WITHOUT directive → registerServerComponent() (RSC components) Fixes component mis-registration that caused node renderer crashes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx | 2 ++ app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx index e3746ee..91540f1 100644 --- a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx +++ b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx @@ -1,3 +1,5 @@ +"use client"; + import React, { useState, useEffect } from 'react'; import * as style from './HeavyMarkdownEditor.module.css'; diff --git a/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx b/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx index d56eeb7..8f6537d 100644 --- a/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx +++ b/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx @@ -1,3 +1,5 @@ +"use client"; + import React, { useState } from 'react'; import * as style from './HelloWorld.module.css'; From 6ca187bdad5d64f7cb48368f55b74eef658b0c43 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 18:50:46 +0300 Subject: [PATCH 11/20] chore: add foreman to development dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add foreman gem for managing dev processes via bin/dev. Temporary solution until system-level foreman is installed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Gemfile | 3 +++ Gemfile.lock | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 31a6284..bed073b 100644 --- a/Gemfile +++ b/Gemfile @@ -48,6 +48,9 @@ end group :development do # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" + + # Foreman for managing dev processes (temporary - consider foreman gem or system install) + gem "foreman" end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index bc84edd..526835a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,6 +122,8 @@ GEM et-orbi (1.3.0) tzinfo execjs (2.10.0) + foreman (0.90.0) + thor (~> 1.4) fugit (1.11.2) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) @@ -399,6 +401,7 @@ DEPENDENCIES brakeman capybara debug + foreman jbuilder kamal propshaft From 562b8a9bc8f685a5d848f8f0a979542d6e2ac1ec Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 19:35:04 +0300 Subject: [PATCH 12/20] chore: switch RORP from local path to GitHub Packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace local development path with GitHub Packages source for react_on_rails_pro gem. Makes the setup portable and production-ready. Configured via bundle config (credentials not in source code). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Gemfile | 6 ++++-- Gemfile.lock | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index bed073b..1a217a3 100644 --- a/Gemfile +++ b/Gemfile @@ -61,5 +61,7 @@ end gem "shakapacker", "~> 8.3" gem "react_on_rails", "~> 16.1.1" -# Using local path for development - change to GitHub packages for production -gem "react_on_rails_pro", path: "/home/ihab/ihab/work/shakacode/react_on_rails/react_on_rails_pro" +# React on Rails Pro from GitHub Packages +source "https://rubygems.pkg.github.com/shakacode-tools" do + gem "react_on_rails_pro" +end diff --git a/Gemfile.lock b/Gemfile.lock index 526835a..2da3961 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,3 @@ -PATH - remote: /home/ihab/ihab/work/shakacode/react_on_rails/react_on_rails_pro - specs: - react_on_rails_pro (4.0.0) - addressable - connection_pool - execjs (~> 2.9) - httpx (~> 1.5) - rainbow - react_on_rails (>= 16.0.0) - GEM remote: https://rubygems.org/ specs: @@ -384,6 +373,17 @@ GEM nokogiri (~> 1.8) zeitwerk (2.7.3) +GEM + remote: https://rubygems.pkg.github.com/shakacode-tools/ + specs: + react_on_rails_pro (4.0.0) + addressable + connection_pool + execjs (~> 2.9) + httpx (~> 1.5) + rainbow + react_on_rails (>= 14.1.0) + PLATFORMS aarch64-linux aarch64-linux-gnu From 37e2df5089f8770dbe99369d406cf43927cb36fa Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 19:42:06 +0300 Subject: [PATCH 13/20] chore: remove foreman gem and cleanup gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove foreman from Gemfile (use system-installed foreman instead) - Remove RSC_CONFIG_AUDIT.md from gitignore (file untracked for reference) Keeps the branch cleaner without temporary dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 3 --- Gemfile | 3 --- Gemfile.lock | 3 --- 3 files changed, 9 deletions(-) diff --git a/.gitignore b/.gitignore index 202edd5..f7e2751 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,3 @@ yarn-debug.log* # npm credentials .npmrc - -# Audit and analysis files -RSC_CONFIG_AUDIT.md diff --git a/Gemfile b/Gemfile index 1a217a3..cd41613 100644 --- a/Gemfile +++ b/Gemfile @@ -48,9 +48,6 @@ end group :development do # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" - - # Foreman for managing dev processes (temporary - consider foreman gem or system install) - gem "foreman" end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 2da3961..c26e23d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -111,8 +111,6 @@ GEM et-orbi (1.3.0) tzinfo execjs (2.10.0) - foreman (0.90.0) - thor (~> 1.4) fugit (1.11.2) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) @@ -401,7 +399,6 @@ DEPENDENCIES brakeman capybara debug - foreman jbuilder kamal propshaft From 4a7fa09a925cc7076406395fbd0020c39391f638 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 20:26:40 +0300 Subject: [PATCH 14/20] feat: add bottom padding to layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add padding-bottom to body to prevent content from touching viewport edge, matching the existing top padding. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/views/layouts/application.html.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9457426..e278c13 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -31,6 +31,7 @@ align-items: flex-start; justify-content: center; padding-top: 2rem; + padding-bottom: 2rem; } From 40269912be4f1f240d8b4de8d10619e0e8166827 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 20:26:40 +0300 Subject: [PATCH 15/20] feat: add complete navigation between all three pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add RSC Markdown Page links to HelloWorld and HeavyMarkdownEditor - Add flexbox with gap for proper spacing between navigation buttons - Remove redundant margin-bottom in favor of gap - All three pages now have bidirectional navigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../ror_components/HeavyMarkdownEditor.jsx | 5 ++++- .../ror_components/HeavyMarkdownEditor.module.css | 5 ++++- app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx | 3 +++ .../src/HelloWorld/ror_components/HelloWorld.module.css | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx index 91540f1..52acaf8 100644 --- a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx +++ b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.jsx @@ -153,12 +153,15 @@ const HeavyMarkdownEditor = (props) => { ← Back to Lightweight HelloWorld + + → Try RSC Markdown Page +
Bundle Impact: Heavy component with markdown libraries (~120KB transferred, 385KB resources in production)
{props.title && (
- Content: {props.title} + Content: {props.title} {props.author && <> by {props.author}} {props.lastModified && <> (updated {new Date(props.lastModified).toLocaleDateString()})}
diff --git a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.module.css b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.module.css index 009418a..7e50eb0 100644 --- a/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.module.css +++ b/app/javascript/src/HeavyMarkdownEditor/ror_components/HeavyMarkdownEditor.module.css @@ -222,6 +222,10 @@ text-align: center; padding-top: 1rem; border-top: 2px solid #ecf0f1; + display: flex; + flex-direction: column; + gap: 0.8rem; + align-items: center; } .link { @@ -233,7 +237,6 @@ border-radius: 4px; font-weight: bold; transition: background-color 0.3s ease, transform 0.2s ease; - margin-bottom: 1rem; } .link:hover { diff --git a/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx b/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx index 8f6537d..a669f16 100644 --- a/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx +++ b/app/javascript/src/HelloWorld/ror_components/HelloWorld.jsx @@ -33,6 +33,9 @@ const HelloWorld = (props) => { → Try Heavy Markdown Editor + + → Try RSC Markdown Page +
Bundle Size: Minimal - just React basics (~10.0KB total in production)
diff --git a/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css b/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css index 76cc71d..a989b24 100644 --- a/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css +++ b/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css @@ -71,6 +71,10 @@ .navigation { text-align: center; + display: flex; + flex-direction: column; + gap: 0.8rem; + align-items: center; } .link { From 34648293c1ee68edce30cd2c4a871a242195c8e8 Mon Sep 17 00:00:00 2001 From: ihabadham Date: Mon, 6 Oct 2025 20:26:41 +0300 Subject: [PATCH 16/20] refactor: convert RSC component to inline styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS modules are not currently supported for React Server Components. Convert RSCMarkdownPage to use inline styles and embedded