diff --git a/files/.editorconfig b/files/.editorconfig new file mode 100644 index 0000000..c35a002 --- /dev/null +++ b/files/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.hbs] +insert_final_newline = false + +[*.{diff,md}] +trim_trailing_whitespace = false diff --git a/files/.ember-cli b/files/.ember-cli new file mode 100644 index 0000000..9152f9f --- /dev/null +++ b/files/.ember-cli @@ -0,0 +1,7 @@ +{ + /** + Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript + rather than JavaScript by default, when a TypeScript version of a given blueprint is available. + */ + "isTypeScriptProject": <%= typescript ? 'true' : 'false' %> +} diff --git a/files/.eslintignore b/files/.eslintignore new file mode 100644 index 0000000..768fab3 --- /dev/null +++ b/files/.eslintignore @@ -0,0 +1,14 @@ +# unconventional js +/blueprints/*/files/ + +# compiled output +/declarations/ +/dist/ + +# misc +/coverage/ +!.* +.*/ + +# ember-try +/.node_modules.ember-try/ diff --git a/files/.eslintrc.js b/files/.eslintrc.js new file mode 100644 index 0000000..42c9dfc --- /dev/null +++ b/files/.eslintrc.js @@ -0,0 +1,67 @@ +'use strict'; + +module.exports = { + root: true, + parser: '<%= typescript ? '@typescript-eslint/parser' : '@babel/eslint-parser' %>', + parserOptions: { + ecmaVersion: 'latest',<% if (!typescript) { %> + sourceType: 'module', + requireConfigFile: false, + babelOptions: { + plugins: [ + ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }], + ], + },<% } %> + }, + plugins: ['ember'<% if (typescript) { %>, '@typescript-eslint'<% } %>], + extends: [ + 'eslint:recommended', + 'plugin:ember/recommended', + 'plugin:prettier/recommended', + ], + env: { + browser: true, + }, + rules: {}, + overrides: [ +<% if (typescript) { %> // ts files + { + files: ['**/*.ts'], + extends: [ + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + ], + rules: {}, + }, +<% } %> // node files + { + files: [ + './.eslintrc.js', + './.prettierrc.js', + './.stylelintrc.js', + './.template-lintrc.js', + './ember-cli-build.js',<% if (blueprint !== 'app') { %> + './index.js',<% } %> + './testem.js', + './blueprints/*/index.js', + './config/**/*.js',<% if (blueprint === 'app') { %> + './lib/*/index.js', + './server/**/*.js',<% } else { %> + './tests/dummy/config/**/*.js',<% } %> + ], +<% if (!typescript) { %> parserOptions: { + sourceType: 'script', + }, +<% } %> env: { + browser: false, + node: true, + }, + extends: ['plugin:n/recommended'], + }, + { + // test files + files: ['tests/**/*-test.{js,ts}'], + extends: ['plugin:qunit/recommended'], + }, + ], +}; diff --git a/files/.github/workflows/ci.yml b/files/.github/workflows/ci.yml new file mode 100644 index 0000000..9885ae1 --- /dev/null +++ b/files/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + push: + branches: + - main + - master + pull_request: {} + +concurrency: + group: ci-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: "Lint" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3<% if (pnpm) { %> + - uses: pnpm/action-setup@v2 + with: + version: 8<% } %> + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: <%= pnpm ? 'pnpm' : yarn ? 'yarn' : 'npm' %> + - name: Install Dependencies + run: <%= pnpm ? 'pnpm install --frozen-lockfile' : yarn ? 'yarn install --frozen-lockfile' : 'npm ci' %> + - name: Lint + run: <%= pnpm ? 'pnpm' : yarn ? 'yarn' : 'npm run' %> lint + + test: + name: "Test" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3<% if (pnpm) { %> + - uses: pnpm/action-setup@v2 + with: + version: 8<% } %> + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: <%= pnpm ? 'pnpm' : yarn ? 'yarn' : 'npm' %> + - name: Install Dependencies + run: <%= pnpm ? 'pnpm install --frozen-lockfile' : yarn ? 'yarn install --frozen-lockfile' : 'npm ci' %> + - name: Run Tests + run: <%= pnpm ? 'pnpm' : yarn ? 'yarn' : 'npm' %> test diff --git a/files/.prettierignore b/files/.prettierignore new file mode 100644 index 0000000..9385391 --- /dev/null +++ b/files/.prettierignore @@ -0,0 +1,13 @@ +# unconventional js +/blueprints/*/files/ + +# compiled output +/dist/ + +# misc +/coverage/ +!.* +.*/ + +# ember-try +/.node_modules.ember-try/ diff --git a/files/.prettierrc.js b/files/.prettierrc.js new file mode 100644 index 0000000..e5f7b6d --- /dev/null +++ b/files/.prettierrc.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = { + overrides: [ + { + files: '*.{js,ts}', + options: { + singleQuote: true, + }, + }, + ], +}; diff --git a/files/.stylelintignore b/files/.stylelintignore new file mode 100644 index 0000000..a0cf71c --- /dev/null +++ b/files/.stylelintignore @@ -0,0 +1,8 @@ +# unconventional files +/blueprints/*/files/ + +# compiled output +/dist/ + +# addons +/.node_modules.ember-try/ diff --git a/files/.stylelintrc.js b/files/.stylelintrc.js new file mode 100644 index 0000000..021c539 --- /dev/null +++ b/files/.stylelintrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'], +}; diff --git a/files/.template-lintrc.js b/files/.template-lintrc.js new file mode 100644 index 0000000..f35f61c --- /dev/null +++ b/files/.template-lintrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + extends: 'recommended', +}; diff --git a/files/README.md b/files/README.md new file mode 100644 index 0000000..5c8ddf0 --- /dev/null +++ b/files/README.md @@ -0,0 +1,58 @@ +# <%= name %> + +This README outlines the details of collaborating on this Ember application. +A short introduction of this app could easily go here. + +## Prerequisites + +You will need the following things properly installed on your computer. + +- [Git](https://git-scm.com/) +- [Node.js](https://nodejs.org/)<% if (pnpm) { %> +- [pnpm](https://pnpm.io/)<% } else if (yarn) { %> +- [Yarn](https://yarnpkg.com/)<% } else { %> (with npm)<% } %> +- [Ember CLI](https://cli.emberjs.com/release/) +- [Google Chrome](https://google.com/chrome/) + +## Installation + +- `git clone ` this repository +- `cd <%= appDirectory %>` +- `<% if (pnpm) { %>pnpm<% } else if (yarn) { %>yarn<% } else { %>npm<% } %> install` + +## Running / Development + +- `<%= invokeScriptPrefix %> start` +- Visit your app at [http://localhost:4200](http://localhost:4200). +- Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests). + +### Code Generators + +Make use of the many generators for code, try `ember help generate` for more details + +### Running Tests + +- `<%= invokeScriptPrefix %> test` +- `<%= invokeScriptPrefix %> test:ember <% if (npm) { %>-- <% } %>--server` + +### Linting + +- `<%= invokeScriptPrefix %> lint` +- `<%= invokeScriptPrefix %> lint:fix` + +### Building + +- `<%= execBinPrefix %> ember build` (development) +- `<%= invokeScriptPrefix %> build` (production) + +### Deploying + +Specify what it takes to deploy your app. + +## Further Reading / Useful Links + +- [ember.js](https://emberjs.com/) +- [ember-cli](https://cli.emberjs.com/release/) +- Development Browser Extensions + - [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) + - [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) diff --git a/files-override/app/app.js b/files/app/app.ts similarity index 95% rename from files-override/app/app.js rename to files/app/app.ts index 9f0c043..3e8457c 100644 --- a/files-override/app/app.js +++ b/files/app/app.ts @@ -7,7 +7,7 @@ import config from './config/environment'; let d = window.define; for (const [name, module] of Object.entries(compatModules)) { - d(name, function () { + d(name, function() { return module; }); } diff --git a/files/app/components/.gitkeep b/files/app/components/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/files/app/config/environment.js b/files/app/config/environment.ts similarity index 100% rename from files/app/config/environment.js rename to files/app/config/environment.ts diff --git a/files/app/router.ts b/files/app/router.ts new file mode 100644 index 0000000..521696a --- /dev/null +++ b/files/app/router.ts @@ -0,0 +1,11 @@ +import EmberRouter from '@ember/routing/router'; +import config from '<%= modulePrefix %>/config/environment'; + +export default class Router extends EmberRouter { + location = config.locationType; + rootURL = config.rootURL; +} + +Router.map(function () {<% if (typescript) { %> + // Add route declarations here +<% } %>}); diff --git a/files/app/routes/.gitkeep b/files/app/routes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/files/app/templates/application.gts b/files/app/templates/application.gts new file mode 100644 index 0000000..1ef136e --- /dev/null +++ b/files/app/templates/application.gts @@ -0,0 +1,17 @@ +import { pageTitle } from 'ember-page-title'; +<% if (welcome) {%>import { WelcomePage } from 'ember-welcome-page';<% } %> + +export default Route( + +); diff --git a/files/config/ember-cli-update.json b/files/config/ember-cli-update.json new file mode 100644 index 0000000..ff2630f --- /dev/null +++ b/files/config/ember-cli-update.json @@ -0,0 +1,18 @@ +{ + "schemaVersion": "1.0.0", + "packages": [ + { + "name": "ember-cli", + "version": "<%= emberCLIVersion %>", + "blueprints": [ + { + "name": "<%= blueprint %>", + "outputRepo": "https://github.com/ember-cli/ember-<%= blueprint === 'app' ? 'new' : 'addon' %>-output", + "codemodsSource": "ember-<%= blueprint %>-codemods-manifest@1", + "isBaseBlueprint": true, + "options": [<%= blueprintOptions %>] + } + ] + } + ] +} diff --git a/files/config/environment.js b/files/config/environment.js new file mode 100644 index 0000000..10a7d5b --- /dev/null +++ b/files/config/environment.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function (environment) { + const ENV = { + modulePrefix: '<%= modulePrefix %>', + environment, + rootURL: '/', + locationType: 'history', + EmberENV: { + EXTEND_PROTOTYPES: false, + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true + }, + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + }, + }; + + if (environment === 'development') { + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + } + + if (environment === 'test') { + // Testem prefers this... + ENV.locationType = 'none'; + + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; + + ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; + } + + if (environment === 'production') { + // here you can enable a production-specific feature + } + + return ENV; +}; diff --git a/files/config/optional-features.json b/files/config/optional-features.json new file mode 100644 index 0000000..5329dd9 --- /dev/null +++ b/files/config/optional-features.json @@ -0,0 +1,7 @@ +{ + "application-template-wrapper": false, + "default-async-observers": true, + "jquery-integration": false, + "template-only-glimmer-components": true, + "no-implicit-route-model": true +} diff --git a/files/config/targets.js b/files/config/targets.js new file mode 100644 index 0000000..1e48e05 --- /dev/null +++ b/files/config/targets.js @@ -0,0 +1,11 @@ +'use strict'; + +const browsers = [ + 'last 1 Chrome versions', + 'last 1 Firefox versions', + 'last 1 Safari versions', +]; + +module.exports = { + browsers, +}; diff --git a/files-override/ember-cli-build.js b/files/ember-cli-build.js similarity index 62% rename from files-override/ember-cli-build.js rename to files/ember-cli-build.js index ebb76e5..f2bb264 100644 --- a/files-override/ember-cli-build.js +++ b/files/ember-cli-build.js @@ -3,8 +3,10 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { maybeEmbroider } = require('@embroider/test-setup'); -module.exports = function (defaults) { - let app = new EmberApp(defaults, {}); +module.exports = function(defaults) { + let app = new EmberApp(defaults, { + // Add options here + }); return maybeEmbroider(app); }; diff --git a/files-override/.gitignore b/files/gitignore similarity index 98% rename from files-override/.gitignore rename to files/gitignore index b034d62..71ad79d 100644 --- a/files-override/.gitignore +++ b/files/gitignore @@ -1,7 +1,6 @@ # compiled output /dist/ /declarations/ -/tmp/ # dependencies /node_modules/ diff --git a/files/package.json b/files/package.json new file mode 100644 index 0000000..661f2ac --- /dev/null +++ b/files/package.json @@ -0,0 +1,118 @@ +{ + "name": "<%= name %>", + "version": "0.0.0", + "private": true, + "description": "Small description for <%= name %> goes here", + "repository": "", + "license": "MIT", + "author": "", + "directories": { + "doc": "doc", + "test": "tests" + }, + "scripts": { + "build": "ember build --environment=production", + "lint": "concurrently \"<%= packageManager %>:lint:*(!fix)\" --names \"lint:\"", + "lint:css": "stylelint \"**/*.css\"", + "lint:css:fix": "concurrently \"<%= packageManager %>:lint:css -- --fix\"", + "lint:fix": "concurrently \"<%= packageManager %>:lint:*:fix\" --names \"fix:\"", + "lint:hbs": "ember-template-lint .", + "lint:hbs:fix": "ember-template-lint . --fix", + "lint:js": "eslint . --cache", + "lint:js:fix": "eslint . --fix<% if (typescript) { %>", + "lint:types": "tsc --noEmit<% } %>", + "start": "ember serve", + "test": "concurrently \"<%= packageManager %>:lint\" \"<%= packageManager %>:test:*\" --names \"lint,test:\"", + "test:ember": "ember test" + }, + "devDependencies": { + "@babel/core": "^7.25.2", + "<% if (!typescript) { %>@babel/eslint-parser": "^7.25.1", + "@babel/plugin-proposal-decorators": "^7.24.7", + "<% } %>@ember/optional-features": "^2.1.0", + "@ember/string": "^4.0.0", + "@ember/test-helpers": "^3.3.1<% if (embroider) { %>", + "@embroider/compat": "^3.6.0", + "@embroider/core": "^3.4.14", + "@embroider/webpack": "^4.0.4<% } %>", + "@glimmer/component": "^1.1.2", + "@glimmer/tracking": "^1.1.2<% if (typescript) { %>", + "@glint/environment-ember-loose": "^1.4.0", + "@glint/template": "^1.4.0", + "@tsconfig/ember": "^3.0.8", + "@types/ember": "^4.0.11", + "@types/ember-data": "^4.4.16", + "@types/ember-data__adapter": "^4.0.6", + "@types/ember-data__model": "^4.0.5", + "@types/ember-data__serializer": "^4.0.6", + "@types/ember-data__store": "^4.0.7", + "@types/ember__application": "^4.0.11", + "@types/ember__array": "^4.0.10", + "@types/ember__component": "^4.0.22", + "@types/ember__controller": "^4.0.12", + "@types/ember__debug": "^4.0.8", + "@types/ember__destroyable": "^4.0.5", + "@types/ember__engine": "^4.0.11", + "@types/ember__error": "^4.0.6", + "@types/ember__helper": "^4.0.8", + "@types/ember__modifier": "^4.0.9", + "@types/ember__object": "^4.0.12", + "@types/ember__owner": "^4.0.9", + "@types/ember__polyfills": "^4.0.6", + "@types/ember__routing": "^4.0.22", + "@types/ember__runloop": "^4.0.10", + "@types/ember__service": "^4.0.9", + "@types/ember__string": "^3.16.3", + "@types/ember__template": "^4.0.7", + "@types/ember__test": "^4.0.6", + "@types/ember__utils": "^4.0.7", + "@types/qunit": "^2.19.10", + "@types/rsvp": "^4.0.9", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0<% } %>", + "broccoli-asset-rev": "^3.0.0", + "concurrently": "^8.2.2", + "ember-auto-import": "^2.7.4", + "ember-cli": "~<%= emberCLIVersion %>", + "ember-cli-app-version": "^7.0.0", + "ember-cli-babel": "^8.2.0", + "ember-cli-clean-css": "^3.0.0", + "ember-cli-dependency-checker": "^3.3.2", + "ember-cli-htmlbars": "^6.3.0", + "ember-cli-inject-live-reload": "^2.1.0<% if (!embroider) { %>", + "ember-cli-sri": "^2.1.1", + "ember-cli-terser": "^4.0.2<% } %>", + "ember-data": "~5.4.0-beta.11", + "ember-fetch": "^8.1.2", + "ember-load-initializers": "^2.1.2", + "ember-modifier": "^4.2.0", + "ember-page-title": "^8.2.3", + "ember-qunit": "^8.1.0", + "ember-resolver": "^12.0.1", + "ember-source": "~5.12.0-beta.1", + "ember-template-lint": "^6.0.0<% if (welcome) { %>", + "ember-welcome-page": "^7.0.2<% } %>", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-ember": "^12.2.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-qunit": "^8.1.1", + "loader.js": "^4.7.0", + "prettier": "^3.3.3", + "qunit": "^2.22.0", + "qunit-dom": "^3.2.0", + "stylelint": "^15.11.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-prettier": "^4.1.0", + "tracked-built-ins": "^3.3.0<% if (typescript) { %>", + "typescript": "^5.5.4<% } %>", + "webpack": "^5.93.0" + }, + "engines": { + "node": ">= 18" + }, + "ember": { + "edition": "octane" + } +} diff --git a/files/public/robots.txt b/files/public/robots.txt new file mode 100644 index 0000000..f591645 --- /dev/null +++ b/files/public/robots.txt @@ -0,0 +1,3 @@ +# http://www.robotstxt.org +User-agent: * +Disallow: diff --git a/files-override/testem.js b/files/testem.js similarity index 100% rename from files-override/testem.js rename to files/testem.js diff --git a/files/tests/helpers/index.ts b/files/tests/helpers/index.ts new file mode 100644 index 0000000..e190f56 --- /dev/null +++ b/files/tests/helpers/index.ts @@ -0,0 +1,43 @@ +import { + setupApplicationTest as upstreamSetupApplicationTest, + setupRenderingTest as upstreamSetupRenderingTest, + setupTest as upstreamSetupTest, + type SetupTestOptions, +} from 'ember-qunit'; + +// This file exists to provide wrappers around ember-qunit's +// test setup functions. This way, you can easily extend the setup that is +// needed per test type. + +function setupApplicationTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupApplicationTest(hooks, options); + + // Additional setup for application tests can be done here. + // + // For example, if you need an authenticated session for each + // application test, you could do: + // + // hooks.beforeEach(async function () { + // await authenticateSession(); // ember-simple-auth + // }); + // + // This is also a good place to call test setup functions coming + // from other addons: + // + // setupIntl(hooks, 'en-us'); // ember-intl + // setupMirage(hooks); // ember-cli-mirage +} + +function setupRenderingTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupRenderingTest(hooks, options); + + // Additional setup for rendering tests can be done here. +} + +function setupTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupTest(hooks, options); + + // Additional setup for unit tests can be done here. +} + +export { setupApplicationTest, setupRenderingTest, setupTest }; diff --git a/files-override/tests/index.html b/files/tests/index.html similarity index 100% rename from files-override/tests/index.html rename to files/tests/index.html diff --git a/files/tests/integration/.gitkeep b/files/tests/integration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/files-override/tests/test-helper.js b/files/tests/test-helper.ts similarity index 100% rename from files-override/tests/test-helper.js rename to files/tests/test-helper.ts diff --git a/files/tests/unit/.gitkeep b/files/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/files/tsconfig.json b/files/tsconfig.json new file mode 100644 index 0000000..f53dc6e --- /dev/null +++ b/files/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@tsconfig/ember/tsconfig.json", + "compilerOptions": { + // The combination of `baseUrl` with `paths` allows Ember's classic package + // layout, which is not resolvable with the Node resolution algorithm, to + // work with TypeScript. + "baseUrl": ".", + "paths": { + "<%= name %>/tests/*": ["tests/*"], + "<%= name %>/*": ["app/*"], + "*": ["types/*"] + } + } +} diff --git a/files/types/ember-data/types/registries/model.d.ts b/files/types/ember-data/types/registries/model.d.ts new file mode 100644 index 0000000..bdd8c0f --- /dev/null +++ b/files/types/ember-data/types/registries/model.d.ts @@ -0,0 +1,7 @@ +/** + * Catch-all for ember-data. + */ +export default interface ModelRegistry { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any; +} diff --git a/files/types/global.d.ts b/files/types/global.d.ts new file mode 100644 index 0000000..2c531e2 --- /dev/null +++ b/files/types/global.d.ts @@ -0,0 +1 @@ +import '@glint/environment-ember-loose';