diff --git a/.ember-cli b/.ember-cli deleted file mode 100644 index ee64cfe..0000000 --- a/.ember-cli +++ /dev/null @@ -1,9 +0,0 @@ -{ - /** - Ember CLI sends analytics information by default. The data is completely - anonymous, but there are times when you might want to disable this behavior. - - Setting `disableAnalytics` to true will prevent any data from being sent. - */ - "disableAnalytics": false -} diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..c0d6652 --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +NODE_ENV=development diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 72df373..0000000 --- a/.eslintignore +++ /dev/null @@ -1,20 +0,0 @@ -# unconventional js -/blueprints/*/files/ -/vendor/ - -# compiled output -/dist/ -/tmp/ - -# dependencies -/bower_components/ -/node_modules/ - -# misc -/coverage/ -!.* - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/package.json.ember-try diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 9285859..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -module.exports = { - root: true, - parser: 'babel-eslint', - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', - ecmaFeatures: { - legacyDecorators: true - } - }, - plugins: [ - 'ember' - ], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended' - ], - env: { - browser: true - }, - rules: {}, - overrides: [ - // node files - { - files: [ - '.eslintrc.js', - '.template-lintrc.js', - 'ember-cli-build.js', - 'index.js', - 'testem.js', - 'blueprints/*/index.js', - 'config/**/*.js', - 'tests/dummy/config/**/*.js' - ], - excludedFiles: [ - 'addon/**', - 'addon-test-support/**', - 'app/**', - 'tests/dummy/app/**' - ], - parserOptions: { - sourceType: 'script' - }, - env: { - browser: false, - node: true - }, - plugins: ['node'], - extends: ['plugin:node/recommended'] - } - ] -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a697747 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,95 @@ +name: CI + +on: + push: + branches: + - main + - master + pull_request: {} + +concurrency: + group: ci-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: "Lints" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: pnpm + - name: Install Dependencies + run: pnpm install --frozen-lockfile + - name: Lint + run: pnpm lint + + test: + name: "Tests" + runs-on: ubuntu-latest + timeout-minutes: 10 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: pnpm + - name: Install Dependencies + run: pnpm install --frozen-lockfile + - name: Run Tests + run: pnpm test + # For the Try Scenarios + - id: set-matrix + run: | + echo "matrix=$(pnpm -s dlx @embroider/try list)" >> $GITHUB_OUTPUT + + floating: + name: "Floating Dependencies" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: pnpm + - name: Install Dependencies + run: pnpm install --no-lockfile + - name: Run Tests + run: pnpm test + + try-scenarios: + name: ${{ matrix.name }} + runs-on: ubuntu-latest + needs: "test" + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: ${{fromJson(needs.test.outputs.matrix)}} + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: pnpm + - name: Apply Scenario + run: | + pnpm dlx @embroider/try apply ${{ matrix.name }} + - name: Install Dependencies + run: pnpm install --no-lockfile + - name: Run Tests + run: pnpm test + env: ${{ matrix.env }} diff --git a/.github/workflows/push-dist.yml b/.github/workflows/push-dist.yml new file mode 100644 index 0000000..c4c6ae0 --- /dev/null +++ b/.github/workflows/push-dist.yml @@ -0,0 +1,37 @@ +# Because this library needs to be built, +# we can't easily point package.json files at the git repo for easy cross-repo testing. +# +# This workflow brings back that capability by placing the compiled assets on a "dist" branch +# (configurable via the "branch" option below) +name: Push dist + +on: + push: + branches: + - main + - master + +jobs: + push-dist: + name: Push dist + permissions: + contents: write + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: pnpm + - name: Install Dependencies + run: pnpm install --frozen-lockfile + - name: Build + run: pnpm build + - uses: kategengler/put-built-npm-package-contents-on-branch@a8f939b1c3a57b62efbc5d73685f55e97db734bb # v2.1.0 + with: + branch: dist + pack-command: pnpm pack + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index c0f17b9..0049e30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,20 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. - # compiled output -/dist/ -/tmp/ +dist/ +dist-tests/ +declarations/ + +# from scenarios +tmp/ +config/optional-features.json +ember-cli-build.cjs -# dependencies -/bower_components/ -/node_modules/ +# npm/pnpm/yarn pack output +*.tgz -# misc -/.env* -/.pnp* -/.sass-cache -/connect.lock -/coverage/ -/libpeerconnection.log -/npm-debug.log* -/testem.log -/yarn-error.log -/.idea +# deps & caches +node_modules/ +.eslintcache +.prettiercache -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/package.json.ember-try +# potentially containing secrets +*.local diff --git a/.npmignore b/.npmignore deleted file mode 100644 index bd09adf..0000000 --- a/.npmignore +++ /dev/null @@ -1,32 +0,0 @@ -# compiled output -/dist/ -/tmp/ - -# dependencies -/bower_components/ - -# misc -/.bowerrc -/.editorconfig -/.ember-cli -/.env* -/.eslintignore -/.eslintrc.js -/.git/ -/.gitignore -/.template-lintrc.js -/.travis.yml -/.watchmanconfig -/bower.json -/config/ember-try.js -/CONTRIBUTING.md -/ember-cli-build.js -/testem.js -/tests/ -/yarn.lock -.gitkeep - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/package.json.ember-try diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8b7b5fd --- /dev/null +++ b/.prettierignore @@ -0,0 +1,12 @@ +# compiled output +/dist/ +/dist-*/ +/declarations/ + +# misc +/coverage/ +pnpm-lock.yaml +*.yaml +*.yml +*.md +*.html diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..9cc6b3d --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,12 @@ +export default { + plugins: ['prettier-plugin-ember-template-tag'], + overrides: [ + { + files: '*.{js,gjs,ts,gts,mjs,mts,cjs,cts}', + options: { + singleQuote: true, + templateSingleQuote: false, + }, + }, + ], +}; diff --git a/.template-lintrc.js b/.template-lintrc.js deleted file mode 100644 index f387370..0000000 --- a/.template-lintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - extends: 'octane' -}; diff --git a/.template-lintrc.mjs b/.template-lintrc.mjs new file mode 100644 index 0000000..8b6625c --- /dev/null +++ b/.template-lintrc.mjs @@ -0,0 +1,4 @@ +export default { + extends: 'recommended', + checkHbsTemplateLiterals: false, +}; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 345135f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -language: node_js -node_js: - # we recommend testing addons with the same minimum supported node version as Ember CLI - # so that your addon works for all apps - - "10" - -dist: xenial - -addons: - chrome: stable - -cache: - directories: - - $HOME/.npm - -env: - global: - # See https://git.io/vdao3 for details. - - JOBS=1 - -branches: - only: - - master - # npm version tags - - /^v\d+\.\d+\.\d+/ - -jobs: - fast_finish: true - allow_failures: - - env: EMBER_TRY_SCENARIO=ember-canary - - include: - # runs linting and tests with current locked deps - - stage: "Tests" - name: "Tests" - script: - - npm run lint - - npm run test:ember - - - stage: "Additional Tests" - name: "Floating Dependencies" - install: - - npm install --no-package-lock - script: - - npm run test:ember - - # we recommend new addons test the current and previous LTS - # as well as latest stable release (bonus points to beta/canary) - - env: EMBER_TRY_SCENARIO=ember-lts-4.4.5 - - env: EMBER_TRY_SCENARIO=ember-lts-4.8.6 - - env: EMBER_TRY_SCENARIO=ember-lts-4.12.3 - - env: EMBER_TRY_SCENARIO=ember-release - - env: EMBER_TRY_SCENARIO=ember-beta - - env: EMBER_TRY_SCENARIO=ember-canary - - env: EMBER_TRY_SCENARIO=ember-default-with-jquery - - env: EMBER_TRY_SCENARIO=ember-classic - -script: - - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO diff --git a/.try.mjs b/.try.mjs new file mode 100644 index 0000000..c330833 --- /dev/null +++ b/.try.mjs @@ -0,0 +1,48 @@ +const compatFiles = { + 'ember-cli-build.cjs': `const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { compatBuild } = require('@embroider/compat'); +module.exports = async function (defaults) { + const { buildOnce } = await import('@embroider/vite'); + let app = new EmberApp(defaults); + return compatBuild(app, buildOnce); +};`, + 'config/optional-features.json': JSON.stringify({ + 'application-template-wrapper': false, + 'default-async-observers': true, + 'jquery-integration': false, + 'template-only-glimmer-components': true, + 'no-implicit-route-model': true, + }), +}; + +const compatDeps = { + '@embroider/compat': '^4.0.3', + 'ember-cli': '^5.12.0', + 'ember-auto-import': '^2.10.0', + '@ember/optional-features': '^2.2.0', +}; + +export default { + scenarios: [ + { + name: 'ember-lts-5.8', + npm: { devDependencies: { 'ember-source': '~5.8.0', ...compatDeps } }, + env: { ENABLE_COMPAT_BUILD: true }, + files: compatFiles, + }, + { + name: 'ember-lts-5.12', + npm: { devDependencies: { 'ember-source': '~5.12.0', ...compatDeps } }, + env: { ENABLE_COMPAT_BUILD: true }, + files: compatFiles, + }, + { + name: 'ember-lts-6.4', + npm: { devDependencies: { 'ember-source': 'npm:ember-source@~6.4.0' } }, + }, + { + name: 'ember-latest', + npm: { devDependencies: { 'ember-source': 'npm:ember-source@latest' } }, + }, + ], +}; diff --git a/.watchmanconfig b/.watchmanconfig deleted file mode 100644 index e7834e3..0000000 --- a/.watchmanconfig +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ignore_dirs": ["tmp", "dist"] -} diff --git a/AGENTS.md b/AGENTS.md index 96021f0..da2f3d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,13 +7,14 @@ making changes. ## 1. What this repo is -`ember-cli-raygun` is an **Ember CLI addon** (v2.0.0, Octane edition, -targeting Ember 4.12) that integrates the [Raygun.com](https://raygun.com) -crash-reporting and Pulse RUM service into an Ember application by wrapping -the [raygun4js](https://github.com/MindscapeHQ/raygun4js) browser library. +`ember-cli-raygun` is a **v2 Ember addon** (Embroider/Vite-compatible) that +integrates the [Raygun.com](https://raygun.com) crash-reporting and Pulse +RUM service into an Ember application by wrapping the +[raygun4js](https://github.com/MindscapeHQ/raygun4js) browser library. -It is published to npm as `ember-cli-raygun` and consumed via -`ember install ember-cli-raygun`. +It is published to npm as `ember-cli-raygun`. Consumers install it with +their package manager (`pnpm add ember-cli-raygun`, `npm install …`, +`yarn add …`) — there is no blueprint and no `ember install` step. --- @@ -21,110 +22,127 @@ It is published to npm as `ember-cli-raygun` and consumed via ``` . -├── index.js # Build-time addon entry point (Node) -├── blueprints/ember-cli-raygun/index.js # `ember install` blueprint -├── addon/ # Real addon source (browser runtime) -│ ├── services/raygun.js # Ember Service wrapping rg4js -│ └── instance-initializers/raygun.js # Boot-time wiring -├── app/ # One-line re-exports into host namespace -│ ├── services/raygun.js -│ └── instance-initializers/raygun.js -├── config/ -│ ├── environment.js # Addon's own ember-cli config -│ └── ember-try.js # Compatibility scenarios +├── addon-main.cjs # v2 addon entry (one-line @embroider/addon-shim) +├── rollup.config.mjs # Builds src/ → dist/ + declarations/ +├── babel.config.cjs +├── babel.publish.config.cjs +├── src/ # Published source +│ ├── index.ts # Public exports: setupRaygun, RaygunService +│ ├── setup.ts # setupRaygun(appInstance, config) +│ ├── services/raygun.ts # Ember Service wrapping window.rg4js +│ └── template-registry.ts # Glint template registry +├── demo-app/ # Manual-testing app, served by `pnpm start` +│ ├── app.gts # EmberApp (strict resolver) + setupRaygun wiring +│ ├── styles.css +│ └── templates/ +│ ├── application.gts +│ ├── error-maker.gts # Buttons that throw / report errors +│ └── other-one.gts ├── tests/ -│ ├── dummy/ # Full Ember app used as test host -│ ├── unit/ # Service + initializer unit tests -│ └── test-helper.js -├── vendor/ # (empty placeholder) +│ ├── index.html +│ ├── test-helper.ts # Minimal TestApp (Router + RaygunService only) +│ └── unit/ +│ ├── services/raygun-test.ts # Service surface coverage +│ └── setup-test.ts # setupRaygun branch coverage +├── unpublished-development-types/ # Ambient types for dev only +├── index.html # Demo-app vite entry +├── vite.config.mjs +├── testem.cjs +├── tsconfig.json / tsconfig.publish.json +├── eslint.config.mjs / .template-lintrc.mjs / .prettierrc.mjs +├── .try.mjs # @embroider/try compat scenarios +├── .github/workflows/ +│ ├── ci.yml # Lint + test + try-scenarios matrix +│ └── push-dist.yml # Publishes built tarball to `dist` branch +├── pnpm-workspace.yaml / pnpm-lock.yaml ├── package.json -├── ember-cli-build.js -├── testem.js ├── README.md -└── CONTRIBUTING.md +├── CONTRIBUTING.md +└── AGENTS.md # ← you are here ``` **Where new code goes** -| You're adding… | Put it in… | -| ---------------------------------------- | --------------------------------------------- | -| New Ember service / initializer logic | `addon/...`, plus a re-export in `app/...` | -| Build-time HTML or config behavior | `index.js` | -| `ember install` scaffolding | `blueprints/ember-cli-raygun/index.js` | -| Unit tests | `tests/unit/...` | -| End-to-end / integration test fixtures | `tests/dummy/...` | +| You're adding… | Put it in… | +| ----------------------------------- | ------------------------------------------------ | +| New service / setupRaygun behavior | `src/...` | +| Public types or exports | `src/index.ts` | +| Demo-app pages, styling, examples | `demo-app/...` | +| Unit tests | `tests/unit/...` | +| Build/packaging changes | `rollup.config.mjs`, `addon-main.cjs` | +| CI / matrix | `.github/workflows/ci.yml`, `.try.mjs` | --- ## 3. Architecture (mental model) -There are **two execution contexts** to keep straight: +### Public exports (`src/index.ts`) -### Build time (Node.js, runs `index.js`) +- `RaygunService` — Ember `Service` wrapping `window.rg4js`. Every method + (`send`, `setUser`, `trackEvent`, plus setters for `apiKey`, + `enableCrashReporting`, `enablePulse`, `options`) is guarded by an + rg4js-availability check and `console.warn`s instead of throwing when + the CDN script didn't load. +- `setupRaygun(appInstance, config)` — explicit bootstrap. Consumers call + this from an instance initializer (or `App.instanceInitializer({...})`). -1. `contentFor('head', config)` injects an inline ` ``` -Next, set your API key in `config/environment.js`: +If you'd rather skip Raygun entirely in development, wrap the snippet in +an `{{#if}}` (classic builds) or just omit it from the dev `index.html`. +The runtime degrades gracefully — every service call no-ops with a +`console.warn` when `window.rg4js` is absent. + +### 2. Add your config to `config/environment.js` ```js -var ENV = { - // ... - raygun: { - apiKey: "paste_your_api_key_here", - enableCrashReporting: (environment === "production") - } - // ... +module.exports = function (environment) { + const ENV = { + /* ... */ + raygun: { + apiKey: 'paste_your_api_key_here', + enableCrashReporting: environment === 'production', + enablePulse: true, + // options: { allowInsecureSubmissions: true }, + }, + }; + return ENV; +}; ``` -*The default blueprint (which runs during ember install ember-cli-raygun) will add the above config in your app's config/environment.js file.* +### 3. Wire up the runtime (replaces the deprecated instance-initializer) -## Release +In v2.x the addon shipped an instance-initializer that automatically +called into raygun4js after boot. **Instance initializers are deprecated +in modern Ember**, so v3 removes ours and exposes a `setupRaygun()` +function that you call yourself. Pick whichever spot fits your app: -Raygun will now track errors in your deployed application. By default, Ember CLI Raygun is disabled unless your environment is set to "production". You can configure this behavior in `config/environment.js`. +#### Option A — your own instance-initializer (recommended, minimal diff) -# Additional Configruation +`setupRaygun` needs an `ApplicationInstance` (so it can `lookup` the +service and the router), so the most natural place to call it is from a +host-owned instance-initializer. This is also the smallest possible +diff if you're upgrading from v2.x. -## CORS +```js +// app/instance-initializers/raygun.js +import config from 'my-app/config/environment'; +import { setupRaygun } from 'ember-cli-raygun'; -`ember-cli-raygun` will automatically inject the [raygun4js](https://github.com/MindscapeHQ/raygun4js) bootstrap script into the head of your Ember app. This is the most reliable way to catch errors (even during app initialization). +export function initialize(appInstance) { + setupRaygun(appInstance, config.raygun); +} -If you’re using CORS without `unsafe-inline`, you’ll need to add the following directives to ensure `rg4js` and Raygun load correctly: +export default { initialize }; +``` -* `script-src` - - 'sha256-kOJzCjwwBHVC6EAEX5M+ovfu9sE7JG0G9LcYssttn6I=' - - 'http://cdn.raygun.io' +#### Option B — register the initializer inline in `app/app.js` -* `connect-src` - - https://api.raygun.io +If you'd rather not add a separate file, register it directly on the +`Application` class: -### Accessing Raygun +```js +// app/app.js +import Application from '@ember/application'; +import Resolver from 'ember-resolver'; +import loadInitializers from 'ember-load-initializers'; +import config from 'my-app/config/environment'; +import { setupRaygun } from 'ember-cli-raygun'; + +export default class App extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; +} + +App.instanceInitializer({ + name: 'raygun', + initialize(appInstance) { + setupRaygun(appInstance, config.raygun); + }, +}); + +loadInitializers(App, config.modulePrefix); +``` + +> Don't be tempted to call `setupRaygun(this, …)` from +> `Application#ready()` — `this` is the `Application`, not an +> `ApplicationInstance`, and it has no `lookup` method. + +`setupRaygun` is a no-op when `config.raygun.enableCrashReporting` is +false, so it's safe to call unconditionally. -Functions you might need on `rg4js` are exposed as an [Ember Service](https://guides.emberjs.com/release/tutorial/part-2/service-injection/), for instance tracking custom events: +## Using the service + +Inject `service:raygun` anywhere you need it: ```js import Route from '@ember/routing/route'; -import { inject as service } from '@ember/service'; +import { service } from '@ember/service'; -export default class IndexRoute extends Route { +export default class ApplicationRoute extends Route { @service raygun; beforeModel() { + this.raygun.setUser({ + identifier: 'user-123', + isAnonymous: false, + email: 'a@b.com', + fullName: 'Ada Lovelace', + }); + this.raygun.trackEvent({ type: 'customTiming', name: 'IndexRouteBeforeModel', - duration: 1200 - }) + duration: 1200, + }); + + this.raygun.send(new Error('manual report')); } } ``` -## User Tracking - -Check out the [Customers](https://github.com/MindscapeHQ/raygun4js#customers) section in the raygun4js documentation for full details. - -Add the following snippet into your application route in `app/routes/application.js`: +Every method guards against `rg4js` being unavailable (e.g. blocked by +CSP or network) and `console.warn`s instead of throwing. -```js -// ... - @service user; - @service raygun; +## Content Security Policy - beforeModel: () { - this.setRaygunUser(); - }, +If your app uses CSP without `unsafe-inline`, allow the inline loader +script and the Raygun CDN/API: - setRaygunUser: () { - this.raygun.setUser({ - identifier: this.get("user.id"), - isAnonymous: false, - email: this.get("user.email"), - firstName: this.get("user.firstName"), - fullName: this.get("user.fullName") - }); - }, -// ... -``` - -## Thanks! :heart: - -Thanks to: - - * [@aklkv](https://github.com/aklkv) - * [@jakesjews](https://github.com/jakesjews) - * [@jrjamespdx](https://github.com/jrjamespdx) - * [@fundead](https://github.com/fundead) - * [@JonathanPrince](https://github.com/JonathanPrince) - * [@j5alive](https://github.com/j5alive) - * [@josephambe](https://github.com/josephambe) - * [@pixelhandler](https://github.com/pixelhandler) - * [@archit](https://github.com/archit) - * [@cibernox](https://github.com/cibernox) - * [@dwnz](https://github.com/dwnz) +* `script-src` + * `'sha256-kOJzCjwwBHVC6EAEX5M+ovfu9sE7JG0G9LcYssttn6I='` + * `https://cdn.raygun.io` +* `connect-src` + * `https://api.raygun.io` -For your contributions on the previous version of this addon :) +## Migrating from v2.x -## Contributing +| v2.x | v3.x | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------- | +| `ember install ember-cli-raygun` | `pnpm add -D ember-cli-raygun` + manual config | +| Loader injected by `contentFor('head')` | Paste the loader ` + +
+ + +