@ember/app-blueprint 6.9.0-alpha.2 → 6.10.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,8 @@ on:
8
8
  types:
9
9
  - labeled
10
10
  - unlabeled
11
+ branches:
12
+ - main
11
13
 
12
14
  concurrency:
13
15
  group: plan-release-alpha # only the latest one of these should ever be running
@@ -0,0 +1,95 @@
1
+ name: Plan Beta Release
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches:
6
+ - beta
7
+ pull_request_target: # This workflow has permissions on the repo, do NOT run code from PRs in this workflow. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
8
+ types:
9
+ - labeled
10
+ - unlabeled
11
+ branches:
12
+ - beta
13
+
14
+ concurrency:
15
+ group: plan-release-beta # only the latest one of these should ever be running
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ is-this-a-release:
20
+ name: "Is this a release?"
21
+ runs-on: ubuntu-latest
22
+ outputs:
23
+ command: ${{ steps.check-release.outputs.command }}
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 2
29
+ ref: 'beta'
30
+ # This will only cause the `is-this-a-release` job to have a "command" of `release`
31
+ # when the .release-plan.json file was changed on the last commit.
32
+ - id: check-release
33
+ run: if git diff --name-only HEAD HEAD~1 | grep -w -q ".release-plan.json"; then echo "command=release"; fi >> $GITHUB_OUTPUT
34
+
35
+ create-prepare-release-pr:
36
+ name: Create Prepare Release PR
37
+ runs-on: ubuntu-latest
38
+ timeout-minutes: 5
39
+ needs: is-this-a-release
40
+ permissions:
41
+ contents: write
42
+ issues: read
43
+ pull-requests: write
44
+ # only run on push event or workflow dispatch if plan wasn't updated (don't create a release plan when we're releasing)
45
+ # only run on labeled event if the PR has already been merged
46
+ if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.is-this-a-release.outputs.command != 'release') || (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true)
47
+
48
+ steps:
49
+ - uses: actions/checkout@v4
50
+ # We need to download lots of history so that
51
+ # github-changelog can discover what's changed since the last release
52
+ with:
53
+ fetch-depth: 0
54
+ ref: 'beta'
55
+ - uses: pnpm/action-setup@v4
56
+ - uses: actions/setup-node@v4
57
+ with:
58
+ node-version: 18
59
+ cache: pnpm
60
+ - run: pnpm install --frozen-lockfile
61
+ - name: "Generate Explanation and Prep Changelogs"
62
+ id: explanation
63
+ run: |
64
+ set +e
65
+ pnpm release-plan prepare 2> >(tee -a release-plan-stderr.txt >&2)
66
+
67
+ if [ $? -ne 0 ]; then
68
+ release_plan_output=$(cat release-plan-stderr.txt)
69
+ else
70
+ release_plan_output=$(jq .description .release-plan.json -r)
71
+ rm release-plan-stderr.txt
72
+
73
+ if [ $(jq '.solution | length' .release-plan.json) -eq 1 ]; then
74
+ new_version=$(jq -r '.solution[].newVersion' .release-plan.json)
75
+ echo "new_version=v$new_version" >> $GITHUB_OUTPUT
76
+ fi
77
+ fi
78
+ echo 'text<<EOF' >> $GITHUB_OUTPUT
79
+ echo "$release_plan_output" >> $GITHUB_OUTPUT
80
+ echo 'EOF' >> $GITHUB_OUTPUT
81
+ env:
82
+ GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
83
+
84
+ - uses: peter-evans/create-pull-request@v7
85
+ with:
86
+ commit-message: "Prepare Release ${{ steps.explanation.outputs.new_version}} using 'release-plan'"
87
+ labels: "internal"
88
+ branch: release-preview
89
+ title: Prepare Beta Release ${{ steps.explanation.outputs.new_version }}
90
+ body: |
91
+ This PR is a preview of the release that [release-plan](https://github.com/embroider-build/release-plan) has prepared. To release you should just merge this PR 👍
92
+
93
+ -----------------------------------------
94
+
95
+ ${{ steps.explanation.outputs.text }}
@@ -0,0 +1,95 @@
1
+ name: Plan Stable Release
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches:
6
+ - release
7
+ pull_request_target: # This workflow has permissions on the repo, do NOT run code from PRs in this workflow. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
8
+ types:
9
+ - labeled
10
+ - unlabeled
11
+ branches:
12
+ - release
13
+
14
+ concurrency:
15
+ group: plan-release # only the latest one of these should ever be running
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ is-this-a-release:
20
+ name: "Is this a release?"
21
+ runs-on: ubuntu-latest
22
+ outputs:
23
+ command: ${{ steps.check-release.outputs.command }}
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 2
29
+ ref: 'release'
30
+ # This will only cause the `is-this-a-release` job to have a "command" of `release`
31
+ # when the .release-plan.json file was changed on the last commit.
32
+ - id: check-release
33
+ run: if git diff --name-only HEAD HEAD~1 | grep -w -q ".release-plan.json"; then echo "command=release"; fi >> $GITHUB_OUTPUT
34
+
35
+ create-prepare-release-pr:
36
+ name: Create Prepare Release PR
37
+ runs-on: ubuntu-latest
38
+ timeout-minutes: 5
39
+ needs: is-this-a-release
40
+ permissions:
41
+ contents: write
42
+ issues: read
43
+ pull-requests: write
44
+ # only run on push event or workflow dispatch if plan wasn't updated (don't create a release plan when we're releasing)
45
+ # only run on labeled event if the PR has already been merged
46
+ if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.is-this-a-release.outputs.command != 'release') || (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true)
47
+
48
+ steps:
49
+ - uses: actions/checkout@v4
50
+ # We need to download lots of history so that
51
+ # github-changelog can discover what's changed since the last release
52
+ with:
53
+ fetch-depth: 0
54
+ ref: 'release'
55
+ - uses: pnpm/action-setup@v4
56
+ - uses: actions/setup-node@v4
57
+ with:
58
+ node-version: 18
59
+ cache: pnpm
60
+ - run: pnpm install --frozen-lockfile
61
+ - name: "Generate Explanation and Prep Changelogs"
62
+ id: explanation
63
+ run: |
64
+ set +e
65
+ pnpm release-plan prepare 2> >(tee -a release-plan-stderr.txt >&2)
66
+
67
+ if [ $? -ne 0 ]; then
68
+ release_plan_output=$(cat release-plan-stderr.txt)
69
+ else
70
+ release_plan_output=$(jq .description .release-plan.json -r)
71
+ rm release-plan-stderr.txt
72
+
73
+ if [ $(jq '.solution | length' .release-plan.json) -eq 1 ]; then
74
+ new_version=$(jq -r '.solution[].newVersion' .release-plan.json)
75
+ echo "new_version=v$new_version" >> $GITHUB_OUTPUT
76
+ fi
77
+ fi
78
+ echo 'text<<EOF' >> $GITHUB_OUTPUT
79
+ echo "$release_plan_output" >> $GITHUB_OUTPUT
80
+ echo 'EOF' >> $GITHUB_OUTPUT
81
+ env:
82
+ GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
83
+
84
+ - uses: peter-evans/create-pull-request@v7
85
+ with:
86
+ commit-message: "Prepare Release ${{ steps.explanation.outputs.new_version}} using 'release-plan'"
87
+ labels: "internal"
88
+ branch: release-preview
89
+ title: Prepare Stable Release ${{ steps.explanation.outputs.new_version }}
90
+ body: |
91
+ This PR is a preview of the release that [release-plan](https://github.com/embroider-build/release-plan) has prepared. To release you should just merge this PR 👍
92
+
93
+ -----------------------------------------
94
+
95
+ ${{ steps.explanation.outputs.text }}
@@ -0,0 +1,42 @@
1
+ # For every push to the primary branch with .release-plan.json modified,
2
+ # runs release-plan.
3
+
4
+ name: Publish Beta
5
+
6
+ on:
7
+ workflow_dispatch:
8
+ push:
9
+ branches:
10
+ - beta
11
+ paths:
12
+ - '.release-plan.json'
13
+
14
+ concurrency:
15
+ group: publish-${{ github.head_ref || github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ publish:
20
+ name: "NPM Publish"
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: write
24
+ pull-requests: write
25
+ id-token: write
26
+ attestations: write
27
+
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: pnpm/action-setup@v4
31
+ - uses: actions/setup-node@v4
32
+ with:
33
+ node-version: 18
34
+ # This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable
35
+ registry-url: 'https://registry.npmjs.org'
36
+ cache: pnpm
37
+ - run: pnpm install --frozen-lockfile
38
+ - name: Publish to NPM
39
+ run: NPM_CONFIG_PROVENANCE=true pnpm release-plan publish --publish-branch=beta --github-prerelease
40
+ env:
41
+ GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
42
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,42 @@
1
+ # For every push to the primary branch with .release-plan.json modified,
2
+ # runs release-plan.
3
+
4
+ name: Publish Stable
5
+
6
+ on:
7
+ workflow_dispatch:
8
+ push:
9
+ branches:
10
+ - release
11
+ paths:
12
+ - '.release-plan.json'
13
+
14
+ concurrency:
15
+ group: publish-${{ github.head_ref || github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ publish:
20
+ name: "NPM Publish"
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: write
24
+ pull-requests: write
25
+ id-token: write
26
+ attestations: write
27
+
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: pnpm/action-setup@v4
31
+ - uses: actions/setup-node@v4
32
+ with:
33
+ node-version: 18
34
+ # This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable
35
+ registry-url: 'https://registry.npmjs.org'
36
+ cache: pnpm
37
+ - run: pnpm install --frozen-lockfile
38
+ - name: Publish to NPM
39
+ run: NPM_CONFIG_PROVENANCE=true pnpm release-plan publish --publish-branch=release
40
+ env:
41
+ GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
42
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -2,29 +2,21 @@
2
2
  "solution": {
3
3
  "@ember/app-blueprint": {
4
4
  "impact": "minor",
5
- "oldVersion": "6.9.0-alpha.1",
6
- "newVersion": "6.9.0-alpha.2",
5
+ "oldVersion": "6.10.0-alpha.0",
6
+ "newVersion": "6.10.0-alpha.1",
7
7
  "tagName": "alpha",
8
8
  "constraints": [
9
9
  {
10
10
  "impact": "minor",
11
11
  "reason": "Appears in changelog section :rocket: Enhancement"
12
12
  },
13
- {
14
- "impact": "patch",
15
- "reason": "Appears in changelog section :bug: Bug Fix"
16
- },
17
13
  {
18
14
  "impact": "patch",
19
15
  "reason": "Appears in changelog section :memo: Documentation"
20
- },
21
- {
22
- "impact": "patch",
23
- "reason": "Appears in changelog section :house: Internal"
24
16
  }
25
17
  ],
26
18
  "pkgJSONPath": "./package.json"
27
19
  }
28
20
  },
29
- "description": "## Release (2025-10-14)\n\n* @ember/app-blueprint 6.9.0-alpha.2 (minor)\n\n#### :rocket: Enhancement\n* `@ember/app-blueprint`\n * [#103](https://github.com/ember-cli/ember-app-blueprint/pull/103) [beta] update Vite to latest (v7) ([@mansona](https://github.com/mansona))\n * [#98](https://github.com/ember-cli/ember-app-blueprint/pull/98) Update deps ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n * [#95](https://github.com/ember-cli/ember-app-blueprint/pull/95) [Beta] add services directory ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n * [#91](https://github.com/ember-cli/ember-app-blueprint/pull/91) [bugfix beta] add legacy inspector support ([@mansona](https://github.com/mansona))\n\n#### :bug: Bug Fix\n* `@ember/app-blueprint`\n * [#100](https://github.com/ember-cli/ember-app-blueprint/pull/100) [beta] swap to the Vitest beta to fix CI ([@mansona](https://github.com/mansona))\n * [#88](https://github.com/ember-cli/ember-app-blueprint/pull/88) [bugfix beta] fix the use of ember test in the new blueprint ([@mansona](https://github.com/mansona))\n * [#86](https://github.com/ember-cli/ember-app-blueprint/pull/86) [bugfix beta] update ember-cli to beta ([@mansona](https://github.com/mansona))\n * [#82](https://github.com/ember-cli/ember-app-blueprint/pull/82) Use TypeScript way of accessing potentially undefined `podModulePrefix` ([@pichfl](https://github.com/pichfl))\n * [#78](https://github.com/ember-cli/ember-app-blueprint/pull/78) Use strict mode for all CJS files ([@simonihmig](https://github.com/simonihmig))\n\n#### :memo: Documentation\n* `@ember/app-blueprint`\n * [#97](https://github.com/ember-cli/ember-app-blueprint/pull/97) [documentation beta] update readme for Vite ([@mansona](https://github.com/mansona))\n * [#64](https://github.com/ember-cli/ember-app-blueprint/pull/64) Update the release document to match the ember-cli process ([@mansona](https://github.com/mansona))\n * [#81](https://github.com/ember-cli/ember-app-blueprint/pull/81) Correct example usage command in README ([@abeforgit](https://github.com/abeforgit))\n * [#80](https://github.com/ember-cli/ember-app-blueprint/pull/80) Fix formatting of README file ([@bertdeblock](https://github.com/bertdeblock))\n\n#### :house: Internal\n* `@ember/app-blueprint`\n * [#108](https://github.com/ember-cli/ember-app-blueprint/pull/108) update release-plan ([@mansona](https://github.com/mansona))\n * [#106](https://github.com/ember-cli/ember-app-blueprint/pull/106) Merge beta into main ([@mansona](https://github.com/mansona))\n * [#105](https://github.com/ember-cli/ember-app-blueprint/pull/105) Prepare Beta Release v6.8.0-beta.8 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#104](https://github.com/ember-cli/ember-app-blueprint/pull/104) Merge release into beta ([@mansona](https://github.com/mansona))\n * [#102](https://github.com/ember-cli/ember-app-blueprint/pull/102) Prepare Beta Release v6.8.0-beta.7 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#101](https://github.com/ember-cli/ember-app-blueprint/pull/101) [beta] update node version used in CI ([@mansona](https://github.com/mansona))\n * [#96](https://github.com/ember-cli/ember-app-blueprint/pull/96) Prepare Beta Release v6.8.0-beta.6 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#93](https://github.com/ember-cli/ember-app-blueprint/pull/93) Add Windows tests ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n * [#92](https://github.com/ember-cli/ember-app-blueprint/pull/92) Prepare Beta Release v6.8.0-beta.5 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#89](https://github.com/ember-cli/ember-app-blueprint/pull/89) Prepare Beta Release v6.8.0-beta.4 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#87](https://github.com/ember-cli/ember-app-blueprint/pull/87) Prepare Beta Release v6.8.0-beta.3 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#85](https://github.com/ember-cli/ember-app-blueprint/pull/85) Prepare Stable Release v6.7.2 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#84](https://github.com/ember-cli/ember-app-blueprint/pull/84) Prepare Beta Release v6.8.0-beta.2 ([@github-actions[bot]](https://github.com/apps/github-actions))\n * [#83](https://github.com/ember-cli/ember-app-blueprint/pull/83) update ember source to latest beta ([@mansona](https://github.com/mansona))\n\n#### Committers: 7\n- Arne Bertrand ([@abeforgit](https://github.com/abeforgit))\n- Bert De Block ([@bertdeblock](https://github.com/bertdeblock))\n- Chris Manson ([@mansona](https://github.com/mansona))\n- Florian Pichler ([@pichfl](https://github.com/pichfl))\n- Simon Ihmig ([@simonihmig](https://github.com/simonihmig))\n- [@NullVoxPopuli](https://github.com/NullVoxPopuli)\n- [@github-actions[bot]](https://github.com/apps/github-actions)\n"
21
+ "description": "## Release (2025-10-31)\n\n* @ember/app-blueprint 6.10.0-alpha.1 (minor)\n\n#### :rocket: Enhancement\n* `@ember/app-blueprint`\n * [#125](https://github.com/ember-cli/ember-app-blueprint/pull/125) Glint 2 (for `--typescript` projects) ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n * [#124](https://github.com/ember-cli/ember-app-blueprint/pull/124) Use modern EmberData/WarpDrive ([@runspired](https://github.com/runspired))\n * [#113](https://github.com/ember-cli/ember-app-blueprint/pull/113) Prepare 6.10 alpha ([@mansona](https://github.com/mansona))\n\n#### :memo: Documentation\n* `@ember/app-blueprint`\n * [#114](https://github.com/ember-cli/ember-app-blueprint/pull/114) update RELEASE.md with notes for after ember-cli release ([@mansona](https://github.com/mansona))\n\n#### Committers: 3\n- Chris Manson ([@mansona](https://github.com/mansona))\n- Chris Thoburn ([@runspired](https://github.com/runspired))\n- [@NullVoxPopuli](https://github.com/NullVoxPopuli)\n"
30
22
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## Release (2025-10-31)
4
+
5
+ * @ember/app-blueprint 6.10.0-alpha.1 (minor)
6
+
7
+ #### :rocket: Enhancement
8
+ * `@ember/app-blueprint`
9
+ * [#125](https://github.com/ember-cli/ember-app-blueprint/pull/125) Glint 2 (for `--typescript` projects) ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
10
+ * [#124](https://github.com/ember-cli/ember-app-blueprint/pull/124) Use modern EmberData/WarpDrive ([@runspired](https://github.com/runspired))
11
+ * [#113](https://github.com/ember-cli/ember-app-blueprint/pull/113) Prepare 6.10 alpha ([@mansona](https://github.com/mansona))
12
+
13
+ #### :memo: Documentation
14
+ * `@ember/app-blueprint`
15
+ * [#114](https://github.com/ember-cli/ember-app-blueprint/pull/114) update RELEASE.md with notes for after ember-cli release ([@mansona](https://github.com/mansona))
16
+
17
+ #### Committers: 3
18
+ - Chris Manson ([@mansona](https://github.com/mansona))
19
+ - Chris Thoburn ([@runspired](https://github.com/runspired))
20
+ - [@NullVoxPopuli](https://github.com/NullVoxPopuli)
21
+
3
22
  ## Release (2025-10-14)
4
23
 
5
24
  * @ember/app-blueprint 6.9.0-alpha.2 (minor)
package/RELEASE.md CHANGED
@@ -120,6 +120,13 @@ You can use [this saved search](https://github.com/ember-cli/ember-app-blueprint
120
120
  - Check the `Release Alpha` GitHub action to make sure the release succeeded
121
121
 
122
122
 
123
+ ### Release ember-cli and update ember-cli versions
124
+
125
+ After doing all this release process you can go and release ember-cli. Once ember-cli has been updated you will need to come back here and update the ember-cli reference to be the release (and not the pre-release) for each of the branches.
126
+
127
+ This is necessary because we're not in the same repository and can't make release `ember-cli` and `@ember/app-blueprint` atomically.
128
+
129
+
123
130
  ## Changelog updates
124
131
 
125
132
  `release-plan` is designed to automatically generate a Changelog that includes the titles of every PR that was merged since the last release. As we would like to make use of this auto-generated Changelog we need to make sure that PRs are named correctly and the Changelog included in the "Prepare Release" PRs are what we were expecting.
package/eslint.config.mjs CHANGED
@@ -25,6 +25,11 @@ export default [
25
25
  pluginJs.configs.recommended,
26
26
  eslintConfigPrettier,
27
27
  {
28
- ignores: ['tests/fixtures/*', 'files/ember-cli-build.js'],
28
+ ignores: [
29
+ 'tests/fixtures/*',
30
+ 'files/ember-cli-build.js',
31
+ 'files/_js_*',
32
+ 'files/_ts_*',
33
+ ],
29
34
  },
30
35
  ];
@@ -16,6 +16,7 @@ import globals from 'globals';
16
16
  import js from '@eslint/js';
17
17
 
18
18
  import ember from 'eslint-plugin-ember/recommended';
19
+ <% if (warpDrive) { %>import WarpDrive from 'eslint-plugin-warp-drive/recommended';<% } %>
19
20
  import eslintConfigPrettier from 'eslint-config-prettier';
20
21
  import qunit from 'eslint-plugin-qunit';
21
22
  import n from 'eslint-plugin-n';
@@ -32,6 +33,8 @@ export default [
32
33
  eslintConfigPrettier,
33
34
  ember.configs.base,
34
35
  ember.configs.gjs,
36
+ <% if (warpDrive) { %>...WarpDrive,<% } %>
37
+
35
38
  /**
36
39
  * Ignores must be in their own object
37
40
  * https://eslint.org/docs/latest/use/configure/ignore
@@ -18,6 +18,7 @@ import js from '@eslint/js';
18
18
  import ts from 'typescript-eslint';
19
19
 
20
20
  import ember from 'eslint-plugin-ember/recommended';
21
+ <% if (warpDrive) { %>import WarpDrive from 'eslint-plugin-warp-drive/recommended';<% } %>
21
22
 
22
23
  import eslintConfigPrettier from 'eslint-config-prettier';
23
24
  import qunit from 'eslint-plugin-qunit';
@@ -43,6 +44,7 @@ export default ts.config(
43
44
  ember.configs.base,
44
45
  ember.configs.gjs,
45
46
  ember.configs.gts,
47
+ <% if (warpDrive) { %>...WarpDrive,<% } %>
46
48
  eslintConfigPrettier,
47
49
  /**
48
50
  * Ignores must be in their own object
package/files/app/app.ts CHANGED
@@ -1,3 +1,4 @@
1
+ <% if (warpDrive) { %>import '@warp-drive/ember/install';<% } %>
1
2
  import Application from '@ember/application';
2
3
  import compatModules from '@embroider/virtual/compat-modules';
3
4
  import Resolver from 'ember-resolver';
@@ -0,0 +1,17 @@
1
+ import { useLegacyStore } from '@warp-drive/legacy';
2
+ import { JSONAPICache } from '@warp-drive/json-api';
3
+
4
+ const Store = useLegacyStore({
5
+ linksMode: true,
6
+ cache: JSONAPICache,
7
+ handlers: [
8
+ // -- your handlers here
9
+ ],
10
+ schemas: [
11
+ // -- your schemas here
12
+ ],
13
+ });
14
+
15
+ type Store = InstanceType<typeof Store>;
16
+
17
+ export default Store;
@@ -4,19 +4,22 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4
4
  const { compatBuild } = require('@embroider/compat');
5
5
 
6
6
  module.exports = async function (defaults) {
7
- const { buildOnce } = await import('@embroider/vite');
7
+ <% if (warpDrive) {%>const { setConfig } = await import('@warp-drive/core/build-config');
8
+ <% } %>const { buildOnce } = await import('@embroider/vite');
9
+
8
10
  let app = new EmberApp(defaults, {
9
- <% if (emberData) {%>emberData: {
10
- deprecations: {
11
- // New projects can safely leave this deprecation disabled.
12
- // If upgrading, to opt-into the deprecated behavior, set this to true and then follow:
13
- // https://deprecations.emberjs.com/id/ember-data-deprecate-store-extends-ember-object
14
- // before upgrading to Ember Data 6.0
15
- DEPRECATE_STORE_EXTENDS_EMBER_OBJECT: false,
16
- },
11
+ // Add options here
12
+ });
13
+ <% if (warpDrive) {%>
14
+ setConfig(app, __dirname, {
15
+ // this should be the most recent <major>.<minor> version for
16
+ // which all deprecations have been fully resolved
17
+ // and should be updated when that changes
18
+ compatWith: '5.8',
19
+ deprecations: {
20
+ // ... list individual deprecations that have been resolved here
17
21
  },
18
- <% } %>// Add options here
19
22
  });
20
-
23
+ <% } %>
21
24
  return compatBuild(app, buildOnce);
22
25
  };
@@ -22,7 +22,7 @@
22
22
  "lint:hbs:fix": "ember-template-lint . --fix",
23
23
  "lint:js": "eslint . --cache",
24
24
  "lint:js:fix": "eslint . --fix<% if (typescript) { %>",
25
- "lint:types": "glint<% } %>",
25
+ "lint:types": "ember-tsc --noEmit<% } %>",
26
26
  "start": "vite",
27
27
  "test": "vite build --mode development && ember test --path dist"
28
28
  },
@@ -35,16 +35,7 @@
35
35
  "@babel/runtime": "^7.28.4",
36
36
  "@babel/plugin-transform-runtime": "^7.28.3<% if (typescript) { %>",
37
37
  "@babel/plugin-transform-typescript": "^7.28.0<% } %>",
38
- "@babel/eslint-parser": "^7.28.4<% if (typescript && emberData) { %>",
39
- "@ember-data/adapter": "~5.6.0",
40
- "@ember-data/graph": "~5.6.0",
41
- "@ember-data/json-api": "~5.6.0",
42
- "@ember-data/legacy-compat": "~5.6.0",
43
- "@ember-data/model": "~5.6.0",
44
- "@ember-data/request": "~5.6.0",
45
- "@ember-data/request-utils": "~5.6.0",
46
- "@ember-data/serializer": "~5.6.0",
47
- "@ember-data/store": "~5.6.0<% } %><% if (typescript) { %>",
38
+ "@babel/eslint-parser": "^7.28.4<% if (typescript) { %>",
48
39
  "@ember/app-tsconfig": "^1.0.3<% } %>",
49
40
  "@ember/optional-features": "^2.2.0",
50
41
  "@ember/string": "^4.0.1",
@@ -59,36 +50,38 @@
59
50
  "@embroider/legacy-inspector-support": "^0.1.3",
60
51
  "@eslint/js": "^9.37.0",
61
52
  "@glimmer/component": "^2.0.0<% if (typescript) { %>",
62
- "@glint/core": "^1.5.2",
63
- "@glint/environment-ember-loose": "^1.5.2",
64
- "@glint/environment-ember-template-imports": "^1.5.2",
65
- "@glint/template": "^1.6.1<% } %>",
53
+ "@glint/ember-tsc": "^1.0.4",
54
+ "@glint/template": "^1.6.2",
55
+ "@glint/tsserver-plugin": "^2.0.4<% } %>",
66
56
  "@rollup/plugin-babel": "^6.0.4<% if (typescript) { %>",
67
57
  "@types/qunit": "^2.19.13",
68
- "@types/rsvp": "^4.0.9<% if (emberData) {%>",
69
- "@warp-drive/core-types": "~5.6.0<% }} %><% if (emberData) { %>",
70
- "@warp-drive/ember": "~5.6.0<% } %>",
58
+ "@types/rsvp": "^4.0.9<% } %><% if (warpDrive) { %>",
59
+ "@warp-drive/core": "5.8.0",
60
+ "@warp-drive/ember": "5.8.0",
61
+ "@warp-drive/json-api": "5.8.0",
62
+ "@warp-drive/legacy": "5.8.0",
63
+ "@warp-drive/utilities": "5.8.0<% } %>",
71
64
  "babel-plugin-ember-template-compilation": "^2.4.1",
72
65
  "concurrently": "^9.2.1",
73
66
  "decorator-transforms": "^2.3.0",
74
67
  "ember-auto-import": "^2.11.1",
75
68
  "ember-cli": "~6.9.0-alpha.1",
76
69
  "ember-cli-babel": "^8.2.0",
77
- "ember-cli-deprecation-workflow": "^3.4.0<% if (emberData) { %>",
78
- "ember-data": "~5.6.0<% } %>",
70
+ "ember-cli-deprecation-workflow": "^3.4.0",
79
71
  "ember-load-initializers": "^3.0.1",
80
72
  "ember-modifier": "^4.2.2",
81
73
  "ember-page-title": "^9.0.3",
82
74
  "ember-qunit": "^9.0.4",
83
75
  "ember-resolver": "^13.1.1",
84
- "ember-source": "~6.9.0-alpha.6",
76
+ "ember-source": "~6.10.0-alpha.1",
85
77
  "ember-template-lint": "^7.9.3<% if (welcome) { %>",
86
78
  "ember-welcome-page": "^7.0.2<% } %>",
87
79
  "eslint": "^9.37.0",
88
80
  "eslint-config-prettier": "^10.1.8",
89
81
  "eslint-plugin-ember": "^12.7.4",
90
82
  "eslint-plugin-n": "^17.23.1",
91
- "eslint-plugin-qunit": "^8.2.5",
83
+ "eslint-plugin-qunit": "^8.2.5<% if (warpDrive) { %>",
84
+ "eslint-plugin-warp-drive": "5.8.0<% } %>",
92
85
  "globals": "^16.4.0",
93
86
  "prettier": "^3.6.2",
94
87
  "prettier-plugin-ember-template-tag": "^2.1.0",
@@ -1,3 +1,4 @@
1
+ <% if (warpDrive) { %>import '@warp-drive/ember/install';<% } %>
1
2
  import Application from '<%= modulePrefix %>/app';
2
3
  import config from '<%= modulePrefix %>/config/environment';
3
4
  import * as QUnit from 'qunit';
@@ -1,9 +1,6 @@
1
1
  {
2
2
  "extends": "@ember/app-tsconfig",
3
3
  "include": ["app", "tests", "types"],
4
- "glint": {
5
- "environment": ["ember-loose", "ember-template-imports"]
6
- },
7
4
  "compilerOptions": {
8
5
  "allowJs": true,
9
6
  "paths": {
@@ -11,6 +8,11 @@
11
8
  "<%= name %>/*": ["./app/*"],
12
9
  "*": ["./types/*"]
13
10
  },
14
- "types": ["ember-source/types", "@embroider/core/virtual", "vite/client"]
11
+ "types": [
12
+ "ember-source/types",
13
+ "@embroider/core/virtual",
14
+ "vite/client",
15
+ "@glint/ember-tsc/types"
16
+ ]
15
17
  }
16
18
  }
package/index.js CHANGED
@@ -40,6 +40,7 @@ module.exports = {
40
40
  options.ciProvider && `"--ci-provider=${options.ciProvider}"`,
41
41
  options.typescript && `"--typescript"`,
42
42
  !options.emberData && `"--no-ember-data"`,
43
+ !options.warpDrive && `"--no-warp-drive"`,
43
44
  ]
44
45
  .filter(Boolean)
45
46
  .join(',\n ') +
@@ -75,7 +76,7 @@ module.exports = {
75
76
  blueprint: 'app',
76
77
  blueprintOptions,
77
78
  lang: options.lang,
78
- emberData: options.emberData,
79
+ warpDrive: options.warpDrive ?? options.emberData,
79
80
  ciProvider: options.ciProvider,
80
81
  typescript: options.typescript,
81
82
  packageManager: options.packageManager ?? 'npm',
@@ -101,9 +102,11 @@ module.exports = {
101
102
  );
102
103
  }
103
104
 
104
- if (!options.emberData) {
105
- files = files.filter((file) => !file.includes('models/'));
106
- files = files.filter((file) => !file.includes('ember-data/'));
105
+ const warpDrive = options.warpDrive || options.emberData;
106
+ if (!warpDrive) {
107
+ files = files.filter((file) => !file.includes('services/store.ts'));
108
+ } else {
109
+ files = files.filter((file) => !file.includes('services/.gitkeep'));
107
110
  }
108
111
 
109
112
  this._files = files;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ember/app-blueprint",
3
- "version": "6.9.0-alpha.2",
3
+ "version": "6.10.0-alpha.1",
4
4
  "description": "Blueprint for next generation of Ember apps",
5
5
  "keywords": [
6
6
  "ember-blueprint"
@@ -108,15 +108,31 @@ describe('Blueprint Arguments', function () {
108
108
  it('installs ember-data by default', async function () {
109
109
  const { files } = await generateApp();
110
110
 
111
- expect(parse(files['package.json']).devDependencies['ember-data']).to.not
112
- .be.undefined;
111
+ expect(parse(files['package.json']).devDependencies['@warp-drive/core'])
112
+ .to.not.be.undefined;
113
113
  });
114
114
 
115
115
  it('does not add ember-data if you pass --no-ember-data', async function () {
116
116
  const { files } = await generateApp({ flags: ['--no-ember-data'] });
117
117
 
118
- expect(parse(files['package.json']).devDependencies['ember-data']).to.be
119
- .undefined;
118
+ expect(parse(files['package.json']).devDependencies['@warp-drive/core'])
119
+ .to.be.undefined;
120
+ });
121
+ });
122
+
123
+ describe('--no-warp-drive', async function () {
124
+ it('installs warp-drive by default', async function () {
125
+ const { files } = await generateApp();
126
+
127
+ expect(parse(files['package.json']).devDependencies['@warp-drive/core'])
128
+ .to.not.be.undefined;
129
+ });
130
+
131
+ it('does not add warp-drive if you pass --no-warp-drive', async function () {
132
+ const { files } = await generateApp({ flags: ['--no-warp-drive'] });
133
+
134
+ expect(parse(files['package.json']).devDependencies['@warp-drive/core'])
135
+ .to.be.undefined;
120
136
  });
121
137
  });
122
138
 
@@ -0,0 +1,14 @@
1
+ import Route from '@ember/routing/route';
2
+ import { service } from '@ember/service';
3
+
4
+ export default class ApplicationRoute extends Route {
5
+ @service store;
6
+
7
+ model() {
8
+ return {
9
+ person: this.store.request({
10
+ url: 'https://swapi.dev/api/people/1',
11
+ }),
12
+ };
13
+ }
14
+ }
@@ -0,0 +1,30 @@
1
+ import { useLegacyStore } from '@warp-drive/legacy';
2
+ import { JSONAPICache } from '@warp-drive/json-api';
3
+ import { withDefaults } from '@warp-drive/legacy/model/migration-support';
4
+
5
+ const Store = useLegacyStore({
6
+ linksMode: true,
7
+ cache: JSONAPICache,
8
+ handlers: [
9
+ {
10
+ request() {
11
+ return Promise.resolve({
12
+ data: {
13
+ type: 'person',
14
+ id: '1',
15
+ attributes: { name: 'Luke Skywalker' },
16
+ },
17
+ });
18
+ },
19
+ },
20
+ ],
21
+ schemas: [
22
+ // -- your schemas here
23
+ withDefaults({
24
+ type: 'person',
25
+ fields: [{ kind: 'field', name: 'name' }],
26
+ }),
27
+ ],
28
+ });
29
+
30
+ export default Store;
@@ -0,0 +1,22 @@
1
+ import { pageTitle } from 'ember-page-title';
2
+ import { Request } from '@warp-drive/ember';
3
+
4
+ <template>
5
+ {{pageTitle "MyTestApp"}}
6
+
7
+ {{outlet}}
8
+
9
+ {{! The following component displays Ember's default welcome message. }}
10
+ <Request @request={{@model.person}}>
11
+ <:loading>
12
+ <p>Loading person...</p>
13
+ </:loading>
14
+ <:error as |error|>
15
+ <p>Error loading person: {{error.message}}</p>
16
+ </:error>
17
+ <:content as |result|>
18
+ <h1>Welcome {{result.data.name}}</h1>
19
+ </:content>
20
+ </Request>
21
+ {{! Feel free to remove this! }}
22
+ </template>
@@ -0,0 +1,13 @@
1
+ import { module, test } from 'qunit';
2
+ import { setupApplicationTest } from 'ember-qunit';
3
+ import { visit } from '@ember/test-helpers';
4
+
5
+ module('Application | index', function (hooks) {
6
+ setupApplicationTest(hooks);
7
+
8
+ test('visiting / shows welcome message', async function (assert) {
9
+ await visit('/');
10
+
11
+ assert.dom('h1').hasText('Welcome Luke Skywalker');
12
+ });
13
+ });
@@ -0,0 +1,26 @@
1
+ import Route from '@ember/routing/route';
2
+ import { service } from '@ember/service';
3
+ import { withReactiveResponse } from '@warp-drive/core/request';
4
+ import type { Type } from '@warp-drive/core/types/symbols';
5
+ import type Store from 'test-app/services/store';
6
+
7
+ export interface Person {
8
+ id: string;
9
+ $type: 'person';
10
+ name: string;
11
+ [Type]: 'person';
12
+ }
13
+
14
+ export default class ApplicationRoute extends Route {
15
+ @service declare store: Store;
16
+
17
+ model() {
18
+ return {
19
+ person: this.store.request(
20
+ withReactiveResponse<Person>({
21
+ url: 'https://swapi.dev/api/people/1',
22
+ }),
23
+ ),
24
+ };
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import { useLegacyStore } from '@warp-drive/legacy';
2
+ import { JSONAPICache } from '@warp-drive/json-api';
3
+ import { withDefaults } from '@warp-drive/legacy/model/migration-support';
4
+
5
+ const Store = useLegacyStore({
6
+ linksMode: true,
7
+ cache: JSONAPICache,
8
+ handlers: [
9
+ {
10
+ request<T>(): Promise<T> {
11
+ return Promise.resolve({
12
+ data: {
13
+ type: 'person',
14
+ id: '1',
15
+ attributes: { name: 'Luke Skywalker' }
16
+ },
17
+ } as T);
18
+ }
19
+ }
20
+ ],
21
+ schemas: [
22
+ // -- your schemas here
23
+ withDefaults({
24
+ type: 'person',
25
+ fields: [{ kind: 'field', name: 'name' }],
26
+ }),
27
+ ],
28
+ });
29
+
30
+ type Store = InstanceType<typeof Store>;
31
+
32
+ export default Store;
@@ -0,0 +1,32 @@
1
+ import { pageTitle } from 'ember-page-title';
2
+ import { Request } from '@warp-drive/ember';
3
+ import type { TOC } from '@ember/component/template-only';
4
+ import type { Future } from '@warp-drive/core/request';
5
+ import type { ReactiveDataDocument } from '@warp-drive/core/reactive';
6
+ import type { Person } from 'test-app/routes/application';
7
+
8
+ const Route: TOC<{ Args: {
9
+ model: {
10
+ person: Future<ReactiveDataDocument<Person>>
11
+ }
12
+ } }> = <template>
13
+ {{pageTitle "MyTestApp"}}
14
+
15
+ {{outlet}}
16
+
17
+ {{! The following component displays Ember's default welcome message. }}
18
+ <Request @request={{@model.person}}>
19
+ <:loading>
20
+ <p>Loading person...</p>
21
+ </:loading>
22
+ <:error as |error|>
23
+ <p>Error loading person: {{error.message}}</p>
24
+ </:error>
25
+ <:content as |result|>
26
+ <h1>Welcome {{result.data.name}}</h1>
27
+ </:content>
28
+ </Request>
29
+ {{! Feel free to remove this! }}
30
+ </template>
31
+
32
+ export default Route;
@@ -0,0 +1,13 @@
1
+ import { module, test } from 'qunit';
2
+ import { setupApplicationTest } from 'ember-qunit';
3
+ import { visit } from '@ember/test-helpers';
4
+
5
+ module('Application | index', function (hooks) {
6
+ setupApplicationTest(hooks);
7
+
8
+ test('visiting / shows welcome message', async function (assert) {
9
+ await visit('/');
10
+
11
+ assert.dom('h1').hasText('Welcome Luke Skywalker');
12
+ });
13
+ });
@@ -56,7 +56,7 @@ describe('linting & formatting', function () {
56
56
  it('glint passes', async function () {
57
57
  expect(
58
58
  JSON.parse(app.files['package.json']).scripts['lint:types'],
59
- ).to.equal('glint');
59
+ ).to.equal('ember-tsc --noEmit');
60
60
 
61
61
  let { exitCode, stdout } = await app.execa('pnpm', ['lint:types']);
62
62
 
@@ -0,0 +1,137 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import fixturify from 'fixturify';
3
+
4
+ import { generateApp } from './helpers.mjs';
5
+
6
+ it('Slow(JavaScript): Runs tests', async function () {
7
+ let app = await generateApp({
8
+ flags: ['--pnpm', '--typescript'],
9
+ skipNpm: false,
10
+ });
11
+
12
+ fixturify.writeSync(
13
+ app.dir,
14
+ fixturify.readSync('./tests/fixtures/warpdrive-js'),
15
+ );
16
+
17
+ let { stdout: stdout2, exitCode: exitCode2 } = await app.execa('pnpm', [
18
+ 'test',
19
+ ]);
20
+
21
+ if (!process.env.CI) {
22
+ console.log(stdout2);
23
+ }
24
+
25
+ expect(stdout2).to.match(/ok .* Application \| index/);
26
+ expect(stdout2).to.match(/ok .* Ember.onerror/);
27
+
28
+ expect(stdout2).to.contain('# tests 2');
29
+ expect(stdout2).to.contain('# pass 2');
30
+ expect(stdout2).to.contain('# skip 0');
31
+ expect(stdout2).to.contain('# todo 0');
32
+ expect(stdout2).to.contain('# ok');
33
+
34
+ expect(exitCode2).to.equal(0);
35
+ });
36
+
37
+ it('Slow(TypeScript): Runs tests', async function () {
38
+ let app = await generateApp({
39
+ flags: ['--pnpm', '--typescript'],
40
+ skipNpm: false,
41
+ });
42
+
43
+ fixturify.writeSync(
44
+ app.dir,
45
+ fixturify.readSync('./tests/fixtures/warpdrive-ts'),
46
+ );
47
+
48
+ let { stdout: stdout2, exitCode: exitCode2 } = await app.execa('pnpm', [
49
+ 'test',
50
+ ]);
51
+
52
+ if (!process.env.CI) {
53
+ console.log(stdout2);
54
+ }
55
+
56
+ expect(stdout2).to.match(/ok .* Application \| index/);
57
+ expect(stdout2).to.match(/ok .* Ember.onerror/);
58
+
59
+ expect(stdout2).to.contain('# tests 2');
60
+ expect(stdout2).to.contain('# pass 2');
61
+ expect(stdout2).to.contain('# skip 0');
62
+ expect(stdout2).to.contain('# todo 0');
63
+ expect(stdout2).to.contain('# ok');
64
+ expect(exitCode2).to.equal(0);
65
+ });
66
+
67
+ describe('linting & formatting', function () {
68
+ describe('JavaScript', function () {
69
+ let app;
70
+
71
+ beforeAll(async function () {
72
+ /**
73
+ * We are passing --pnpm here because it's just faster to run in CI and realistically
74
+ * we don't need to worry about the differences between pnpm and npm at this level
75
+ */
76
+ app = await generateApp({ flags: ['--pnpm'], skipNpm: false });
77
+ fixturify.writeSync(
78
+ app.dir,
79
+ fixturify.readSync('./tests/fixtures/warpdrive-js'),
80
+ );
81
+ });
82
+
83
+ it('yields output without errors', async function (context) {
84
+ // Lint errors on windows machines - probably because of line-endings.
85
+ // TODO fix the config so that a newly generated app doens't fail lint on windows
86
+ if (process.platform === 'win32') {
87
+ context.skip();
88
+ }
89
+
90
+ let { exitCode } = await app.execa('pnpm', ['lint']);
91
+
92
+ expect(exitCode).to.equal(0);
93
+ });
94
+ });
95
+
96
+ describe('TypeScript', function () {
97
+ let app;
98
+
99
+ beforeAll(async function () {
100
+ /**
101
+ * We are passing --pnpm here because it's just faster to run in CI and realistically
102
+ * we don't need to worry about the differences between pnpm and npm at this level
103
+ */
104
+ app = await generateApp({
105
+ flags: ['--typescript', '--pnpm'],
106
+ skipNpm: false,
107
+ });
108
+ fixturify.writeSync(
109
+ app.dir,
110
+ fixturify.readSync('./tests/fixtures/warpdrive-js'),
111
+ );
112
+ });
113
+
114
+ it('yields output without errors', async function (context) {
115
+ // Lint errors on windows machines - probably because of line-endings.
116
+ // TODO fix the config so that a newly generated app doens't fail lint on windows
117
+ if (process.platform === 'win32') {
118
+ context.skip();
119
+ }
120
+
121
+ let { exitCode } = await app.execa('pnpm', ['lint']);
122
+
123
+ expect(exitCode).to.equal(0);
124
+ });
125
+
126
+ it('glint passes', async function () {
127
+ expect(
128
+ JSON.parse(app.files['package.json']).scripts['lint:types'],
129
+ ).to.equal('glint');
130
+
131
+ let { exitCode, stdout } = await app.execa('pnpm', ['lint:types']);
132
+
133
+ console.log(stdout);
134
+ expect(exitCode).to.equal(0);
135
+ });
136
+ });
137
+ });
File without changes