@tolgee/cli 2.0.3 → 2.1.0

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 (91) hide show
  1. package/dist/cli.js +15 -23
  2. package/dist/commands/extract/check.js +2 -6
  3. package/dist/commands/extract/print.js +2 -6
  4. package/dist/commands/pull.js +2 -4
  5. package/dist/commands/sync/compare.js +2 -6
  6. package/dist/commands/sync/sync.js +1 -5
  7. package/dist/commands/tag.js +1 -5
  8. package/dist/config/tolgeerc.js +4 -6
  9. package/dist/extractor/extractor.js +40 -66
  10. package/dist/extractor/parser/extractComment.js +78 -0
  11. package/dist/extractor/parser/generalMapper.js +82 -0
  12. package/dist/extractor/parser/generateReport.js +161 -0
  13. package/dist/extractor/parser/iterator.js +37 -0
  14. package/dist/extractor/parser/mergerMachine.js +66 -0
  15. package/dist/extractor/parser/nodeUtils.js +21 -0
  16. package/dist/extractor/parser/parser.js +129 -0
  17. package/dist/extractor/parser/rules/tComponentGeneral.js +45 -0
  18. package/dist/extractor/parser/rules/tFunctionGeneral.js +41 -0
  19. package/dist/extractor/parser/rules/tNsSourceGeneral.js +36 -0
  20. package/dist/extractor/parser/tokenMergers/closingTagMerger.js +27 -0
  21. package/dist/extractor/parser/tokenMergers/commentsMerger.js +36 -0
  22. package/dist/extractor/parser/tokenMergers/stringMerger.js +50 -0
  23. package/dist/extractor/parser/tokenMergers/templateStringMerger.js +55 -0
  24. package/dist/extractor/parser/tokenMergers/typesAsMergerer.js +40 -0
  25. package/dist/extractor/parser/tokenMergers/typesCastMerger.js +28 -0
  26. package/dist/extractor/parser/tree/getTranslateProps.js +54 -0
  27. package/dist/extractor/parser/tree/getValue.js +17 -0
  28. package/dist/extractor/parser/tree/parseGeneral.js +51 -0
  29. package/dist/extractor/parser/tree/parseList.js +33 -0
  30. package/dist/extractor/parser/tree/parseObject.js +130 -0
  31. package/dist/extractor/parser/tree/parseProps.js +56 -0
  32. package/dist/extractor/parser/tree/parseTag.js +26 -0
  33. package/dist/extractor/parser/types.js +1 -0
  34. package/dist/extractor/parserReact/ParserReact.js +30 -0
  35. package/dist/extractor/parserReact/jsxMapper.js +24 -0
  36. package/dist/extractor/parserReact/rules/createElement.js +62 -0
  37. package/dist/extractor/parserReact/rules/tComponent.js +9 -0
  38. package/dist/extractor/parserReact/rules/tFunction.js +7 -0
  39. package/dist/extractor/parserReact/rules/useTranslate.js +7 -0
  40. package/dist/extractor/parserReact/tokenMergers/createElementMerger.js +35 -0
  41. package/dist/extractor/parserReact/tokenMergers/tComponentMerger.js +20 -0
  42. package/dist/extractor/parserReact/tokenMergers/tFunctionMerger.js +23 -0
  43. package/dist/extractor/parserReact/tokenMergers/useTranslateMerger.js +20 -0
  44. package/dist/extractor/parserSvelte/ParserSvelte.js +32 -0
  45. package/dist/extractor/parserSvelte/contextConstants.js +1 -0
  46. package/dist/extractor/parserSvelte/rules/scriptTag.js +26 -0
  47. package/dist/extractor/parserSvelte/rules/tComponent.js +9 -0
  48. package/dist/extractor/parserSvelte/rules/tFunction.js +7 -0
  49. package/dist/extractor/parserSvelte/rules/useTranslate.js +7 -0
  50. package/dist/extractor/parserSvelte/svelteMapper.js +39 -0
  51. package/dist/extractor/parserSvelte/svelteTreeTransform.js +38 -0
  52. package/dist/extractor/parserSvelte/tokenMergers/getTranslateMerger.js +20 -0
  53. package/dist/extractor/parserSvelte/tokenMergers/scriptTagMerger.js +20 -0
  54. package/dist/extractor/parserSvelte/tokenMergers/tComponentMerger.js +20 -0
  55. package/dist/extractor/parserSvelte/tokenMergers/tFunctionMerger.js +29 -0
  56. package/dist/extractor/parserVue/ParserVue.js +45 -0
  57. package/dist/extractor/parserVue/contextConstants.js +3 -0
  58. package/dist/extractor/parserVue/rules/exportDefaultObject.js +14 -0
  59. package/dist/extractor/parserVue/rules/globalTFunction.js +7 -0
  60. package/dist/extractor/parserVue/rules/scriptTag.js +31 -0
  61. package/dist/extractor/parserVue/rules/tComponent.js +9 -0
  62. package/dist/extractor/parserVue/rules/tFunction.js +7 -0
  63. package/dist/extractor/parserVue/rules/useTranslate.js +7 -0
  64. package/dist/extractor/parserVue/tokenMergers/exportDefaultObjectMerger.js +25 -0
  65. package/dist/extractor/parserVue/tokenMergers/globalTFunctionMerger.js +36 -0
  66. package/dist/extractor/parserVue/tokenMergers/scriptTagMerger.js +20 -0
  67. package/dist/extractor/parserVue/tokenMergers/tComponentMerger.js +20 -0
  68. package/dist/extractor/parserVue/tokenMergers/tFunctionMerger.js +37 -0
  69. package/dist/extractor/parserVue/tokenMergers/useTranslateMerger.js +20 -0
  70. package/dist/extractor/parserVue/vueMapper.js +51 -0
  71. package/dist/extractor/parserVue/vueTreeTransform.js +109 -0
  72. package/dist/extractor/runner.js +52 -4
  73. package/dist/extractor/visualizers/printTokens.js +7 -0
  74. package/dist/extractor/visualizers/tokensToString.js +28 -0
  75. package/dist/extractor/visualizers/visualizeRules.js +40 -0
  76. package/dist/extractor/warnings.js +4 -0
  77. package/dist/extractor/worker.js +10 -7
  78. package/dist/options.js +5 -0
  79. package/extractor.d.ts +8 -1
  80. package/package.json +2 -4
  81. package/schema.json +18 -6
  82. package/dist/client/internal/requester.js +0 -130
  83. package/dist/extractor/machines/comments.js +0 -78
  84. package/dist/extractor/machines/react.js +0 -705
  85. package/dist/extractor/machines/shared/comments.js +0 -79
  86. package/dist/extractor/machines/shared/properties.js +0 -380
  87. package/dist/extractor/machines/shared/translateCall.js +0 -141
  88. package/dist/extractor/machines/svelte.js +0 -429
  89. package/dist/extractor/machines/vue/decoder.js +0 -194
  90. package/dist/extractor/machines/vue/extract.js +0 -491
  91. package/dist/extractor/processors/vueSfc.js +0 -55
