react_on_rails 16.1.2 → 16.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/.rubocop.yml +85 -0
  4. data/Gemfile.development_dependencies +8 -7
  5. data/Gemfile.lock +158 -119
  6. data/Steepfile +56 -0
  7. data/lib/generators/react_on_rails/base_generator.rb +43 -120
  8. data/lib/generators/react_on_rails/dev_tests_generator.rb +2 -1
  9. data/lib/generators/react_on_rails/generator_helper.rb +102 -2
  10. data/lib/generators/react_on_rails/install_generator.rb +36 -156
  11. data/lib/generators/react_on_rails/js_dependency_manager.rb +383 -0
  12. data/lib/generators/react_on_rails/templates/base/base/.dev-services.yml.example +76 -0
  13. data/lib/generators/react_on_rails/templates/base/base/bin/shakapacker-precompile-hook +30 -0
  14. data/lib/generators/react_on_rails/templates/base/base/bin/switch-bundler +141 -0
  15. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +44 -45
  16. data/lib/generators/react_on_rails/templates/base/base/config/{shakapacker.yml → shakapacker.yml.tt} +28 -3
  17. data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +15 -9
  18. data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +42 -6
  19. data/lib/react_on_rails/configuration.rb +149 -32
  20. data/lib/react_on_rails/controller.rb +3 -3
  21. data/lib/react_on_rails/dev/pack_generator.rb +168 -2
  22. data/lib/react_on_rails/dev/process_manager.rb +136 -14
  23. data/lib/react_on_rails/dev/server_manager.rb +194 -26
  24. data/lib/react_on_rails/dev/service_checker.rb +200 -0
  25. data/lib/react_on_rails/doctor.rb +341 -12
  26. data/lib/react_on_rails/engine.rb +75 -1
  27. data/lib/react_on_rails/git_utils.rb +3 -1
  28. data/lib/react_on_rails/helper.rb +70 -192
  29. data/lib/react_on_rails/locales/base.rb +17 -5
  30. data/lib/react_on_rails/packer_utils.rb +79 -2
  31. data/lib/react_on_rails/packs_generator.rb +57 -39
  32. data/lib/react_on_rails/prerender_error.rb +74 -17
  33. data/lib/react_on_rails/pro_helper.rb +64 -0
  34. data/lib/react_on_rails/react_component/render_options.rb +7 -7
  35. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +2 -5
  36. data/lib/react_on_rails/smart_error.rb +326 -0
  37. data/lib/react_on_rails/system_checker.rb +8 -9
  38. data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +16 -7
  39. data/lib/react_on_rails/utils.rb +241 -55
  40. data/lib/react_on_rails/version.rb +1 -1
  41. data/lib/react_on_rails/version_checker.rb +383 -35
  42. data/lib/tasks/generate_packs.rake +12 -6
  43. data/lib/tasks/locale.rake +6 -1
  44. data/rakelib/docker.rake +26 -0
  45. data/rakelib/dummy_apps.rake +30 -0
  46. data/rakelib/example_type.rb +121 -0
  47. data/rakelib/examples_config.yml +52 -0
  48. data/rakelib/lint.rake +52 -0
  49. data/rakelib/node_package.rake +15 -0
  50. data/rakelib/rbs.rake +70 -0
  51. data/rakelib/run_rspec.rake +223 -0
  52. data/rakelib/shakapacker_examples.rake +171 -0
  53. data/rakelib/task_helpers.rb +134 -0
  54. data/rakelib/update_changelog.rake +73 -0
  55. data/react_on_rails.gemspec +4 -3
  56. data/sig/README.md +52 -0
  57. data/sig/react_on_rails/configuration.rbs +96 -0
  58. data/sig/react_on_rails/controller.rbs +15 -0
  59. data/sig/react_on_rails/dev/file_manager.rbs +15 -0
  60. data/sig/react_on_rails/dev/pack_generator.rbs +19 -0
  61. data/sig/react_on_rails/dev/process_manager.rbs +22 -0
  62. data/sig/react_on_rails/dev/server_manager.rbs +39 -0
  63. data/sig/react_on_rails/dev/service_checker.rbs +22 -0
  64. data/sig/react_on_rails/error.rbs +4 -0
  65. data/sig/react_on_rails/generators/js_dependency_manager.rbs +123 -0
  66. data/sig/react_on_rails/git_utils.rbs +8 -0
  67. data/sig/react_on_rails/helper.rbs +65 -0
  68. data/sig/react_on_rails/json_parse_error.rbs +10 -0
  69. data/sig/react_on_rails/locales.rbs +46 -0
  70. data/sig/react_on_rails/packer_utils.rbs +15 -0
  71. data/sig/react_on_rails/prerender_error.rbs +21 -0
  72. data/sig/react_on_rails/server_rendering_pool.rbs +12 -0
  73. data/sig/react_on_rails/smart_error.rbs +28 -0
  74. data/sig/react_on_rails/test_helper.rbs +11 -0
  75. data/sig/react_on_rails/utils.rbs +34 -0
  76. data/sig/react_on_rails/version_checker.rbs +12 -0
  77. data/sig/react_on_rails.rbs +17 -0
  78. metadata +49 -32
  79. data/AI_AGENT_INSTRUCTIONS.md +0 -63
  80. data/CHANGELOG.md +0 -1836
  81. data/CLAUDE.md +0 -135
  82. data/CODING_AGENTS.md +0 -313
  83. data/CONTRIBUTING.md +0 -668
  84. data/Dockerfile_tests +0 -12
  85. data/KUDOS.md +0 -114
  86. data/LICENSE.md +0 -47
  87. data/LICENSES/README.md +0 -14
  88. data/NEWS.md +0 -62
  89. data/PROJECTS.md +0 -63
  90. data/REACT-ON-RAILS-PRO-LICENSE.md +0 -129
  91. data/README.md +0 -217
  92. data/SUMMARY.md +0 -88
  93. data/TODO.md +0 -135
  94. data/bin/lefthook/check-trailing-newlines +0 -38
  95. data/bin/lefthook/get-changed-files +0 -26
  96. data/bin/lefthook/prettier-format +0 -26
  97. data/bin/lefthook/ruby-autofix +0 -26
  98. data/bin/lefthook/ruby-lint +0 -27
  99. data/docker-compose.yml +0 -11
  100. data/eslint.config.ts +0 -232
  101. data/knip.ts +0 -114
  102. data/lib/react_on_rails/pro/NOTICE +0 -21
  103. data/lib/react_on_rails/pro/helper.rb +0 -122
  104. data/lib/react_on_rails/pro/utils.rb +0 -53
  105. data/tsconfig.eslint.json +0 -6
  106. data/tsconfig.json +0 -19
