diff --git a/.eslintignore b/.eslintignore
index 4447ad67265..885e2cf3c7c 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -12,3 +12,4 @@ node_modules/
spec/
dist/
tmp/
+documentation/
diff --git a/.gitattributes b/.gitattributes
index 546b134a0ce..2ba82579ac6 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -27,3 +27,7 @@
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
+
+# Ember App
+*.gjs linguist-language=js linguist-detectable
+*.gts linguist-language=ts linguist-detectable
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 90492aebc06..a7d0c1c2661 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,2 +1,2 @@
chat:
-- plugins/chat/**/*
+ - plugins/chat/**/*
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 057208eda32..b308d844199 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -1,14 +1,17 @@
-name: "Pull Request Labeler"
+name: Pull Request Labeler
+
on:
-- pull_request_target
+ - pull_request_target
+
+permissions:
+ contents: read
+ pull-requests: write
jobs:
triage:
- permissions:
- contents: read
- pull-requests: write
runs-on: ubuntu-latest
+
steps:
- - uses: actions/labeler@v4
- with:
- repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ - uses: actions/labeler@v4
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/licenses.yml b/.github/workflows/licenses.yml
index de665ecf290..40e53ad0c4a 100644
--- a/.github/workflows/licenses.yml
+++ b/.github/workflows/licenses.yml
@@ -15,7 +15,7 @@ permissions:
jobs:
build:
- if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
+ if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
@@ -36,8 +36,7 @@ jobs:
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
- restore-keys: |
- ${{ runner.os }}-gem-
+ restore-keys: ${{ runner.os }}-gem-
- name: Setup gems
run: |
@@ -61,8 +60,7 @@ jobs:
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ restore-keys: ${{ runner.os }}-yarn-
- name: Check RubyGems Licenses
if: ${{ !cancelled() }}
diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
index b2125eea167..0ded454e9e6 100644
--- a/.github/workflows/linting.yml
+++ b/.github/workflows/linting.yml
@@ -15,13 +15,16 @@ permissions:
jobs:
build:
- if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
+ if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
timeout-minutes: 30
steps:
+ - name: Set working directory owner
+ run: chown root:root .
+
- uses: actions/checkout@v3
with:
fetch-depth: 1
@@ -36,8 +39,7 @@ jobs:
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
- restore-keys: |
- ${{ runner.os }}-gem-
+ restore-keys: ${{ runner.os }}-gem-
- name: Setup gems
run: |
@@ -58,11 +60,10 @@ jobs:
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ restore-keys: ${{ runner.os }}-yarn-
- name: Yarn install
- run: yarn install
+ run: yarn install --frozen-lockfile
- name: Rubocop
if: ${{ !cancelled() }}
@@ -70,33 +71,27 @@ jobs:
- name: syntax_tree
if: ${{ !cancelled() }}
- run: bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake')
+ run: |
+ set -E
+ bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake')
- name: ESLint (core)
if: ${{ !cancelled() }}
- run: yarn eslint app/assets/javascripts
+ run: yarn lint:js
- name: ESLint (core plugins)
if: ${{ !cancelled() }}
- run: yarn eslint plugins
+ run: yarn lint:js-plugins
- name: Prettier
if: ${{ !cancelled() }}
run: |
yarn prettier -v
- yarn pprettier --list-different \
- "app/assets/stylesheets/**/*.scss" \
- "app/assets/javascripts/**/*.js" \
- "plugins/**/assets/stylesheets/**/*.scss" \
- "plugins/**/assets/javascripts/**/*.js"
+ yarn lint:prettier
- name: Ember template lint
if: ${{ !cancelled() }}
- run: |
- yarn ember-template-lint \
- --no-error-on-unmatched-pattern \
- "app/assets/javascripts/**/*.hbs" \
- "plugins/**/assets/javascripts/**/*.hbs"
+ run: yarn lint:hbs
- name: English locale lint (core)
if: ${{ !cancelled() }}
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 2598bcac746..d8c991f8809 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,20 +17,19 @@ permissions:
jobs:
build:
- if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
- name: ${{ matrix.target }} ${{ matrix.build_type }}
+ if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
+ name: ${{ matrix.target }} ${{ matrix.build_type }} ${{ matrix.ruby }}
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
- container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}
+ container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.1') && '-ruby-3.1.0' || '' }}
timeout-minutes: 20
env:
DISCOURSE_HOSTNAME: www.example.com
- RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
RAILS_ENV: test
PGUSER: discourse
PGPASSWORD: discourse
- USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' }}
- CAPBYARA_DEFAULT_MAX_WAIT_TIME: 4
+ USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
+ CAPYBARA_DEFAULT_MAX_WAIT_TIME: 10
strategy:
fail-fast: false
@@ -38,6 +37,7 @@ jobs:
matrix:
build_type: [backend, frontend, system, annotations]
target: [core, plugins]
+ ruby: ["3.2"]
exclude:
- build_type: annotations
target: plugins
@@ -71,9 +71,8 @@ jobs:
uses: actions/cache@v3
with:
path: vendor/bundle
- key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
- restore-keys: |
- ${{ runner.os }}-gem-
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: ${{ runner.os }}-${{ matrix.ruby }}-gem-
- name: Setup gems
run: |
@@ -94,11 +93,10 @@ jobs:
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ restore-keys: ${{ runner.os }}-yarn-
- name: Yarn install
- run: yarn install
+ run: yarn install --frozen-lockfile
- name: Checkout official plugins
if: matrix.target == 'plugins'
@@ -113,10 +111,9 @@ jobs:
id: app-cache
with:
path: tmp/app-cache
- key: >- # postgres version, hash of migrations, "parallel?"
+ key: >-
${{ runner.os }}-
${{ hashFiles('.github/workflows/tests.yml') }}-
- ${{ matrix.postgres }}-
${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}-
${{ env.USES_PARALLEL_DATABASES }}
@@ -153,18 +150,50 @@ jobs:
- name: Fetch turbo_rspec_runtime.log cache
uses: actions/cache@v3
id: test-runtime-cache
- if: matrix.build_type == 'backend' && matrix.target == 'core'
+ if: matrix.build_type == 'backend' || matrix.build_type == 'system'
with:
path: tmp/turbo_rspec_runtime.log
- key: rspec-runtime-backend-core
+ key: rspec-runtime-${{ matrix.build_type }}-${{ matrix.target }}-${{ github.run_id }}
+ restore-keys: rspec-runtime-${{ matrix.build_type }}-${{ matrix.target }}-
+
+ - name: Check Zeitwerk eager_load
+ if: matrix.build_type == 'backend'
+ env:
+ LOAD_PLUGINS: ${{ (matrix.target == 'plugins') && '1' || '0' }}
+ run: |
+ if ! bin/rails zeitwerk:check --trace; then
+ echo
+ echo "---------------------------------------------"
+ echo
+ echo "::error::'bin/rails zeitwerk:check' failed - the app will fail to boot with 'eager_load=true' (e.g. in production)."
+ echo "To reproduce locally, run 'bin/rails zeitwerk:check'."
+ echo "Alternatively, you can run your local server/tests with the 'DISCOURSE_ZEITWERK_EAGER_LOAD=1' environment variable."
+ echo
+ exit 1
+ fi
+
+ - name: Check Zeitwerk reloading
+ if: matrix.build_type == 'backend'
+ env:
+ LOAD_PLUGINS: ${{ (matrix.target == 'plugins') && '1' || '0' }}
+ run: |
+ if ! bin/rails runner 'Rails.application.reloader.reload!'; then
+ echo
+ echo "---------------------------------------------"
+ echo
+ echo "::error::Zeitwerk reload failed - the app will not be able to reload properly in development."
+ echo "To reproduce locally, run \`bin/rails runner 'Rails.application.reloader.reload!'\`."
+ echo
+ exit 1
+ fi
- name: Core RSpec
if: matrix.build_type == 'backend' && matrix.target == 'core'
- run: bin/turbo_rspec --verbose
+ run: bin/turbo_rspec --use-runtime-info --verbose --format documentation
- name: Plugin RSpec
if: matrix.build_type == 'backend' && matrix.target == 'plugins'
- run: bin/rake plugin:turbo_spec
+ run: bin/rake plugin:turbo_spec['*','--verbose --format documentation --use-runtime-info']
- name: Plugin QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'plugins'
@@ -181,11 +210,12 @@ jobs:
- name: Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
- run: bin/rspec spec/system --format documentation --profile
+ run: RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error PARALLEL_TEST_PROCESSORS=4 bin/turbo_rspec --use-runtime-info --profile=50 --verbose --format documentation spec/system
- name: Plugin System Tests
if: matrix.build_type == 'system' && matrix.target == 'plugins'
- run: LOAD_PLUGINS=1 bin/rspec plugins/*/spec/system --format documentation --profile
+ run: LOAD_PLUGINS=1 RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error PARALLEL_TEST_PROCESSORS=4 bin/turbo_rspec --use-runtime-info --profile=50 --verbose --format documentation plugins/*/spec/system
+ timeout-minutes: 30
- name: Upload failed system test screenshots
uses: actions/upload-artifact@v3
@@ -212,7 +242,7 @@ jobs:
timeout-minutes: 30
core_frontend_tests:
- if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
+ if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
name: core frontend (${{ matrix.browser }})
runs-on: ubuntu-20.04-8core
container:
@@ -250,26 +280,25 @@ jobs:
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ restore-keys: ${{ runner.os }}-yarn-
- name: Yarn install
working-directory: ./app/assets/javascripts/discourse
- run: yarn install
+ run: yarn install --frozen-lockfile
- name: Ember Build
working-directory: ./app/assets/javascripts/discourse
run: |
mkdir /tmp/emberbuild
- yarn ember build --environment=test -o /tmp/emberbuild
+ yarn ember build --environment=test -o /tmp/emberbuild
- name: Core QUnit
working-directory: ./app/assets/javascripts/discourse
- run: yarn ember exam --path /tmp/emberbuild --load-balance --parallel=5 --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random
+ run: yarn ember exam --path /tmp/emberbuild --load-balance --parallel=5 --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random
timeout-minutes: 15
- uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
- name: ember-exam-execution-${{matrix.browser}}
+ name: ember-exam-execution-${{ matrix.browser }}
path: ./app/assets/javascripts/discourse/test-execution-*.json
diff --git a/.gitignore b/.gitignore
index ad4ff4d9294..6b335523351 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,7 @@
!/plugins/discourse-local-dates
!/plugins/discourse-narrative-bot
!/plugins/discourse-presence
-!/plugins/lazy-yt/
+!/plugins/discourse-lazy-videos/
!/plugins/chat/
!/plugins/poll/
!/plugins/styleguide
@@ -52,12 +52,20 @@
# We provide a .sample but people can use newer versions if they want to
.ruby-version
+.ruby-gemset
+
+# Likewise, there is a .vscode-sample for VSCode config
+.vscode
# Front-end
dist
node_modules
yarn-error.log
+# Linting artifacts
+.eslintcache
+/lint-progress/
+
# Auto-generated plugin JS assets
/app/assets/javascripts/plugins/*
diff --git a/.jsdoc b/.jsdoc
new file mode 100644
index 00000000000..06d1cf60830
--- /dev/null
+++ b/.jsdoc
@@ -0,0 +1,21 @@
+// jsdoc doesn't accept paths starting with _ (which is the case on github runners)
+// so we need to alter the default config
+{
+ "source": {
+ "excludePattern": ""
+ },
+ "templates": {
+ "default": {
+ "includeDate": false
+ }
+ },
+ "opts": {
+ "template": "./node_modules/tidy-jsdoc",
+ "prism-theme": "prism-custom",
+ "encoding": "utf8",
+ "recurse": true
+ },
+ "metadata": {
+ "title": "Discourse"
+ }
+}
diff --git a/.licensed.yml b/.licensed.yml
index 044e732fad2..75e581cdb55 100644
--- a/.licensed.yml
+++ b/.licensed.yml
@@ -51,6 +51,7 @@ reviewed:
- net-imap # Ruby (bundled gem)
- net-pop # Ruby (bundled gem)
- net-smtp # Ruby (bundled gem)
+ - nio4r # MIT + BSD
- omniauth # MIT
- pg # Ruby
- r2 # Apache-2.0 (Twitter)
diff --git a/.licensee.json b/.licensee.json
index 6fe0d279c89..93d376127f5 100644
--- a/.licensee.json
+++ b/.licensee.json
@@ -11,7 +11,9 @@
"packages": {
"@fortawesome/fontawesome-free": "*",
"ember-template-lint-plugin-discourse": "*",
- "squoosh": "2.0.0"
+ "spawn-command": "0.0.2",
+ "squoosh": "2.0.0",
+ "taffydb": "2.6.2"
},
"corrections": true
-}
\ No newline at end of file
+}
diff --git a/.prettierignore b/.prettierignore
index 93b35f929e2..c1caccc0683 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -3,6 +3,7 @@ plugins/**/assets/stylesheets/vendor/
plugins/**/assets/javascripts/vendor/
plugins/**/config/locales/**/*.yml
plugins/**/config/*.yml
+documentation/
package.json
config/locales/**/*.yml
!config/locales/**/*.en*.yml
diff --git a/.prettierrc b/.prettierrc
index 0967ef424bc..8a1423e9391 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1 +1,17 @@
-{}
+{
+ "plugins": ["prettier-plugin-ember-template-tag"],
+ "overrides": [
+ {
+ "files": "*.gjs",
+ "options": {
+ "parser": "ember-template-tag"
+ }
+ },
+ {
+ "files": "*.gts",
+ "options": {
+ "parser": "ember-template-tag"
+ }
+ }
+ ]
+}
diff --git a/.rubocop.yml b/.rubocop.yml
index 4d4ad6d8d80..68abba36ad9 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -7,3 +7,7 @@ Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
Discourse/NoResetColumnInformationInMigrations:
Enabled: true
+
+Lint/Debugger:
+ Exclude:
+ - script/**/*
diff --git a/.ruby-version.sample b/.ruby-version.sample
index ff365e06b95..e4604e3afd0 100644
--- a/.ruby-version.sample
+++ b/.ruby-version.sample
@@ -1 +1 @@
-3.1.3
+3.2.1
diff --git a/.template-lintrc.js b/.template-lintrc.js
index a5c4998a0ce..2c70a9c5068 100644
--- a/.template-lintrc.js
+++ b/.template-lintrc.js
@@ -5,6 +5,7 @@ module.exports = {
rules: {
"no-action-modifiers": true,
"no-args-paths": true,
+ "no-array-prototype-extensions": false,
"no-attrs-in-components": true,
"no-capital-arguments": false, // TODO: we extensively use `args` argument name
"no-curly-component-invocation": {
@@ -15,12 +16,15 @@ module.exports = {
"directory-item-value",
"directory-table-header-title",
"loading-spinner",
- "mobile-directory-item-label",
+ "directory-item-label",
],
},
"no-implicit-this": {
allow: ["loading-spinner"],
},
+ "no-obscure-array-access": false,
+ "require-mandatory-role-attributes": false,
+ "require-media-caption": false,
// Begin prettier compatibility
"eol-last": false,
"self-closing-void-elements": false,
diff --git a/.vscode-sample/extensions.json b/.vscode-sample/extensions.json
new file mode 100644
index 00000000000..86c6cd8f91c
--- /dev/null
+++ b/.vscode-sample/extensions.json
@@ -0,0 +1,12 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
+ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
+
+ // List of extensions which should be recommended for users of this workspace.
+ "recommendations": [
+ "esbenp.prettier-vscode",
+ "typed-ember.glint-vscode",
+ "chiragpat.vscode-glimmer",
+ "dbaeumer.vscode-eslint"
+ ]
+}
diff --git a/.vscode-sample/settings.json b/.vscode-sample/settings.json
new file mode 100644
index 00000000000..5650eb57a33
--- /dev/null
+++ b/.vscode-sample/settings.json
@@ -0,0 +1,12 @@
+{
+ "[gjs]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[gts]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "eslint.validate": [
+ "glimmer-js",
+ "glimmer-ts"
+ ]
+}
diff --git a/Gemfile b/Gemfile
index f42b8d9cc3d..647aefea8ad 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,7 +18,7 @@ else
# this allows us to include the bits of rails we use without pieces we do not.
#
# To issue a rails update bump the version number here
- rails_version = "7.0.4.3"
+ rails_version = "7.0.5.1"
gem "actionmailer", rails_version
gem "actionpack", rails_version
gem "actionview", rails_version
@@ -32,8 +32,8 @@ end
gem "json"
# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals
-# This is a desired upgrade we should get to.
-gem "sprockets", "3.7.2"
+# We intend to drop sprockets rather than upgrade to 4.x
+gem "sprockets", git: "https://github.com/rails/sprockets", branch: "3.x"
# this will eventually be added to rails,
# allows us to precompile all our templates in the unicorn master
@@ -41,7 +41,7 @@ gem "actionview_precompiler", require: false
gem "discourse-seed-fu"
-gem "mail", git: "https://github.com/discourse/mail.git"
+gem "mail"
gem "mini_mime"
gem "mini_suffix"
@@ -71,8 +71,6 @@ gem "rails_multisite"
gem "fast_xs", platform: :ruby
-gem "xorcist"
-
gem "fastimage"
gem "aws-sdk-s3", require: false
@@ -98,14 +96,13 @@ gem "omniauth-oauth2", require: false
gem "omniauth-google-oauth2"
-# pending: https://github.com/ohler55/oj/issues/789
-gem "oj", "3.13.14"
+gem "oj"
gem "pg"
gem "mini_sql"
gem "pry-rails", require: false
gem "pry-byebug", require: false
-gem "r2", require: false
+gem "rtlcss", require: false
gem "rake"
gem "thor", require: false
@@ -147,6 +144,7 @@ group :test do
gem "selenium-webdriver", require: false
gem "test-prof"
gem "webdrivers", require: false
+ gem "rails-dom-testing", require: false
end
group :test, :development do
@@ -160,7 +158,7 @@ group :test, :development do
gem "rspec-rails"
- gem "shoulda-matchers", require: false
+ gem "shoulda-matchers", require: false, github: "thoughtbot/shoulda-matchers"
gem "rspec-html-matchers"
gem "byebug", require: ENV["RM_INFO"].nil?, platform: :mri
gem "rubocop-discourse", require: false
@@ -180,6 +178,7 @@ group :development do
gem "better_errors", platform: :mri, require: !!ENV["BETTER_ERRORS"]
gem "binding_of_caller"
gem "yaml-lint"
+ gem "yard"
end
if ENV["ALLOW_DEV_POPULATE"] == "1"
@@ -229,10 +228,9 @@ gem "logstash-event", require: false
gem "logstash-logger", require: false
gem "logster"
-# NOTE: later versions of sassc are causing a segfault, possibly dependent on processer architecture
-# and until resolved should be locked at 2.0.1
-gem "sassc", "2.0.1", require: false
-gem "sassc-rails"
+# These are forks of sassc and sassc-rails with dart-sass support
+gem "dartsass-ruby"
+gem "dartsass-sprockets"
gem "rotp", require: false
@@ -274,8 +272,7 @@ gem "faraday-retry"
# https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
gem "net-http"
-# workaround for prometheus-client
-gem "webrick", require: false
-
# Workaround until Ruby ships with cgi version 0.3.6 or higher.
gem "cgi", ">= 0.3.6", require: false
+
+gem "tzinfo-data"
diff --git a/Gemfile.lock b/Gemfile.lock
index 1d24db2da52..60f09c27d00 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,32 +1,41 @@
GIT
- remote: https://github.com/discourse/mail.git
- revision: 5b700fc95ee66378e0cf2559abc73c8bc3062a4b
+ remote: https://github.com/rails/sprockets
+ revision: f4d3dae71ef29c44b75a49cfbf8032cce07b423a
+ branch: 3.x
specs:
- mail (2.8.0.edge)
- mini_mime (>= 0.1.1)
+ sprockets (3.7.2)
+ concurrent-ruby (~> 1.0)
+ rack (> 1, < 3)
+
+GIT
+ remote: https://github.com/thoughtbot/shoulda-matchers.git
+ revision: 783a90554053002017510285bc736099b2749c22
+ specs:
+ shoulda-matchers (5.3.0)
+ activesupport (>= 5.2.0)
GEM
remote: https://rubygems.org/
specs:
- actionmailer (7.0.4.3)
- actionpack (= 7.0.4.3)
- actionview (= 7.0.4.3)
- activejob (= 7.0.4.3)
- activesupport (= 7.0.4.3)
+ actionmailer (7.0.5.1)
+ actionpack (= 7.0.5.1)
+ actionview (= 7.0.5.1)
+ activejob (= 7.0.5.1)
+ activesupport (= 7.0.5.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
- actionpack (7.0.4.3)
- actionview (= 7.0.4.3)
- activesupport (= 7.0.4.3)
- rack (~> 2.0, >= 2.2.0)
+ actionpack (7.0.5.1)
+ actionview (= 7.0.5.1)
+ activesupport (= 7.0.5.1)
+ rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
- actionview (7.0.4.3)
- activesupport (= 7.0.4.3)
+ actionview (7.0.5.1)
+ activesupport (= 7.0.5.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@@ -35,20 +44,20 @@ GEM
actionview (>= 6.0.a)
active_model_serializers (0.8.4)
activemodel (>= 3.0)
- activejob (7.0.4.3)
- activesupport (= 7.0.4.3)
+ activejob (7.0.5.1)
+ activesupport (= 7.0.5.1)
globalid (>= 0.3.6)
- activemodel (7.0.4.3)
- activesupport (= 7.0.4.3)
- activerecord (7.0.4.3)
- activemodel (= 7.0.4.3)
- activesupport (= 7.0.4.3)
- activesupport (7.0.4.3)
+ activemodel (7.0.5.1)
+ activesupport (= 7.0.5.1)
+ activerecord (7.0.5.1)
+ activemodel (= 7.0.5.1)
+ activesupport (= 7.0.5.1)
+ activesupport (7.0.5.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- addressable (2.8.1)
+ addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
@@ -73,20 +82,20 @@ GEM
aws-sigv4 (~> 1.1)
aws-sigv4 (1.5.0)
aws-eventstream (~> 1, >= 1.0.2)
- better_errors (2.9.1)
- coderay (>= 1.0.0)
+ better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
+ rouge (>= 1.0.0)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
- bootsnap (1.15.0)
+ bootsnap (1.16.0)
msgpack (~> 1.2)
builder (3.2.4)
bullet (7.0.7)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
- capybara (3.38.0)
+ capybara (3.39.2)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -101,8 +110,8 @@ GEM
chunky_png (1.4.0)
coderay (1.1.3)
colored2 (3.1.2)
- concurrent-ruby (1.1.10)
- connection_pool (2.3.0)
+ concurrent-ruby (1.2.2)
+ connection_pool (2.4.1)
cose (1.3.0)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
@@ -110,8 +119,17 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
- css_parser (1.13.0)
+ css_parser (1.14.0)
addressable
+ dartsass-ruby (3.0.1)
+ sass-embedded (~> 1.54)
+ dartsass-sprockets (3.0.0)
+ dartsass-ruby (~> 3.0)
+ railties (>= 4.0.0)
+ sprockets (> 3.0)
+ sprockets-rails
+ tilt
+ date (3.3.3)
debug_inspector (1.1.0)
diff-lcs (1.5.0)
diffy (3.4.2)
@@ -124,31 +142,34 @@ GEM
faker (~> 2.16)
literate_randomizer
docile (1.4.0)
- ecma-re-validator (0.4.0)
- regexp_parser (~> 2.2)
email_reply_trimmer (0.1.13)
- erubi (1.11.0)
- excon (0.96.0)
+ erubi (1.12.0)
+ excon (0.100.0)
execjs (2.8.1)
- exifr (1.3.10)
+ exifr (1.4.0)
fabrication (2.30.0)
faker (2.23.0)
i18n (>= 1.8.11, < 2)
fakeweb (1.3.0)
- faraday (2.7.2)
+ faraday (2.7.10)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
- faraday-retry (2.0.0)
+ faraday-retry (2.2.0)
faraday (~> 2.0)
fast_blank (1.0.1)
fast_xs (0.8.0)
- fastimage (2.2.6)
+ fastimage (2.2.7)
ffi (1.15.5)
fspath (3.1.2)
gc_tracer (1.5.1)
- globalid (1.0.1)
+ globalid (1.1.0)
activesupport (>= 5.0)
+ google-protobuf (3.23.4)
+ google-protobuf (3.23.4-aarch64-linux)
+ google-protobuf (3.23.4-arm64-darwin)
+ google-protobuf (3.23.4-x86_64-darwin)
+ google-protobuf (3.23.4-x86_64-linux)
guess_html_encoding (0.0.11)
hana (1.3.7)
hashdiff (1.0.1)
@@ -157,38 +178,37 @@ GEM
hkdf (1.0.0)
htmlentities (4.3.4)
http_accept_language (2.1.1)
- i18n (1.12.0)
+ i18n (1.14.1)
concurrent-ruby (~> 1.0)
- image_optim (0.31.2)
+ image_optim (0.31.3)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
image_size (>= 1.5, < 4)
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
- image_size (3.2.0)
+ image_size (3.3.0)
in_threads (1.6.0)
jmespath (1.6.2)
json (2.6.3)
json-schema (3.0.0)
addressable (>= 2.8)
- json_schemer (0.2.23)
- ecma-re-validator (~> 0.3)
+ json_schemer (1.0.3)
hana (~> 1.3)
regexp_parser (~> 2.0)
- uri_template (~> 0.7)
- jwt (2.6.0)
+ simpleidn (~> 0.2)
+ jwt (2.7.1)
kgio (2.11.4)
- libv8-node (16.10.0.0)
- libv8-node (16.10.0.0-aarch64-linux)
- libv8-node (16.10.0.0-arm64-darwin)
- libv8-node (16.10.0.0-x86_64-darwin)
- libv8-node (16.10.0.0-x86_64-darwin-19)
- libv8-node (16.10.0.0-x86_64-linux)
+ language_server-protocol (3.17.0.3)
+ libv8-node (18.16.0.0)
+ libv8-node (18.16.0.0-aarch64-linux)
+ libv8-node (18.16.0.0-arm64-darwin)
+ libv8-node (18.16.0.0-x86_64-darwin)
+ libv8-node (18.16.0.0-x86_64-linux)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
literate_randomizer (0.4.0)
- lograge (0.12.0)
+ lograge (0.13.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
@@ -196,37 +216,43 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
- logster (2.11.3)
- loofah (2.19.1)
+ logster (2.12.2)
+ loofah (2.21.3)
crass (~> 1.0.2)
- nokogiri (>= 1.5.9)
+ nokogiri (>= 1.12.0)
lru_redux (1.1.0)
lz4-ruby (0.3.3)
+ mail (2.8.1)
+ mini_mime (>= 0.1.1)
+ net-imap
+ net-pop
+ net-smtp
matrix (0.4.2)
maxminddb (0.1.22)
memory_profiler (1.0.1)
- message_bus (4.3.1)
+ message_bus (4.3.7)
rack (>= 1.1.3)
method_source (1.0.0)
mini_mime (1.1.2)
- mini_portile2 (2.8.1)
- mini_racer (0.6.3)
- libv8-node (~> 16.10.0.0)
- mini_scheduler (0.15.0)
+ mini_portile2 (2.8.4)
+ mini_racer (0.8.0)
+ libv8-node (~> 18.16.0.0)
+ mini_scheduler (0.16.0)
sidekiq (>= 4.2.3, < 7.0)
mini_sql (1.4.0)
mini_suffix (0.3.3)
ffi (~> 1.9)
- minitest (5.17.0)
- mocha (2.0.2)
+ minitest (5.19.0)
+ mocha (2.1.0)
ruby2_keywords (>= 0.0.5)
- msgpack (1.6.0)
+ msgpack (1.7.2)
multi_json (1.15.0)
multi_xml (0.6.0)
mustache (1.1.1)
net-http (0.3.2)
uri
- net-imap (0.3.1)
+ net-imap (0.3.7)
+ date
net-protocol
net-pop (0.1.2)
net-protocol
@@ -234,17 +260,17 @@ GEM
timeout
net-smtp (0.3.3)
net-protocol
- nio4r (2.5.8)
- nokogiri (1.14.2)
- mini_portile2 (~> 2.8.0)
+ nio4r (2.5.9)
+ nokogiri (1.15.3)
+ mini_portile2 (~> 2.8.2)
racc (~> 1.4)
- nokogiri (1.14.2-aarch64-linux)
+ nokogiri (1.15.3-aarch64-linux)
racc (~> 1.4)
- nokogiri (1.14.2-arm64-darwin)
+ nokogiri (1.15.3-arm64-darwin)
racc (~> 1.4)
- nokogiri (1.14.2-x86_64-darwin)
+ nokogiri (1.15.3-x86_64-darwin)
racc (~> 1.4)
- nokogiri (1.14.2-x86_64-linux)
+ nokogiri (1.15.3-x86_64-linux)
racc (~> 1.4)
oauth (1.1.0)
oauth-tty (~> 1.0, >= 1.0.1)
@@ -258,7 +284,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
- oj (3.13.14)
+ oj (3.15.1)
omniauth (1.9.2)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@@ -281,17 +307,18 @@ GEM
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
- openssl (3.0.2)
- openssl-signature_algorithm (1.2.1)
- openssl (> 2.0, < 3.1)
- optimist (3.0.1)
- parallel (1.22.1)
- parallel_tests (4.0.0)
+ openssl (3.1.0)
+ openssl-signature_algorithm (1.3.0)
+ openssl (> 2.0)
+ optimist (3.1.0)
+ parallel (1.23.0)
+ parallel_tests (4.2.1)
parallel
- parser (3.2.0.0)
+ parser (3.2.2.3)
ast (~> 2.4.1)
- pg (1.4.5)
- prettier_print (1.2.0)
+ racc
+ pg (1.4.6)
+ prettier_print (1.2.1)
progress (3.6.0)
pry (0.14.2)
coderay (~> 1.1)
@@ -301,39 +328,40 @@ GEM
pry (>= 0.13, < 0.15)
pry-rails (0.3.9)
pry (>= 0.10.4)
- public_suffix (5.0.1)
- puma (6.0.2)
+ public_suffix (5.0.3)
+ puma (6.3.0)
nio4r (~> 2.0)
- r2 (0.2.7)
- racc (1.6.2)
- rack (2.2.5)
- rack-mini-profiler (3.0.0)
+ racc (1.7.1)
+ rack (2.2.8)
+ rack-mini-profiler (3.1.0)
rack (>= 1.2.0)
- rack-protection (3.0.5)
+ rack-protection (3.0.6)
rack
- rack-test (2.0.2)
+ rack-test (2.1.0)
rack (>= 1.3)
- rails-dom-testing (2.0.3)
- activesupport (>= 4.2.0)
+ rails-dom-testing (2.1.1)
+ activesupport (>= 5.0.0)
+ minitest
nokogiri (>= 1.6)
- rails-html-sanitizer (1.5.0)
- loofah (~> 2.19, >= 2.19.1)
- rails_failover (0.8.1)
- activerecord (> 6.0, < 7.1)
+ rails-html-sanitizer (1.6.0)
+ loofah (~> 2.21)
+ nokogiri (~> 1.14)
+ rails_failover (2.0.1)
+ activerecord (>= 6.1, <= 7.1)
concurrent-ruby
- railties (> 6.0, < 7.1)
- rails_multisite (4.0.1)
- activerecord (> 5.0, < 7.1)
- railties (> 5.0, < 7.1)
- railties (7.0.4.3)
- actionpack (= 7.0.4.3)
- activesupport (= 7.0.4.3)
+ railties (>= 6.1, <= 7.1)
+ rails_multisite (5.0.0)
+ activerecord (>= 6.0)
+ railties (>= 6.0)
+ railties (7.0.5.1)
+ actionpack (= 7.0.5.1)
+ activesupport (= 7.0.5.1)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
- raindrops (0.20.0)
+ raindrops (0.20.1)
rake (13.0.6)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
@@ -343,16 +371,17 @@ GEM
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rchardet (1.8.0)
- redis (4.8.0)
- redis-namespace (1.9.0)
+ redis (4.8.1)
+ redis-namespace (1.11.0)
redis (>= 4)
- regexp_parser (2.6.1)
+ regexp_parser (2.8.1)
request_store (1.5.1)
rack (>= 1.4)
- rexml (3.2.5)
+ rexml (3.2.6)
rinku (2.0.6)
rotp (6.2.2)
- rqrcode (2.1.2)
+ rouge (4.1.3)
+ rqrcode (2.2.0)
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
@@ -360,76 +389,85 @@ GEM
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
- rspec-core (3.12.0)
+ rspec-core (3.12.2)
rspec-support (~> 3.12.0)
- rspec-expectations (3.12.2)
+ rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-html-matchers (0.10.0)
nokogiri (~> 1)
rspec (>= 3.0.0.a)
- rspec-mocks (3.12.2)
+ rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
- rspec-rails (6.0.1)
+ rspec-rails (6.0.3)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
- rspec-core (~> 3.11)
- rspec-expectations (~> 3.11)
- rspec-mocks (~> 3.11)
- rspec-support (~> 3.11)
- rspec-support (3.12.0)
+ rspec-core (~> 3.12)
+ rspec-expectations (~> 3.12)
+ rspec-mocks (~> 3.12)
+ rspec-support (~> 3.12)
+ rspec-support (3.12.1)
rss (0.2.9)
rexml
- rswag-specs (2.8.0)
+ rswag-specs (2.10.1)
activesupport (>= 3.1, < 7.1)
json-schema (>= 2.2, < 4.0)
railties (>= 3.1, < 7.1)
rspec-core (>= 2.14)
- rubocop (1.43.0)
+ rtlcss (0.2.1)
+ mini_racer (>= 0.6.3)
+ rubocop (1.55.1)
json (~> 2.3)
+ language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
- parser (>= 3.2.0.0)
+ parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
- rubocop-ast (>= 1.24.1, < 2.0)
+ rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
- rubocop-ast (1.24.1)
- parser (>= 3.1.1.0)
- rubocop-discourse (3.0.3)
+ rubocop-ast (1.29.0)
+ parser (>= 3.2.1.0)
+ rubocop-capybara (2.18.0)
+ rubocop (~> 1.41)
+ rubocop-discourse (3.3.0)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
- rubocop-rspec (2.16.0)
+ rubocop-factory_bot (2.23.1)
rubocop (~> 1.33)
- ruby-prof (1.4.5)
- ruby-progressbar (1.11.0)
+ rubocop-rspec (2.23.0)
+ rubocop (~> 1.33)
+ rubocop-capybara (~> 2.17)
+ rubocop-factory_bot (~> 2.22)
+ ruby-prof (1.6.3)
+ ruby-progressbar (1.13.0)
ruby-readability (0.7.0)
guess_html_encoding (>= 0.0.4)
nokogiri (>= 1.6.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
- sanitize (6.0.0)
+ sanitize (6.0.2)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
- sassc (2.0.1)
- ffi (~> 1.9)
- rake
- sassc-rails (2.1.2)
- railties (>= 4.0.0)
- sassc (>= 2.0)
- sprockets (> 3.0)
- sprockets-rails
- tilt
- selenium-webdriver (4.7.1)
+ sass-embedded (1.64.1)
+ google-protobuf (~> 3.23)
+ rake (>= 13.0.0)
+ sass-embedded (1.64.1-aarch64-linux-gnu)
+ google-protobuf (~> 3.23)
+ sass-embedded (1.64.1-arm64-darwin)
+ google-protobuf (~> 3.23)
+ sass-embedded (1.64.1-x86_64-darwin)
+ google-protobuf (~> 3.23)
+ sass-embedded (1.64.1-x86_64-linux-gnu)
+ google-protobuf (~> 3.23)
+ selenium-webdriver (4.10.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
- shoulda-matchers (5.3.0)
- activesupport (>= 5.2.0)
- sidekiq (6.5.8)
+ sidekiq (6.5.9)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
@@ -439,27 +477,28 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
+ simpleidn (0.2.1)
+ unf (~> 0.1.4)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
- sprockets (3.7.2)
- concurrent-ruby (~> 1.0)
- rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sshkey (2.0.0)
- stackprof (0.2.23)
- syntax_tree (5.2.0)
+ stackprof (0.2.25)
+ syntax_tree (6.1.1)
prettier_print (>= 1.2.0)
syntax_tree-disable_ternary (1.0.0)
- test-prof (1.1.0)
- thor (1.2.1)
- tilt (2.0.11)
- timeout (0.3.1)
- tzinfo (2.0.5)
+ test-prof (1.2.2)
+ thor (1.2.2)
+ tilt (2.2.0)
+ timeout (0.4.0)
+ tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
+ tzinfo-data (1.2023.3)
+ tzinfo (>= 1.0.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
@@ -471,27 +510,25 @@ GEM
raindrops (~> 0.7)
uniform_notifier (1.16.0)
uri (0.12.2)
- uri_template (0.7.0)
- version_gem (1.1.1)
+ version_gem (1.1.3)
web-push (3.0.0)
hkdf (~> 1.0)
jwt (~> 2.0)
openssl (~> 3.0)
- webdrivers (5.2.0)
+ webdrivers (5.3.1)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
- selenium-webdriver (~> 4.0)
+ selenium-webdriver (~> 4.0, < 4.11)
webmock (3.18.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
- webrick (1.7.0)
websocket (1.2.9)
- xorcist (1.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
- yaml-lint (0.0.10)
- zeitwerk (2.6.6)
+ yaml-lint (0.1.2)
+ yard (0.9.34)
+ zeitwerk (2.6.10)
PLATFORMS
aarch64-linux
@@ -503,14 +540,14 @@ PLATFORMS
x86_64-linux
DEPENDENCIES
- actionmailer (= 7.0.4.3)
- actionpack (= 7.0.4.3)
- actionview (= 7.0.4.3)
+ actionmailer (= 7.0.5.1)
+ actionpack (= 7.0.5.1)
+ actionview (= 7.0.5.1)
actionview_precompiler
active_model_serializers (~> 0.8.3)
- activemodel (= 7.0.4.3)
- activerecord (= 7.0.4.3)
- activesupport (= 7.0.4.3)
+ activemodel (= 7.0.5.1)
+ activerecord (= 7.0.5.1)
+ activesupport (= 7.0.5.1)
addressable
annotate
aws-sdk-s3
@@ -528,6 +565,8 @@ DEPENDENCIES
cose
cppjieba_rb
css_parser
+ dartsass-ruby
+ dartsass-sprockets
diffy
digest
discourse-fonts
@@ -559,7 +598,7 @@ DEPENDENCIES
loofah
lru_redux
lz4-ruby
- mail!
+ mail
maxminddb
memory_profiler
message_bus
@@ -577,7 +616,7 @@ DEPENDENCIES
net-pop
net-smtp
nokogiri
- oj (= 3.13.14)
+ oj
omniauth
omniauth-facebook
omniauth-github
@@ -589,13 +628,13 @@ DEPENDENCIES
pry-byebug
pry-rails
puma
- r2
rack
rack-mini-profiler
rack-protection
+ rails-dom-testing
rails_failover
rails_multisite
- railties (= 7.0.4.3)
+ railties (= 7.0.5.1)
rake
rb-fsevent
rbtrace
@@ -610,18 +649,17 @@ DEPENDENCIES
rspec-rails
rss
rswag-specs
+ rtlcss
rubocop-discourse
ruby-prof
ruby-readability
rubyzip
sanitize
- sassc (= 2.0.1)
- sassc-rails
selenium-webdriver
- shoulda-matchers
+ shoulda-matchers!
sidekiq
simplecov
- sprockets (= 3.7.2)
+ sprockets!
sprockets-rails
sshkey
stackprof
@@ -629,15 +667,15 @@ DEPENDENCIES
syntax_tree-disable_ternary
test-prof
thor
+ tzinfo-data
uglifier
unf
unicorn
web-push
webdrivers
webmock
- webrick
- xorcist
yaml-lint
+ yard
BUNDLED WITH
- 2.4.1
+ 2.4.13
diff --git a/README.md b/README.md
index 4673f84cc3f..42452e4f87c 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ To get your environment setup, follow the community setup guide for your operati
If you're familiar with how Rails works and are comfortable setting up your own environment, you can also try out the [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md), which is aimed primarily at Ubuntu and macOS environments.
-Before you get started, ensure you have the following minimum versions: [Ruby 2.7+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 13+](https://www.postgresql.org/download/), [Redis 6.2+](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
+Before you get started, ensure you have the following minimum versions: [Ruby 3.2+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 13](https://www.postgresql.org/download/), [Redis 7](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
## Setting up Discourse
@@ -51,7 +51,7 @@ Discourse supports the **latest, stable releases** of all major browsers and pla
| Microsoft Edge | | |
| Mozilla Firefox | | |
-Additionally, we aim to support Safari on iOS 12.5+ until January 2023 (Discourse 3.0).
+Additionally, we aim to support Safari on iOS 15.7+.
## Built With
diff --git a/app/assets/javascripts/.licensee.json b/app/assets/javascripts/.licensee.json
index b3518d7a131..ae2abbd2b64 100644
--- a/app/assets/javascripts/.licensee.json
+++ b/app/assets/javascripts/.licensee.json
@@ -10,15 +10,16 @@
]
},
"packages": {
+ "cli-table": "0.3.11",
"component-bind": "1.0.0",
"component-inherit": "0.0.3",
"duplex": "1.0.0",
"glob": "3.1.21",
"indexof": "0.0.1",
"inherits": "1.0.2",
- "jsonify": "0.0.0",
- "messageformat": "0.1.5",
+ "jsonify": "0.0.1",
"line-stream": "0.0.0",
+ "messageformat": "0.1.5",
"regenerator-transform": "0.10.1",
"source-map": "0.1.43",
"sourcemap-validator": "1.1.1"
diff --git a/app/assets/javascripts/admin/addon/adapters/api-key.js b/app/assets/javascripts/admin/addon/adapters/api-key.js
index 860e4c50692..6e1ad0eb327 100644
--- a/app/assets/javascripts/admin/addon/adapters/api-key.js
+++ b/app/assets/javascripts/admin/addon/adapters/api-key.js
@@ -1,13 +1,13 @@
-import RESTAdapter from "discourse/adapters/rest";
+import RestAdapter from "discourse/adapters/rest";
-export default RESTAdapter.extend({
- jsonMode: true,
+export default class ApiKey extends RestAdapter {
+ jsonMode = true;
basePath() {
return "/admin/api/";
- },
+ }
apiNameFor() {
return "key";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/build-plugin.js b/app/assets/javascripts/admin/addon/adapters/build-plugin.js
index 3a81ab4e573..98b875ba94b 100644
--- a/app/assets/javascripts/admin/addon/adapters/build-plugin.js
+++ b/app/assets/javascripts/admin/addon/adapters/build-plugin.js
@@ -1,11 +1,11 @@
import RestAdapter from "discourse/adapters/rest";
export default function buildPluginAdapter(pluginName) {
- return RestAdapter.extend({
+ return class extends RestAdapter {
pathFor(store, type, findArgs) {
return (
- "/admin/plugins/" + pluginName + this._super(store, type, findArgs)
+ "/admin/plugins/" + pluginName + super.pathFor(store, type, findArgs)
);
- },
- });
+ }
+ };
}
diff --git a/app/assets/javascripts/admin/addon/adapters/customization-base.js b/app/assets/javascripts/admin/addon/adapters/customization-base.js
index 272103ee8a8..d20f15d1dca 100644
--- a/app/assets/javascripts/admin/addon/adapters/customization-base.js
+++ b/app/assets/javascripts/admin/addon/adapters/customization-base.js
@@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
+export default class CustomizationBase extends RestAdapter {
basePath() {
return "/admin/customize/";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/email-style.js b/app/assets/javascripts/admin/addon/adapters/email-style.js
index 12919f04b0d..e4465ef56eb 100644
--- a/app/assets/javascripts/admin/addon/adapters/email-style.js
+++ b/app/assets/javascripts/admin/addon/adapters/email-style.js
@@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
+export default class EmailStyle extends RestAdapter {
pathFor() {
return "/admin/customize/email_style";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/embedding.js b/app/assets/javascripts/admin/addon/adapters/embedding.js
index ba3fb816b80..966098fd4d1 100644
--- a/app/assets/javascripts/admin/addon/adapters/embedding.js
+++ b/app/assets/javascripts/admin/addon/adapters/embedding.js
@@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
+export default class Embedding extends RestAdapter {
pathFor() {
return "/admin/customize/embedding";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/staff-action-log.js b/app/assets/javascripts/admin/addon/adapters/staff-action-log.js
index d281f9746be..9a9d1d6c0b4 100644
--- a/app/assets/javascripts/admin/addon/adapters/staff-action-log.js
+++ b/app/assets/javascripts/admin/addon/adapters/staff-action-log.js
@@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
+export default class StaffActionLog extends RestAdapter {
basePath() {
return "/admin/logs/";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/tag-group.js b/app/assets/javascripts/admin/addon/adapters/tag-group.js
index 4c12654d967..4caa9172b92 100644
--- a/app/assets/javascripts/admin/addon/adapters/tag-group.js
+++ b/app/assets/javascripts/admin/addon/adapters/tag-group.js
@@ -1,5 +1,5 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
- jsonMode: true,
-});
+export default class TagGroup extends RestAdapter {
+ jsonMode = true;
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/theme.js b/app/assets/javascripts/admin/addon/adapters/theme.js
index cf34ab42f5f..66f901b2cdb 100644
--- a/app/assets/javascripts/admin/addon/adapters/theme.js
+++ b/app/assets/javascripts/admin/addon/adapters/theme.js
@@ -1,9 +1,10 @@
import RestAdapter from "discourse/adapters/rest";
-export default RestAdapter.extend({
+export default class Theme extends RestAdapter {
+ jsonMode = true;
basePath() {
return "/admin/";
- },
+ }
afterFindAll(results) {
let map = {};
@@ -20,7 +21,5 @@ export default RestAdapter.extend({
theme.set("parentThemes", mappedParents);
});
return results;
- },
-
- jsonMode: true,
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/web-hook-event.js b/app/assets/javascripts/admin/addon/adapters/web-hook-event.js
index 1acd38386ba..8a6fa2b082d 100644
--- a/app/assets/javascripts/admin/addon/adapters/web-hook-event.js
+++ b/app/assets/javascripts/admin/addon/adapters/web-hook-event.js
@@ -1,7 +1,7 @@
-import RESTAdapter from "discourse/adapters/rest";
+import RestAdapter from "discourse/adapters/rest";
-export default RESTAdapter.extend({
+export default class WebHookEvent extends RestAdapter {
basePath() {
return "/admin/api/";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/adapters/web-hook.js b/app/assets/javascripts/admin/addon/adapters/web-hook.js
index 1acd38386ba..813f7dbf03b 100644
--- a/app/assets/javascripts/admin/addon/adapters/web-hook.js
+++ b/app/assets/javascripts/admin/addon/adapters/web-hook.js
@@ -1,7 +1,7 @@
-import RESTAdapter from "discourse/adapters/rest";
+import RestAdapter from "discourse/adapters/rest";
-export default RESTAdapter.extend({
+export default class WebHook extends RestAdapter {
basePath() {
return "/admin/api/";
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/components/ace-editor.hbs b/app/assets/javascripts/admin/addon/components/ace-editor.hbs
similarity index 100%
rename from app/assets/javascripts/admin/addon/templates/components/ace-editor.hbs
rename to app/assets/javascripts/admin/addon/components/ace-editor.hbs
diff --git a/app/assets/javascripts/admin/addon/components/ace-editor.js b/app/assets/javascripts/admin/addon/components/ace-editor.js
index 06ed3763031..84aa4351e15 100644
--- a/app/assets/javascripts/admin/addon/components/ace-editor.js
+++ b/app/assets/javascripts/admin/addon/components/ace-editor.js
@@ -1,31 +1,33 @@
+import { action } from "@ember/object";
+import { classNames } from "@ember-decorators/component";
+import { observes, on } from "@ember-decorators/object";
import Component from "@ember/component";
import getURL from "discourse-common/lib/get-url";
import loadScript from "discourse/lib/load-script";
import I18n from "I18n";
-import { bind, observes } from "discourse-common/utils/decorators";
-import { on } from "@ember/object/evented";
+import { bind } from "discourse-common/utils/decorators";
const COLOR_VARS_REGEX =
/\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
-export default Component.extend({
- mode: "css",
- classNames: ["ace-wrapper"],
- _editor: null,
- _skipContentChangeEvent: null,
- disabled: false,
- htmlPlaceholder: false,
+@classNames("ace-wrapper")
+export default class AceEditor extends Component {
+ mode = "css";
+ disabled = false;
+ htmlPlaceholder = false;
+ _editor = null;
+ _skipContentChangeEvent = null;
@observes("editorId")
editorIdChanged() {
if (this.autofocus) {
this.send("focus");
}
- },
+ }
didRender() {
this._skipContentChangeEvent = false;
- },
+ }
@observes("content")
contentChanged() {
@@ -33,14 +35,14 @@ export default Component.extend({
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setValue(content);
}
- },
+ }
@observes("mode")
modeChanged() {
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setMode("ace/mode/" + this.mode);
}
- },
+ }
@observes("placeholder")
placeholderChanged() {
@@ -49,12 +51,12 @@ export default Component.extend({
placeholder: this.placeholder,
});
}
- },
+ }
@observes("disabled")
disabledStateChanged() {
this.changeDisabledState();
- },
+ }
changeDisabledState() {
const editor = this._editor;
@@ -67,9 +69,10 @@ export default Component.extend({
});
editor.container.parentNode.setAttribute("data-disabled", disabled);
}
- },
+ }
- _destroyEditor: on("willDestroyElement", function () {
+ @on("willDestroyElement")
+ _destroyEditor() {
if (this._editor) {
this._editor.destroy();
this._editor = null;
@@ -80,16 +83,16 @@ export default Component.extend({
}
$(window).off("ace:resize");
- }),
+ }
resize() {
if (this._editor) {
this._editor.resize();
}
- },
+ }
didInsertElement() {
- this._super(...arguments);
+ super.didInsertElement(...arguments);
loadScript("/javascripts/ace/ace.js").then(() => {
window.ace.require(["ace/ace"], (loadedAce) => {
loadedAce.config.set("loadWorkerFromBlob", false);
@@ -153,13 +156,13 @@ export default Component.extend({
this._darkModeListener.addListener(this.setAceTheme);
});
});
- },
+ }
willDestroyElement() {
if (this._darkModeListener) {
this._darkModeListener.removeListener(this.setAceTheme);
}
- },
+ }
@bind
setAceTheme() {
@@ -170,7 +173,7 @@ export default Component.extend({
this._editor.setTheme(
`ace/theme/${schemeType === "dark" ? "chaos" : "chrome"}`
);
- },
+ }
warnSCSSDeprecations() {
if (
@@ -197,21 +200,20 @@ export default Component.extend({
this._editor.getSession().setAnnotations(warnings);
- this.setWarning(
+ this.setWarning?.(
warnings.length
? I18n.t("admin.customize.theme.scss_color_variables_warning")
: false
);
- },
+ }
- actions: {
- focus() {
- if (this._editor) {
- this._editor.focus();
- this._editor.navigateFileEnd();
- }
- },
- },
+ @action
+ focus() {
+ if (this._editor) {
+ this._editor.focus();
+ this._editor.navigateFileEnd();
+ }
+ }
_overridePlaceholder(loadedAce) {
const originalPlaceholderSetter =
@@ -239,5 +241,5 @@ export default Component.extend({
this.$updatePlaceholder();
};
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/components/admin-backups-logs.hbs b/app/assets/javascripts/admin/addon/components/admin-backups-logs.hbs
similarity index 100%
rename from app/assets/javascripts/admin/addon/templates/components/admin-backups-logs.hbs
rename to app/assets/javascripts/admin/addon/components/admin-backups-logs.hbs
diff --git a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js
index c707c99b70a..e1c12d04a32 100644
--- a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js
+++ b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js
@@ -1,28 +1,26 @@
-import { observes, on } from "discourse-common/utils/decorators";
+import { classNames } from "@ember-decorators/component";
+import { observes, on } from "@ember-decorators/object";
import Component from "@ember/component";
import I18n from "I18n";
import discourseDebounce from "discourse-common/lib/debounce";
import { scheduleOnce } from "@ember/runloop";
-export default Component.extend({
- classNames: ["admin-backups-logs"],
- showLoadingSpinner: false,
- hasFormattedLogs: false,
- noLogsMessage: I18n.t("admin.backups.logs.none"),
-
- init() {
- this._super(...arguments);
- this._reset();
- },
+@classNames("admin-backups-logs")
+export default class AdminBackupsLogs extends Component {
+ showLoadingSpinner = false;
+ hasFormattedLogs = false;
+ noLogsMessage = I18n.t("admin.backups.logs.none");
+ formattedLogs = "";
+ index = 0;
_reset() {
this.setProperties({ formattedLogs: "", index: 0 });
- },
+ }
_scrollDown() {
const div = this.element;
div.scrollTop = div.scrollHeight;
- },
+ }
@on("init")
@observes("logs.[]")
@@ -31,7 +29,7 @@ export default Component.extend({
this._reset(); // reset the cached logs whenever the model is reset
this.renderLogs();
}
- },
+ }
_updateFormattedLogsFunc() {
const logs = this.logs;
@@ -55,13 +53,13 @@ export default Component.extend({
this.renderLogs();
scheduleOnce("afterRender", this, this._scrollDown);
- },
+ }
@on("init")
@observes("logs.[]")
_updateFormattedLogs() {
discourseDebounce(this, this._updateFormattedLogsFunc, 150);
- },
+ }
renderLogs() {
const formattedLogs = this.formattedLogs;
@@ -76,5 +74,5 @@ export default Component.extend({
} else {
this.set("showLoadingSpinner", false);
}
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/components/admin-editable-field.hbs b/app/assets/javascripts/admin/addon/components/admin-editable-field.hbs
similarity index 100%
rename from app/assets/javascripts/admin/addon/templates/components/admin-editable-field.hbs
rename to app/assets/javascripts/admin/addon/components/admin-editable-field.hbs
diff --git a/app/assets/javascripts/admin/addon/components/admin-editable-field.js b/app/assets/javascripts/admin/addon/components/admin-editable-field.js
index 892a3208e86..a99265b20cb 100644
--- a/app/assets/javascripts/admin/addon/components/admin-editable-field.js
+++ b/app/assets/javascripts/admin/addon/components/admin-editable-field.js
@@ -1,28 +1,22 @@
+import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import { action } from "@ember/object";
-export default Component.extend({
- tagName: "",
-
- buffer: "",
- editing: false,
-
- init() {
- this._super(...arguments);
- this.set("editing", false);
- },
+@tagName("")
+export default class AdminEditableField extends Component {
+ buffer = "";
+ editing = false;
@action
edit(event) {
event?.preventDefault();
this.set("buffer", this.value);
this.toggleProperty("editing");
- },
+ }
- actions: {
- save() {
- // Action has to toggle 'editing' property.
- this.action(this.buffer);
- },
- },
-});
+ @action
+ save() {
+ // Action has to toggle 'editing' property.
+ this.action(this.buffer);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/components/admin-form-row.hbs b/app/assets/javascripts/admin/addon/components/admin-form-row.hbs
similarity index 100%
rename from app/assets/javascripts/admin/addon/templates/components/admin-form-row.hbs
rename to app/assets/javascripts/admin/addon/components/admin-form-row.hbs
diff --git a/app/assets/javascripts/admin/addon/components/admin-form-row.js b/app/assets/javascripts/admin/addon/components/admin-form-row.js
index 6217c6b913f..266301263d4 100644
--- a/app/assets/javascripts/admin/addon/components/admin-form-row.js
+++ b/app/assets/javascripts/admin/addon/components/admin-form-row.js
@@ -1,4 +1,5 @@
+import { classNames } from "@ember-decorators/component";
import Component from "@ember/component";
-export default Component.extend({
- classNames: ["row"],
-});
+
+@classNames("row")
+export default class AdminFormRow extends Component {}
diff --git a/app/assets/javascripts/admin/addon/components/admin-graph.js b/app/assets/javascripts/admin/addon/components/admin-graph.js
index 1107abeb2ca..4ef05fca32e 100644
--- a/app/assets/javascripts/admin/addon/components/admin-graph.js
+++ b/app/assets/javascripts/admin/addon/components/admin-graph.js
@@ -1,9 +1,10 @@
+import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import loadScript from "discourse/lib/load-script";
-export default Component.extend({
- tagName: "canvas",
- type: "line",
+@tagName("canvas")
+export default class AdminGraph extends Component {
+ type = "line";
refreshChart() {
const ctx = this.element.getContext("2d");
@@ -49,11 +50,11 @@ export default Component.extend({
};
this._chart = new window.Chart(ctx, config);
- },
+ }
didInsertElement() {
loadScript("/javascripts/Chart.min.js").then(() =>
this.refreshChart.apply(this)
);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/components/admin-nav.gjs b/app/assets/javascripts/admin/addon/components/admin-nav.gjs
new file mode 100644
index 00000000000..be3aa02cb4a
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/admin-nav.gjs
@@ -0,0 +1,15 @@
+import { tagName } from "@ember-decorators/component";
+import Component from "@ember/component";
+
+@tagName("")
+export default class AdminNav extends Component {
+
+