@tramvai/cli 4.35.0 → 4.36.2

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.
Files changed (38) hide show
  1. package/lib/builder/webpack/tokens.d.ts +3 -0
  2. package/lib/builder/webpack/tokens.d.ts.map +1 -1
  3. package/lib/di/tokens/config.d.ts +1 -0
  4. package/lib/di/tokens/config.d.ts.map +1 -1
  5. package/lib/library/babel/index.d.ts +1 -1
  6. package/lib/library/babel/index.d.ts.map +1 -1
  7. package/lib/library/babel/index.js +3 -1
  8. package/lib/library/babel/index.js.map +1 -1
  9. package/lib/library/babel/plugins/fill-declare-action-name.d.ts +6 -0
  10. package/lib/library/babel/plugins/fill-declare-action-name.d.ts.map +1 -0
  11. package/lib/library/babel/plugins/fill-declare-action-name.js +95 -0
  12. package/lib/library/babel/plugins/fill-declare-action-name.js.map +1 -0
  13. package/lib/library/babel/plugins/types.h.d.ts +2 -2
  14. package/lib/library/babel/plugins/types.h.d.ts.map +1 -1
  15. package/lib/library/webpack/utils/transpiler.d.ts +1 -0
  16. package/lib/library/webpack/utils/transpiler.d.ts.map +1 -1
  17. package/lib/library/webpack/utils/transpiler.js +3 -3
  18. package/lib/library/webpack/utils/transpiler.js.map +1 -1
  19. package/lib/schema/autogeneratedSchema.json +30 -15
  20. package/lib/typings/configEntry/cli.d.ts +5 -0
  21. package/lib/typings/configEntry/cli.d.ts.map +1 -1
  22. package/package.json +5 -5
  23. package/schema.json +30 -15
  24. package/src/library/babel/index.ts +3 -0
  25. package/src/library/babel/plugins/__fixtures__/fill-declare-action-name/import-mixed.ts +17 -0
  26. package/src/library/babel/plugins/__fixtures__/fill-declare-action-name/import-with-name.ts +28 -0
  27. package/src/library/babel/plugins/__fixtures__/fill-declare-action-name/import-without-name.ts +25 -0
  28. package/src/library/babel/plugins/__fixtures__/fill-declare-action-name/require-with-name.ts +21 -0
  29. package/src/library/babel/plugins/__fixtures__/fill-declare-action-name/require-without-name.ts +19 -0
  30. package/src/library/babel/plugins/__snapshots__/fill-declare-action-name.spec.ts.snap +266 -0
  31. package/src/library/babel/plugins/fill-declare-action-name.spec.ts +37 -0
  32. package/src/library/babel/plugins/fill-declare-action-name.ts +110 -0
  33. package/src/library/babel/plugins/types.h.ts +2 -2
  34. package/src/library/webpack/utils/transpiler.ts +9 -1
  35. package/src/models/config.spec.ts +4 -0
  36. package/src/schema/autogeneratedSchema.json +30 -15
  37. package/src/schema/tramvai.spec.ts +2 -0
  38. package/src/typings/configEntry/cli.ts +5 -0