data/eslint.config.ts DELETED
@@ -1,232 +0,0 @@
1
- import path from 'node:path';
2
- import { globalIgnores } from 'eslint/config';
3
- import jest from 'eslint-plugin-jest';
4
- import prettierRecommended from 'eslint-plugin-prettier/recommended';
5
- import testingLibrary from 'eslint-plugin-testing-library';
6
- import globals from 'globals';
7
- import tsEslint from 'typescript-eslint';
8
- import { includeIgnoreFile } from '@eslint/compat';
9
- import js from '@eslint/js';
10
- import { FlatCompat } from '@eslint/eslintrc';
11
-
12
- const compat = new FlatCompat({
13
- baseDirectory: __dirname,
14
- recommendedConfig: js.configs.recommended,
15
- allConfig: js.configs.all,
16
- });
17
-
18
- const config = tsEslint.config([
19
- includeIgnoreFile(path.resolve(__dirname, '.gitignore')),
20
- globalIgnores([
21
- // compiled code
22
- 'node_package/lib/',
23
- // used for tests only
24
- 'spec/react_on_rails/dummy-for-generators',
25
- // temporary and generated files
26
- 'spec/dummy/.yalc',
27
- 'spec/dummy/public',
28
- 'spec/dummy/vendor',
29
- 'spec/dummy/tmp',
30
- 'spec/dummy/app/assets/config/manifest.js',
31
- 'spec/dummy/client/app/packs/server-bundle.js',
32
- '**/*.res.js',
33
- '**/coverage',
34
- '**/assets/webpack/',
35
- '**/public/webpack/',
36
- '**/generated/',
37
- '**/app/assets/javascripts/application.js',
38
- '**/cable.js',
39
- '**/public/packs*/',
40
- '**/gen-examples/',
41
- '**/bundle/',
42
- // dependencies
43
- '**/node_modules/',
44
- // fixtures
45
- '**/fixtures/',
46
- '**/.yalc/**/*',
47
- // generator templates - exclude TypeScript templates that need tsconfig.json
48
- '**/templates/**/*.tsx',
49
- '**/templates/**/*.ts',
50
- ]),
51
- {
52
- files: ['**/*.[jt]s', '**/*.[jt]sx', '**/*.[cm][jt]s'],
53
- },
54
- js.configs.recommended,
55
- compat.extends('eslint-config-shakacode'),
56
- {
57
- languageOptions: {
58
- globals: {
59
- ...globals.browser,
60
- ...globals.node,
61
- },
62
-
63
- parserOptions: {
64
- requireConfigFile: false,
65
-
66
- babelOptions: {
67
- presets: ['@babel/preset-env', '@babel/preset-react'],
68
- },
69
- },
70
- },
71
-
72
- settings: {
73
- 'import/core-modules': ['react-redux'],
74
-
75
- 'import/resolver': {
76
- alias: [['Assets', './spec/dummy/client/app/assets']],
77
-
78
- node: {
79
- extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
80
- },
81
- },
82
- },
83
-
84
- rules: {
85
- 'no-shadow': 'off',
86
- 'no-console': 'off',
87
- 'function-paren-newline': 'off',
88
- 'object-curly-newline': 'off',
89
- 'no-restricted-syntax': ['error', 'SequenceExpression'],
90
- 'no-void': [
91
- 'error',
92
- {
93
- allowAsStatement: true,
94
- },
95
- ],
96
-
97
- 'import/extensions': [
98
- 'error',
99
- 'ignorePackages',
100
- {
101
- js: 'never',
102
- jsx: 'never',
103
- ts: 'never',
104
- tsx: 'never',
105
- },
106
- ],
107
-
108
- 'import/first': 'off',
109
- 'import/no-extraneous-dependencies': 'off',
110
- // The rule seems broken: it's reporting errors on imports in files using `export` too,
111
- // not just `module.exports`.
112
- 'import/no-import-module-exports': 'off',
113
- 'import/no-unresolved': [
114
- 'error',
115
- {
116
- ignore: ['\\.res\\.js$'],
117
- },
118
- ],
119
- 'react/destructuring-assignment': [
120
- 'error',
121
- 'always',
122
- {
123
- ignoreClassFields: true,
124
- },
125
- ],
126
- 'react/forbid-prop-types': 'off',
127
- 'react/function-component-definition': [
128
- 'error',
129
- {
130
- namedComponents: ['arrow-function', 'function-declaration'],
131
- unnamedComponents: 'arrow-function',
132
- },
133
- ],
134
- 'react/jsx-props-no-spreading': 'off',
135
- 'react/static-property-placement': 'off',
136
- 'jsx-a11y/anchor-is-valid': 'off',
137
- 'react/jsx-filename-extension': [
138
- 'error',
139
- {
140
- extensions: ['.jsx', '.tsx'],
141
- },
142
- ],
143
- },
144
- },
145
- {
146
- files: ['node_package/**/*'],
147
- rules: {
148
- 'import/extensions': ['error', 'ignorePackages'],
149
- },
150
- },
151
- {
152
- files: ['lib/generators/react_on_rails/templates/**/*'],
153
- rules: {
154
- // It doesn't use package.json from the template
155
- 'import/no-unresolved': 'off',
156
- // We have `const [name, setName] = useState(props.name)` so can't just destructure props
157
- 'react/destructuring-assignment': 'off',
158
- // React 19 doesn't need PropTypes - we're targeting modern React
159
- 'react/prop-types': 'off',
160
- },
161
- },
162
- {
163
- files: ['spec/dummy/**/*'],
164
- rules: {
165
- // The dummy app dependencies are managed separately and may not be installed
166
- 'import/no-unresolved': 'off',
167
- },
168
- },
169
- {
170
- files: ['**/*.ts{x,}', '**/*.[cm]ts'],
171
-
172
- extends: tsEslint.configs.strictTypeChecked,
173
-
174
- languageOptions: {
175
- parserOptions: {
176
- projectService: {
177
- allowDefaultProject: ['eslint.config.ts', 'knip.ts', 'node_package/tests/*.test.{ts,tsx}'],
178
- // Needed because `import * as ... from` instead of `import ... from` doesn't work in this file
179
- // for some imports.
180
- defaultProject: 'tsconfig.eslint.json',
181
- },
182
- },
183
- },
184
-
185
- rules: {
186
- '@typescript-eslint/no-namespace': 'off',
187
- '@typescript-eslint/no-shadow': 'error',
188
- '@typescript-eslint/no-confusing-void-expression': [
189
- 'error',
190
- {
191
- ignoreArrowShorthand: true,
192
- },
193
- ],
194
- // Too many false positives
195
- '@typescript-eslint/no-unnecessary-condition': 'off',
196
- '@typescript-eslint/no-unused-vars': [
197
- 'error',
198
- {
199
- caughtErrorsIgnorePattern: '^_',
200
- },
201
- ],
202
- '@typescript-eslint/restrict-template-expressions': 'off',
203
- },
204
- },
205
- {
206
- files: ['**/app-react16/**/*'],
207
- rules: {
208
- 'react/no-deprecated': 'off',
209
- },
210
- },
211
- {
212
- files: ['node_package/tests/**', '**/*.test.{js,jsx,ts,tsx}'],
213
-
214
- extends: [
215
- jest.configs['flat/recommended'],
216
- jest.configs['flat/style'],
217
- testingLibrary.configs['flat/dom'],
218
- ],
219
-
220
- rules: {
221
- // Allows Jest mocks before import
222
- 'import/first': 'off',
223
- // Avoiding these methods complicates tests and isn't useful for our purposes
224
- 'testing-library/no-node-access': 'off',
225
- },
226
- },
227
- // must be the last config in the array
228
- // https://github.com/prettier/eslint-plugin-prettier?tab=readme-ov-file#configuration-new-eslintconfigjs
229
- prettierRecommended,
230
- ]);
231
-
232
- export default config;
data/knip.ts DELETED
@@ -1,114 +0,0 @@
1
- import type { KnipConfig } from 'knip';
2
-
3
- const config: KnipConfig = {
4
- // ! at the end means files are used in production
5
- workspaces: {
6
- '.': {
7
- entry: [
8
- 'node_package/src/ReactOnRails.node.ts!',
9
- 'node_package/src/pro/ReactOnRailsRSC.ts!',
10
- 'node_package/src/pro/registerServerComponent/client.tsx!',
11
- 'node_package/src/pro/registerServerComponent/server.tsx!',
12
- 'node_package/src/pro/registerServerComponent/server.rsc.ts!',
13
- 'node_package/src/pro/wrapServerComponentRenderer/server.tsx!',
14
- 'node_package/src/pro/wrapServerComponentRenderer/server.rsc.tsx!',
15
- 'node_package/src/pro/RSCRoute.tsx!',
16
- 'node_package/src/pro/ServerComponentFetchError.ts!',
17
- 'node_package/src/pro/getReactServerComponent.server.ts!',
18
- 'node_package/src/pro/transformRSCNodeStream.ts!',
19
- 'node_package/src/loadJsonFile.ts!',
20
- 'eslint.config.ts',
21
- ],
22
- project: ['node_package/src/**/*.[jt]s{x,}!', 'node_package/tests/**/*.[jt]s{x,}'],
23
- babel: {
24
- config: ['node_package/babel.config.js'],
25
- },
26
- ignore: [
27
- 'node_package/tests/emptyForTesting.js',
28
- // Pro features exported for external consumption
29
- 'node_package/src/pro/streamServerRenderedReactComponent.ts:transformRenderStreamChunksToResultObject',
30
- 'node_package/src/pro/streamServerRenderedReactComponent.ts:streamServerRenderedComponent',
31
- 'node_package/src/pro/ServerComponentFetchError.ts:isServerComponentFetchError',
32
- 'node_package/src/pro/RSCRoute.tsx:RSCRouteProps',
33
- 'node_package/src/pro/streamServerRenderedReactComponent.ts:StreamingTrackers',
34
- ],
35
- ignoreBinaries: [
36
- // Knip fails to detect it's declared in devDependencies
37
- 'nps',
38
- // local scripts
39
- 'node_package/scripts/.*',
40
- ],
41
- ignoreDependencies: [
42
- // Required for TypeScript compilation, but we don't depend on Turbolinks itself.
43
- '@types/turbolinks',
44
- // The Knip ESLint plugin fails to detect these are transitively required by a config,
45
- // though we don't actually use its rules anywhere.
46
- '@babel/eslint-parser',
47
- '@babel/preset-react',
48
- 'eslint-config-shakacode',
49
- 'eslint-import-resolver-alias',
50
- 'eslint-plugin-import',
51
- 'eslint-plugin-jsx-a11y',
52
- 'eslint-plugin-react',
53
- 'eslint-plugin-react-hooks',
54
- // These are used as transitive dependencies and missing from package.json
55
- '@eslint/eslintrc',
56
- '@eslint/js',
57
- // used by Jest
58
- 'jsdom',
59
- // This is an optional peer dependency because users without RSC don't need it
60
- // but Knip doesn't like such dependencies to be referenced directly in code
61
- 'react-on-rails-rsc',
62
- ],
63
- },
64
- 'spec/dummy': {
65
- entry: [
66
- 'app/assets/config/manifest.js!',
67
- 'client/app/packs/**/*.js!',
68
- // Not sure why this isn't detected as a dependency of client/app/packs/server-bundle.js
69
- 'client/app/generated/server-bundle-generated.js!',
70
- 'spec/fixtures/automated_packs_generation/**/*.js{x,}',
71
- 'config/webpack/{production,development,test}.js',
72
- // Declaring this as webpack.config instead doesn't work correctly
73
- 'config/webpack/webpack.config.js',
74
- ],
75
- ignore: ['**/app-react16/**/*'],
76
- project: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}!', 'config/webpack/*.js'],
77
- paths: {
78
- 'Assets/*': ['client/app/assets/*'],
79
- },
80
- ignoreBinaries: [
81
- // Has to be installed globally
82
- 'yalc',
83
- // Local binaries
84
- 'bin/.*',
85
- ],
86
- ignoreDependencies: [
87
- // Knip thinks it can be a devDependency, but it's supposed to be in dependencies.
88
- '@babel/runtime',
89
- // There's no ReScript plugin for Knip
90
- '@rescript/react',
91
- // The Babel plugin fails to detect it
92
- 'babel-plugin-transform-react-remove-prop-types',
93
- // This one is weird. It's long-deprecated and shouldn't be necessary.
94
- // Probably need to update the Webpack config.
95
- 'node-libs-browser',
96
- // The below dependencies are not detected by the Webpack plugin
97
- // due to the config issue.
98
- 'css-loader',
99
- 'expose-loader',
100
- 'file-loader',
101
- 'imports-loader',
102
- 'mini-css-extract-plugin',
103
- 'null-loader',
104
- 'sass',
105
- 'sass-loader',
106
- 'sass-resources-loader',
107
- 'style-loader',
108
- 'url-loader',
109
- ],
110
- },
111
- },
112
- };
113
-
114
- export default config;
@@ -1,21 +0,0 @@
1
- # React on Rails Pro License
2
-
3
- The files in this directory and its subdirectories are licensed under the **React on Rails Pro** license, which is separate from the MIT license that covers the core React on Rails functionality.
4
-
5
- ## License Terms
6
-
7
- These files are proprietary software and are **NOT** covered by the MIT license found in the root LICENSE.md file. Usage requires a valid React on Rails Pro license.
8
-
9
- ## Distribution
10
-
11
- Files in this directory will be **omitted** from future distributions of the open source React on Rails Ruby gem. They are exclusively available to React on Rails Pro licensees.
12
-
13
- ## License Reference
14
-
15
- For the complete React on Rails Pro license terms, see: `REACT-ON-RAILS-PRO-LICENSE.md` in the root directory of this repository.
16
-
17
- ## More Information
18
-
19
- For React on Rails Pro licensing information and to obtain a license, please visit:
20
- - [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/)
21
- - Contact: [react_on_rails@shakacode.com](mailto:react_on_rails@shakacode.com)
@@ -1,122 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # /*
4
- # * Copyright (c) 2025 Shakacode LLC
5
- # *
6
- # * This file is NOT licensed under the MIT (open source) license.
7
- # * It is part of the React on Rails Pro offering and is licensed separately.
8
- # *
9
- # * Unauthorized copying, modification, distribution, or use of this file,
10
- # * via any medium, is strictly prohibited without a valid license agreement
11
- # * from Shakacode LLC.
12
- # *
13
- # * For licensing terms, please see:
14
- # * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
15
- # */
16
-
17
- module ReactOnRails
18
- module Pro
19
- module Helper
20
- IMMEDIATE_HYDRATION_PRO_WARNING = "[REACT ON RAILS] The 'immediate_hydration' feature requires a " \
21
- "React on Rails Pro license. " \
22
- "Please visit https://shakacode.com/react-on-rails-pro to learn more."
23
-
24
- # Generates the complete component specification script tag.
25
- # Handles both immediate hydration (Pro feature) and standard cases.
26
- def generate_component_script(render_options)
27
- # Setup the page_loaded_js, which is the same regardless of prerendering or not!
28
- # The reason is that React is smart about not doing extra work if the server rendering did its job.
29
- component_specification_tag = content_tag(:script,
30
- json_safe_and_pretty(render_options.client_props).html_safe,
31
- type: "application/json",
32
- class: "js-react-on-rails-component",
33
- id: "js-react-on-rails-component-#{render_options.dom_id}",
34
- "data-component-name" => render_options.react_component_name,
35
- "data-trace" => (render_options.trace ? true : nil),
36
- "data-dom-id" => render_options.dom_id,
37
- "data-store-dependencies" =>
38
- render_options.store_dependencies&.to_json,
39
- "data-immediate-hydration" =>
40
- (render_options.immediate_hydration ? true : nil))
41
-
42
- # Add immediate invocation script if immediate hydration is enabled
43
- spec_tag = if render_options.immediate_hydration
44
- # Escape dom_id for JavaScript context
45
- escaped_dom_id = escape_javascript(render_options.dom_id)
46
- immediate_script = content_tag(:script, %(
47
- typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsComponentLoaded('#{escaped_dom_id}');
48
- ).html_safe)
49
- "#{component_specification_tag}\n#{immediate_script}"
50
- else
51
- component_specification_tag
52
- end
53
-
54
- pro_warning_badge = pro_warning_badge_if_needed(render_options.explicitly_disabled_pro_options)
55
- "#{pro_warning_badge}\n#{spec_tag}".html_safe
56
- end
57
-
58
- # Generates the complete store hydration script tag.
59
- # Handles both immediate hydration (Pro feature) and standard cases.
60
- def generate_store_script(redux_store_data)
61
- pro_options_check_result = ReactOnRails::Pro::Utils.disable_pro_render_options_if_not_licensed(redux_store_data)
62
- redux_store_data = pro_options_check_result[:raw_options]
63
- explicitly_disabled_pro_options = pro_options_check_result[:explicitly_disabled_pro_options]
64
-
65
- store_hydration_data = content_tag(:script,
66
- json_safe_and_pretty(redux_store_data[:props]).html_safe,
67
- type: "application/json",
68
- "data-js-react-on-rails-store" => redux_store_data[:store_name].html_safe,
69
- "data-immediate-hydration" =>
70
- (redux_store_data[:immediate_hydration] ? true : nil))
71
-
72
- # Add immediate invocation script if immediate hydration is enabled and Pro license is valid
73
- store_hydration_scripts = if redux_store_data[:immediate_hydration]
74
- # Escape store_name for JavaScript context
75
- escaped_store_name = escape_javascript(redux_store_data[:store_name])
76
- immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe
77
- typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}');
78
- JS
79
- )
80
- "#{store_hydration_data}\n#{immediate_script}"
81
- else
82
- store_hydration_data
83
- end
84
-
85
- pro_warning_badge = pro_warning_badge_if_needed(explicitly_disabled_pro_options)
86
- "#{pro_warning_badge}\n#{store_hydration_scripts}".html_safe
87
- end
88
-
89
- def pro_warning_badge_if_needed(explicitly_disabled_pro_options)
90
- return "" unless explicitly_disabled_pro_options.any?
91
-
92
- disabled_features_message = disabled_pro_features_message(explicitly_disabled_pro_options)
93
- warning_message = "[REACT ON RAILS] #{disabled_features_message}\n" \
94
- "Please visit https://shakacode.com/react-on-rails-pro to learn more."
95
- puts warning_message
96
- Rails.logger.warn warning_message
97
-
98
- tooltip_text = "#{disabled_features_message} Click to learn more."
99
-
100
- <<~HTML.strip
101
- <a href="https://shakacode.com/react-on-rails-pro" target="_blank" rel="noopener noreferrer" title="#{tooltip_text}">
102
- <div style="position: fixed; top: 0; right: 0; width: 180px; height: 180px; overflow: hidden; z-index: 9999; pointer-events: none;">
103
- <div style="position: absolute; top: 50px; right: -40px; transform: rotate(45deg); background-color: rgba(220, 53, 69, 0.85); color: white; padding: 7px 40px; text-align: center; font-weight: bold; font-family: sans-serif; font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); pointer-events: auto;">
104
- React On Rails Pro Required
105
- </div>
106
- </div>
107
- </a>
108
- HTML
109
- end
110
-
111
- def disabled_pro_features_message(explicitly_disabled_pro_options)
112
- return "".html_safe unless explicitly_disabled_pro_options.any?
113
-
114
- feature_list = explicitly_disabled_pro_options.join(", ")
115
- feature_word = explicitly_disabled_pro_options.size == 1 ? "feature" : "features"
116
- "The '#{feature_list}' #{feature_word} " \
117
- "#{explicitly_disabled_pro_options.size == 1 ? 'requires' : 'require'} a " \
118
- "React on Rails Pro license. "
119
- end
120
- end
121
- end
122
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # /*
4
- # * Copyright (c) 2025 Shakacode LLC
5
- # *
6
- # * This file is NOT licensed under the MIT (open source) license.
7
- # * It is part of the React on Rails Pro offering and is licensed separately.
8
- # *
9
- # * Unauthorized copying, modification, distribution, or use of this file,
10
- # * via any medium, is strictly prohibited without a valid license agreement
11
- # * from Shakacode LLC.
12
- # *
13
- # * For licensing terms, please see:
14
- # * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
15
- # */
16
-
17
- module ReactOnRails
18
- module Pro
19
- module Utils
20
- PRO_ONLY_OPTIONS = %i[immediate_hydration].freeze
21
-
22
- # Checks if React on Rails Pro features are available
23
- # @return [Boolean] true if Pro license is valid, false otherwise
24
- def self.support_pro_features?
25
- ReactOnRails::Utils.react_on_rails_pro_licence_valid?
26
- end
27
-
28
- def self.disable_pro_render_options_if_not_licensed(raw_options)
29
- if support_pro_features?
30
- return {
31
- raw_options: raw_options,
32
- explicitly_disabled_pro_options: []
33
- }
34
- end
35
-
36
- raw_options_after_disable = raw_options.dup
37
-
38
- explicitly_disabled_pro_options = PRO_ONLY_OPTIONS.select do |option|
39
- # Use global configuration if it's not overridden in the options
40
- next ReactOnRails.configuration.send(option) if raw_options[option].nil?
41
-
42
- raw_options[option]
43
- end
44
- explicitly_disabled_pro_options.each { |option| raw_options_after_disable[option] = false }
45
-
46
- {
47
- raw_options: raw_options_after_disable,
48
- explicitly_disabled_pro_options: explicitly_disabled_pro_options
49
- }
50
- end
51
- end
52
- end
53
- end
data/tsconfig.eslint.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "allowSyntheticDefaultImports": true
5
- }
6
- }
data/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "extends": "@tsconfig/node14",
3
- "compilerOptions": {
4
- "allowJs": true,
5
- "esModuleInterop": false,
6
- // needed for Jest tests even though we don't use .tsx
7
- "jsx": "react-jsx",
8
- "lib": ["dom", "es2020"],
9
- "noImplicitAny": true,
10
- "outDir": "node_package/lib",
11
- "allowImportingTsExtensions": true,
12
- "rewriteRelativeImportExtensions": true,
13
- "strict": true,
14
- "incremental": true,
15
- "target": "es2020",
16
- "typeRoots": ["./node_modules/@types", "./node_package/types"]
17
- },
18
- "include": ["node_package/src/**/*", "node_package/types/**/*"]
19
- }