@@ -0,0 +1,39 @@
1
+ export const svelteMapper = (token) => {
2
+ switch (token.type) {
3
+ // strings
4
+ case 'punctuation.definition.string.begin.svelte':
5
+ return 'string.begin';
6
+ case 'punctuation.definition.string.end.svelte':
7
+ return 'string.end';
8
+ case 'string.quoted.svelte':
9
+ return 'string.body';
10
+ case 'string.unquoted.svelte':
11
+ return 'string';
12
+ // svelte template expression
13
+ case 'punctuation.section.embedded.begin.svelte':
14
+ return 'expression.template.begin';
15
+ case 'punctuation.section.embedded.end.svelte':
16
+ return 'expression.template.end';
17
+ //
18
+ case 'punctuation.definition.variable.svelte':
19
+ return 'store.accessor.svelte';
20
+ // svelte template
21
+ // tags
22
+ case 'punctuation.definition.tag.begin.svelte':
23
+ return token.token === '</' ? 'tag.closing.begin' : 'tag.regular.begin';
24
+ case 'punctuation.definition.tag.end.svelte':
25
+ return token.token === '/>' ? 'tag.self-closing.end' : 'tag.regular.end';
26
+ case 'support.class.component.svelte':
27
+ case 'entity.name.tag.svelte':
28
+ return 'tag.name';
29
+ case 'entity.other.attribute-name.svelte':
30
+ return 'tag.attribute.name';
31
+ case 'punctuation.separator.key-value.svelte':
32
+ return 'operator.assignment';
33
+ // html comments
34
+ case 'punctuation.definition.comment.svelte':
35
+ return 'comment.definition';
36
+ case 'comment.block.svelte':
37
+ return 'comment.block';
38
+ }
39
+ };
@@ -0,0 +1,38 @@
1
+ import { SVELTE_SCRIPT } from './contextConstants.js';
2
+ /**
3
+ * Putting scripts to the top
4
+ *
5
+ * ```
6
+ * <div>{$t('key1')}</div>
7
+ * <script>
8
+ * const {t} = getTranslate('namespace')
9
+ * </script>
10
+ * ```
11
+ *
12
+ * transforming essentially to this:
13
+ *
14
+ * ```
15
+ * const {t} = getTranslate('namespace')
16
+ *
17
+ * <div>{$t('key1')}</div>
18
+ * ```
19
+ */
20
+ export const svelteTreeTransform = (root) => {
21
+ if (root.type !== 'expr') {
22
+ return { tree: root };
23
+ }
24
+ const scripts = [];
25
+ const other = [];
26
+ for (const node of root.values) {
27
+ if (node.type === 'expr' && node.context === SVELTE_SCRIPT) {
28
+ scripts.push(...node.values);
29
+ }
30
+ else {
31
+ other.push(node);
32
+ }
33
+ }
34
+ // put scripts to top
35
+ // and other to bottom
36
+ root.values = [...scripts, ...other];
37
+ return { tree: root };
38
+ };
@@ -0,0 +1,20 @@
1
+ // getTranslate(
2
+ export const getTranslateMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'function.call' && token === 'getTranslate') {
10
+ return 1 /* S.ExpectBracket */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectBracket */:
14
+ if (type === 'expression.begin') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.get.translate',
20
+ };
@@ -0,0 +1,20 @@
1
+ // <script
2
+ export const scriptTagMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'tag.regular.begin') {
10
+ return 1 /* S.ExpectTemplate */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectTemplate */:
14
+ if (type === 'tag.name' && token === 'script') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.script.tag',
20
+ };
@@ -0,0 +1,20 @@
1
+ // <T
2
+ export const tComponentMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'tag.regular.begin') {
10
+ return 1 /* S.ExpectT */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectT */:
14
+ if (type === 'tag.name' && token === 'T') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.t.component',
20
+ };
@@ -0,0 +1,29 @@
1
+ // t(
2
+ export const tFunctionMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'store.accessor.svelte' && token === '$') {
10
+ return 1 /* S.ExpectT */;
11
+ }
12
+ else if (type === 'acessor.dot') {
13
+ return 3 /* S.Ignore */;
14
+ }
15
+ break;
16
+ case 1 /* S.ExpectT */:
17
+ if (type === 'function.call' && token === 't') {
18
+ return 2 /* S.ExpectBracket */;
19
+ }
20
+ break;
21
+ case 2 /* S.ExpectBracket */:
22
+ if (type === 'expression.begin') {
23
+ return end.MERGE_ALL;
24
+ }
25
+ break;
26
+ }
27
+ },
28
+ customType: 'trigger.t.function',
29
+ };
@@ -0,0 +1,45 @@
1
+ import { pipeMachines } from '../parser/mergerMachine.js';
2
+ import { DEFAULT_BLOCKS, DEFAULT_MERGERERS, Parser } from '../parser/parser.js';
3
+ import { generalMapper } from '../parser/generalMapper.js';
4
+ import { vueMapper } from './vueMapper.js';
5
+ import { vueTreeTransform } from './vueTreeTransform.js';
6
+ import { globalTFunctionMerger } from './tokenMergers/globalTFunctionMerger.js';
7
+ import { tFunctionMerger } from './tokenMergers/tFunctionMerger.js';
8
+ import { useTranslateMerger } from './tokenMergers/useTranslateMerger.js';
9
+ import { exportDefaultObjectMerger } from './tokenMergers/exportDefaultObjectMerger.js';
10
+ import { scriptTagMerger } from './tokenMergers/scriptTagMerger.js';
11
+ import { tComponentMerger } from './tokenMergers/tComponentMerger.js';
12
+ import { globalTFunction } from './rules/globalTFunction.js';
13
+ import { tFunction } from './rules/tFunction.js';
14
+ import { useTranslate } from './rules/useTranslate.js';
15
+ import { tComponent } from './rules/tComponent.js';
16
+ import { scriptTag } from './rules/scriptTag.js';
17
+ import { exportDefaultObject } from './rules/exportDefaultObject.js';
18
+ const vueMappers = [generalMapper, vueMapper];
19
+ export const vueMergers = pipeMachines([
20
+ ...DEFAULT_MERGERERS,
21
+ globalTFunctionMerger,
22
+ tFunctionMerger,
23
+ useTranslateMerger,
24
+ tComponentMerger,
25
+ scriptTagMerger,
26
+ exportDefaultObjectMerger,
27
+ ]);
28
+ export const ParserVue = () => {
29
+ return Parser({
30
+ mappers: vueMappers,
31
+ blocks: {
32
+ ...DEFAULT_BLOCKS,
33
+ },
34
+ rules: [
35
+ globalTFunction,
36
+ tFunction,
37
+ useTranslate,
38
+ tComponent,
39
+ scriptTag,
40
+ exportDefaultObject,
41
+ ],
42
+ merger: vueMergers,
43
+ treeTransform: vueTreeTransform,
44
+ });
45
+ };
@@ -0,0 +1,3 @@
1
+ export const VUE_SCRIPT_REGULAR = 'script.regular';
2
+ export const VUE_SCRIPT_SETUP = 'script.setup';
3
+ export const VUE_COMPONENT_CONFIG = 'vue.component.config';
@@ -0,0 +1,14 @@
1
+ import { parseObject } from '../../parser/tree/parseObject.js';
2
+ import { VUE_COMPONENT_CONFIG } from '../contextConstants.js';
3
+ // export default { setup() { .... } }
4
+ // ^^^^^^^^^^^^^^^^------------------^
5
+ export const exportDefaultObject = {
6
+ trigger: 'trigger.export.default.object',
7
+ call(context) {
8
+ const result = parseObject(context);
9
+ if (result.type === 'dict' && result.value['setup']) {
10
+ result.context = VUE_COMPONENT_CONFIG;
11
+ }
12
+ return result;
13
+ },
14
+ };
@@ -0,0 +1,7 @@
1
+ import { tFunctionGeneral } from '../../parser/rules/tFunctionGeneral.js';
2
+ export const globalTFunction = {
3
+ trigger: 'trigger.global.t.function',
4
+ call(context) {
5
+ return tFunctionGeneral(context, false);
6
+ },
7
+ };
@@ -0,0 +1,31 @@
1
+ import { parseTag } from '../../parser/tree/parseTag.js';
2
+ import { VUE_SCRIPT_REGULAR, VUE_SCRIPT_SETUP } from '../contextConstants.js';
3
+ // <script setup>....</script>
4
+ // ^^^^^^^-----------^^^^^^^^^
5
+ export const scriptTag = {
6
+ trigger: 'trigger.script.tag',
7
+ call(context) {
8
+ const line = context.getCurrentLine();
9
+ const { props, child } = parseTag(context);
10
+ const result = {
11
+ type: 'expr',
12
+ line,
13
+ values: [props],
14
+ };
15
+ if (child) {
16
+ if (child.type === 'expr') {
17
+ result.values.push(...child.values);
18
+ }
19
+ else {
20
+ result.values.push(child);
21
+ }
22
+ }
23
+ if (props.type === 'dict' && Boolean(props.value['setup'])) {
24
+ result.context = VUE_SCRIPT_SETUP;
25
+ }
26
+ else {
27
+ result.context = VUE_SCRIPT_REGULAR;
28
+ }
29
+ return result;
30
+ },
31
+ };
@@ -0,0 +1,9 @@
1
+ import { tComponentGeneral } from '../../parser/rules/tComponentGeneral.js';
2
+ // <T keyName="test">Default</T>
3
+ // ^^-----------------------^^^^
4
+ export const tComponent = {
5
+ trigger: 'trigger.t.component',
6
+ call(context) {
7
+ return tComponentGeneral(context);
8
+ },
9
+ };
@@ -0,0 +1,7 @@
1
+ import { tFunctionGeneral } from '../../parser/rules/tFunctionGeneral.js';
2
+ export const tFunction = {
3
+ trigger: 'trigger.t.function',
4
+ call(context) {
5
+ return tFunctionGeneral(context, true);
6
+ },
7
+ };
@@ -0,0 +1,7 @@
1
+ import { tNsSourceGeneral } from '../../parser/rules/tNsSourceGeneral.js';
2
+ export const useTranslate = {
3
+ trigger: 'trigger.use.translate',
4
+ call(context) {
5
+ return tNsSourceGeneral(context);
6
+ },
7
+ };
@@ -0,0 +1,25 @@
1
+ // export default {
2
+ export const exportDefaultObjectMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ switch (state) {
7
+ case 0 /* S.Idle */:
8
+ if (type === 'keyword.export') {
9
+ return 1 /* S.ExpectDefault */;
10
+ }
11
+ break;
12
+ case 1 /* S.ExpectDefault */:
13
+ if (type === 'keyword.default') {
14
+ return 2 /* S.ExpectBlockStart */;
15
+ }
16
+ break;
17
+ case 2 /* S.ExpectBlockStart */:
18
+ if (type === 'block.begin') {
19
+ return end.MERGE_ALL;
20
+ }
21
+ break;
22
+ }
23
+ },
24
+ customType: 'trigger.export.default.object',
25
+ };
@@ -0,0 +1,36 @@
1
+ // $t(
2
+ export const globalTFunctionMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'function.call' && token === '$t') {
10
+ return 1 /* S.ExpectBracket */;
11
+ }
12
+ else if (type === 'variable' && token === 'this') {
13
+ return 2 /* S.ExpectDot */;
14
+ }
15
+ else if (type === 'acessor.dot') {
16
+ return 4 /* S.Ignore */;
17
+ }
18
+ break;
19
+ case 2 /* S.ExpectDot */:
20
+ if (type === 'acessor.dot') {
21
+ return 3 /* S.ExpectCall */;
22
+ }
23
+ break;
24
+ case 3 /* S.ExpectCall */:
25
+ if (type === 'function.call' && token === '$t') {
26
+ return 1 /* S.ExpectBracket */;
27
+ }
28
+ break;
29
+ case 1 /* S.ExpectBracket */:
30
+ if (type === 'expression.begin') {
31
+ return end.MERGE_ALL;
32
+ }
33
+ }
34
+ },
35
+ customType: 'trigger.global.t.function',
36
+ };
@@ -0,0 +1,20 @@
1
+ // <script
2
+ export const scriptTagMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'tag.regular.begin') {
10
+ return 1 /* S.ExpectTemplate */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectTemplate */:
14
+ if (type === 'tag.name' && token === 'script') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.script.tag',
20
+ };
@@ -0,0 +1,20 @@
1
+ // <T
2
+ export const tComponentMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'tag.regular.begin') {
10
+ return 1 /* S.ExpectT */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectT */:
14
+ if (type === 'tag.name' && token === 'T') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.t.component',
20
+ };
@@ -0,0 +1,37 @@
1
+ // t(
2
+ export const tFunctionMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'function.call' && token === 't') {
10
+ return 3 /* S.ExpectBracket */;
11
+ }
12
+ else if (type === 'variable' && token === 't') {
13
+ return 1 /* S.ExpectDot */;
14
+ }
15
+ else if (type === 'acessor.dot') {
16
+ return 4 /* S.Ignore */;
17
+ }
18
+ break;
19
+ case 3 /* S.ExpectBracket */:
20
+ if (type === 'expression.begin') {
21
+ return end.MERGE_ALL;
22
+ }
23
+ break;
24
+ case 1 /* S.ExpectDot */:
25
+ if (type === 'acessor.dot') {
26
+ return 2 /* S.ExpectValueMethod */;
27
+ }
28
+ break;
29
+ case 2 /* S.ExpectValueMethod */:
30
+ if (type === 'function.call') {
31
+ return 3 /* S.ExpectBracket */;
32
+ }
33
+ break;
34
+ }
35
+ },
36
+ customType: 'trigger.t.function',
37
+ };
@@ -0,0 +1,20 @@
1
+ // useTranslate(
2
+ export const useTranslateMerger = {
3
+ initial: 0 /* S.Idle */,
4
+ step: (state, t, end) => {
5
+ const type = t.customType;
6
+ const token = t.token;
7
+ switch (state) {
8
+ case 0 /* S.Idle */:
9
+ if (type === 'function.call' && token === 'useTranslate') {
10
+ return 1 /* S.ExpectBracket */;
11
+ }
12
+ break;
13
+ case 1 /* S.ExpectBracket */:
14
+ if (type === 'expression.begin') {
15
+ return end.MERGE_ALL;
16
+ }
17
+ }
18
+ },
19
+ customType: 'trigger.use.translate',
20
+ };
@@ -0,0 +1,51 @@
1
+ export const vueMapper = (token) => {
2
+ const type = token.type;
3
+ switch (token.type) {
4
+ // vue template expression
5
+ case 'punctuation.definition.string.begin.html.vue':
6
+ return 'expression.template.begin';
7
+ case 'punctuation.definition.string.end.html.vue':
8
+ return 'expression.template.end';
9
+ // vue template tags
10
+ case 'punctuation.definition.tag.begin.html':
11
+ case 'punctuation.definition.tag.begin.html.vue':
12
+ return token.token === '</' ? 'tag.closing.begin' : 'tag.regular.begin';
13
+ case 'punctuation.definition.tag.end.html.vue':
14
+ case 'punctuation.definition.tag.end.html':
15
+ return token.token === '/>' ? 'tag.self-closing.end' : 'tag.regular.end';
16
+ case type.match(/^entity\.name\.tag\.[^.]+\.html\.vue$/) ? type : false:
17
+ case 'entity.name.tag.html':
18
+ return 'tag.name';
19
+ case 'entity.other.attribute-name.html.vue':
20
+ case 'entity.other.attribute-name.html':
21
+ return 'tag.attribute.name';
22
+ case 'punctuation.separator.key-value.html':
23
+ case 'punctuation.separator.key-value.html.vue':
24
+ return 'operator.assignment';
25
+ // html string attributes
26
+ case 'punctuation.definition.string.begin.html':
27
+ return 'string.begin';
28
+ case 'punctuation.definition.string.end.html':
29
+ return 'string.end';
30
+ case 'string.quoted.single.html':
31
+ case 'string.quoted.double.html':
32
+ return 'string.body';
33
+ case 'string.unquoted.html':
34
+ return 'string';
35
+ // html comments
36
+ case 'punctuation.definition.comment.html':
37
+ return 'comment.definition';
38
+ case 'comment.block.html':
39
+ return 'comment.block';
40
+ // ignore template modifiers
41
+ // we only basically care about the content
42
+ case 'punctuation.attribute-shorthand.event.html.vue':
43
+ case 'punctuation.attribute-shorthand.bind.html.vue':
44
+ return 'ignore';
45
+ // `export default` is needed to track down setup function
46
+ case 'keyword.control.export.ts':
47
+ return 'keyword.export';
48
+ case 'keyword.control.default.ts':
49
+ return 'keyword.default';
50
+ }
51
+ };
@@ -0,0 +1,109 @@
1
+ import { VUE_SCRIPT_REGULAR, VUE_SCRIPT_SETUP, VUE_COMPONENT_CONFIG, } from './contextConstants.js';
2
+ /*
3
+ * We get this
4
+ *
5
+ * `(item) {item, item}`
6
+ *
7
+ * so we put the expression insides one level up (never mind the arguments):
8
+ *
9
+ * `item, item, item`
10
+ */
11
+ function flattenOneLevel(nodes) {
12
+ const result = [];
13
+ nodes.forEach((node) => {
14
+ if (node.type === 'expr') {
15
+ result.push(...node.values);
16
+ }
17
+ else {
18
+ result.push(node);
19
+ }
20
+ });
21
+ return result;
22
+ }
23
+ /*
24
+ * We get structure like this
25
+ * {
26
+ * setup(item) {
27
+ * item, item
28
+ * }
29
+ * }
30
+ * and setup content should be on top level
31
+ */
32
+ function bringSetupToTopLevel(context, node) {
33
+ const setupContent = [];
34
+ for (const item of node.values) {
35
+ if (item.type === 'dict' && item.context === VUE_COMPONENT_CONFIG) {
36
+ const { setup, ...rest } = item.value;
37
+ if (setup.type === 'expr') {
38
+ if (setup.values.length === 0) {
39
+ context.warnings.push({
40
+ line: setup.line,
41
+ warning: 'W_VUE_SETUP_IS_A_REFERENCE',
42
+ });
43
+ }
44
+ setupContent.push(...flattenOneLevel(setup.values));
45
+ item.value = { ...rest };
46
+ }
47
+ }
48
+ }
49
+ return [node, ...setupContent];
50
+ }
51
+ /**
52
+ * Putting scripts to the top and extracting setup function, so:
53
+ *
54
+ * ```
55
+ * <template>
56
+ * <div>{t('key1')}</div>
57
+ * <template>
58
+ * <script>
59
+ * export default {
60
+ * setup() {
61
+ * const {t} = useTranslate('namespace')
62
+ * },
63
+ * ...
64
+ * }
65
+ * </script>
66
+ * ```
67
+ *
68
+ * transforming essentially to this:
69
+ *
70
+ * ```
71
+ * export default {
72
+ * ...
73
+ * }
74
+ * const {t} = useTranslate('namespace')
75
+ * <template>
76
+ * <div>{{ t('key1') }}</div>
77
+ * <template>
78
+ * ```
79
+ */
80
+ export const vueTreeTransform = (root) => {
81
+ if (root.type !== 'expr') {
82
+ return { tree: root };
83
+ }
84
+ const context = {
85
+ keys: [],
86
+ warnings: [],
87
+ };
88
+ const scripts = [];
89
+ const other = [];
90
+ for (const node of root.values) {
91
+ if (node.type === 'expr' &&
92
+ (node.context === VUE_SCRIPT_REGULAR || node.context === VUE_SCRIPT_SETUP)) {
93
+ if (node.context === VUE_SCRIPT_REGULAR) {
94
+ // we need to dig deeper for the `setup` function
95
+ scripts.push(...bringSetupToTopLevel(context, node));
96
+ }
97
+ else {
98
+ scripts.push(...node.values);
99
+ }
100
+ }
101
+ else {
102
+ other.push(node);
103
+ }
104
+ }
105
+ // put scripts to top
106
+ // and other to bottom
107
+ root.values = [...scripts, ...other];
108
+ return { tree: root, report: context };
109
+ };