Skip to content

Commit ade0a34

Browse files
committed
Improve shape of decorators config
1 parent 054a94e commit ade0a34

21 files changed

Lines changed: 166 additions & 58 deletions

README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@ following command:
2323
npx ember-native-class-codemod http://localhost:4200/path/to/server [OPTIONS] path/of/files/ or/some**/*glob.js
2424
```
2525

26-
The codemod accepts the following options:
27-
28-
| Option | Value | Default | Details |
29-
| --------------------------- | ------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30-
| `--class-fields` | boolean | `true` | Enable/disable transformation using class fields |
31-
| `--decorators` | boolean | `true` | Enable/disable transformation using decorators |
32-
| `--classic-decorator` | boolean | `true` | Enable/disable adding the [`@classic` decorator](https://github.com/pzuraq/ember-classic-decorator), which helps with transitioning Ember Octane |
33-
| `--type` | String | Empty (match all types in path) | Apply transformation to only passed type. The type can be one of `services`, `routes`, `components`, `controllers` |
34-
| `--quote` | String | `'single'` | Whether to use double or single quotes by default for new statements that are added during the codemod. |
35-
| `--objectLiteralDecorators` | String | String[] | undefined | Allow-list for decorators currently applied to object literal properties that can be safely applied to class properties. Pass as a comma-separated string if using as a CLI-option. Otherwise pass as an array of strings. |
26+
### Options
27+
28+
The codemod accepts the following options, passed as CLI arguments, set in a `.codemods.{json,js,cjs,yml}` file, or set in a `"codemods"` object in `package.json`.
29+
30+
| Option | Type | Default | Details |
31+
| ----------------------------------------------- | ----------------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32+
| `--class-fields` / `classFields` | `boolean` | `true` | Enable/disable transformation using class fields |
33+
| `--decorators` / `decorators` | `boolean \| DecoratorsConfig` | `true` | Set to `false` to disable transformation using decorators. Set to `DecoratorsConfig` object (see below) to pass additional decorator options. |
34+
| `--classic-decorator` / `classicDecorator` | `boolean` | `true` | Enable/disable adding the [`@classic` decorator](https://github.com/pzuraq/ember-classic-decorator), which helps with transitioning Ember Octane |
35+
| `--type` / `type` | `'services' \| 'routes' \| 'components' \| 'controllers' \| undefined`' | `undefined` | Apply transformation to only passed type. If `undefined, will match all types in path. |
36+
| `--quote` / `quote` | `'single' \| 'double'` | `'single'` | Whether to use double or single quotes by default for new statements that are added during the codemod. |
37+
| `--ignore-leaking-state` / `ignoreLeakingState` | `string[]` | `['queryParams']` | Allow-list for `ObjectExpression` or `ArrayExpression` properties to ignore issues detailed in [eslint-plugin-ember/avoid-leaking-state-in-ember-objects](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/avoid-leaking-state-in-ember-objects.md). In the classic class syntax, using arrays and objects as default properties causes their state to "leak" between instances. If you have custom properties where you know that the shared state won't be a problem (for example, read-only configuration values), you can use this config to ignore them. NOTE: Passing this option will override the defaults, so ensure you include `'queryParams'` in the list unless you explicitly wish to disallow it. |
38+
| `DecoratorsConfig` | An object with the following properties. | See below. | Allow-list for decorators currently applied to object literal properties that can be safely applied to class properties. Pass as a comma-separated string if using as a CLI-option. Otherwise pass as an array of strings. |
39+
| `DecoratorsConfig.inObjectLiterals` | `string \| string[]` | `[]` | Allow-list for decorators currently applied to object literal properties that can be safely applied to class properties. Pass as a comma-separated string if using as a CLI-option. Otherwise pass as an array of strings. NOTE: Decorators on object methods will be allowed by default. |
3640

3741
### Gathering Runtime Data
3842

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"camelcase": "^6.3.0",
5151
"codemod-cli": "^3.2.0",
5252
"cosmiconfig": "^8.0.0",
53+
"deepmerge-ts": "^4.3.0",
5354
"ember-codemods-telemetry-helpers": "^3.0.0",
5455
"fs-extra": "^8.0.1",
5556
"git-repo-info": "^2.1.0",

test/config/config.test.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,59 @@
11
import { describe, expect, test } from '@jest/globals';
22
import path from 'path';
3-
import getConfig from '../../transforms/helpers/config';
3+
import getConfig, { mergeConfig } from '../../transforms/helpers/config';
44
import { DEFAULT_OPTIONS } from '../../transforms/helpers/options';
55

