-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
Copy pathindex.ts
176 lines (157 loc) · 6.22 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import type { DeprecationOptions } from '@ember/debug/lib/deprecate';
import { ENV } from '@ember/-internals/environment';
import { VERSION } from '@ember/version';
import { deprecate, assert } from '@ember/debug';
import { dasherize } from '../string/index';
function isEnabled(options: DeprecationOptions) {
return Object.hasOwnProperty.call(options.since, 'enabled') || ENV._ALL_DEPRECATIONS_ENABLED;
}
let numEmberVersion = parseFloat(ENV._OVERRIDE_DEPRECATION_VERSION ?? VERSION);
/* until must only be a minor version or major version */
export function emberVersionGte(until: string, emberVersion = numEmberVersion) {
let significantUntil = until.replace(/(\.0+)/g, '');
return emberVersion >= parseFloat(significantUntil);
}
export function isRemoved(options: DeprecationOptions) {
return emberVersionGte(options.until);
}
interface DeprecationObject {
options: DeprecationOptions;
test: boolean;
isEnabled: boolean;
isRemoved: boolean;
}
function deprecation(options: DeprecationOptions) {
return {
options,
test: !isEnabled(options),
isEnabled: isEnabled(options) || isRemoved(options),
isRemoved: isRemoved(options),
};
}
/*
To add a deprecation, you must add a new entry to the `DEPRECATIONS` object.
The entry should be an object with the following properties:
* `id` (required): A string that uniquely identifies the deprecation. This
should be a short, descriptive name, typically dasherized.
* `for` (required): The string `ember-source` -- every deprecation from this
package is for `ember-source`.
* `since` (required): An object with `available` and `enabled`. `available` is
the first version of Ember that the deprecation is available in. `enabled` is
the version of Ember that the deprecation was first enabled. This is used as
a feature flag deprecations. For public APIs, the `enabled` value is added
only once the deprecation RFC is [Ready for Release](https://github.com/emberjs/rfcs#ready-for-release).
* `until` (required): The version of Ember that the deprecation will be removed
* `url` (required): A URL to the deprecation guide for the deprecation. This
URL can be constructed in advance of the deprecation being added to the
[deprecation app](https://github.com/ember-learn/deprecation-app) by
following this format: `https://deprecations.emberjs.com/deprecations/{{id}}`.
For example:
`deprecate` should then be called using the entry from the `DEPRECATIONS` object.
```ts
import { DEPRECATIONS } from '@ember/-internals/deprecations';
//...
deprecateUntil(message, DEPRECATIONS.MY_DEPRECATION);
```
`expectDeprecation` should also use the DEPRECATIONS object, but it should be noted
that it uses `isEnabled` instead of `test` because the expectations of `expectDeprecation`
are the opposite of `test`.
```ts
expectDeprecation(
() => {
assert.equal(foo, bar(), 'foo is equal to bar'); // something that triggers the deprecation
},
/matchesMessage/,
DEPRECATIONS.MY_DEPRECATION.isEnabled
);
```
Tests can be conditionally run based on whether a deprecation is enabled or not:
```ts
[`${testUnless(DEPRECATIONS.MY_DEPRECATION.isRemoved)} specific deprecated feature tested only in this test`]
```
This test will be skipped when the MY_DEPRECATION is removed.
When adding a deprecation, we need to guard all the code that will eventually be removed, including tests.
For tests that are not specifically testing the deprecated feature, we need to figure out how to
test the behavior without encountering the deprecated feature, just as users would.
*/
export const DEPRECATIONS = {
DEPRECATE_IMPORT_EMBER(importName: string) {
return deprecation({
id: `deprecate-import-${dasherize(importName).toLowerCase()}-from-ember`,
for: 'ember-source',
since: { available: '5.10.0' },
until: '7.0.0',
url: `https://deprecations.emberjs.com/id/import-${dasherize(
importName
).toLowerCase()}-from-ember`,
});
},
DEPRECATE_IMPLICIT_ROUTE_MODEL: deprecation({
id: 'deprecate-implicit-route-model',
for: 'ember-source',
since: { available: '5.3.0', enabled: '5.3.0' },
until: '6.0.0',
url: 'https://deprecations.emberjs.com/v5.x/#toc_deprecate-implicit-route-model',
}),
DEPRECATE_TEMPLATE_ACTION: deprecation({
id: 'template-action',
url: 'https://deprecations.emberjs.com/id/template-action',
until: '6.0.0',
for: 'ember-source',
since: {
available: '5.9.0',
enabled: '5.9.0',
},
}),
DEPRECATE_COMPONENT_TEMPLATE_RESOLVING: deprecation({
id: 'component-template-resolving',
url: 'https://deprecations.emberjs.com/id/component-template-resolving',
until: '6.0.0',
for: 'ember-source',
since: {
available: '5.10.0',
enabled: '5.10.0',
},
}),
DEPRECATE_ARRAY_PROTOTYPE_EXTENSIONS: deprecation({
id: 'deprecate-array-prototype-extensions',
url: 'https://deprecations.emberjs.com/id/deprecate-array-prototype-extensions',
until: '6.0.0',
for: 'ember-source',
since: {
available: '5.10.0',
enabled: '5.10.0',
},
}),
DEPRECATE_IMPORT_INJECT: deprecation({
for: 'ember-source',
id: 'importing-inject-from-ember-service',
since: {
available: '6.2.0',
},
until: '7.0.0',
url: 'https://deprecations.emberjs.com/id/importing-inject-from-ember-service',
}),
};
export function deprecateUntil(message: string, deprecation: DeprecationObject) {
const { options } = deprecation;
assert(
'deprecateUntil must only be called for ember-source',
Boolean(options.for === 'ember-source')
);
if (deprecation.isRemoved) {
throw new Error(
`The API deprecated by ${options.id} was removed in ember-source ${options.until}. The message was: ${message}. Please see ${options.url} for more details.`
);
}
deprecate(message, deprecation.test, options);
}
const { EXTEND_PROTOTYPES } = ENV as {
EXTEND_PROTOTYPES: { Array?: boolean };
};
if (EXTEND_PROTOTYPES.Array !== false) {
deprecateUntil(
'Array prototype extensions are deprecated. Follow the deprecation guide for migration instructions, and set EmberENV.EXTEND_PROTOTYPES to false in your config/environment.js',
DEPRECATIONS.DEPRECATE_ARRAY_PROTOTYPE_EXTENSIONS
);
}