@@ -0,0 +1,17 @@
1
+ import { declareAction } from '@tramvai/core';
2
+
3
+ const action = declareAction({
4
+ name: 'action',
5
+ fn: () => {
6
+ console.log('action');
7
+ },
8
+ });
9
+
10
+ const secondAction = declareAction({
11
+ fn: () => {
12
+ console.log('second action');
13
+ },
14
+ conditions: {
15
+ onlyBrowser: true,
16
+ },
17
+ });
@@ -0,0 +1,28 @@
1
+ import { declareAction } from '@tramvai/core';
2
+
3
+ const action = declareAction({
4
+ name: 'action',
5
+ fn: () => {
6
+ console.log('action');
7
+ },
8
+ });
9
+
10
+ const secondAction = declareAction({
11
+ name: 'secondAction',
12
+ fn: () => {
13
+ console.log('second action');
14
+ },
15
+ conditions: {
16
+ onlyBrowser: true,
17
+ },
18
+ });
19
+
20
+ export default declareAction({
21
+ name: 'anonymousAction',
22
+ fn: () => {
23
+ console.log('anonymous action');
24
+ },
25
+ conditions: {
26
+ onlyBrowser: true,
27
+ },
28
+ });
@@ -0,0 +1,25 @@
1
+ import { declareAction } from '@tramvai/core';
2
+
3
+ const action = declareAction({
4
+ fn: () => {
5
+ console.log('action');
6
+ },
7
+ });
8
+
9
+ const secondAction = declareAction({
10
+ fn: () => {
11
+ console.log('second action');
12
+ },
13
+ conditions: {
14
+ onlyBrowser: true,
15
+ },
16
+ });
17
+
18
+ export default declareAction({
19
+ fn: () => {
20
+ console.log('anonymous action');
21
+ },
22
+ conditions: {
23
+ onlyBrowser: true,
24
+ },
25
+ });
@@ -0,0 +1,21 @@
1
+ // @ts-ignore
2
+ const { declareAction } = require('@tramvai/core');
3
+
4
+ // @ts-ignore
5
+ const action = declareAction({
6
+ name: 'action',
7
+ fn: () => {
8
+ console.log('action');
9
+ },
10
+ });
11
+
12
+ // @ts-ignore
13
+ const secondAction = declareAction({
14
+ name: 'secondAction',
15
+ fn: () => {
16
+ console.log('second action');
17
+ },
18
+ conditions: {
19
+ onlyBrowser: true,
20
+ },
21
+ });
@@ -0,0 +1,19 @@
1
+ // @ts-ignore
2
+ const { declareAction } = require('@tramvai/core');
3
+
4
+ // @ts-ignore
5
+ const action = declareAction({
6
+ fn: () => {
7
+ console.log('action');
8
+ },
9
+ });
10
+
11
+ // @ts-ignore
12
+ const secondAction = declareAction({
13
+ fn: () => {
14
+ console.log('second action');
15
+ },
16
+ conditions: {
17
+ onlyBrowser: true,
18
+ },
19
+ });
@@ -0,0 +1,266 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`fill-declare-action-name import: do nothing: import: do nothing 1`] = `
4
+
5
+ import { declareAction } from '@tramvai/core';
6
+
7
+ const action = declareAction({
8
+ name: 'action',
9
+ fn: () => {
10
+ console.log('action');
11
+ },
12
+ });
13
+
14
+ const secondAction = declareAction({
15
+ name: 'secondAction',
16
+ fn: () => {
17
+ console.log('second action');
18
+ },
19
+ conditions: {
20
+ onlyBrowser: true,
21
+ },
22
+ });
23
+
24
+ export default declareAction({
25
+ name: 'anonymousAction',
26
+ fn: () => {
27
+ console.log('anonymous action');
28
+ },
29
+ conditions: {
30
+ onlyBrowser: true,
31
+ },
32
+ });
33
+
34
+ ↓ ↓ ↓ ↓ ↓ ↓
35
+
36
+ import { declareAction } from '@tramvai/core';
37
+ var action = declareAction({
38
+ name: 'action',
39
+ fn: function fn() {
40
+ console.log('action');
41
+ },
42
+ });
43
+ var secondAction = declareAction({
44
+ name: 'secondAction',
45
+ fn: function fn() {
46
+ console.log('second action');
47
+ },
48
+ conditions: {
49
+ onlyBrowser: true,
50
+ },
51
+ });
52
+ export default declareAction({
53
+ name: 'anonymousAction',
54
+ fn: function fn() {
55
+ console.log('anonymous action');
56
+ },
57
+ conditions: {
58
+ onlyBrowser: true,
59
+ },
60
+ });
61
+
62
+
63
+ `;
64
+
65
+ exports[`fill-declare-action-name import: fill absent name: import: fill absent name 1`] = `
66
+
67
+ import { declareAction } from '@tramvai/core';
68
+
69
+ const action = declareAction({
70
+ name: 'action',
71
+ fn: () => {
72
+ console.log('action');
73
+ },
74
+ });
75
+
76
+ const secondAction = declareAction({
77
+ fn: () => {
78
+ console.log('second action');
79
+ },
80
+ conditions: {
81
+ onlyBrowser: true,
82
+ },
83
+ });
84
+
85
+ ↓ ↓ ↓ ↓ ↓ ↓
86
+
87
+ import { declareAction } from '@tramvai/core';
88
+ var action = declareAction({
89
+ name: 'action',
90
+ fn: function fn() {
91
+ console.log('action');
92
+ },
93
+ });
94
+ var secondAction = declareAction({
95
+ name: 'secondAction__-5f0ssw',
96
+ fn: function fn() {
97
+ console.log('second action');
98
+ },
99
+ conditions: {
100
+ onlyBrowser: true,
101
+ },
102
+ });
103
+
104
+
105
+ `;
106
+
107
+ exports[`fill-declare-action-name import: fill all actions: import: fill all actions 1`] = `
108
+
109
+ import { declareAction } from '@tramvai/core';
110
+
111
+ const action = declareAction({
112
+ fn: () => {
113
+ console.log('action');
114
+ },
115
+ });
116
+
117
+ const secondAction = declareAction({
118
+ fn: () => {
119
+ console.log('second action');
120
+ },
121
+ conditions: {
122
+ onlyBrowser: true,
123
+ },
124
+ });
125
+
126
+ export default declareAction({
127
+ fn: () => {
128
+ console.log('anonymous action');
129
+ },
130
+ conditions: {
131
+ onlyBrowser: true,
132
+ },
133
+ });
134
+
135
+ ↓ ↓ ↓ ↓ ↓ ↓
136
+
137
+ import { declareAction } from '@tramvai/core';
138
+ var action = declareAction({
139
+ name: 'action__n5c5ae',
140
+ fn: function fn() {
141
+ console.log('action');
142
+ },
143
+ });
144
+ var secondAction = declareAction({
145
+ name: 'secondAction__n5fz8b',
146
+ fn: function fn() {
147
+ console.log('second action');
148
+ },
149
+ conditions: {
150
+ onlyBrowser: true,
151
+ },
152
+ });
153
+ export default declareAction({
154
+ name: 'import-without-name.ts__797bng',
155
+ fn: function fn() {
156
+ console.log('anonymous action');
157
+ },
158
+ conditions: {
159
+ onlyBrowser: true,
160
+ },
161
+ });
162
+
163
+
164
+ `;
165
+
166
+ exports[`fill-declare-action-name require: do nothing: require: do nothing 1`] = `
167
+
168
+ // @ts-ignore
169
+ const { declareAction } = require('@tramvai/core');
170
+
171
+ // @ts-ignore
172
+ const action = declareAction({
173
+ name: 'action',
174
+ fn: () => {
175
+ console.log('action');
176
+ },
177
+ });
178
+
179
+ // @ts-ignore
180
+ const secondAction = declareAction({
181
+ name: 'secondAction',
182
+ fn: () => {
183
+ console.log('second action');
184
+ },
185
+ conditions: {
186
+ onlyBrowser: true,
187
+ },
188
+ });
189
+
190
+ ↓ ↓ ↓ ↓ ↓ ↓
191
+
192
+ // @ts-ignore
193
+ var _require = require('@tramvai/core'),
194
+ declareAction = _require.declareAction;
195
+
196
+ // @ts-ignore
197
+ var action = declareAction({
198
+ name: 'action',
199
+ fn: function fn() {
200
+ console.log('action');
201
+ },
202
+ });
203
+
204
+ // @ts-ignore
205
+ var secondAction = declareAction({
206
+ name: 'secondAction',
207
+ fn: function fn() {
208
+ console.log('second action');
209
+ },
210
+ conditions: {
211
+ onlyBrowser: true,
212
+ },
213
+ });
214
+
215
+
216
+ `;
217
+
218
+ exports[`fill-declare-action-name require: fill all actions: require: fill all actions 1`] = `
219
+
220
+ // @ts-ignore
221
+ const { declareAction } = require('@tramvai/core');
222
+
223
+ // @ts-ignore
224
+ const action = declareAction({
225
+ fn: () => {
226
+ console.log('action');
227
+ },
228
+ });
229
+
230
+ // @ts-ignore
231
+ const secondAction = declareAction({
232
+ fn: () => {
233
+ console.log('second action');
234
+ },
235
+ conditions: {
236
+ onlyBrowser: true,
237
+ },
238
+ });
239
+
240
+ ↓ ↓ ↓ ↓ ↓ ↓
241
+
242
+ // @ts-ignore
243
+ var _require = require('@tramvai/core'),
244
+ declareAction = _require.declareAction;
245
+
246
+ // @ts-ignore
247
+ var action = declareAction({
248
+ name: 'action__l6frq0',
249
+ fn: function fn() {
250
+ console.log('action');
251
+ },
252
+ });
253
+
254
+ // @ts-ignore
255
+ var secondAction = declareAction({
256
+ name: 'secondAction__h789zd',
257
+ fn: function fn() {
258
+ console.log('second action');
259
+ },
260
+ conditions: {
261
+ onlyBrowser: true,
262
+ },
263
+ });
264
+
265
+
266
+ `;
@@ -0,0 +1,37 @@
1
+ import path from 'path';
2
+ import pluginTester from 'babel-plugin-tester';
3
+ import babelConfig from '../index';
4
+
5
+ pluginTester({
6
+ plugin: {}, // плагин уже есть в основном конфиге, если подключить ещё тут то babel упадёт
7
+ pluginName: 'fill-declare-action-name',
8
+ filename: path.join(__dirname, '__fixtures__', 'fill-declare-action-name', 'test'),
9
+ babelOptions: babelConfig({
10
+ typescript: true,
11
+ generateDataQaTag: false,
12
+ loader: false,
13
+ enableFillDeclareActionNamePlugin: true,
14
+ }),
15
+ tests: {
16
+ 'import: fill absent name': {
17
+ fixture: 'import-mixed.ts',
18
+ snapshot: true,
19
+ },
20
+ 'import: do nothing': {
21
+ fixture: 'import-with-name.ts',
22
+ snapshot: true,
23
+ },
24
+ 'import: fill all actions': {
25
+ fixture: 'import-without-name.ts',
26
+ snapshot: true,
27
+ },
28
+ 'require: do nothing': {
29
+ fixture: 'require-with-name.ts',
30
+ snapshot: true,
31
+ },
32
+ 'require: fill all actions': {
33
+ fixture: 'require-without-name.ts',
34
+ snapshot: true,
35
+ },
36
+ },
37
+ });
@@ -0,0 +1,110 @@
1
+ import type { Plugin } from './types.h';
2
+
3
+ function hashCode(s: string) {
4
+ let h = 0;
5
+ let i = 0;
6
+ // eslint-disable-next-line no-bitwise
7
+ if (s.length > 0) while (i < s.length) h = ((h << 5) - h + s.charCodeAt(i++)) | 0;
8
+ return h.toString(36);
9
+ }
10
+
11
+ export const fillDeclareActionName: Plugin<{ declareActionName: string | null }> = (babel) => {
12
+ const { types: t } = babel;
13
+
14
+ return {
15
+ pre() {
16
+ this.declareActionName = null;
17
+ },
18
+ visitor: {
19
+ Program: {
20
+ enter(enterPath) {
21
+ enterPath.traverse({
22
+ ImportDeclaration: (path) => {
23
+ if (this.declareActionName) return; // нет смысла идти дальше
24
+ if (path.node.source.value !== '@tramvai/core') return;
25
+
26
+ const specifier = path.node.specifiers.find(
27
+ (s) =>
28
+ t.isImportSpecifier(s) &&
29
+ 'name' in s.imported &&
30
+ s.imported.name === 'declareAction'
31
+ );
32
+
33
+ if (specifier) {
34
+ this.declareActionName = specifier.local.name;
35
+ }
36
+ },
37
+ // тут смотрим на const {declareAction} = require('@tramvai/core')
38
+ VariableDeclarator: (path) => {
39
+ if (this.declareActionName) return; // нет смысла идти дальше
40
+
41
+ if (
42
+ !t.isCallExpression(path.node.init) ||
43
+ !t.isIdentifier(path.node.init.callee) ||
44
+ path.node.init.callee.name !== 'require'
45
+ ) {
46
+ return;
47
+ }
48
+
49
+ const [argument] = path.node.init.arguments;
50
+
51
+ if (!argument || ('value' in argument && argument.value !== '@tramvai/core')) return;
52
+ if (!t.isObjectPattern(path.node.id)) return;
53
+
54
+ const declareActionNameProperty = path.node.id.properties.find(
55
+ (p) => 'key' in p && 'name' in p.key && p.key.name === 'declareAction'
56
+ );
57
+
58
+ if (
59
+ declareActionNameProperty &&
60
+ 'value' in declareActionNameProperty &&
61
+ 'name' in declareActionNameProperty.value
62
+ ) {
63
+ this.declareActionName = declareActionNameProperty.value.name;
64
+ }
65
+ },
66
+ });
67
+ },
68
+ },
69
+ CallExpression(path) {
70
+ if (!this.declareActionName) return;
71
+ if ('name' in path.node.callee && path.node.callee.name !== this.declareActionName) return;
72
+
73
+ const args = path.node.arguments;
74
+
75
+ if (args.length !== 1) return;
76
+ if (!t.isObjectExpression(args[0])) return;
77
+
78
+ const nameProperty = args[0].properties.find(
79
+ (p) => 'key' in p && 'name' in p.key && p.key.name === 'name'
80
+ );
81
+
82
+ if (nameProperty) return;
83
+
84
+ let additionalDebugName: string;
85
+
86
+ // @ts-expect-error easier to write this rather than adding if statements and type assertions
87
+ const potentialVariableName = path.parentPath.node.id?.name as string | undefined;
88
+
89
+ if (!potentialVariableName) {
90
+ additionalDebugName = this.file.opts.generatorOpts.sourceFileName ?? '';
91
+ } else {
92
+ additionalDebugName = potentialVariableName;
93
+ }
94
+
95
+ const filePath = this.file.opts.filename;
96
+ const cwd = this.file.opts.cwd ?? '';
97
+ const projectFilePath = filePath.replace(cwd, '');
98
+ const { line, column } = path.node.loc.start;
99
+
100
+ const sid = hashCode(`${projectFilePath}:${line}:${column}`);
101
+
102
+ const name = `${additionalDebugName}__${sid}`;
103
+
104
+ args[0].properties.unshift(t.objectProperty(t.identifier('name'), t.stringLiteral(name)));
105
+ },
106
+ },
107
+ };
108
+ };
109
+
110
+ export default fillDeclareActionName;
@@ -1,8 +1,8 @@
1
- import type { PluginObj, template, types } from '@babel/core';
1
+ import type { PluginObj, PluginPass, template, types } from '@babel/core';
2
2
 