66
describe('config', () => {
7-
test('it has default options', () => {
8-
const config = getConfig();
9-
expect(config).toStrictEqual(DEFAULT_OPTIONS);
7+
describe('getConfig', () => {
8+
test('it has default options', () => {
9+
const config = getConfig();
10+
expect(config).toStrictEqual(DEFAULT_OPTIONS);
11+
});
12+
13+
test.each(['json', 'js', 'cjs', 'yml', 'yaml', 'package'])(
14+
'should read %s config',
15+
(fixture) => {
16+
const config = getConfig(pathFor(fixture));
17+
expect(config).toStrictEqual(
18+
mergeConfig(DEFAULT_OPTIONS, {
19+
classFields: false,
20+
quote: 'double',
21+
decorators: {
22+
inObjectLiterals: [`${fixture}DecOne`, `${fixture}DecTwo`],
23+
},
24+
})
25+
);
26+
}
27+
);
1028
});
1129

12-
test.each(['json', 'js', 'cjs', 'yml', 'yaml', 'package'])(
13-
'should read %s config',
14-
(fixture) => {
15-
const config = getConfig(pathFor(fixture));
16-
expect(config).toStrictEqual({
30+
describe('mergeConfig', () => {
31+
test('it allows overwriting the ignoreLeakingState config', () => {
32+
expect(
33+
mergeConfig(DEFAULT_OPTIONS, {
34+
ignoreLeakingState: ['queryParams', 'ignoreMyLeakyState'],
35+
})
36+
).toStrictEqual({
1737
...DEFAULT_OPTIONS,
18-
classFields: false,
19-
quote: 'double',
20-
objectLiteralDecorators: [`${fixture}DecOne`, `${fixture}DecTwo`],
38+
ignoreLeakingState: ['queryParams', 'ignoreMyLeakyState'],
2139
});
22-
}
23-
);
40+
});
41+
42+
test('it deep merges the decorators config', () => {
43+
expect(
44+
mergeConfig(DEFAULT_OPTIONS, {
45+
decorators: {
46+
inObjectLiterals: ['computer'],
47+
},
48+
})
49+
).toStrictEqual({
50+
...DEFAULT_OPTIONS,
51+
decorators: {
52+
inObjectLiterals: ['computer'],
53+
},
54+
});
55+
});
56+
});
2457
});
2558

2659
function pathFor(extension: string): string {
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module.exports = {
22
classFields: false,
33
quote: 'double',
4-
objectLiteralDecorators: ['cjsDecOne', 'cjsDecTwo']
4+
decorators: {
5+
inObjectLiterals: ['cjsDecOne', 'cjsDecTwo']
6+
}
57
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module.exports = {
22
classFields: false,
33
quote: 'double',
4-
objectLiteralDecorators: ['jsDecOne', 'jsDecTwo']
4+
decorators: {
5+
inObjectLiterals: ['jsDecOne', 'jsDecTwo']
6+
}
57
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"classFields": false,
33
"quote": "double",
4-
"objectLiteralDecorators": ["jsonDecOne", "jsonDecTwo"]
4+
"decorators": {
5+
"inObjectLiterals": ["jsonDecOne", "jsonDecTwo"]
6+
}
57
}

test/config/fixtures/package/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
"codemods": {
33
"classFields": false,
44
"quote": "double",
5-
"objectLiteralDecorators": ["packageDecOne", "packageDecTwo"]
5+
"decorators": {
6+
"inObjectLiterals": ["packageDecOne", "packageDecTwo"]
7+
}
68
}
79
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
classFields: false
22
quote: 'double'
3-
objectLiteralDecorators:
4-
- yamlDecOne
5-
- yamlDecTwo
3+
decorators:
4+
inObjectLiterals:
5+
- yamlDecOne
6+
- yamlDecTwo
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
classFields: false
22
quote: 'double'
3-
objectLiteralDecorators:
4-
- ymlDecOne
5-
- ymlDecTwo
3+
decorators:
4+
inObjectLiterals:
5+
- ymlDecOne
6+
- ymlDecTwo
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import EmberObject from '@ember/object';
2+
3+
const Foo = EmberObject.extend({
4+
queryParams: {},
5+
ignoreMyLeakyState: {}
6+
});

0 commit comments

Comments
 (0)