From 3b5ad234d9dffd868e2ac6b3a68ae13e351bda9d Mon Sep 17 00:00:00 2001 From: malachirwin Date: Fri, 28 Apr 2023 22:45:48 -0400 Subject: [PATCH 01/49] add lightning-cad install generator --- lib/generators/lightning_cad/USAGE | 8 + .../lightning_cad/install_generator.rb | 178 ++++++++++++++++++ .../lightning_cad/templates/.eslintrc.js | 123 ++++++++++++ .../lightning_cad/templates/Procfile.dev | 2 + .../app/controllers/editor_controller.rb | 4 + .../app/javascript/components/App.jsx | 88 +++++++++ .../components/LocalIconFactory.jsx | 56 ++++++ .../javascript/components/MaterialIcon.jsx | 26 +++ .../config/initializers/smartJSON.js | 40 ++++ .../controllers/react_controller.js | 22 +++ .../app/views/editor/editor.html.slim | 2 + .../lightning_cad/templates/babel.config.cjs | 7 + .../lightning_cad/templates/bin/dev | 9 + .../lightning_cad/templates/jest.config.js | 17 ++ .../templates/lib/tasks/javascript_tests.rake | 7 + .../spec/javascript/components/.eslintrc.js | 5 + .../spec/javascript/components/AppSpec.jsx | 9 + .../spec/javascript/components/TestSetup.js | 10 + .../components/__mocks__/FilePathMock.js | 2 + .../components/support/matchMedia.js | 13 ++ .../spec/javascript/helpers/initializers.js | 18 ++ .../spec/javascript/shared/.eslintrc.js | 5 + .../spec/javascript/shared/TestSetup.js | 11 ++ .../spec/javascript/shared/testSpec.js | 5 + .../templates/spec/support/jasmine.json | 9 + .../lightning_cad/templates/webpack.config.js | 146 ++++++++++++++ 26 files changed, 822 insertions(+) create mode 100644 lib/generators/lightning_cad/USAGE create mode 100644 lib/generators/lightning_cad/install_generator.rb create mode 100644 lib/generators/lightning_cad/templates/.eslintrc.js create mode 100644 lib/generators/lightning_cad/templates/Procfile.dev create mode 100644 lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb create mode 100644 lib/generators/lightning_cad/templates/app/javascript/components/App.jsx create mode 100644 lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx create mode 100644 lib/generators/lightning_cad/templates/app/javascript/components/MaterialIcon.jsx create mode 100644 lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js create mode 100644 lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js create mode 100644 lib/generators/lightning_cad/templates/app/views/editor/editor.html.slim create mode 100644 lib/generators/lightning_cad/templates/babel.config.cjs create mode 100644 lib/generators/lightning_cad/templates/bin/dev create mode 100644 lib/generators/lightning_cad/templates/jest.config.js create mode 100644 lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/shared/testSpec.js create mode 100644 lib/generators/lightning_cad/templates/spec/support/jasmine.json create mode 100644 lib/generators/lightning_cad/templates/webpack.config.js diff --git a/lib/generators/lightning_cad/USAGE b/lib/generators/lightning_cad/USAGE new file mode 100644 index 00000000..f0bda794 --- /dev/null +++ b/lib/generators/lightning_cad/USAGE @@ -0,0 +1,8 @@ +Description: + Explain the generator + +Example: + bin/rails generate lightning-cad:install Thing + + This will create: + what/will/it/create diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb new file mode 100644 index 00000000..70412b52 --- /dev/null +++ b/lib/generators/lightning_cad/install_generator.rb @@ -0,0 +1,178 @@ +require 'rails' + +module LightningCad + module Generators + class InstallGenerator < ::Rails::Generators::Base + source_root File.expand_path('./templates', __dir__) + + def install_lightning_cad + say 'Adding lightning-cad dependency' + run('yarn add git+ssh://git@github.com/RoleModel/lightning-cad.git#master') + end + + def install_yarn_dependencies + say 'Adding additional javascript dependencies' + + dependencies = %w[ + @honeybadger-io/js@5.3.0 + @honeybadger-io/webpack@^1.2.0 + @babel/preset-env@7.21.4 + @babel/preset-react@7.18.6 + @babel/plugin-syntax-jsx@7.21.4 + @babel/core@7.21.4 + mobx-react@^6.1.5 + mobx-utils@^5.5.2 + mobx@^5.15.2 + glob@^10.2.2 + react@16.9.0 + react-dom@16.9.0 + import-glob@1.5.0 + react-router-dom@^5.0.1 + react-popper@^1.3.7 + @hotwired/turbo-rails@7.3.0 + @hotwired/stimulus@3.2.1 + ] + run("yarn add #{dependencies.join(" ")}") + end + + def install_yarn_dev_dependencies + say 'Adding javascript devDependencies' + + dev_dependencies = %w[ + @testing-library/jest-dom@^5.16.5 + @testing-library/react@^12.1.2 + @testing-library/user-event@^13.1.8 + eslint@^6.8.0 + fetch-mock@^9.11.0 + jasmine@^4.6.0 + jest@^29.5.0 + babel-jest@^29.5.0 + ] + run("yarn add --dev #{dev_dependencies.join(" ")}") + end + + def install_yarn_optional_dependencies + say 'Adding optional dependencies' + say "THREE.js packages are not required if this project does not implement 3D views" + run("yarn add --optional three@^0.144.0") + end + + def remove_importmaps_and_unused_js + remove_file 'config/importmap.rb' + gsub_file 'app/views/layouts/application.html.erb', '<%= javascript_importmap_tags %>', "<%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>" + + hello_controller = "\nimport HelloController from './hello_controller.js'\napplication.register('hello', HelloController)\n" + gsub_file 'app/javascript/controllers/index.js', hello_controller, '' + + remove_file 'app/javascript/packs/hello_react.jsx' + remove_file 'app/javascript/controllers/hello_controller.js' + end + + def add_yarn_tasks + say 'Adding package.json test scripts' + + yarn_scripts = <<-'JS' + "test": "bundle exec rake javascript_tests", + "test_view": "NODE_ENV=test yarn node --experimental-vm-modules $(yarn bin jest --watch)", + "test_view_ci": "NODE_ENV=test yarn node --experimental-vm-modules $(yarn bin jest)", + "test_shared": "NODE_ENV=test NODE_PATH=\"./node_modules:./app/javascript:$NODE_PATH\" jasmine", + "build": "webpack --config webpack.config.js", + JS + inject_into_file 'package.json', yarn_scripts, before: " \"eslint\": \"eslint" + end + + def add_jest_config + say 'Adding jest config' + copy_file 'jest.config.js', 'jest.config.js' + end + + def add_webpack_config + say 'Adding webpack config' + copy_file 'webpack.config.js', 'webpack.config.js' + + build_files = <<-TEXT + /app/assets/builds/* + !/app/assets/builds/.keep + TEXT + append_to_file '.gitignore', build_files + end + + def setup_javascript_specs + say "Set up jest/jasmine environment and basic test harness" + + copy_file 'lib/tasks/javascript_tests.rake', 'lib/tasks/javascript_tests.rake' + + copy_file 'spec/javascript/components/.eslintrc.js', 'spec/javascript/components/.eslintrc.js' + copy_file 'spec/javascript/components/TestSetup.js', 'spec/javascript/components/TestSetup.js' + copy_file 'spec/javascript/components/__mocks__/FilePathMock.js', 'spec/javascript/components/__mocks__/FilePathMock.js' + copy_file 'spec/javascript/components/support/matchMedia.js', 'spec/javascript/components/support/matchMedia.js' + copy_file 'babel.config.cjs', 'babel.config.cjs' + + copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' + copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' + + copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' + + copy_file 'spec/support/jasmine.json', 'spec/support/jasmine.json' + end + + def create_basic_app + say "Creating React App Component" + copy_file 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js' + copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' + copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' + copy_file 'app/javascript/components/App.jsx', 'app/javascript/components/App.jsx' + copy_file 'spec/javascript/components/AppSpec.jsx', 'spec/javascript/components/AppSpec.jsx' + end + + def add_stylesheets + stylesheets = <<-CSS + @import '@rolemodel/lightning-cad/drawing-editor-react/stylesheets/MultiPerspectiveProjectEditorView.scss'; + + .canvas-area { + height: calc(100vh - $header-height); + } + + body, html { + margin: 0 + } + CSS + + append_to_file 'app/assets/stylesheets/application.scss', stylesheets + end + + def global_configuration + copy_file '.eslintrc.js', '.eslintrc.js' + end + + def create_controller + say "Creating Rails controller and view" + copy_file 'app/controllers/editor_controller.rb', 'app/controllers/editor_controller.rb' + copy_file 'app/views/editor/editor.html.slim', 'app/views/editor/editor.html.slim' + route "get '/editor/*all', to: 'editor#editor'" + route "get :editor, to: 'editor#editor'" + end + + def add_javascript_initializers + say "Adding JavaScript initializers" + initializer_setup = <<~JS + import './config/initializers/**/*.js' + JS + append_to_file 'app/javascript/application.js', initializer_setup + copy_file 'app/javascript/config/initializers/smartJSON.js', 'app/javascript/config/initializers/smartJSON.js' + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' + # To prevent smartJSON from throwing an error + run 'mkdir app/javascript/shared' + run 'mkdir app/javascript/shared/domain-models' + run 'touch app/javascript/shared/domain-models/.keep' + end + + def add_dev_startup_command + say "Adding bin/dev for starting the application" + copy_file 'Procfile.dev', 'Procfile.dev' + copy_file 'bin/dev', 'bin/dev' + run 'chmod +x bin/dev' + end + end + end +end diff --git a/lib/generators/lightning_cad/templates/.eslintrc.js b/lib/generators/lightning_cad/templates/.eslintrc.js new file mode 100644 index 00000000..f0f5e0a8 --- /dev/null +++ b/lib/generators/lightning_cad/templates/.eslintrc.js @@ -0,0 +1,123 @@ +export default { + root: true, + env: { + browser: true, + node: true, + es6: true, + }, + plugins: ["react"], + extends: ["eslint:recommended", "plugin:react/recommended"], + parser: "babel-eslint", + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 2017, + }, + rules: { + "accessor-pairs": "warn", + "arrow-body-style": "warn", + "arrow-parens": ["warn", "as-needed"], + "arrow-spacing": "warn", + "comma-dangle": ["warn", "only-multiline"], + "comma-style": ["warn", "last"], + "computed-property-spacing": ["warn", "never"], + "consistent-this": "warn", + curly: ["warn", "multi-line"], + "default-case": "warn", + "dot-location": ["warn", "property"], + eqeqeq: "warn", + "generator-star-spacing": "warn", + "id-blacklist": "warn", + "id-match": "warn", + "jsx-quotes": "warn", + "linebreak-style": ["warn", "unix"], + "max-nested-callbacks": "warn", + "no-array-constructor": "warn", + "no-caller": "warn", + "no-catch-shadow": "warn", + "no-console": "off", + "no-continue": "warn", + "no-div-regex": "warn", + "no-duplicate-imports": "warn", + "no-extra-label": "warn", + "no-extra-semi": "warn", + "no-floating-decimal": "warn", + "no-implicit-coercion": [ + "warn", + { + boolean: false, + number: false, + string: false, + }, + ], + "no-implied-eval": "warn", + "no-inner-declarations": ["warn", "functions"], + "no-invalid-this": "warn", + "no-iterator": "warn", + "no-label-var": "warn", + "no-labels": "warn", + "no-lone-blocks": "warn", + "no-mixed-requires": "warn", + "no-mixed-spaces-and-tabs": "warn", + "no-multi-str": "warn", + "no-new": "warn", + "no-new-func": "warn", + "no-new-object": "warn", + "no-new-require": "warn", + "no-new-wrappers": "warn", + "no-octal-escape": "warn", + "no-process-exit": "warn", + "no-proto": "warn", + "no-redeclare": "warn", + "no-restricted-globals": "warn", + "no-restricted-imports": "warn", + "no-restricted-modules": "warn", + "no-restricted-syntax": "warn", + "no-script-url": "warn", + "no-self-compare": "warn", + "no-shadow-restricted-names": "warn", + "no-spaced-func": "warn", + "no-undef": "warn", + "no-undef-init": "warn", + "no-unexpected-multiline": "warn", + "no-unmodified-loop-condition": "warn", + "no-unneeded-ternary": [ + "warn", + { + defaultAssignment: true, + }, + ], + "no-unreachable": "warn", + "no-unused-vars": [ + "warn", + { + argsIgnorePattern: "^_", // Allow unused arguments starting with an underscore + varsIgnorePattern: "^_", // Allow unused variables starting with an underscore + }, + ], + "no-useless-call": "warn", + "no-useless-concat": "warn", + "no-useless-constructor": "warn", + "no-useless-escape": "warn", + "no-var": "warn", + "no-void": "warn", + "no-whitespace-before-property": "warn", + "no-with": "warn", + "prefer-arrow-callback": "warn", + "prefer-const": "warn", + "prefer-template": "warn", + "require-yield": "warn", + semi: ["warn", "never"], + "sort-imports": "warn", + "template-curly-spacing": "warn", + "wrap-regex": "warn", + "yield-star-spacing": "warn", + yoda: ["warn", "never"], + }, + settings: { + react: { + version: "16.6.0", + }, + }, +}; diff --git a/lib/generators/lightning_cad/templates/Procfile.dev b/lib/generators/lightning_cad/templates/Procfile.dev new file mode 100644 index 00000000..03c54b1d --- /dev/null +++ b/lib/generators/lightning_cad/templates/Procfile.dev @@ -0,0 +1,2 @@ +web: bin/rails server -p 3000 +js: yarn build --watch diff --git a/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb new file mode 100644 index 00000000..37a649b7 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb @@ -0,0 +1,4 @@ +class EditorController < ApplicationController + def editor + end +end diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx new file mode 100644 index 00000000..24797955 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx @@ -0,0 +1,88 @@ +// Run this example by adding <%= javascript_pack_tag 'hello_react' %> to the head of your layout file, +// like app/views/layouts/application.html.erb. All it does is render
App React
at the bottom +// of the page. + +import React from 'react' +import { createBrowserHistory } from 'history' +import PropTypes from 'prop-types' + +import { + Icon, + IconFactoryContext, + MultiPerspectiveProjectEditorView, +} from '@rolemodel/lightning-cad/drawing-editor-react/index.js' +import { Router } from 'react-router-dom' +import LocalIconFactory from './LocalIconFactory.jsx' + +import { + DrawingEditor, + VersionedProject, + Project +} from '@rolemodel/lightning-cad/drawing-editor/index.js' + +export default class App extends React.Component { + static propTypes = { + basePath: PropTypes.string, + backPath: PropTypes.string + } + + static defaultProps = { + basePath: '/', + backPath: '/' + } + + constructor(props) { + super(props) + this._modalRoot = document.getElementById('modal_root') || document.createElement('div') + + this._project = new VersionedProject(new Project()) + + this._drawingEditors = { top: new DrawingEditor(this._project) } + } + + modalRoot() { return this._modalRoot } + + history() { + if (!this._history) { + this._history = createBrowserHistory({ basename: this.props.basePath }) + } + return this._history + } + + iconFactory() { + return this._iconFactory ??= new LocalIconFactory() + } + + render() { + return ( + + + ( + + + Back + + ), + }, + }, + }} + /> + + + ) + } +} diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx new file mode 100644 index 00000000..819ba99d --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx @@ -0,0 +1,56 @@ +import React from 'react' +import classnames from 'classnames' + +import { IconFactory } from '@rolemodel/lightning-cad/drawing-editor-react/index.js' + +import MaterialIcon from './MaterialIcon.jsx' + +const customIcons = {} + +export default class LocalIconFactory extends IconFactory { + constructor(props) { + super(props); + + this._iconNameAlias = { + KeyboardArrowLeft: "keyboard_arrow_left", + KeyboardArrowRight: "keyboard_arrow_right", + KeyboardArrowDown: "keyboard_arrow_down", + ArrowBack: "keyboard_backspace", + Lock: "lock", + LockOpen: "lock_open", + Visibility: "visibility", + VisibilityOff: "visibility_off", + undo: "arrow_back", + redo: "arrow_forward", + }; + } + + makeIcon(name, otherProps) { + const iconName = this._iconNameAlias[name] || name; + + const iconProps = { + className: otherProps.className, + title: otherProps.hoverText || otherProps.name, + }; + + if (iconName in customIcons) { + return this._customIcon(iconName, iconProps); + } + + return ; + } + + /* eslint-disable react/no-danger */ + _customIcon(iconName, { className, ...otherProps }) { + // Setting innerHTML is not dangerous with these SVG files since we created + // them and they are part of this app's code. + return ( + + ); + } + /* eslint-enable react/no-danger */ +} diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/MaterialIcon.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/MaterialIcon.jsx new file mode 100644 index 00000000..7b934742 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/components/MaterialIcon.jsx @@ -0,0 +1,26 @@ +import React from 'react' +import classnames from 'classnames' +import * as PropTypes from 'prop-types' + +function MaterialIcon({ iconName, iconProps: { className, ...otherProps } }) { + return ( + + {iconName} + + ) +} + +MaterialIcon.propTypes = { + iconName: PropTypes.string, + iconProps: PropTypes.shape({ + className: PropTypes.string, + title: PropTypes.string, + hoverText: PropTypes.string, + name: PropTypes.string + }) +} + +export default MaterialIcon diff --git a/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js new file mode 100644 index 00000000..9ba364b3 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js @@ -0,0 +1,40 @@ +// import { SmartObjectBuilder } from '@rolemodel/lightning-cad/smartJSON/index.js' + +// let isWebpackEnvironment +// // If fs can't be required or is stubbed out, we're in a webpack environment. +// // Otherwise, we're in a node/test environment. +// try { +// const fs = await import('fs') +// // The glob package uses readdirSync, so that's a good one to check +// isWebpackEnvironment = typeof fs.readdirSync !== 'function' +// } catch { +// isWebpackEnvironment = true +// } + +// let domainModels = [] +// if (isWebpackEnvironment) { +// // Usually browser +// domainModels = await import('../../shared/domain-models/**/*.js') +// } else { +// // Node/test environment +// const path = await import('path') +// const glob = await import('glob') +// const url = await import('url') + +// const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) +// const files = glob.sync('**/*.js', { +// cwd: path.resolve(path.join(__dirname, '../../shared/domain-models')), +// }) + +// domainModels = [] + +// await Promise.all( +// files.map(async (file) => { +// domainModels.push(await import(`../../shared/domain-models/${file}`)) +// }) +// ) +// } + +// SmartObjectBuilder.configure((config) => { +// config.classes.addClasses(...domainModels) +// }) diff --git a/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js b/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js new file mode 100644 index 00000000..14c95162 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js @@ -0,0 +1,22 @@ +import { Controller } from '@hotwired/stimulus' +import React from 'react' +import ReactDOM from 'react-dom' +import App from '../components/App.jsx' + +const registeredComponents = { + App, +} + +export default class extends Controller { + connect() { + const componentName = this.element.dataset.component + const Component = registeredComponents[componentName] + + if (Component) { + const props = JSON.parse(this.element.dataset.props) + ReactDOM.render(React.createElement(Component, props), this.element) + } else { + throw new Error('Unrecognized React component name!') + } + } +} diff --git a/lib/generators/lightning_cad/templates/app/views/editor/editor.html.slim b/lib/generators/lightning_cad/templates/app/views/editor/editor.html.slim new file mode 100644 index 00000000..3297a591 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/views/editor/editor.html.slim @@ -0,0 +1,2 @@ += react_component 'App', basePath: editor_path +#modal_root diff --git a/lib/generators/lightning_cad/templates/babel.config.cjs b/lib/generators/lightning_cad/templates/babel.config.cjs new file mode 100644 index 00000000..d1f738ea --- /dev/null +++ b/lib/generators/lightning_cad/templates/babel.config.cjs @@ -0,0 +1,7 @@ +module.exports = { + presets: [ + ["@babel/preset-env", { targets: { node: "current" } }], + ["@babel/preset-react", { targets: { node: "current" } }], + ], + plugins: ["@babel/plugin-syntax-jsx"], +}; diff --git a/lib/generators/lightning_cad/templates/bin/dev b/lib/generators/lightning_cad/templates/bin/dev new file mode 100644 index 00000000..c1cb98b0 --- /dev/null +++ b/lib/generators/lightning_cad/templates/bin/dev @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if ! foreman version &> /dev/null +then + echo "Installing foreman..." + gem install foreman +fi + +foreman start -f Procfile.dev "$@" diff --git a/lib/generators/lightning_cad/templates/jest.config.js b/lib/generators/lightning_cad/templates/jest.config.js new file mode 100644 index 00000000..1311fee4 --- /dev/null +++ b/lib/generators/lightning_cad/templates/jest.config.js @@ -0,0 +1,17 @@ +export default { + roots: ["app/javascript", "spec/javascript/components"], + testRegex: "\\Spec\\.(js|jsx)$", + testEnvironmentOptions: { + url: "http://localhost", + }, + transformIgnorePatterns: ["/node_modules(?!\/\@rolemodel\/lightning-cad)/"], + setupFilesAfterEnv: ["./spec/javascript/components/TestSetup.js"], + modulePaths: ["/app/javascript"], + setupFilesAfterEnv: ["./spec/javascript/components/TestSetup.js"], + moduleNameMapper: { + "\\.svg$": + "/node_modules/@rolemodel/lightning-cad/drawing-editor-react/__tests__/mocks/svgMock.js", + "\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": + "/spec/javascript/support/FilePathMock.js", + }, +}; diff --git a/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake b/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake new file mode 100644 index 00000000..3696fea7 --- /dev/null +++ b/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake @@ -0,0 +1,7 @@ +desc 'run javascript tests' +task javascript_tests: :environment do |t| + success = true + success &&= system('yarn test_shared') + success &&= system('yarn test_view_ci') + abort('JS tests failed') unless success +end diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js b/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js new file mode 100644 index 00000000..14e7364d --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js @@ -0,0 +1,5 @@ +export default { + env: { + jest: true + } +} diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx b/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx new file mode 100644 index 00000000..755427f7 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx @@ -0,0 +1,9 @@ +import React from "react" +import { render } from "@testing-library/react" +import App from "components/App.jsx" + +describe("App", () => { + it("renders without crashing", () => { + expect(() => render()).not.toThrow() + }) +}) diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js new file mode 100644 index 00000000..2f23b55a --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js @@ -0,0 +1,10 @@ +import '@testing-library/jest-dom/extend-expect' +import '@rolemodel/lightning-cad/geometry/index.js' + +import '../helpers/initializers.js' +import setupJSDOM from '@rolemodel/lightning-cad/drawing-editor/spec/helpers/setupJSDOM.js' + +// Install our mock for Canvas elements +setupJSDOM() + +await import('./support/matchMedia.js') diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js b/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js new file mode 100644 index 00000000..d40186d5 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js @@ -0,0 +1,2 @@ +// Jest mock for requiring static assets +export default 'test-file-stub' diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js b/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js new file mode 100644 index 00000000..c99d2c0f --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js @@ -0,0 +1,13 @@ +global.matchMedia = function(_queryString) { + const mockMediaQueryList = { + matches: false, + addListener: () => {}, + removeListener: () => {}, + addEventListener: () => {}, + removeEventListener: () => {} + } + + return mockMediaQueryList +} + +window.matchMedia = global.matchMedia diff --git a/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js b/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js new file mode 100644 index 00000000..e7c47b03 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js @@ -0,0 +1,18 @@ +import fs from 'fs' +import path from 'path' +import * as url from 'url' +const __dirname = url.fileURLToPath(new URL(".", import.meta.url)) + +const absoluteBasePath = path.resolve( + path.join(__dirname, '../../../app/javascript/config/initializers') +) + +const files = fs.readdirSync(absoluteBasePath) + +await Promise.all( + files.map(async (file) => { + if (file.endsWith('.js')) { + await import(path.join(absoluteBasePath, file)) + } + }) +) diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js new file mode 100644 index 00000000..560fa983 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js @@ -0,0 +1,5 @@ +export default { + env: { + jasmine: true + } +} diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js new file mode 100644 index 00000000..7703d15a --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js @@ -0,0 +1,11 @@ +// Bring Array extensions +import "@rolemodel/lightning-cad/standard-utilities/index.js" + +import '../helpers/initializers.js' + +import EqualityHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/EqualityHelper.js' +import ToIncludeHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/ToIncludeHelper.js' + +beforeAll(EqualityHelper) +beforeAll(ToIncludeHelper) + diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/testSpec.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/testSpec.js new file mode 100644 index 00000000..4ea8e277 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/testSpec.js @@ -0,0 +1,5 @@ +describe('Foo', () => { + it('works', () => { + expect().nothing() + }) +}) diff --git a/lib/generators/lightning_cad/templates/spec/support/jasmine.json b/lib/generators/lightning_cad/templates/spec/support/jasmine.json new file mode 100644 index 00000000..3c1264ea --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/support/jasmine.json @@ -0,0 +1,9 @@ +{ + "spec_dir": "spec/javascript/shared", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "TestSetup.js" + ] +} diff --git a/lib/generators/lightning_cad/templates/webpack.config.js b/lib/generators/lightning_cad/templates/webpack.config.js new file mode 100644 index 00000000..25c5f1c6 --- /dev/null +++ b/lib/generators/lightning_cad/templates/webpack.config.js @@ -0,0 +1,146 @@ +import path from 'path' +import webpack from 'webpack' +import TerserPlugin from 'terser-webpack-plugin' +import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack' +import MiniCssExtractPlugin from 'mini-css-extract-plugin' +import RemoveEmptyScriptsPlugin from 'webpack-remove-empty-scripts' +import CssMinimizerPlugin from 'css-minimizer-webpack-plugin' + +let mode = 'development' + +if (process.env.RAILS_ENV === 'production' || process.env.CI === 'true') { + mode = 'production' +} + +export default { + mode, + devtool: 'source-map', + entry: { + application: [ + './app/javascript/application.js', + './app/assets/stylesheets/application.scss', + ], + }, + experiments: { + asyncWebAssembly: true, + topLevelAwait: true, + }, + output: { + filename: '[name].js', + sourceMapFilename: '[file].map', + path: path.resolve('app/assets/builds'), + }, + resolve: { + modules: ['node_modules'], + extensions: ['.js', '.jsx'], + alias: { + // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. + // Because THREE's package.json has an exports field with different files for + // import and require, without this alias THREE was being added to the bundle twice. + // Not only is that a size problem, but the custom extensions lightning-cad adds to + // CJS version of THREE aren't picked up because the ESM version of THREE appears first + // in the bundle and THREE has a check to prevent THREE from being instantiated twice. + // + 'three/examples': path.resolve('node_modules/three/examples'), + // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. + three: path.resolve('node_modules/three/build/three.module.js'), + + // LCAD uses `require` to bring in mathjs, but airfield_designer uses `import`, so there are + // two mathjs module instances in play, and without this line both end up in the final bundle. + // TODO: Once LCAD migrates to ES Modules, this line can be removed. + mathjs: path.resolve('node_modules/mathjs/lib/esm'), + + // Webpack apparently doesn't support the * in package.imports, so we need to duplicate + // package.imports here for webpack. + '#components': path.resolve('app/javascript/components'), + '#shared': path.resolve('app/javascript/shared'), + '#three': path.resolve('app/javascript/config/extensions/three.js'), + }, + fallback: { + module: false, + }, + }, + module: { + rules: [ + { + test: /\.(mjs|cjs|js|jsx)$/, + loader: 'import-glob', + }, + { + test: /\.scss/, + loader: 'import-glob', + }, + { + test: /\/icons\/.*.svg$/, + type: 'asset/source', + }, + { + test: /\.(jpg|jpeg|png|gif|tiff|ico|eot|otf|ttf|woff|woff2)$/i, + use: 'asset/resource', + }, + { + test: /\.(mjs|cjs|js|jsx)$/, + include: /app\/javascript|\/cypress|@rolemodel\/lightning-cad/, + loader: 'esbuild-loader', + options: { + loader: 'jsx', + target: 'esnext', + }, + }, + { + test: /\.(sa|sc|c)ss$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'], + }, + ], + }, + optimization: { + minimize: mode === 'production', + minimizer: [ + new TerserPlugin({ + terserOptions: { + keep_classnames: true, + mangle: { + keep_fnames: /^[A-Z]/, + }, + compress: { + keep_fnames: false, + }, + }, + }), + new CssMinimizerPlugin(), + ], + }, + plugins: [ + // cleans up the empty styles.js file Webpack generates + new RemoveEmptyScriptsPlugin(), + + // Extract CSS into its own file for the Rails asset pipeline to pick up + new MiniCssExtractPlugin(), + + // We're compiling all JS to a single application.js file + new webpack.optimize.LimitChunkCountPlugin({ + maxChunks: 1, + }), + + // Replace ENV variables at build time + new webpack.DefinePlugin({ + 'process.env.HONEYBADGER_API_KEY': JSON.stringify( + process.env.HONEYBADGER_API_KEY + ), + 'process.env.HONEYBADGER_ENV': JSON.stringify( + process.env.HONEYBADGER_ENV + ), + 'process.env.RAILS_ENV': JSON.stringify(process.env.RAILS_ENV), + 'process.env.SOURCE_VERSION': JSON.stringify(process.env.SOURCE_VERSION), + }), + + // Send source maps to HoneyBadger in production for easier debugging + mode === 'production' && + !process.env.CI && + new HoneybadgerSourceMapPlugin({ + apiKey: process.env.HONEYBADGER_API_KEY, + assetsUrl: process.env.ASSETS_URL, + revision: process.env.SOURCE_VERSION, + }), + ].filter(Boolean), +} From 16236f6a49ab57cfd43afa67153bf368e9788179 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Sat, 29 Apr 2023 06:49:44 -0400 Subject: [PATCH 02/49] update big int reference --- lib/generators/rolemodel/saas/devise/devise_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/rolemodel/saas/devise/devise_generator.rb b/lib/generators/rolemodel/saas/devise/devise_generator.rb index 25b78096..6d14fa83 100644 --- a/lib/generators/rolemodel/saas/devise/devise_generator.rb +++ b/lib/generators/rolemodel/saas/devise/devise_generator.rb @@ -21,7 +21,7 @@ def install_devise generate 'devise:install' generate :devise, 'user first_name:string last_name:string' - generate :migration, 'add_organization_and_role_to_users organization_id:bigint:index role:string super_admin:boolean' + generate :migration, 'add_organization_and_role_to_users organization:belongs_to role:string super_admin:boolean' file_name = Dir.glob(Rails.root.join('db/migrate', '*_add_organization_and_role_to_users.rb', )).last gsub_file file_name, /:role, :string$/, ":role, :string, default: 'user', null: false" gsub_file file_name, /:super_admin, :boolean$/, ':super_admin, :boolean, default: false, null: false' From fcd8926903097c7da66dcc9e22e32c06654e0ae9 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Sat, 29 Apr 2023 06:55:15 -0400 Subject: [PATCH 03/49] update devise again --- lib/generators/rolemodel/saas/devise/devise_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/rolemodel/saas/devise/devise_generator.rb b/lib/generators/rolemodel/saas/devise/devise_generator.rb index 6d14fa83..6a169cf0 100644 --- a/lib/generators/rolemodel/saas/devise/devise_generator.rb +++ b/lib/generators/rolemodel/saas/devise/devise_generator.rb @@ -21,7 +21,7 @@ def install_devise generate 'devise:install' generate :devise, 'user first_name:string last_name:string' - generate :migration, 'add_organization_and_role_to_users organization:belongs_to role:string super_admin:boolean' + generate :migration, 'add_organization_and_role_to_users organization:bigint:index role:string super_admin:boolean' file_name = Dir.glob(Rails.root.join('db/migrate', '*_add_organization_and_role_to_users.rb', )).last gsub_file file_name, /:role, :string$/, ":role, :string, default: 'user', null: false" gsub_file file_name, /:super_admin, :boolean$/, ':super_admin, :boolean, default: false, null: false' From 31ffbed6568ecbeeef84378773c8ede7ee939045 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Sat, 29 Apr 2023 07:14:45 -0400 Subject: [PATCH 04/49] fix organization migration --- lib/generators/rolemodel/saas/devise/devise_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/rolemodel/saas/devise/devise_generator.rb b/lib/generators/rolemodel/saas/devise/devise_generator.rb index 6a169cf0..25b78096 100644 --- a/lib/generators/rolemodel/saas/devise/devise_generator.rb +++ b/lib/generators/rolemodel/saas/devise/devise_generator.rb @@ -21,7 +21,7 @@ def install_devise generate 'devise:install' generate :devise, 'user first_name:string last_name:string' - generate :migration, 'add_organization_and_role_to_users organization:bigint:index role:string super_admin:boolean' + generate :migration, 'add_organization_and_role_to_users organization_id:bigint:index role:string super_admin:boolean' file_name = Dir.glob(Rails.root.join('db/migrate', '*_add_organization_and_role_to_users.rb', )).last gsub_file file_name, /:role, :string$/, ":role, :string, default: 'user', null: false" gsub_file file_name, /:super_admin, :boolean$/, ':super_admin, :boolean, default: false, null: false' From dc3d17f203b38c77eb33626e0f2cbed453292959 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Sat, 29 Apr 2023 07:46:05 -0400 Subject: [PATCH 05/49] Updates for running rails new with esbuild --- .../lightning_cad/install_generator.rb | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 70412b52..f1a2c245 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -14,8 +14,6 @@ def install_yarn_dependencies say 'Adding additional javascript dependencies' dependencies = %w[ - @honeybadger-io/js@5.3.0 - @honeybadger-io/webpack@^1.2.0 @babel/preset-env@7.21.4 @babel/preset-react@7.18.6 @babel/plugin-syntax-jsx@7.21.4 @@ -29,8 +27,6 @@ def install_yarn_dependencies import-glob@1.5.0 react-router-dom@^5.0.1 react-popper@^1.3.7 - @hotwired/turbo-rails@7.3.0 - @hotwired/stimulus@3.2.1 ] run("yarn add #{dependencies.join(" ")}") end @@ -42,7 +38,6 @@ def install_yarn_dev_dependencies @testing-library/jest-dom@^5.16.5 @testing-library/react@^12.1.2 @testing-library/user-event@^13.1.8 - eslint@^6.8.0 fetch-mock@^9.11.0 jasmine@^4.6.0 jest@^29.5.0 @@ -57,10 +52,7 @@ def install_yarn_optional_dependencies run("yarn add --optional three@^0.144.0") end - def remove_importmaps_and_unused_js - remove_file 'config/importmap.rb' - gsub_file 'app/views/layouts/application.html.erb', '<%= javascript_importmap_tags %>', "<%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>" - + def remove_unused_js hello_controller = "\nimport HelloController from './hello_controller.js'\napplication.register('hello', HelloController)\n" gsub_file 'app/javascript/controllers/index.js', hello_controller, '' @@ -89,12 +81,6 @@ def add_jest_config def add_webpack_config say 'Adding webpack config' copy_file 'webpack.config.js', 'webpack.config.js' - - build_files = <<-TEXT - /app/assets/builds/* - !/app/assets/builds/.keep - TEXT - append_to_file '.gitignore', build_files end def setup_javascript_specs @@ -166,13 +152,6 @@ def add_javascript_initializers run 'mkdir app/javascript/shared/domain-models' run 'touch app/javascript/shared/domain-models/.keep' end - - def add_dev_startup_command - say "Adding bin/dev for starting the application" - copy_file 'Procfile.dev', 'Procfile.dev' - copy_file 'bin/dev', 'bin/dev' - run 'chmod +x bin/dev' - end end end end From d97554ce1635d2e869427fc0380461b48fa5b880 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Sat, 29 Apr 2023 07:58:26 -0400 Subject: [PATCH 06/49] Remove unneeded css --- lib/generators/lightning_cad/install_generator.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index f1a2c245..a1dea679 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -118,10 +118,6 @@ def add_stylesheets .canvas-area { height: calc(100vh - $header-height); } - - body, html { - margin: 0 - } CSS append_to_file 'app/assets/stylesheets/application.scss', stylesheets From 60cd6ad488148c801422c98c73c8631fb365dc93 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Mon, 19 Jun 2023 16:30:57 -0500 Subject: [PATCH 07/49] Update to use the package approach --- .../lightning_cad/install_generator.rb | 20 ++++++++----------- lib/generators/lightning_cad/templates/.npmrc | 2 ++ .../app/javascript/components/App.jsx | 2 +- .../components/LocalIconFactory.jsx | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 lib/generators/lightning_cad/templates/.npmrc diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index a1dea679..7c8ff0e3 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -5,15 +5,14 @@ module Generators class InstallGenerator < ::Rails::Generators::Base source_root File.expand_path('./templates', __dir__) - def install_lightning_cad - say 'Adding lightning-cad dependency' - run('yarn add git+ssh://git@github.com/RoleModel/lightning-cad.git#master') - end - def install_yarn_dependencies - say 'Adding additional javascript dependencies' + say 'Adding lightning-cad dependency' + copy_file '.npmrc', '.npmrc' dependencies = %w[ + @rolemodel/lightning-cad@^8.0.0 + @rolemodel/lightning-cad-ui@^0.2.0 + @rolemodel/optics@^0.4.0 @babel/preset-env@7.21.4 @babel/preset-react@7.18.6 @babel/plugin-syntax-jsx@7.21.4 @@ -27,6 +26,7 @@ def install_yarn_dependencies import-glob@1.5.0 react-router-dom@^5.0.1 react-popper@^1.3.7 + classnames@^2.2.5 ] run("yarn add #{dependencies.join(" ")}") end @@ -113,14 +113,10 @@ def create_basic_app def add_stylesheets stylesheets = <<-CSS - @import '@rolemodel/lightning-cad/drawing-editor-react/stylesheets/MultiPerspectiveProjectEditorView.scss'; - - .canvas-area { - height: calc(100vh - $header-height); - } + @import '@rolemodel/lightning-cad-ui/scss/lightning-cad.scss'; CSS - append_to_file 'app/assets/stylesheets/application.scss', stylesheets + prepend_to_file 'app/assets/stylesheets/application.scss', stylesheets end def global_configuration diff --git a/lib/generators/lightning_cad/templates/.npmrc b/lib/generators/lightning_cad/templates/.npmrc new file mode 100644 index 00000000..6376c0b3 --- /dev/null +++ b/lib/generators/lightning_cad/templates/.npmrc @@ -0,0 +1,2 @@ +@rolemodel:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN} diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx index 24797955..fcf44d80 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx @@ -10,7 +10,7 @@ import { Icon, IconFactoryContext, MultiPerspectiveProjectEditorView, -} from '@rolemodel/lightning-cad/drawing-editor-react/index.js' +} from '@rolemodel/lightning-cad-ui/index.js' import { Router } from 'react-router-dom' import LocalIconFactory from './LocalIconFactory.jsx' diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx index 819ba99d..f1c95a7b 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx @@ -1,7 +1,7 @@ import React from 'react' import classnames from 'classnames' -import { IconFactory } from '@rolemodel/lightning-cad/drawing-editor-react/index.js' +import { IconFactory } from '@rolemodel/lightning-cad-ui/index.js' import MaterialIcon from './MaterialIcon.jsx' From d6389b5b48a26955c1930e0b7e76ed154572c1a5 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Mon, 19 Jun 2023 16:47:05 -0500 Subject: [PATCH 08/49] Remove index files from import paths --- .../lightning_cad/templates/app/javascript/components/App.jsx | 4 ++-- .../templates/app/javascript/components/LocalIconFactory.jsx | 2 +- .../templates/app/javascript/config/initializers/smartJSON.js | 2 +- .../templates/spec/javascript/components/TestSetup.js | 2 +- .../templates/spec/javascript/shared/TestSetup.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx index fcf44d80..04150ce6 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx @@ -10,7 +10,7 @@ import { Icon, IconFactoryContext, MultiPerspectiveProjectEditorView, -} from '@rolemodel/lightning-cad-ui/index.js' +} from '@rolemodel/lightning-cad-ui' import { Router } from 'react-router-dom' import LocalIconFactory from './LocalIconFactory.jsx' @@ -18,7 +18,7 @@ import { DrawingEditor, VersionedProject, Project -} from '@rolemodel/lightning-cad/drawing-editor/index.js' +} from '@rolemodel/lightning-cad/drawing-editor' export default class App extends React.Component { static propTypes = { diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx index f1c95a7b..b45c6828 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/LocalIconFactory.jsx @@ -1,7 +1,7 @@ import React from 'react' import classnames from 'classnames' -import { IconFactory } from '@rolemodel/lightning-cad-ui/index.js' +import { IconFactory } from '@rolemodel/lightning-cad-ui' import MaterialIcon from './MaterialIcon.jsx' diff --git a/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js index 9ba364b3..42034b1f 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js +++ b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js @@ -1,4 +1,4 @@ -// import { SmartObjectBuilder } from '@rolemodel/lightning-cad/smartJSON/index.js' +// import { SmartObjectBuilder } from '@rolemodel/lightning-cad/smartJSON' // let isWebpackEnvironment // // If fs can't be required or is stubbed out, we're in a webpack environment. diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js index 2f23b55a..64e3cf26 100644 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js +++ b/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js @@ -1,5 +1,5 @@ import '@testing-library/jest-dom/extend-expect' -import '@rolemodel/lightning-cad/geometry/index.js' +import '@rolemodel/lightning-cad/geometry' import '../helpers/initializers.js' import setupJSDOM from '@rolemodel/lightning-cad/drawing-editor/spec/helpers/setupJSDOM.js' diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js index 7703d15a..8594e82e 100644 --- a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js @@ -1,5 +1,5 @@ // Bring Array extensions -import "@rolemodel/lightning-cad/standard-utilities/index.js" +import "@rolemodel/lightning-cad/standard-utilities" import '../helpers/initializers.js' From 62db7574a38af6a2de4f4f55fac35d6f7130d13f Mon Sep 17 00:00:00 2001 From: malachirwin Date: Mon, 19 Jun 2023 16:53:25 -0500 Subject: [PATCH 09/49] add editor layout --- lib/generators/lightning_cad/install_generator.rb | 1 + .../templates/app/controllers/editor_controller.rb | 1 + .../templates/app/views/layouts/editor.html.slim.tt | 11 +++++++++++ 3 files changed, 13 insertions(+) create mode 100644 lib/generators/lightning_cad/templates/app/views/layouts/editor.html.slim.tt diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 7c8ff0e3..a152c363 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -125,6 +125,7 @@ def global_configuration def create_controller say "Creating Rails controller and view" + template 'app/views/layouts/editor.html.slim' copy_file 'app/controllers/editor_controller.rb', 'app/controllers/editor_controller.rb' copy_file 'app/views/editor/editor.html.slim', 'app/views/editor/editor.html.slim' route "get '/editor/*all', to: 'editor#editor'" diff --git a/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb index 37a649b7..7b6e43ca 100644 --- a/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb +++ b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb @@ -1,4 +1,5 @@ class EditorController < ApplicationController def editor + render layout: :editor end end diff --git a/lib/generators/lightning_cad/templates/app/views/layouts/editor.html.slim.tt b/lib/generators/lightning_cad/templates/app/views/layouts/editor.html.slim.tt new file mode 100644 index 00000000..a6afe5d7 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/views/layouts/editor.html.slim.tt @@ -0,0 +1,11 @@ +doctype html +html + head + title <%= Rails.application.class.name.deconstantize.titleize %> + = csrf_meta_tags + = csp_meta_tag + = stylesheet_link_tag 'application', 'data-turbo-track': 'reload' + = javascript_include_tag 'application', 'data-turbo-track': 'reload', defer: true + meta content="width=device-width, initial-scale=1" name="viewport" + body + = yield From db92d9bea63aa863f53c70ba9e5812a91cb8bfc3 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Mon, 19 Jun 2023 16:55:09 -0500 Subject: [PATCH 10/49] fix usage of layout --- .../templates/app/controllers/editor_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb index 7b6e43ca..b9d616bd 100644 --- a/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb +++ b/lib/generators/lightning_cad/templates/app/controllers/editor_controller.rb @@ -1,5 +1,5 @@ class EditorController < ApplicationController def editor - render layout: :editor + render layout: 'editor' end end From 14d321c7adbc09945ff9073f367863cfda789972 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 28 Jun 2023 14:12:40 -0500 Subject: [PATCH 11/49] update the smart json initializer --- .../config/initializers/smartJSON.js | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js index 42034b1f..ea6106de 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js +++ b/lib/generators/lightning_cad/templates/app/javascript/config/initializers/smartJSON.js @@ -1,40 +1,38 @@ -// import { SmartObjectBuilder } from '@rolemodel/lightning-cad/smartJSON' +import { SmartObjectBuilder } from '@rolemodel/lightning-cad/smartJSON' -// let isWebpackEnvironment -// // If fs can't be required or is stubbed out, we're in a webpack environment. -// // Otherwise, we're in a node/test environment. -// try { -// const fs = await import('fs') -// // The glob package uses readdirSync, so that's a good one to check -// isWebpackEnvironment = typeof fs.readdirSync !== 'function' -// } catch { -// isWebpackEnvironment = true -// } +let domainModelModules = [] +if (import.meta.webpackContext) { + const domainModelsContext = await import.meta.webpackContext( + '../../shared/domain-models', + { + recursive: true, + regExp: /.js$/, + } + ) + // Usually browser + domainModelModules = domainModelsContext.keys().map(domainModelsContext) +} else { + // Node/test environment + const path = await import('path') + const glob = await import('glob') + const url = await import('url') -// let domainModels = [] -// if (isWebpackEnvironment) { -// // Usually browser -// domainModels = await import('../../shared/domain-models/**/*.js') -// } else { -// // Node/test environment -// const path = await import('path') -// const glob = await import('glob') -// const url = await import('url') + const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) + const files = glob.sync('**/*.js', { + cwd: path.resolve(path.join(__dirname, '../../shared/domain-models')) + }) -// const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) -// const files = glob.sync('**/*.js', { -// cwd: path.resolve(path.join(__dirname, '../../shared/domain-models')), -// }) + domainModelModules = [] -// domainModels = [] + await Promise.all( + files.map(async (file) => { + domainModelModules.push(await import(`../../shared/domain-models/${file}`)) + }) + ) +} -// await Promise.all( -// files.map(async (file) => { -// domainModels.push(await import(`../../shared/domain-models/${file}`)) -// }) -// ) -// } +const domainModels = domainModelModules.map(({ default: module }) => module) -// SmartObjectBuilder.configure((config) => { -// config.classes.addClasses(...domainModels) -// }) +SmartObjectBuilder.configure((config) => { + config.classes.addClasses(...domainModels) +}) From fef579f6a6fa03fe9f48822e90cd66a42f4a1a0f Mon Sep 17 00:00:00 2001 From: malachirwin Date: Fri, 18 Aug 2023 10:38:35 -0500 Subject: [PATCH 12/49] update webpack config --- .../lightning_cad/templates/webpack.config.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/generators/lightning_cad/templates/webpack.config.js b/lib/generators/lightning_cad/templates/webpack.config.js index 25c5f1c6..4c1e61cc 100644 --- a/lib/generators/lightning_cad/templates/webpack.config.js +++ b/lib/generators/lightning_cad/templates/webpack.config.js @@ -3,7 +3,6 @@ import webpack from 'webpack' import TerserPlugin from 'terser-webpack-plugin' import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack' import MiniCssExtractPlugin from 'mini-css-extract-plugin' -import RemoveEmptyScriptsPlugin from 'webpack-remove-empty-scripts' import CssMinimizerPlugin from 'css-minimizer-webpack-plugin' let mode = 'development' @@ -22,7 +21,6 @@ export default { ], }, experiments: { - asyncWebAssembly: true, topLevelAwait: true, }, output: { @@ -80,12 +78,20 @@ export default { }, { test: /\.(mjs|cjs|js|jsx)$/, - include: /app\/javascript|\/cypress|@rolemodel\/lightning-cad/, + include: /app\/javascript|@rolemodel\/lightning-cad/, loader: 'esbuild-loader', options: { loader: 'jsx', target: 'esnext', }, + // ES Module has stricter rules than CommonJS, so file extensions must be + // used in import statements. To ease migration from CommonJS to ESM, + // uncomment the fullySpecified option below to allow Webpack to use a + // looser set of rules. Not recommend for new projects or the long term. + resolve: { + // Allows importing JS files without specifying the file extension. + fullySpecified: false + } }, { test: /\.(sa|sc|c)ss$/i, @@ -111,9 +117,6 @@ export default { ], }, plugins: [ - // cleans up the empty styles.js file Webpack generates - new RemoveEmptyScriptsPlugin(), - // Extract CSS into its own file for the Rails asset pipeline to pick up new MiniCssExtractPlugin(), From 1c86527008f7afe74a47a7b9d87767422a0859ae Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 2 Nov 2023 07:50:37 -0500 Subject: [PATCH 13/49] Remove jest --- lib/generators/lightning_cad/USAGE | 2 +- .../lightning_cad/install_generator.rb | 39 ++----------------- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/lib/generators/lightning_cad/USAGE b/lib/generators/lightning_cad/USAGE index f0bda794..07bae697 100644 --- a/lib/generators/lightning_cad/USAGE +++ b/lib/generators/lightning_cad/USAGE @@ -1,5 +1,5 @@ Description: - Explain the generator + This generator requires JS setup including webpack, react, etc... Example: bin/rails generate lightning-cad:install Thing diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index a152c363..f2cae5bb 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -10,9 +10,9 @@ def install_yarn_dependencies copy_file '.npmrc', '.npmrc' dependencies = %w[ - @rolemodel/lightning-cad@^8.0.0 - @rolemodel/lightning-cad-ui@^0.2.0 - @rolemodel/optics@^0.4.0 + @rolemodel/lightning-cad@^8.2.0 + @rolemodel/lightning-cad-ui@^0.4.0 + @rolemodel/optics@^0.5.1 @babel/preset-env@7.21.4 @babel/preset-react@7.18.6 @babel/plugin-syntax-jsx@7.21.4 @@ -35,13 +35,7 @@ def install_yarn_dev_dependencies say 'Adding javascript devDependencies' dev_dependencies = %w[ - @testing-library/jest-dom@^5.16.5 - @testing-library/react@^12.1.2 - @testing-library/user-event@^13.1.8 - fetch-mock@^9.11.0 jasmine@^4.6.0 - jest@^29.5.0 - babel-jest@^29.5.0 ] run("yarn add --dev #{dev_dependencies.join(" ")}") end @@ -64,44 +58,17 @@ def add_yarn_tasks say 'Adding package.json test scripts' yarn_scripts = <<-'JS' - "test": "bundle exec rake javascript_tests", - "test_view": "NODE_ENV=test yarn node --experimental-vm-modules $(yarn bin jest --watch)", - "test_view_ci": "NODE_ENV=test yarn node --experimental-vm-modules $(yarn bin jest)", "test_shared": "NODE_ENV=test NODE_PATH=\"./node_modules:./app/javascript:$NODE_PATH\" jasmine", "build": "webpack --config webpack.config.js", JS inject_into_file 'package.json', yarn_scripts, before: " \"eslint\": \"eslint" end - def add_jest_config - say 'Adding jest config' - copy_file 'jest.config.js', 'jest.config.js' - end - def add_webpack_config say 'Adding webpack config' copy_file 'webpack.config.js', 'webpack.config.js' end - def setup_javascript_specs - say "Set up jest/jasmine environment and basic test harness" - - copy_file 'lib/tasks/javascript_tests.rake', 'lib/tasks/javascript_tests.rake' - - copy_file 'spec/javascript/components/.eslintrc.js', 'spec/javascript/components/.eslintrc.js' - copy_file 'spec/javascript/components/TestSetup.js', 'spec/javascript/components/TestSetup.js' - copy_file 'spec/javascript/components/__mocks__/FilePathMock.js', 'spec/javascript/components/__mocks__/FilePathMock.js' - copy_file 'spec/javascript/components/support/matchMedia.js', 'spec/javascript/components/support/matchMedia.js' - copy_file 'babel.config.cjs', 'babel.config.cjs' - - copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' - copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' - - copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' - - copy_file 'spec/support/jasmine.json', 'spec/support/jasmine.json' - end - def create_basic_app say "Creating React App Component" copy_file 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js' From 76bf06681e2a70e342f480975bce366c176eb920 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 2 Nov 2023 08:44:05 -0500 Subject: [PATCH 14/49] Update install generator to use npm pkg set script instead of appending --- .../lightning_cad/install_generator.rb | 23 +++++-------------- .../lightning_cad/templates/jasmine.json | 6 +++++ 2 files changed, 12 insertions(+), 17 deletions(-) create mode 100644 lib/generators/lightning_cad/templates/jasmine.json diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index f2cae5bb..efa4ef53 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -28,7 +28,7 @@ def install_yarn_dependencies react-popper@^1.3.7 classnames@^2.2.5 ] - run("yarn add #{dependencies.join(" ")}") + run "yarn add #{dependencies.join(" ")}" end def install_yarn_dev_dependencies @@ -37,31 +37,20 @@ def install_yarn_dev_dependencies dev_dependencies = %w[ jasmine@^4.6.0 ] - run("yarn add --dev #{dev_dependencies.join(" ")}") + run "yarn add --dev #{dev_dependencies.join(" ")}" end def install_yarn_optional_dependencies say 'Adding optional dependencies' say "THREE.js packages are not required if this project does not implement 3D views" - run("yarn add --optional three@^0.144.0") - end - - def remove_unused_js - hello_controller = "\nimport HelloController from './hello_controller.js'\napplication.register('hello', HelloController)\n" - gsub_file 'app/javascript/controllers/index.js', hello_controller, '' - - remove_file 'app/javascript/packs/hello_react.jsx' - remove_file 'app/javascript/controllers/hello_controller.js' + run "yarn add --optional three@^0.144.0" end def add_yarn_tasks - say 'Adding package.json test scripts' + say 'Adding package.json scripts' - yarn_scripts = <<-'JS' - "test_shared": "NODE_ENV=test NODE_PATH=\"./node_modules:./app/javascript:$NODE_PATH\" jasmine", - "build": "webpack --config webpack.config.js", - JS - inject_into_file 'package.json', yarn_scripts, before: " \"eslint\": \"eslint" + run 'npm pkg set scripts.build="webpack --config webpack.config.js"' + run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' end def add_webpack_config diff --git a/lib/generators/lightning_cad/templates/jasmine.json b/lib/generators/lightning_cad/templates/jasmine.json new file mode 100644 index 00000000..1cec6cba --- /dev/null +++ b/lib/generators/lightning_cad/templates/jasmine.json @@ -0,0 +1,6 @@ +{ + "spec_dir": "spec/javascript/shared", + "spec_files": ["**/*[sS]pec.js"], + "helpers": ["TestSetup.js"], + "stopSpecOnExpectationFailure": true +} From b7fb2ad7eb49bdbca1525406e0f2e202463ee1e1 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 16:25:12 -0600 Subject: [PATCH 15/49] Cleanup testing setup --- .../lightning_cad/install_generator.rb | 24 ++++++++----------- .../spec/javascript/components/.eslintrc.js | 5 ---- .../spec/javascript/components/AppSpec.jsx | 9 ------- .../spec/javascript/components/TestSetup.js | 10 -------- .../components/__mocks__/FilePathMock.js | 2 -- .../components/support/matchMedia.js | 13 ---------- .../templates/spec/support/jasmine.json | 9 ------- 7 files changed, 10 insertions(+), 62 deletions(-) delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js delete mode 100644 lib/generators/lightning_cad/templates/spec/support/jasmine.json diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index efa4ef53..289697b2 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -31,26 +31,23 @@ def install_yarn_dependencies run "yarn add #{dependencies.join(" ")}" end - def install_yarn_dev_dependencies - say 'Adding javascript devDependencies' - - dev_dependencies = %w[ - jasmine@^4.6.0 - ] - run "yarn add --dev #{dev_dependencies.join(" ")}" - end - def install_yarn_optional_dependencies say 'Adding optional dependencies' say "THREE.js packages are not required if this project does not implement 3D views" run "yarn add --optional three@^0.144.0" end - def add_yarn_tasks - say 'Adding package.json scripts' + def add_jasmine_tests + say 'Adding jasmine' + run "yarn add --dev jasmine@^5.1.0" - run 'npm pkg set scripts.build="webpack --config webpack.config.js"' run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' + + copy_file 'jasmine.json', 'jasmine.json' + copy_file 'spec/javascript/helpers/initializer.js', 'spec/javascript/helpers/initializer.js' + copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' + copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' + copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' end def add_webpack_config @@ -64,11 +61,10 @@ def create_basic_app copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' copy_file 'app/javascript/components/App.jsx', 'app/javascript/components/App.jsx' - copy_file 'spec/javascript/components/AppSpec.jsx', 'spec/javascript/components/AppSpec.jsx' end def add_stylesheets - stylesheets = <<-CSS + stylesheets = <<~CSS @import '@rolemodel/lightning-cad-ui/scss/lightning-cad.scss'; CSS diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js b/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js deleted file mode 100644 index 14e7364d..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - env: { - jest: true - } -} diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx b/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx deleted file mode 100644 index 755427f7..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/AppSpec.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from "react" -import { render } from "@testing-library/react" -import App from "components/App.jsx" - -describe("App", () => { - it("renders without crashing", () => { - expect(() => render()).not.toThrow() - }) -}) diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js deleted file mode 100644 index 64e3cf26..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/TestSetup.js +++ /dev/null @@ -1,10 +0,0 @@ -import '@testing-library/jest-dom/extend-expect' -import '@rolemodel/lightning-cad/geometry' - -import '../helpers/initializers.js' -import setupJSDOM from '@rolemodel/lightning-cad/drawing-editor/spec/helpers/setupJSDOM.js' - -// Install our mock for Canvas elements -setupJSDOM() - -await import('./support/matchMedia.js') diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js b/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js deleted file mode 100644 index d40186d5..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/__mocks__/FilePathMock.js +++ /dev/null @@ -1,2 +0,0 @@ -// Jest mock for requiring static assets -export default 'test-file-stub' diff --git a/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js b/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js deleted file mode 100644 index c99d2c0f..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/components/support/matchMedia.js +++ /dev/null @@ -1,13 +0,0 @@ -global.matchMedia = function(_queryString) { - const mockMediaQueryList = { - matches: false, - addListener: () => {}, - removeListener: () => {}, - addEventListener: () => {}, - removeEventListener: () => {} - } - - return mockMediaQueryList -} - -window.matchMedia = global.matchMedia diff --git a/lib/generators/lightning_cad/templates/spec/support/jasmine.json b/lib/generators/lightning_cad/templates/spec/support/jasmine.json deleted file mode 100644 index 3c1264ea..00000000 --- a/lib/generators/lightning_cad/templates/spec/support/jasmine.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "spec_dir": "spec/javascript/shared", - "spec_files": [ - "**/*[sS]pec.js" - ], - "helpers": [ - "TestSetup.js" - ] -} From bc113600bf70d3f2fd47d91ae485eb5d2f01a5ce Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 16:27:39 -0600 Subject: [PATCH 16/49] fix typo --- lib/generators/lightning_cad/install_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 289697b2..5bcb6b46 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -44,7 +44,7 @@ def add_jasmine_tests run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' copy_file 'jasmine.json', 'jasmine.json' - copy_file 'spec/javascript/helpers/initializer.js', 'spec/javascript/helpers/initializer.js' + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' From dccf1cc305bba3d4504fa38f295b6ae7297dbacb Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 16:30:48 -0600 Subject: [PATCH 17/49] update the file paths --- .../templates/spec/javascript/shared/TestSetup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js index 8594e82e..8e124c86 100644 --- a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js @@ -3,8 +3,8 @@ import "@rolemodel/lightning-cad/standard-utilities" import '../helpers/initializers.js' -import EqualityHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/EqualityHelper.js' -import ToIncludeHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/ToIncludeHelper.js' +import EqualityHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/EqualityHelper' +import ToIncludeHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/ToIncludeHelper' beforeAll(EqualityHelper) beforeAll(ToIncludeHelper) From 1413f0dce9845930af617d8de325a0091cf1f475 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 16:38:13 -0600 Subject: [PATCH 18/49] match webpack config to what is currently used by default --- .../lightning_cad/templates/webpack.config.js | 74 ++++++++++--------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/lib/generators/lightning_cad/templates/webpack.config.js b/lib/generators/lightning_cad/templates/webpack.config.js index 4c1e61cc..7d881158 100644 --- a/lib/generators/lightning_cad/templates/webpack.config.js +++ b/lib/generators/lightning_cad/templates/webpack.config.js @@ -17,16 +17,19 @@ export default { entry: { application: [ './app/javascript/application.js', - './app/assets/stylesheets/application.scss', + './app/assets/stylesheets/application.scss' ], + mailer: [ + './app/assets/stylesheets/mailer.scss' + ] }, experiments: { - topLevelAwait: true, + topLevelAwait: true }, output: { filename: '[name].js', sourceMapFilename: '[file].map', - path: path.resolve('app/assets/builds'), + path: path.resolve('app/assets/builds') }, resolve: { modules: ['node_modules'], @@ -52,29 +55,29 @@ export default { // package.imports here for webpack. '#components': path.resolve('app/javascript/components'), '#shared': path.resolve('app/javascript/shared'), - '#three': path.resolve('app/javascript/config/extensions/three.js'), + '#three': path.resolve('app/javascript/config/extensions/three.js') }, fallback: { - module: false, - }, + module: false + } }, module: { rules: [ { test: /\.(mjs|cjs|js|jsx)$/, - loader: 'import-glob', + loader: 'import-glob' }, { test: /\.scss/, - loader: 'import-glob', + loader: 'import-glob' }, { test: /\/icons\/.*.svg$/, - type: 'asset/source', + type: 'asset/source' }, { test: /\.(jpg|jpeg|png|gif|tiff|ico|eot|otf|ttf|woff|woff2)$/i, - use: 'asset/resource', + use: 'asset/resource' }, { test: /\.(mjs|cjs|js|jsx)$/, @@ -82,7 +85,7 @@ export default { loader: 'esbuild-loader', options: { loader: 'jsx', - target: 'esnext', + target: 'esnext' }, // ES Module has stricter rules than CommonJS, so file extensions must be // used in import statements. To ease migration from CommonJS to ESM, @@ -95,9 +98,18 @@ export default { }, { test: /\.(sa|sc|c)ss$/i, - use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'], - }, - ], + use: [ + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { + url: false + } + }, + 'postcss-loader' + ] + } + ] }, optimization: { minimize: mode === 'production', @@ -110,11 +122,11 @@ export default { }, compress: { keep_fnames: false, - }, - }, + } + } }), - new CssMinimizerPlugin(), - ], + new CssMinimizerPlugin() + ] }, plugins: [ // Extract CSS into its own file for the Rails asset pipeline to pick up @@ -122,28 +134,22 @@ export default { // We're compiling all JS to a single application.js file new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1, + maxChunks: 1 }), // Replace ENV variables at build time new webpack.DefinePlugin({ - 'process.env.HONEYBADGER_API_KEY': JSON.stringify( - process.env.HONEYBADGER_API_KEY - ), - 'process.env.HONEYBADGER_ENV': JSON.stringify( - process.env.HONEYBADGER_ENV - ), + 'process.env.HONEYBADGER_API_KEY': JSON.stringify(process.env.HONEYBADGER_API_KEY), + 'process.env.HONEYBADGER_ENV': JSON.stringify(process.env.HONEYBADGER_ENV), 'process.env.RAILS_ENV': JSON.stringify(process.env.RAILS_ENV), - 'process.env.SOURCE_VERSION': JSON.stringify(process.env.SOURCE_VERSION), + 'process.env.SOURCE_VERSION': JSON.stringify(process.env.SOURCE_VERSION) }), // Send source maps to HoneyBadger in production for easier debugging - mode === 'production' && - !process.env.CI && - new HoneybadgerSourceMapPlugin({ - apiKey: process.env.HONEYBADGER_API_KEY, - assetsUrl: process.env.ASSETS_URL, - revision: process.env.SOURCE_VERSION, - }), - ].filter(Boolean), + (mode === 'production' && !process.env.CI) && new HoneybadgerSourceMapPlugin({ + apiKey: process.env.HONEYBADGER_API_KEY, + assetsUrl: process.env.ASSETS_URL, + revision: process.env.SOURCE_VERSION + }) + ].filter(Boolean) } From 293f3de1cb3732e642725bfec426b180b02f54fd Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 17:10:12 -0600 Subject: [PATCH 19/49] remove dependencies --- lib/generators/lightning_cad/install_generator.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 5bcb6b46..9b13d05e 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -9,20 +9,23 @@ def install_yarn_dependencies say 'Adding lightning-cad dependency' copy_file '.npmrc', '.npmrc' + # @babel/preset-env@7.21.4 + # @babel/preset-react@7.18.6 + # @babel/plugin-syntax-jsx@7.21.4 + # @babel/core@7.21.4 + + + # already added + # react@16.9.0 + # react-dom@16.9.0 dependencies = %w[ @rolemodel/lightning-cad@^8.2.0 @rolemodel/lightning-cad-ui@^0.4.0 @rolemodel/optics@^0.5.1 - @babel/preset-env@7.21.4 - @babel/preset-react@7.18.6 - @babel/plugin-syntax-jsx@7.21.4 - @babel/core@7.21.4 mobx-react@^6.1.5 mobx-utils@^5.5.2 mobx@^5.15.2 glob@^10.2.2 - react@16.9.0 - react-dom@16.9.0 import-glob@1.5.0 react-router-dom@^5.0.1 react-popper@^1.3.7 From 0200b9ff971c848f85b06dbd17d08c729b780c08 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Tue, 7 Nov 2023 17:16:28 -0600 Subject: [PATCH 20/49] remove unnecessary comments --- lib/generators/lightning_cad/install_generator.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 9b13d05e..f6d837dc 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -9,15 +9,6 @@ def install_yarn_dependencies say 'Adding lightning-cad dependency' copy_file '.npmrc', '.npmrc' - # @babel/preset-env@7.21.4 - # @babel/preset-react@7.18.6 - # @babel/plugin-syntax-jsx@7.21.4 - # @babel/core@7.21.4 - - - # already added - # react@16.9.0 - # react-dom@16.9.0 dependencies = %w[ @rolemodel/lightning-cad@^8.2.0 @rolemodel/lightning-cad-ui@^0.4.0 From 81afcf6894f1120db3af6183214442ad475e8aac Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 16:43:01 -0600 Subject: [PATCH 21/49] Update the required dependencies --- .../lightning_cad/install_generator.rb | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index f6d837dc..d20feb96 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -10,25 +10,14 @@ def install_yarn_dependencies copy_file '.npmrc', '.npmrc' dependencies = %w[ - @rolemodel/lightning-cad@^8.2.0 - @rolemodel/lightning-cad-ui@^0.4.0 - @rolemodel/optics@^0.5.1 - mobx-react@^6.1.5 - mobx-utils@^5.5.2 - mobx@^5.15.2 - glob@^10.2.2 - import-glob@1.5.0 - react-router-dom@^5.0.1 - react-popper@^1.3.7 - classnames@^2.2.5 + @rolemodel/lightning-cad + @rolemodel/lightning-cad-ui + @rolemodel/optics + glob + import-glob ] - run "yarn add #{dependencies.join(" ")}" - end - def install_yarn_optional_dependencies - say 'Adding optional dependencies' - say "THREE.js packages are not required if this project does not implement 3D views" - run "yarn add --optional three@^0.144.0" + run "yarn add #{dependencies.join(" ")}" end def add_jasmine_tests From 37ae4e76418c52d9e63d954cd74a91e4b09d16a0 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 16:43:45 -0600 Subject: [PATCH 22/49] split generators into install and jasmine --- lib/generators/lightning_cad/all_generator.rb | 10 +++++++++ .../lightning_cad/install_generator.rb | 13 ----------- .../lightning_cad/jasmine_generator.rb | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 lib/generators/lightning_cad/all_generator.rb create mode 100644 lib/generators/lightning_cad/jasmine_generator.rb diff --git a/lib/generators/lightning_cad/all_generator.rb b/lib/generators/lightning_cad/all_generator.rb new file mode 100644 index 00000000..f587cffc --- /dev/null +++ b/lib/generators/lightning_cad/all_generator.rb @@ -0,0 +1,10 @@ +require 'rails' + +module LightningCad + module Generators + class AllGenerator < ::Rails::Generators::Base + generate 'lightning_cad:install' + generate 'lightning_cad:jasmine' + end + end +end diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index d20feb96..b4f6978e 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -20,19 +20,6 @@ def install_yarn_dependencies run "yarn add #{dependencies.join(" ")}" end - def add_jasmine_tests - say 'Adding jasmine' - run "yarn add --dev jasmine@^5.1.0" - - run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' - - copy_file 'jasmine.json', 'jasmine.json' - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' - copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' - copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' - copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' - end - def add_webpack_config say 'Adding webpack config' copy_file 'webpack.config.js', 'webpack.config.js' diff --git a/lib/generators/lightning_cad/jasmine_generator.rb b/lib/generators/lightning_cad/jasmine_generator.rb new file mode 100644 index 00000000..3f0576c1 --- /dev/null +++ b/lib/generators/lightning_cad/jasmine_generator.rb @@ -0,0 +1,22 @@ +require 'rails' + +module LightningCad + module Generators + class JasmineGenerator < ::Rails::Generators::Base + source_root File.expand_path('./templates', __dir__) + + def add_jasmine_tests + say 'Adding jasmine' + run "yarn add --dev jasmine@^5.1.0" + + run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' + + copy_file 'jasmine.json', 'jasmine.json' + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' + copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' + copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' + copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' + end + end + end +end From bdf1b3e5bd0566d144298647c171e81b33c4b27c Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 16:45:51 -0600 Subject: [PATCH 23/49] Move spec initializer into jasmine generator --- lib/generators/lightning_cad/install_generator.rb | 1 - lib/generators/lightning_cad/jasmine_generator.rb | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index b4f6978e..26c30787 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -61,7 +61,6 @@ def add_javascript_initializers JS append_to_file 'app/javascript/application.js', initializer_setup copy_file 'app/javascript/config/initializers/smartJSON.js', 'app/javascript/config/initializers/smartJSON.js' - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' # To prevent smartJSON from throwing an error run 'mkdir app/javascript/shared' run 'mkdir app/javascript/shared/domain-models' diff --git a/lib/generators/lightning_cad/jasmine_generator.rb b/lib/generators/lightning_cad/jasmine_generator.rb index 3f0576c1..b83437be 100644 --- a/lib/generators/lightning_cad/jasmine_generator.rb +++ b/lib/generators/lightning_cad/jasmine_generator.rb @@ -17,6 +17,12 @@ def add_jasmine_tests copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' end + + def add_test_initializers + say 'Adding test initializers' + + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' + end end end end From 4e3c88af65a3aec7810ba1f5ec041b8871a3265b Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 16:46:08 -0600 Subject: [PATCH 24/49] rename the jasmine generator to test --- lib/generators/lightning_cad/all_generator.rb | 2 +- .../lightning_cad/{jasmine_generator.rb => test_generator.rb} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/generators/lightning_cad/{jasmine_generator.rb => test_generator.rb} (94%) diff --git a/lib/generators/lightning_cad/all_generator.rb b/lib/generators/lightning_cad/all_generator.rb index f587cffc..7266ee63 100644 --- a/lib/generators/lightning_cad/all_generator.rb +++ b/lib/generators/lightning_cad/all_generator.rb @@ -4,7 +4,7 @@ module LightningCad module Generators class AllGenerator < ::Rails::Generators::Base generate 'lightning_cad:install' - generate 'lightning_cad:jasmine' + generate 'lightning_cad:test' end end end diff --git a/lib/generators/lightning_cad/jasmine_generator.rb b/lib/generators/lightning_cad/test_generator.rb similarity index 94% rename from lib/generators/lightning_cad/jasmine_generator.rb rename to lib/generators/lightning_cad/test_generator.rb index b83437be..9f5bafdc 100644 --- a/lib/generators/lightning_cad/jasmine_generator.rb +++ b/lib/generators/lightning_cad/test_generator.rb @@ -2,7 +2,7 @@ module LightningCad module Generators - class JasmineGenerator < ::Rails::Generators::Base + class TestGenerator < ::Rails::Generators::Base source_root File.expand_path('./templates', __dir__) def add_jasmine_tests From c606880660efacab994eec2ee36741fcf306d7d8 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 16:59:44 -0600 Subject: [PATCH 25/49] Remove the extra module around the generators --- lib/generators/lightning_cad/all_generator.rb | 8 +- .../lightning_cad/install_generator.rb | 108 +++++++++--------- .../lightning_cad/test_generator.rb | 32 +++--- 3 files changed, 71 insertions(+), 77 deletions(-) diff --git a/lib/generators/lightning_cad/all_generator.rb b/lib/generators/lightning_cad/all_generator.rb index 7266ee63..efc42b0b 100644 --- a/lib/generators/lightning_cad/all_generator.rb +++ b/lib/generators/lightning_cad/all_generator.rb @@ -1,10 +1,8 @@ require 'rails' module LightningCad - module Generators - class AllGenerator < ::Rails::Generators::Base - generate 'lightning_cad:install' - generate 'lightning_cad:test' - end + class AllGenerator < Rails::Generators::Base + generate 'lightning_cad:install' + generate 'lightning_cad:test' end end diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 26c30787..c64cff87 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -1,71 +1,69 @@ require 'rails' module LightningCad - module Generators - class InstallGenerator < ::Rails::Generators::Base - source_root File.expand_path('./templates', __dir__) + class InstallGenerator < Rails::Generators::Base + source_root File.expand_path('./templates', __dir__) - def install_yarn_dependencies - say 'Adding lightning-cad dependency' - copy_file '.npmrc', '.npmrc' + def install_yarn_dependencies + say 'Adding lightning-cad dependency' + copy_file '.npmrc', '.npmrc' - dependencies = %w[ - @rolemodel/lightning-cad - @rolemodel/lightning-cad-ui - @rolemodel/optics - glob - import-glob - ] + dependencies = %w[ + @rolemodel/lightning-cad + @rolemodel/lightning-cad-ui + @rolemodel/optics + glob + import-glob + ] - run "yarn add #{dependencies.join(" ")}" - end + run "yarn add #{dependencies.join(" ")}" + end - def add_webpack_config - say 'Adding webpack config' - copy_file 'webpack.config.js', 'webpack.config.js' - end + def add_webpack_config + say 'Adding webpack config' + copy_file 'webpack.config.js', 'webpack.config.js' + end - def create_basic_app - say "Creating React App Component" - copy_file 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js' - copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' - copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' - copy_file 'app/javascript/components/App.jsx', 'app/javascript/components/App.jsx' - end + def create_basic_app + say "Creating React App Component" + copy_file 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js' + copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' + copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' + copy_file 'app/javascript/components/App.jsx', 'app/javascript/components/App.jsx' + end - def add_stylesheets - stylesheets = <<~CSS - @import '@rolemodel/lightning-cad-ui/scss/lightning-cad.scss'; - CSS + def add_stylesheets + stylesheets = <<~CSS + @import '@rolemodel/lightning-cad-ui/scss/lightning-cad.scss'; + CSS - prepend_to_file 'app/assets/stylesheets/application.scss', stylesheets - end + prepend_to_file 'app/assets/stylesheets/application.scss', stylesheets + end - def global_configuration - copy_file '.eslintrc.js', '.eslintrc.js' - end + def global_configuration + copy_file '.eslintrc.js', '.eslintrc.js' + end - def create_controller - say "Creating Rails controller and view" - template 'app/views/layouts/editor.html.slim' - copy_file 'app/controllers/editor_controller.rb', 'app/controllers/editor_controller.rb' - copy_file 'app/views/editor/editor.html.slim', 'app/views/editor/editor.html.slim' - route "get '/editor/*all', to: 'editor#editor'" - route "get :editor, to: 'editor#editor'" - end + def create_controller + say "Creating Rails controller and view" + template 'app/views/layouts/editor.html.slim' + copy_file 'app/controllers/editor_controller.rb', 'app/controllers/editor_controller.rb' + copy_file 'app/views/editor/editor.html.slim', 'app/views/editor/editor.html.slim' + route "get '/editor/*all', to: 'editor#editor'" + route "get :editor, to: 'editor#editor'" + end - def add_javascript_initializers - say "Adding JavaScript initializers" - initializer_setup = <<~JS - import './config/initializers/**/*.js' - JS - append_to_file 'app/javascript/application.js', initializer_setup - copy_file 'app/javascript/config/initializers/smartJSON.js', 'app/javascript/config/initializers/smartJSON.js' - # To prevent smartJSON from throwing an error - run 'mkdir app/javascript/shared' - run 'mkdir app/javascript/shared/domain-models' - run 'touch app/javascript/shared/domain-models/.keep' - end + def add_javascript_initializers + say "Adding JavaScript initializers" + initializer_setup = <<~JS + import './config/initializers/**/*.js' + JS + append_to_file 'app/javascript/application.js', initializer_setup + copy_file 'app/javascript/config/initializers/smartJSON.js', 'app/javascript/config/initializers/smartJSON.js' + # To prevent smartJSON from throwing an error + run 'mkdir app/javascript/shared' + run 'mkdir app/javascript/shared/domain-models' + run 'touch app/javascript/shared/domain-models/.keep' end end end diff --git a/lib/generators/lightning_cad/test_generator.rb b/lib/generators/lightning_cad/test_generator.rb index 9f5bafdc..ca02fd0f 100644 --- a/lib/generators/lightning_cad/test_generator.rb +++ b/lib/generators/lightning_cad/test_generator.rb @@ -1,28 +1,26 @@ require 'rails' module LightningCad - module Generators - class TestGenerator < ::Rails::Generators::Base - source_root File.expand_path('./templates', __dir__) + class TestGenerator < Rails::Generators::Base + source_root File.expand_path('./templates', __dir__) - def add_jasmine_tests - say 'Adding jasmine' - run "yarn add --dev jasmine@^5.1.0" + def add_jasmine_tests + say 'Adding jasmine' + run "yarn add --dev jasmine@^5.1.0" - run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' + run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' - copy_file 'jasmine.json', 'jasmine.json' - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' - copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' - copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' - copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' - end + copy_file 'jasmine.json', 'jasmine.json' + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' + copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' + copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' + copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' + end - def add_test_initializers - say 'Adding test initializers' + def add_test_initializers + say 'Adding test initializers' - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' - end + copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' end end end From cc5e750d2c212266c872ccbf1c5e687ff9ed1599 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Wed, 29 Nov 2023 17:01:15 -0600 Subject: [PATCH 26/49] fix all generator --- lib/generators/lightning_cad/all_generator.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/generators/lightning_cad/all_generator.rb b/lib/generators/lightning_cad/all_generator.rb index efc42b0b..00df8ad9 100644 --- a/lib/generators/lightning_cad/all_generator.rb +++ b/lib/generators/lightning_cad/all_generator.rb @@ -2,7 +2,11 @@ module LightningCad class AllGenerator < Rails::Generators::Base - generate 'lightning_cad:install' - generate 'lightning_cad:test' + source_root File.expand_path('./templates', __dir__) + + def run_all_the_generators + generate 'lightning_cad:install' + generate 'lightning_cad:test' + end end end From 485c65c501b4e120dec6c768d5c1d39cba994692 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 30 Nov 2023 08:26:57 -0600 Subject: [PATCH 27/49] Update react controller to match react 18 --- .../app/javascript/controllers/react_controller.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js b/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js index 14c95162..22c14a5c 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js +++ b/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js @@ -1,6 +1,7 @@ import { Controller } from '@hotwired/stimulus' import React from 'react' -import ReactDOM from 'react-dom' +import { createRoot } from 'react-dom/client' + import App from '../components/App.jsx' const registeredComponents = { @@ -13,8 +14,9 @@ export default class extends Controller { const Component = registeredComponents[componentName] if (Component) { + const root = createRoot(this.element) const props = JSON.parse(this.element.dataset.props) - ReactDOM.render(React.createElement(Component, props), this.element) + root.render(React.createElement(component, props)) } else { throw new Error('Unrecognized React component name!') } From 6117d624d491bfb496c2757d2e20861c71749ea2 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 30 Nov 2023 08:32:58 -0600 Subject: [PATCH 28/49] remove optics from install list --- lib/generators/lightning_cad/install_generator.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index c64cff87..4410b36b 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -11,7 +11,6 @@ def install_yarn_dependencies dependencies = %w[ @rolemodel/lightning-cad @rolemodel/lightning-cad-ui - @rolemodel/optics glob import-glob ] From cf176fa84f45a1ebb9b88e4d7a3bb6df904f014c Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:38:03 -0600 Subject: [PATCH 29/49] abscract webpack into its own generator --- lib/generators/lightning_cad/all_generator.rb | 1 + .../lightning_cad/install_generator.rb | 8 +- .../controllers/react_controller.js | 24 ----- .../lightning_cad/webpack_generator.rb | 98 +++++++++++++++++++ 4 files changed, 101 insertions(+), 30 deletions(-) delete mode 100644 lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js create mode 100644 lib/generators/lightning_cad/webpack_generator.rb diff --git a/lib/generators/lightning_cad/all_generator.rb b/lib/generators/lightning_cad/all_generator.rb index 00df8ad9..932ae15c 100644 --- a/lib/generators/lightning_cad/all_generator.rb +++ b/lib/generators/lightning_cad/all_generator.rb @@ -6,6 +6,7 @@ class AllGenerator < Rails::Generators::Base def run_all_the_generators generate 'lightning_cad:install' + generate 'lightning_cad:webpack' generate 'lightning_cad:test' end end diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 4410b36b..8c300294 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -18,14 +18,10 @@ def install_yarn_dependencies run "yarn add #{dependencies.join(" ")}" end - def add_webpack_config - say 'Adding webpack config' - copy_file 'webpack.config.js', 'webpack.config.js' - end - def create_basic_app say "Creating React App Component" - copy_file 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js' + insert_into_file 'app/javascript/controllers/react_controller.js', "import App from '../components/App.jsx'\n", after: "import HelloReact from '../components/HelloReact.jsx'\n" + insert_into_file 'app/javascript/controllers/react_controller.js', " App,\n", after: "const registeredComponents = {\n" copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' copy_file 'app/javascript/components/App.jsx', 'app/javascript/components/App.jsx' diff --git a/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js b/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js deleted file mode 100644 index 22c14a5c..00000000 --- a/lib/generators/lightning_cad/templates/app/javascript/controllers/react_controller.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Controller } from '@hotwired/stimulus' -import React from 'react' -import { createRoot } from 'react-dom/client' - -import App from '../components/App.jsx' - -const registeredComponents = { - App, -} - -export default class extends Controller { - connect() { - const componentName = this.element.dataset.component - const Component = registeredComponents[componentName] - - if (Component) { - const root = createRoot(this.element) - const props = JSON.parse(this.element.dataset.props) - root.render(React.createElement(component, props)) - } else { - throw new Error('Unrecognized React component name!') - } - } -} diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb new file mode 100644 index 00000000..07f3285c --- /dev/null +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -0,0 +1,98 @@ +require 'rails' + +module LightningCad + class WebpackGenerator < Rails::Generators::Base + source_root File.expand_path('./templates', __dir__) + + def add_experimental_features + # copy_file 'webpack.config.js', 'webpack.config.js' + say "Adding experimental features to the config" + + experiments <<~JS + experiments: { + topLevelAwait: true + }, + JS + + insert_into_file 'webpack.config.js', experiments, before: "\n output: {" + end + + def add_resolve_aliases + say 'Adding aliases to the config' + alias_js <<~JS + alias: { + // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. + // Because THREE's package.json has an exports field with different files for + // import and require, without this alias THREE was being added to the bundle twice. + // Not only is that a size problem, but the custom extensions lightning-cad adds to + // CJS version of THREE aren't picked up because the ESM version of THREE appears first + // in the bundle and THREE has a check to prevent THREE from being instantiated twice. + // + 'three/examples': path.resolve('node_modules/three/examples'), + // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. + three: path.resolve('node_modules/three/build/three.module.js'), + + // LCAD uses `require` to bring in mathjs, but rails 7 apps uses `import`, so there are + // two mathjs module instances in play, and without this line both end up in the final bundle. + // TODO: Once LCAD migrates to ES Modules, this line can be removed. + mathjs: path.resolve('node_modules/mathjs/lib/esm'), + + // Webpack apparently doesn't support the * in package.imports, so we need to duplicate + // package.imports here for webpack. + '#components': path.resolve('app/javascript/components'), + '#shared': path.resolve('app/javascript/shared'), + '#three': path.resolve('app/javascript/config/extensions/three.js') + }, + fallback: { + module: false + } + JS + + insert_into_file 'webpack.config.js', alias_js, after: "extensions: ['.js', '.jsx']" + end + + def add_loaders + say 'Adding loaders to the config' + + loaders <<~JS + { + test: /\.(mjs|cjs|js|jsx)$/, + loader: 'import-glob' + }, + { + test: /\.scss/, + loader: 'import-glob' + }, + JS + + insert_into_file 'webpack.config.js', loaders, after: "rules: [\n" + end + + def update_esbuild_loader + say 'Updating esbuild loader in the config' + + insert_into_file 'webpack.config.js', " include: /app\/javascript|@rolemodel\/lightning-cad/,\n", after: "test: /\.(mjs|cjs|js|jsx)$/,\n" + gsub_file 'webpack.config.js', 'es2021', 'esnext' + end + + def add_terser_plugin_options + say 'Updating the terser plugin options in the config' + + terserPlugin <<~JS + new TerserPlugin({ + terserOptions: { + keep_classnames: true, + mangle: { + keep_fnames: /^[A-Z]/, + }, + compress: { + keep_fnames: false, + } + } + }), + JS + + gsub_file 'webpack.config.js', ' new TerserPlugin(),', terserPlugin + end + end +end From 640b9d110e88c9bd2b7562c083409ef6080adc07 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:42:02 -0600 Subject: [PATCH 30/49] fix string assignments --- lib/generators/lightning_cad/webpack_generator.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index 07f3285c..a96da5a3 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -8,7 +8,7 @@ def add_experimental_features # copy_file 'webpack.config.js', 'webpack.config.js' say "Adding experimental features to the config" - experiments <<~JS + experiments = <<~JS experiments: { topLevelAwait: true }, @@ -19,7 +19,7 @@ def add_experimental_features def add_resolve_aliases say 'Adding aliases to the config' - alias_js <<~JS + alias_js = <<~JS alias: { // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. // Because THREE's package.json has an exports field with different files for @@ -54,7 +54,7 @@ def add_resolve_aliases def add_loaders say 'Adding loaders to the config' - loaders <<~JS + loaders = <<~JS { test: /\.(mjs|cjs|js|jsx)$/, loader: 'import-glob' @@ -78,7 +78,7 @@ def update_esbuild_loader def add_terser_plugin_options say 'Updating the terser plugin options in the config' - terserPlugin <<~JS + terserPlugin = <<~JS new TerserPlugin({ terserOptions: { keep_classnames: true, From 28da903b44cb52e5340a068906c2817c94e539d3 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:47:41 -0600 Subject: [PATCH 31/49] fix webpack indentation --- .../lightning_cad/install_generator.rb | 2 +- .../lightning_cad/webpack_generator.rb | 97 ++++++++++--------- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 8c300294..54c0e921 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -20,7 +20,7 @@ def install_yarn_dependencies def create_basic_app say "Creating React App Component" - insert_into_file 'app/javascript/controllers/react_controller.js', "import App from '../components/App.jsx'\n", after: "import HelloReact from '../components/HelloReact.jsx'\n" + insert_into_file 'app/javascript/controllers/react_controller.js', "import App from '../components/App.jsx'\n", before: "import HelloReact from '../components/HelloReact.jsx'\n" insert_into_file 'app/javascript/controllers/react_controller.js', " App,\n", after: "const registeredComponents = {\n" copy_file 'app/javascript/components/MaterialIcon.jsx', 'app/javascript/components/MaterialIcon.jsx' copy_file 'app/javascript/components/LocalIconFactory.jsx', 'app/javascript/components/LocalIconFactory.jsx' diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index a96da5a3..4a1d56d9 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -14,38 +14,39 @@ def add_experimental_features }, JS - insert_into_file 'webpack.config.js', experiments, before: "\n output: {" + insert_into_file 'webpack.config.js', experiments, before: " output: {" end def add_resolve_aliases say 'Adding aliases to the config' alias_js = <<~JS - alias: { - // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. - // Because THREE's package.json has an exports field with different files for - // import and require, without this alias THREE was being added to the bundle twice. - // Not only is that a size problem, but the custom extensions lightning-cad adds to - // CJS version of THREE aren't picked up because the ESM version of THREE appears first - // in the bundle and THREE has a check to prevent THREE from being instantiated twice. - // - 'three/examples': path.resolve('node_modules/three/examples'), - // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. - three: path.resolve('node_modules/three/build/three.module.js'), - - // LCAD uses `require` to bring in mathjs, but rails 7 apps uses `import`, so there are - // two mathjs module instances in play, and without this line both end up in the final bundle. - // TODO: Once LCAD migrates to ES Modules, this line can be removed. - mathjs: path.resolve('node_modules/mathjs/lib/esm'), - - // Webpack apparently doesn't support the * in package.imports, so we need to duplicate - // package.imports here for webpack. - '#components': path.resolve('app/javascript/components'), - '#shared': path.resolve('app/javascript/shared'), - '#three': path.resolve('app/javascript/config/extensions/three.js') - }, - fallback: { - module: false - } + , + alias: { + // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. + // Because THREE's package.json has an exports field with different files for + // import and require, without this alias THREE was being added to the bundle twice. + // Not only is that a size problem, but the custom extensions lightning-cad adds to + // CJS version of THREE aren't picked up because the ESM version of THREE appears first + // in the bundle and THREE has a check to prevent THREE from being instantiated twice. + // + 'three/examples': path.resolve('node_modules/three/examples'), + // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. + three: path.resolve('node_modules/three/build/three.module.js'), + + // LCAD uses `require` to bring in mathjs, but rails 7 apps uses `import`, so there are + // two mathjs module instances in play, and without this line both end up in the final bundle. + // TODO: Once LCAD migrates to ES Modules, this line can be removed. + mathjs: path.resolve('node_modules/mathjs/lib/esm'), + + // Webpack apparently doesn't support the * in package.imports, so we need to duplicate + // package.imports here for webpack. + '#components': path.resolve('app/javascript/components'), + '#shared': path.resolve('app/javascript/shared'), + '#three': path.resolve('app/javascript/config/extensions/three.js') + }, + fallback: { + module: false + } JS insert_into_file 'webpack.config.js', alias_js, after: "extensions: ['.js', '.jsx']" @@ -55,14 +56,14 @@ def add_loaders say 'Adding loaders to the config' loaders = <<~JS - { - test: /\.(mjs|cjs|js|jsx)$/, - loader: 'import-glob' - }, - { - test: /\.scss/, - loader: 'import-glob' - }, + { + test: /\.(mjs|cjs|js|jsx)$/, + loader: 'import-glob' + }, + { + test: /\.scss/, + loader: 'import-glob' + }, JS insert_into_file 'webpack.config.js', loaders, after: "rules: [\n" @@ -71,7 +72,7 @@ def add_loaders def update_esbuild_loader say 'Updating esbuild loader in the config' - insert_into_file 'webpack.config.js', " include: /app\/javascript|@rolemodel\/lightning-cad/,\n", after: "test: /\.(mjs|cjs|js|jsx)$/,\n" + insert_into_file 'webpack.config.js', " include: /app\/javascript|@rolemodel\/lightning-cad/,\n", before: " loader: 'esbuild-loader'," gsub_file 'webpack.config.js', 'es2021', 'esnext' end @@ -79,20 +80,20 @@ def add_terser_plugin_options say 'Updating the terser plugin options in the config' terserPlugin = <<~JS - new TerserPlugin({ - terserOptions: { - keep_classnames: true, - mangle: { - keep_fnames: /^[A-Z]/, - }, - compress: { - keep_fnames: false, - } - } - }), + new TerserPlugin({ + terserOptions: { + keep_classnames: true, + mangle: { + keep_fnames: /^[A-Z]/, + }, + compress: { + keep_fnames: false, + } + } + }), JS - gsub_file 'webpack.config.js', ' new TerserPlugin(),', terserPlugin + gsub_file 'webpack.config.js', " new TerserPlugin(),\n", terserPlugin end end end From 9164c2f303e066375cab3ce54a53761610f70d90 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:52:32 -0600 Subject: [PATCH 32/49] attempt to fix indentation --- .../lightning_cad/webpack_generator.rb | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index 4a1d56d9..7d36e07c 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -8,10 +8,10 @@ def add_experimental_features # copy_file 'webpack.config.js', 'webpack.config.js' say "Adding experimental features to the config" - experiments = <<~JS - experiments: { - topLevelAwait: true - }, + experiments = <<-JS + experiments: { + topLevelAwait: true + }, JS insert_into_file 'webpack.config.js', experiments, before: " output: {" @@ -55,15 +55,15 @@ def add_resolve_aliases def add_loaders say 'Adding loaders to the config' - loaders = <<~JS - { - test: /\.(mjs|cjs|js|jsx)$/, - loader: 'import-glob' - }, - { - test: /\.scss/, - loader: 'import-glob' - }, + loaders = <<-JS + { + test: /\.(mjs|cjs|js|jsx)$/, + loader: 'import-glob' + }, + { + test: /\.scss/, + loader: 'import-glob' + }, JS insert_into_file 'webpack.config.js', loaders, after: "rules: [\n" @@ -72,25 +72,25 @@ def add_loaders def update_esbuild_loader say 'Updating esbuild loader in the config' - insert_into_file 'webpack.config.js', " include: /app\/javascript|@rolemodel\/lightning-cad/,\n", before: " loader: 'esbuild-loader'," + insert_into_file 'webpack.config.js', " include: /app\\/javascript|@rolemodel\\/lightning-cad/,\n", before: " loader: 'esbuild-loader'," gsub_file 'webpack.config.js', 'es2021', 'esnext' end def add_terser_plugin_options say 'Updating the terser plugin options in the config' - terserPlugin = <<~JS - new TerserPlugin({ - terserOptions: { - keep_classnames: true, - mangle: { - keep_fnames: /^[A-Z]/, - }, - compress: { - keep_fnames: false, - } - } - }), + terserPlugin = <<-JS + new TerserPlugin({ + terserOptions: { + keep_classnames: true, + mangle: { + keep_fnames: /^[A-Z]/, + }, + compress: { + keep_fnames: false, + } + } + }), JS gsub_file 'webpack.config.js', " new TerserPlugin(),\n", terserPlugin From 267d5d252700d986cfb21394d7a64a8bae2d59a6 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:56:47 -0600 Subject: [PATCH 33/49] Update indentation --- .../lightning_cad/webpack_generator.rb | 59 +++++++++++-------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index 7d36e07c..df606f83 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -17,33 +17,9 @@ def add_experimental_features insert_into_file 'webpack.config.js', experiments, before: " output: {" end - def add_resolve_aliases - say 'Adding aliases to the config' - alias_js = <<~JS + def add_resolve_fallback + fallback = <<~JS , - alias: { - // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. - // Because THREE's package.json has an exports field with different files for - // import and require, without this alias THREE was being added to the bundle twice. - // Not only is that a size problem, but the custom extensions lightning-cad adds to - // CJS version of THREE aren't picked up because the ESM version of THREE appears first - // in the bundle and THREE has a check to prevent THREE from being instantiated twice. - // - 'three/examples': path.resolve('node_modules/three/examples'), - // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. - three: path.resolve('node_modules/three/build/three.module.js'), - - // LCAD uses `require` to bring in mathjs, but rails 7 apps uses `import`, so there are - // two mathjs module instances in play, and without this line both end up in the final bundle. - // TODO: Once LCAD migrates to ES Modules, this line can be removed. - mathjs: path.resolve('node_modules/mathjs/lib/esm'), - - // Webpack apparently doesn't support the * in package.imports, so we need to duplicate - // package.imports here for webpack. - '#components': path.resolve('app/javascript/components'), - '#shared': path.resolve('app/javascript/shared'), - '#three': path.resolve('app/javascript/config/extensions/three.js') - }, fallback: { module: false } @@ -52,6 +28,37 @@ def add_resolve_aliases insert_into_file 'webpack.config.js', alias_js, after: "extensions: ['.js', '.jsx']" end + def add_resolve_aliases + say 'Adding aliases to the config' + alias_js = <<-JS + alias: { + // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. + // Because THREE's package.json has an exports field with different files for + // import and require, without this alias THREE was being added to the bundle twice. + // Not only is that a size problem, but the custom extensions lightning-cad adds to + // CJS version of THREE aren't picked up because the ESM version of THREE appears first + // in the bundle and THREE has a check to prevent THREE from being instantiated twice. + // + 'three/examples': path.resolve('node_modules/three/examples'), + // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. + three: path.resolve('node_modules/three/build/three.module.js'), + + // LCAD uses `require` to bring in mathjs, but rails 7 apps uses `import`, so there are + // two mathjs module instances in play, and without this line both end up in the final bundle. + // TODO: Once LCAD migrates to ES Modules, this line can be removed. + mathjs: path.resolve('node_modules/mathjs/lib/esm'), + + // Webpack apparently doesn't support the * in package.imports, so we need to duplicate + // package.imports here for webpack. + '#components': path.resolve('app/javascript/components'), + '#shared': path.resolve('app/javascript/shared'), + '#three': path.resolve('app/javascript/config/extensions/three.js') + }, + JS + + insert_into_file 'webpack.config.js', alias_js, before: " fallback: {" + end + def add_loaders say 'Adding loaders to the config' From bf96be305a4592b6c4a58500b94a78c52cae9c33 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 08:58:03 -0600 Subject: [PATCH 34/49] fix var names --- lib/generators/lightning_cad/webpack_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index df606f83..6f4f0b50 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -25,7 +25,7 @@ def add_resolve_fallback } JS - insert_into_file 'webpack.config.js', alias_js, after: "extensions: ['.js', '.jsx']" + insert_into_file 'webpack.config.js', fallback, after: "extensions: ['.js', '.jsx']" end def add_resolve_aliases From 1a4c77206160a54952a81c67e2d19d828bc47793 Mon Sep 17 00:00:00 2001 From: malachirwin Date: Thu, 11 Jan 2024 09:00:12 -0600 Subject: [PATCH 35/49] fix extra new line --- lib/generators/lightning_cad/webpack_generator.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index 6f4f0b50..f29846a7 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -18,12 +18,7 @@ def add_experimental_features end def add_resolve_fallback - fallback = <<~JS - , - fallback: { - module: false - } - JS + fallback = ",\n fallback: {\n module: false\n }" insert_into_file 'webpack.config.js', fallback, after: "extensions: ['.js', '.jsx']" end From 18de83bee269595628715ee87483683c20a93aab Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 19 Apr 2024 08:26:50 -0500 Subject: [PATCH 36/49] add more dependencies --- .../lightning_cad/install_generator.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 54c0e921..636a2ae9 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -8,13 +8,26 @@ def install_yarn_dependencies say 'Adding lightning-cad dependency' copy_file '.npmrc', '.npmrc' + # dependencies = %w[ + # @rolemodel/lightning-cad + # @rolemodel/lightning-cad-ui + # glob + # import-glob + # ] dependencies = %w[ @rolemodel/lightning-cad @rolemodel/lightning-cad-ui - glob - import-glob + mobx-react@^6.1.5 + mobx-utils@^5.5.2 + mobx@^5.15.2 + glob@^10.2.2 + import-glob@1.5.0 + react-router-dom@^5.0.1 + react-popper@^1.3.7 + classnames@^2.2.5 ] + run "yarn add #{dependencies.join(" ")}" end From 78fb889f9333e419ccb49b82417aea2f3128b101 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 19 Apr 2024 09:06:54 -0500 Subject: [PATCH 37/49] Update documentation --- README.md | 4 ++++ lib/generators/lightning_cad/README.md | 31 ++++++++++++++++++++++++++ lib/generators/lightning_cad/USAGE | 17 +++++++++----- 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 lib/generators/lightning_cad/README.md diff --git a/README.md b/README.md index 6e4eaf33..95084d18 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,10 @@ bin/rails g * [Editors](./lib/generators/rolemodel/editors) * [Tailored Select](./lib/generators/rolemodel/tailored_select) +### LightningCAD + +For LightningCAD apps there are [generators](./lib/generators/lightning_cad) to add the required setup + ## Development Install the versions of Node and Ruby specified in `.node-version` and `.ruby-version` on your machine. https://asdf-vm.com/ is a great tool for managing language versions. Then run `npm install -g yarn`. diff --git a/lib/generators/lightning_cad/README.md b/lib/generators/lightning_cad/README.md new file mode 100644 index 00000000..a8ccaa67 --- /dev/null +++ b/lib/generators/lightning_cad/README.md @@ -0,0 +1,31 @@ +# LightningCAD Generator + +Run all the generators: + +``` +rails g lightning_cad:all +``` + +Or run them individually +``` +rails g lightning_cad:install +rails g lightning_cad:webpack +rails g lightning_cad:test +``` + +## Depends On + +- `rolemodel:linters:eslint` +- `rolemodel:optics:base` +- `rolemodel:webpack` +- `rolemodel:react` + +## What you get + +Pulls in [LightningCAD](https://github.com/RoleModel/lightning-cad) and sets up a demo editor + +This will add a route for `/editor` with a blank canvas. + +The main entrypoint into the JavaScript code is through the `/app/javascript/components/App.jsx`. In this file a project is created. You can manually add things to that project to see lines or shapes. + +After running the generators additional setup is required see [how to setup a LightningCAD app](https://github.com/RoleModel/lightning-cad?tab=readme-ov-file#app-setup) for more details. diff --git a/lib/generators/lightning_cad/USAGE b/lib/generators/lightning_cad/USAGE index 07bae697..a9f6e794 100644 --- a/lib/generators/lightning_cad/USAGE +++ b/lib/generators/lightning_cad/USAGE @@ -1,8 +1,15 @@ Description: - This generator requires JS setup including webpack, react, etc... + This generator requires JavaScript setup including webpack, react, and eslint -Example: - bin/rails generate lightning-cad:install Thing + Install: + Installs required dependencies + Generates a demo editor + + Webpack: + Modifies the webpack config to work better for LightningCAD apps - This will create: - what/will/it/create + Test: + Installs jasmine and adds the test setup required for LightningCAD models + +Example: + bin/rails generate lightning-cad:all From f05c2031ddad079923edac82279d8a6853de3b5b Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 19 Apr 2024 09:07:17 -0500 Subject: [PATCH 38/49] Make sure the tools get initialized --- lib/generators/lightning_cad/install_generator.rb | 6 ------ .../templates/app/javascript/components/App.jsx | 4 +++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 636a2ae9..07116f46 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -8,12 +8,6 @@ def install_yarn_dependencies say 'Adding lightning-cad dependency' copy_file '.npmrc', '.npmrc' - # dependencies = %w[ - # @rolemodel/lightning-cad - # @rolemodel/lightning-cad-ui - # glob - # import-glob - # ] dependencies = %w[ @rolemodel/lightning-cad @rolemodel/lightning-cad-ui diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx index 04150ce6..6e3b31fb 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx @@ -37,7 +37,9 @@ export default class App extends React.Component { this._project = new VersionedProject(new Project()) - this._drawingEditors = { top: new DrawingEditor(this._project) } + const top = new DrawingEditor(this._project) + top.toolPalette() + this._drawingEditors = { top } } modalRoot() { return this._modalRoot } From 40c2f3b7434174355e8ad500082516eae861cf05 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 19 Apr 2024 09:11:35 -0500 Subject: [PATCH 39/49] Add chromeCAD support --- lib/generators/lightning_cad/install_generator.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 07116f46..400f1907 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -67,5 +67,13 @@ def add_javascript_initializers run 'mkdir app/javascript/shared/domain-models' run 'touch app/javascript/shared/domain-models/.keep' end + + def setup_chrome_cad + chrome_cad_setup = <<~JS + import { ChromeCADEventEmitter } from '@rolemodel/lightning-cad/drawing-editor' + window.__LCAD_CHROME_CAD_EVENT_EMITTER = new ChromeCADEventEmitter() + JS + append_to_file 'app/javascript/application.js', chrome_cad_setup + end end end From 3fabe031d55e438f5e0d279db4e16f3a7b77209b Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Mon, 22 Apr 2024 08:13:43 -0500 Subject: [PATCH 40/49] update the readme --- lib/generators/lightning_cad/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/README.md b/lib/generators/lightning_cad/README.md index a8ccaa67..90c799ae 100644 --- a/lib/generators/lightning_cad/README.md +++ b/lib/generators/lightning_cad/README.md @@ -26,6 +26,6 @@ Pulls in [LightningCAD](https://github.com/RoleModel/lightning-cad) and sets up This will add a route for `/editor` with a blank canvas. -The main entrypoint into the JavaScript code is through the `/app/javascript/components/App.jsx`. In this file a project is created. You can manually add things to that project to see lines or shapes. +The main entrypoint into the JavaScript code is `/app/javascript/components/App.jsx`. In this file a project is created. You can manually add components like lines or shapes to that project. After running the generators additional setup is required see [how to setup a LightningCAD app](https://github.com/RoleModel/lightning-cad?tab=readme-ov-file#app-setup) for more details. From 44e6872e0d7a2b7c36b4756c0fa2e328a4c25e55 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Mon, 22 Apr 2024 08:20:20 -0500 Subject: [PATCH 41/49] PR Cleanup --- .../lightning_cad/templates/Procfile.dev | 2 - .../app/javascript/components/App.jsx | 4 - .../lightning_cad/templates/webpack.config.js | 155 ------------------ .../lightning_cad/webpack_generator.rb | 1 - 4 files changed, 162 deletions(-) delete mode 100644 lib/generators/lightning_cad/templates/Procfile.dev delete mode 100644 lib/generators/lightning_cad/templates/webpack.config.js diff --git a/lib/generators/lightning_cad/templates/Procfile.dev b/lib/generators/lightning_cad/templates/Procfile.dev deleted file mode 100644 index 03c54b1d..00000000 --- a/lib/generators/lightning_cad/templates/Procfile.dev +++ /dev/null @@ -1,2 +0,0 @@ -web: bin/rails server -p 3000 -js: yarn build --watch diff --git a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx index 6e3b31fb..0b246c1d 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx +++ b/lib/generators/lightning_cad/templates/app/javascript/components/App.jsx @@ -1,7 +1,3 @@ -// Run this example by adding <%= javascript_pack_tag 'hello_react' %> to the head of your layout file, -// like app/views/layouts/application.html.erb. All it does is render
App React
at the bottom -// of the page. - import React from 'react' import { createBrowserHistory } from 'history' import PropTypes from 'prop-types' diff --git a/lib/generators/lightning_cad/templates/webpack.config.js b/lib/generators/lightning_cad/templates/webpack.config.js deleted file mode 100644 index 7d881158..00000000 --- a/lib/generators/lightning_cad/templates/webpack.config.js +++ /dev/null @@ -1,155 +0,0 @@ -import path from 'path' -import webpack from 'webpack' -import TerserPlugin from 'terser-webpack-plugin' -import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack' -import MiniCssExtractPlugin from 'mini-css-extract-plugin' -import CssMinimizerPlugin from 'css-minimizer-webpack-plugin' - -let mode = 'development' - -if (process.env.RAILS_ENV === 'production' || process.env.CI === 'true') { - mode = 'production' -} - -export default { - mode, - devtool: 'source-map', - entry: { - application: [ - './app/javascript/application.js', - './app/assets/stylesheets/application.scss' - ], - mailer: [ - './app/assets/stylesheets/mailer.scss' - ] - }, - experiments: { - topLevelAwait: true - }, - output: { - filename: '[name].js', - sourceMapFilename: '[file].map', - path: path.resolve('app/assets/builds') - }, - resolve: { - modules: ['node_modules'], - extensions: ['.js', '.jsx'], - alias: { - // lightning-cad uses 'require' to pull in THREE, but three-bvh-csg uses 'import'. - // Because THREE's package.json has an exports field with different files for - // import and require, without this alias THREE was being added to the bundle twice. - // Not only is that a size problem, but the custom extensions lightning-cad adds to - // CJS version of THREE aren't picked up because the ESM version of THREE appears first - // in the bundle and THREE has a check to prevent THREE from being instantiated twice. - // - 'three/examples': path.resolve('node_modules/three/examples'), - // TODO: Once lightning-cad migrates to using 'import' to bring in THREE, this alias can be removed. - three: path.resolve('node_modules/three/build/three.module.js'), - - // LCAD uses `require` to bring in mathjs, but airfield_designer uses `import`, so there are - // two mathjs module instances in play, and without this line both end up in the final bundle. - // TODO: Once LCAD migrates to ES Modules, this line can be removed. - mathjs: path.resolve('node_modules/mathjs/lib/esm'), - - // Webpack apparently doesn't support the * in package.imports, so we need to duplicate - // package.imports here for webpack. - '#components': path.resolve('app/javascript/components'), - '#shared': path.resolve('app/javascript/shared'), - '#three': path.resolve('app/javascript/config/extensions/three.js') - }, - fallback: { - module: false - } - }, - module: { - rules: [ - { - test: /\.(mjs|cjs|js|jsx)$/, - loader: 'import-glob' - }, - { - test: /\.scss/, - loader: 'import-glob' - }, - { - test: /\/icons\/.*.svg$/, - type: 'asset/source' - }, - { - test: /\.(jpg|jpeg|png|gif|tiff|ico|eot|otf|ttf|woff|woff2)$/i, - use: 'asset/resource' - }, - { - test: /\.(mjs|cjs|js|jsx)$/, - include: /app\/javascript|@rolemodel\/lightning-cad/, - loader: 'esbuild-loader', - options: { - loader: 'jsx', - target: 'esnext' - }, - // ES Module has stricter rules than CommonJS, so file extensions must be - // used in import statements. To ease migration from CommonJS to ESM, - // uncomment the fullySpecified option below to allow Webpack to use a - // looser set of rules. Not recommend for new projects or the long term. - resolve: { - // Allows importing JS files without specifying the file extension. - fullySpecified: false - } - }, - { - test: /\.(sa|sc|c)ss$/i, - use: [ - MiniCssExtractPlugin.loader, - { - loader: 'css-loader', - options: { - url: false - } - }, - 'postcss-loader' - ] - } - ] - }, - optimization: { - minimize: mode === 'production', - minimizer: [ - new TerserPlugin({ - terserOptions: { - keep_classnames: true, - mangle: { - keep_fnames: /^[A-Z]/, - }, - compress: { - keep_fnames: false, - } - } - }), - new CssMinimizerPlugin() - ] - }, - plugins: [ - // Extract CSS into its own file for the Rails asset pipeline to pick up - new MiniCssExtractPlugin(), - - // We're compiling all JS to a single application.js file - new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1 - }), - - // Replace ENV variables at build time - new webpack.DefinePlugin({ - 'process.env.HONEYBADGER_API_KEY': JSON.stringify(process.env.HONEYBADGER_API_KEY), - 'process.env.HONEYBADGER_ENV': JSON.stringify(process.env.HONEYBADGER_ENV), - 'process.env.RAILS_ENV': JSON.stringify(process.env.RAILS_ENV), - 'process.env.SOURCE_VERSION': JSON.stringify(process.env.SOURCE_VERSION) - }), - - // Send source maps to HoneyBadger in production for easier debugging - (mode === 'production' && !process.env.CI) && new HoneybadgerSourceMapPlugin({ - apiKey: process.env.HONEYBADGER_API_KEY, - assetsUrl: process.env.ASSETS_URL, - revision: process.env.SOURCE_VERSION - }) - ].filter(Boolean) -} diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index f29846a7..c9a41487 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -5,7 +5,6 @@ class WebpackGenerator < Rails::Generators::Base source_root File.expand_path('./templates', __dir__) def add_experimental_features - # copy_file 'webpack.config.js', 'webpack.config.js' say "Adding experimental features to the config" experiments = <<-JS From ffcb40e48b472505548904c23fad91e7b9ae4d11 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Mon, 22 Apr 2024 08:24:19 -0500 Subject: [PATCH 42/49] Cleanup unused files --- .../lightning_cad/templates/babel.config.cjs | 7 ------- lib/generators/lightning_cad/templates/bin/dev | 9 --------- .../lightning_cad/templates/jest.config.js | 17 ----------------- .../templates/lib/tasks/javascript_tests.rake | 1 - 4 files changed, 34 deletions(-) delete mode 100644 lib/generators/lightning_cad/templates/babel.config.cjs delete mode 100644 lib/generators/lightning_cad/templates/bin/dev delete mode 100644 lib/generators/lightning_cad/templates/jest.config.js diff --git a/lib/generators/lightning_cad/templates/babel.config.cjs b/lib/generators/lightning_cad/templates/babel.config.cjs deleted file mode 100644 index d1f738ea..00000000 --- a/lib/generators/lightning_cad/templates/babel.config.cjs +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - presets: [ - ["@babel/preset-env", { targets: { node: "current" } }], - ["@babel/preset-react", { targets: { node: "current" } }], - ], - plugins: ["@babel/plugin-syntax-jsx"], -}; diff --git a/lib/generators/lightning_cad/templates/bin/dev b/lib/generators/lightning_cad/templates/bin/dev deleted file mode 100644 index c1cb98b0..00000000 --- a/lib/generators/lightning_cad/templates/bin/dev +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -if ! foreman version &> /dev/null -then - echo "Installing foreman..." - gem install foreman -fi - -foreman start -f Procfile.dev "$@" diff --git a/lib/generators/lightning_cad/templates/jest.config.js b/lib/generators/lightning_cad/templates/jest.config.js deleted file mode 100644 index 1311fee4..00000000 --- a/lib/generators/lightning_cad/templates/jest.config.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - roots: ["app/javascript", "spec/javascript/components"], - testRegex: "\\Spec\\.(js|jsx)$", - testEnvironmentOptions: { - url: "http://localhost", - }, - transformIgnorePatterns: ["/node_modules(?!\/\@rolemodel\/lightning-cad)/"], - setupFilesAfterEnv: ["./spec/javascript/components/TestSetup.js"], - modulePaths: ["/app/javascript"], - setupFilesAfterEnv: ["./spec/javascript/components/TestSetup.js"], - moduleNameMapper: { - "\\.svg$": - "/node_modules/@rolemodel/lightning-cad/drawing-editor-react/__tests__/mocks/svgMock.js", - "\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": - "/spec/javascript/support/FilePathMock.js", - }, -}; diff --git a/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake b/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake index 3696fea7..ffc529fb 100644 --- a/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake +++ b/lib/generators/lightning_cad/templates/lib/tasks/javascript_tests.rake @@ -2,6 +2,5 @@ desc 'run javascript tests' task javascript_tests: :environment do |t| success = true success &&= system('yarn test_shared') - success &&= system('yarn test_view_ci') abort('JS tests failed') unless success end From 5aa74a4bb7b6db7a15e36defeb349dc281397c50 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Tue, 25 Jun 2024 11:58:20 -0500 Subject: [PATCH 43/49] Update the node version --- .node-version | 2 +- lib/generators/rolemodel/webpack/webpack_generator.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.node-version b/.node-version index 55bffd62..90756595 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -18.15.0 +20.15.0 diff --git a/lib/generators/rolemodel/webpack/webpack_generator.rb b/lib/generators/rolemodel/webpack/webpack_generator.rb index d429265b..d50e4a2e 100644 --- a/lib/generators/rolemodel/webpack/webpack_generator.rb +++ b/lib/generators/rolemodel/webpack/webpack_generator.rb @@ -2,7 +2,7 @@ module Rolemodel class WebpackGenerator < Rails::Generators::Base source_root File.expand_path('templates', __dir__) - NODE_VERSION = '18.15.0'.freeze + NODE_VERSION = '20.15.0'.freeze DEV_DEPS = %w[ @honeybadger-io/webpack From 17fad578f005462df73e4f0a411b426690f2e27c Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Tue, 25 Jun 2024 11:58:47 -0500 Subject: [PATCH 44/49] Update the esbuild target --- lib/generators/rolemodel/webpack/templates/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/rolemodel/webpack/templates/webpack.config.js b/lib/generators/rolemodel/webpack/templates/webpack.config.js index 2b91953d..86fc2688 100644 --- a/lib/generators/rolemodel/webpack/templates/webpack.config.js +++ b/lib/generators/rolemodel/webpack/templates/webpack.config.js @@ -44,7 +44,7 @@ export default { loader: 'esbuild-loader', options: { loader: 'jsx', - target: 'es2021' + target: 'esnext' }, // ES Module has stricter rules than CommonJS, so file extensions must be // used in import statements. To ease migration from CommonJS to ESM, From 158f078ad876da37e40fc6bdbbe6e782f2484722 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Tue, 25 Jun 2024 12:47:28 -0500 Subject: [PATCH 45/49] trim webpack config specific to L.CAD --- lib/generators/lightning_cad/webpack_generator.rb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index c9a41487..82748bf9 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -45,8 +45,7 @@ def add_resolve_aliases // Webpack apparently doesn't support the * in package.imports, so we need to duplicate // package.imports here for webpack. '#components': path.resolve('app/javascript/components'), - '#shared': path.resolve('app/javascript/shared'), - '#three': path.resolve('app/javascript/config/extensions/three.js') + '#shared': path.resolve('app/javascript/shared') }, JS @@ -70,13 +69,6 @@ def add_loaders insert_into_file 'webpack.config.js', loaders, after: "rules: [\n" end - def update_esbuild_loader - say 'Updating esbuild loader in the config' - - insert_into_file 'webpack.config.js', " include: /app\\/javascript|@rolemodel\\/lightning-cad/,\n", before: " loader: 'esbuild-loader'," - gsub_file 'webpack.config.js', 'es2021', 'esnext' - end - def add_terser_plugin_options say 'Updating the terser plugin options in the config' From 7ea71ccd321bdc401e6260b57934dce305255fc5 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Tue, 23 Jul 2024 16:42:14 -0500 Subject: [PATCH 46/49] add node script hooks --- .../lightning_cad/install_generator.rb | 2 + .../templates/app/javascript/helpers/hooks.js | 73 +++++++++++++++++++ .../app/javascript/helpers/register_hooks.js | 3 + .../lightning_cad/test_generator.rb | 2 +- 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js create mode 100644 lib/generators/lightning_cad/templates/app/javascript/helpers/register_hooks.js diff --git a/lib/generators/lightning_cad/install_generator.rb b/lib/generators/lightning_cad/install_generator.rb index 400f1907..e6ff216b 100644 --- a/lib/generators/lightning_cad/install_generator.rb +++ b/lib/generators/lightning_cad/install_generator.rb @@ -62,6 +62,8 @@ def add_javascript_initializers JS append_to_file 'app/javascript/application.js', initializer_setup copy_file 'app/javascript/config/initializers/smartJSON.js', 'app/javascript/config/initializers/smartJSON.js' + copy_file 'app/javascript/helpers/hooks.js', 'app/javascript/helpers/hooks.js' + copy_file 'app/javascript/helpers/register_hooks.js', 'app/javascript/helpers/register_hooks.js' # To prevent smartJSON from throwing an error run 'mkdir app/javascript/shared' run 'mkdir app/javascript/shared/domain-models' diff --git a/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js b/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js new file mode 100644 index 00000000..7e6886e9 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js @@ -0,0 +1,73 @@ +import path from 'node:path' +import * as glob from 'glob' + +const shorthandRoot = path.join(process.cwd(), 'app/javascript') +const config = { + shorthandRoot +} + +export function resolve(specifier, context, nextResolve) { + let finalSpecifier = specifier + if (specifier.startsWith('#')) { + finalSpecifier = resolveShorthandPath(finalSpecifier, context, nextResolve) + } + + if (specifier.includes('*')) { + return resolveGlobPath(finalSpecifier, context, nextResolve) + } + + return nextResolve(finalSpecifier, context) +} + +export function load(specifier, context, nextLoad) { + if (!specifier.includes('*')) return nextLoad(specifier, context) + + const pattern = specifier.replace('file://', '') + const paths = glob.globSync(pattern, { nodir: true }) + + const pathParts = pattern.split('/') + const basePathParts = pathParts.slice(0, pathParts.findIndex(part => part.includes('*'))) + // we need to determine how many times we have a "*" in a folder level. The imports have to go back that far in order to work properly. + const folderLevels = pathParts.length - basePathParts.length - 1 // minus one for the file + const basePath = basePathParts.join('/') + const baseImportPath = `${Array(folderLevels).fill('../').join('')}` + + const getModuleIdentifier = index => `module${index}` + const getImportPath = file => path.join(baseImportPath, path.relative(basePath, file)) + const importStatements = paths.map((file, index) => { + return `import * as ${getModuleIdentifier(index)} from './${getImportPath(file)}'` + }) + const exportStatement = `export default [${paths.map((_s, index) => getModuleIdentifier(index)).join(', ') }]` + + const content = [...importStatements, exportStatement].join('\n') + const source = Buffer.from(content) + + return { + format: "module", + source, + shortCircuit: true + } +} + +function resolveShorthandPath(specifier, _context, _nextResolve) { + return path.join(config.shorthandRoot, specifier.slice(1)) +} + +function resolveGlobPath(specifier, context, _nextResolve) { + // We have to manually resolve the path so that we can load all the files that match the pattern later + let finalPath + if (specifier.startsWith('.')) { // Relative path to parent + const basePath = context.parentURL.replace('file://', '').split('/').slice(0, -1).join('/') + finalPath = path.join(basePath, specifier) + } else if (specifier.startsWith('/')) { // Absolute path + finalPath = specifier + } else { // node modules + finalPath = path.join(process.cwd(), 'node_modules', specifier) + } + + return { + url: `file://${finalPath}`, + type: "module", + shortCircuit: true + } +} diff --git a/lib/generators/lightning_cad/templates/app/javascript/helpers/register_hooks.js b/lib/generators/lightning_cad/templates/app/javascript/helpers/register_hooks.js new file mode 100644 index 00000000..bf581f21 --- /dev/null +++ b/lib/generators/lightning_cad/templates/app/javascript/helpers/register_hooks.js @@ -0,0 +1,3 @@ +import { register } from 'node:module' + +register('./hooks.js', import.meta.url) diff --git a/lib/generators/lightning_cad/test_generator.rb b/lib/generators/lightning_cad/test_generator.rb index ca02fd0f..cbfebfae 100644 --- a/lib/generators/lightning_cad/test_generator.rb +++ b/lib/generators/lightning_cad/test_generator.rb @@ -8,7 +8,7 @@ def add_jasmine_tests say 'Adding jasmine' run "yarn add --dev jasmine@^5.1.0" - run 'npm pkg set scripts.test_shared="NODE_ENV=test NODE_PATH="./node_modules:./app/javascript:$NODE_PATH" jasmine --config=jasmine.json"' + run 'npm pkg set scripts.test_shared="NODE_OPTIONS=\'--import=./app/javascript/helpers/register_hooks.js\' jasmine --config=jasmine.json"' copy_file 'jasmine.json', 'jasmine.json' copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' From 9dc8336c7b3495b163ea4843664f1a6ee699ec38 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 25 Oct 2024 16:12:10 -0500 Subject: [PATCH 47/49] Add file filter loader --- .../templates/app/javascript/helpers/hooks.js | 15 +++++++++-- .../config/webpack/loaders/filter-file.js | 26 +++++++++++++++++++ .../lightning_cad/webpack_generator.rb | 9 ++++++- 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 lib/generators/lightning_cad/templates/config/webpack/loaders/filter-file.js diff --git a/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js b/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js index 7e6886e9..78bd2307 100644 --- a/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js +++ b/lib/generators/lightning_cad/templates/app/javascript/helpers/hooks.js @@ -1,5 +1,6 @@ import path from 'node:path' import * as glob from 'glob' +import filterFile from '../../../config/webpack/loaders/filter-file.js' const shorthandRoot = path.join(process.cwd(), 'app/javascript') const config = { @@ -19,8 +20,18 @@ export function resolve(specifier, context, nextResolve) { return nextResolve(finalSpecifier, context) } -export function load(specifier, context, nextLoad) { - if (!specifier.includes('*')) return nextLoad(specifier, context) +export async function load(specifier, context, nextLoad) { + if (!specifier.includes('*')) { + const result = await nextLoad(specifier, context) + if (!result.source) return result + + const source = filterFile(result.source, 'server') + + return { + ...result, + source + } + } const pattern = specifier.replace('file://', '') const paths = glob.globSync(pattern, { nodir: true }) diff --git a/lib/generators/lightning_cad/templates/config/webpack/loaders/filter-file.js b/lib/generators/lightning_cad/templates/config/webpack/loaders/filter-file.js new file mode 100644 index 00000000..e3effe98 --- /dev/null +++ b/lib/generators/lightning_cad/templates/config/webpack/loaders/filter-file.js @@ -0,0 +1,26 @@ +/** + * Webpack loader to filter server-only or client-only sections of code out of + * a file, based on the current target (e.g., 'web' or 'node') + */ +export default function (source, target = this.target) { + let begin, end + if (target === 'web') { + begin = '// @begin-server-only' + end = '// @end-server-only' + } else { + begin = '// @begin-client-only' + end = '// @end-client-only' + } + + let filteredSource = source + let beginIndex = filteredSource.indexOf(begin) + let endIndex = filteredSource.indexOf(end) + while (beginIndex !== -1) { + const afterExcludedBlock = endIndex === -1 ? '' : filteredSource.slice(endIndex + end.length) + filteredSource = filteredSource.slice(0, beginIndex) + afterExcludedBlock + beginIndex = filteredSource.indexOf(begin) + endIndex = filteredSource.indexOf(end) + } + + return filteredSource +} diff --git a/lib/generators/lightning_cad/webpack_generator.rb b/lib/generators/lightning_cad/webpack_generator.rb index 82748bf9..bf329d90 100644 --- a/lib/generators/lightning_cad/webpack_generator.rb +++ b/lib/generators/lightning_cad/webpack_generator.rb @@ -55,7 +55,14 @@ def add_resolve_aliases def add_loaders say 'Adding loaders to the config' + copy_file 'config/webpack/loaders/filter-file.js' + loaders = <<-JS +, + { + test: /\.jsx?$/, + use: path.resolve('./config/webpack/loaders/filter-file.js') + }, { test: /\.(mjs|cjs|js|jsx)$/, loader: 'import-glob' @@ -66,7 +73,7 @@ def add_loaders }, JS - insert_into_file 'webpack.config.js', loaders, after: "rules: [\n" + insert_into_file 'webpack.config.js', loaders, after: "'postcss-loader'\n ]\n }" end def add_terser_plugin_options From 42f4cc43579db494b01393b89010e33c9255eaed Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 25 Oct 2024 16:44:34 -0500 Subject: [PATCH 48/49] Add browser testing --- .../lightning_cad/templates/jasmine.json | 6 ++--- .../templates/jp-runner.config.js | 14 +++++++++++ .../spec/javascript/{shared => }/.eslintrc.js | 0 .../spec/javascript/browser/TestSetup.js | 1 + .../spec/javascript/helpers/initializers.js | 18 -------------- .../spec/javascript/server/TestSetup.js | 1 + .../spec/javascript/shared/TestSetup.js | 4 +--- .../lightning_cad/test_generator.rb | 24 +++++++++---------- 8 files changed, 31 insertions(+), 37 deletions(-) create mode 100644 lib/generators/lightning_cad/templates/jp-runner.config.js rename lib/generators/lightning_cad/templates/spec/javascript/{shared => }/.eslintrc.js (100%) create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/browser/TestSetup.js delete mode 100644 lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js create mode 100644 lib/generators/lightning_cad/templates/spec/javascript/server/TestSetup.js diff --git a/lib/generators/lightning_cad/templates/jasmine.json b/lib/generators/lightning_cad/templates/jasmine.json index 1cec6cba..77dab913 100644 --- a/lib/generators/lightning_cad/templates/jasmine.json +++ b/lib/generators/lightning_cad/templates/jasmine.json @@ -1,6 +1,6 @@ { - "spec_dir": "spec/javascript/shared", - "spec_files": ["**/*[sS]pec.js"], - "helpers": ["TestSetup.js"], + "spec_dir": "spec/javascript", + "spec_files": ["shared/**/*[sS]pec.js", "server/**/*[sS]pec.js"], + "helpers": ["./shared/TestSetup.js", "./server/TestSetup.js"], "stopSpecOnExpectationFailure": true } diff --git a/lib/generators/lightning_cad/templates/jp-runner.config.js b/lib/generators/lightning_cad/templates/jp-runner.config.js new file mode 100644 index 00000000..e77b41c1 --- /dev/null +++ b/lib/generators/lightning_cad/templates/jp-runner.config.js @@ -0,0 +1,14 @@ +import DetailedTestFormatter from '@rolemodel/jasmine-playwright-runner/src/server/DetailedTestFormatter.js' + +export default { + specPatterns: [ + 'spec/javascript/browser/**/*Spec.js', + 'spec/javascript/browser/**/*Spec.jsx', + 'spec/javascript/shared/**/*Spec.js' + ], + setupFiles: [ + 'spec/javascript/shared/TestSetup.js', + 'spec/javascript/browser/TestSetup.js' + ], + formatter: new DetailedTestFormatter() +} diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js b/lib/generators/lightning_cad/templates/spec/javascript/.eslintrc.js similarity index 100% rename from lib/generators/lightning_cad/templates/spec/javascript/shared/.eslintrc.js rename to lib/generators/lightning_cad/templates/spec/javascript/.eslintrc.js diff --git a/lib/generators/lightning_cad/templates/spec/javascript/browser/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/browser/TestSetup.js new file mode 100644 index 00000000..89bcfaa6 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/browser/TestSetup.js @@ -0,0 +1 @@ +// for browser only test setup diff --git a/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js b/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js deleted file mode 100644 index e7c47b03..00000000 --- a/lib/generators/lightning_cad/templates/spec/javascript/helpers/initializers.js +++ /dev/null @@ -1,18 +0,0 @@ -import fs from 'fs' -import path from 'path' -import * as url from 'url' -const __dirname = url.fileURLToPath(new URL(".", import.meta.url)) - -const absoluteBasePath = path.resolve( - path.join(__dirname, '../../../app/javascript/config/initializers') -) - -const files = fs.readdirSync(absoluteBasePath) - -await Promise.all( - files.map(async (file) => { - if (file.endsWith('.js')) { - await import(path.join(absoluteBasePath, file)) - } - }) -) diff --git a/lib/generators/lightning_cad/templates/spec/javascript/server/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/server/TestSetup.js new file mode 100644 index 00000000..d1e95c66 --- /dev/null +++ b/lib/generators/lightning_cad/templates/spec/javascript/server/TestSetup.js @@ -0,0 +1 @@ +// for server only test setup diff --git a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js index 8e124c86..9e1a00a6 100644 --- a/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js +++ b/lib/generators/lightning_cad/templates/spec/javascript/shared/TestSetup.js @@ -1,11 +1,9 @@ -// Bring Array extensions import "@rolemodel/lightning-cad/standard-utilities" -import '../helpers/initializers.js' +import '../../../app/javascript/config/initializers/**/*.js' import EqualityHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/EqualityHelper' import ToIncludeHelper from '@rolemodel/lightning-cad/standard-utilities/spec/helpers/ToIncludeHelper' beforeAll(EqualityHelper) beforeAll(ToIncludeHelper) - diff --git a/lib/generators/lightning_cad/test_generator.rb b/lib/generators/lightning_cad/test_generator.rb index cbfebfae..c192df87 100644 --- a/lib/generators/lightning_cad/test_generator.rb +++ b/lib/generators/lightning_cad/test_generator.rb @@ -6,21 +6,19 @@ class TestGenerator < Rails::Generators::Base def add_jasmine_tests say 'Adding jasmine' - run "yarn add --dev jasmine@^5.1.0" + run "yarn add --dev jasmine@^5.1.0 @rolemodel/jasmine-playwright-runner @testing-library/react" - run 'npm pkg set scripts.test_shared="NODE_OPTIONS=\'--import=./app/javascript/helpers/register_hooks.js\' jasmine --config=jasmine.json"' + run 'npm pkg set scripts.test:server="NODE_OPTIONS=\'--import=./app/javascript/helpers/register_hooks.js\' jasmine --config=jasmine.json"' + run 'npm pkg set scripts.test:browser="NODE_ENV=test jp-runner"' + run 'npm pkg set scripts.test="yarn test:server && yarn test:browser"' - copy_file 'jasmine.json', 'jasmine.json' - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' - copy_file 'spec/javascript/shared/.eslintrc.js', 'spec/javascript/shared/.eslintrc.js' - copy_file 'spec/javascript/shared/TestSetup.js', 'spec/javascript/shared/TestSetup.js' - copy_file 'spec/javascript/shared/testSpec.js', 'spec/javascript/shared/testSpec.js' - end - - def add_test_initializers - say 'Adding test initializers' - - copy_file 'spec/javascript/helpers/initializers.js', 'spec/javascript/helpers/initializers.js' + copy_file 'jasmine.json' + copy_file 'jp-runner.config.json' + copy_file 'spec/javascript/.eslintrc.js' + copy_file 'spec/javascript/shared/TestSetup.js' + copy_file 'spec/javascript/browser/TestSetup.js' + copy_file 'spec/javascript/server/TestSetup.js' + copy_file 'spec/javascript/shared/testSpec.js' end end end From 1900cf75175592c51b61aa1f8c1ec6929d19d8d9 Mon Sep 17 00:00:00 2001 From: Malachi Irwin Date: Fri, 25 Oct 2024 16:49:13 -0500 Subject: [PATCH 49/49] fix file name --- lib/generators/lightning_cad/test_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/lightning_cad/test_generator.rb b/lib/generators/lightning_cad/test_generator.rb index c192df87..10b0e89c 100644 --- a/lib/generators/lightning_cad/test_generator.rb +++ b/lib/generators/lightning_cad/test_generator.rb @@ -13,7 +13,7 @@ def add_jasmine_tests run 'npm pkg set scripts.test="yarn test:server && yarn test:browser"' copy_file 'jasmine.json' - copy_file 'jp-runner.config.json' + copy_file 'jp-runner.config.js' copy_file 'spec/javascript/.eslintrc.js' copy_file 'spec/javascript/shared/TestSetup.js' copy_file 'spec/javascript/browser/TestSetup.js'