3
3
  export interface Babel {
4
4
  types: typeof types;
5
5
  template: typeof template;
6
6
  }
7
7
 
8
- export type Plugin<PluginOptions = void> = (babel: Babel) => PluginObj<PluginOptions>;
8
+ export type Plugin<PluginOptions = void> = (babel: Babel) => PluginObj<PluginPass & PluginOptions>;
@@ -14,6 +14,7 @@ export type TranspilerConfig = {
14
14
  isServer: boolean;
15
15
  generateDataQaTag: boolean;
16
16
  enableFillActionNamePlugin: boolean;
17
+ enableFillDeclareActionNamePlugin: boolean;
17
18
  typescript: boolean;
18
19
  modules: 'es6' | 'commonjs' | false;
19
20
  loader: boolean;
@@ -50,7 +51,13 @@ export const getTranspilerConfig = (
50
51
  configManager: ConfigManager<CliConfigEntry>,
51
52
  overrideOptions: Partial<TranspilerConfig> = {}
52
53
  ): TranspilerConfig => {
53
- const { generateDataQaTag, alias, enableFillActionNamePlugin, excludesPresetEnv } = configManager;
54
+ const {
55
+ generateDataQaTag,
56
+ alias,
57
+ enableFillActionNamePlugin,
58
+ excludesPresetEnv,
59
+ experiments: { enableFillDeclareActionNamePlugin },
60
+ } = configManager;
54
61
  const { env, modern } = configManager;
55
62
 
56
63
  if (alias) {
@@ -74,5 +81,6 @@ Just check or add configuration to your tsconfig file and remove alias from tram
74
81
  modules: false,
75
82
  typescript: false,
76
83
  ...overrideOptions,
84
+ enableFillDeclareActionNamePlugin,
77
85
  };
78
86
  };
@@ -39,6 +39,7 @@ it('should populate defaults for config', () => {
39
39
  "enableFillActionNamePlugin": false,
40
40
  "experiments": {
41
41
  "autoResolveSharedRequiredVersions": false,
42
+ "enableFillDeclareActionNamePlugin": false,
42
43
  "minicss": {
43
44
  "useImportModule": true,
44
45
  },
@@ -140,6 +141,7 @@ it('should populate defaults for config', () => {
140
141
  "enableFillActionNamePlugin": false,
141
142
  "experiments": {
142
143
  "autoResolveSharedRequiredVersions": false,
144
+ "enableFillDeclareActionNamePlugin": false,
143
145
  "minicss": {
144
146
  "useImportModule": true,
145
147
  },
@@ -280,6 +282,7 @@ it('should populate defaults for overridable options', () => {
280
282
  "enableFillActionNamePlugin": false,
281
283
  "experiments": {
282
284
  "autoResolveSharedRequiredVersions": false,
285
+ "enableFillDeclareActionNamePlugin": false,
283
286
  "minicss": {
284
287
  "useImportModule": true,
285
288
  },
@@ -399,6 +402,7 @@ it('should populate defaults for overridable options', () => {
399
402
  "enableFillActionNamePlugin": false,
400
403
  "experiments": {
401
404
  "autoResolveSharedRequiredVersions": false,
405
+ "enableFillDeclareActionNamePlugin": false,
402
406
  "minicss": {
403
407
  "useImportModule": true,
404
408
  },