@tolgee/cli 1.1.2 → 1.3.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.
- package/dist/commands/login.js +1 -1
- package/dist/commands/pull.js +17 -4
- package/dist/config/tolgeerc.js +1 -1
- package/dist/constants.js +1 -1
- package/dist/extractor/extractor.js +16 -3
- package/dist/extractor/machines/react.js +60 -104
- package/dist/extractor/machines/shared/properties.js +76 -4
- package/dist/extractor/machines/shared/translateCall.js +141 -0
- package/dist/extractor/machines/svelte.js +50 -111
- package/dist/extractor/machines/vue/decoder.js +194 -0
- package/dist/extractor/machines/vue/extract.js +491 -0
- package/dist/extractor/processors/vueSfc.js +55 -0
- package/dist/extractor/tokenizer.js +11 -6
- package/dist/extractor/warnings.js +4 -0
- package/dist/extractor/worker.js +3 -2
- package/extractor.d.ts +3 -1
- package/package.json +18 -18
- package/textmate/HTML.tmLanguage +2650 -0
- package/textmate/Svelte.tmLanguage +80 -0
- package/textmate/THIRD_PARTY_NOTICE +27 -0
- package/textmate/TypeScript.tmLanguage +5888 -9736
- package/textmate/TypeScriptReact.tmLanguage +6137 -10166
- package/textmate/Vue.tmLanguage +1263 -0
package/dist/commands/login.js
CHANGED
@@ -10,7 +10,7 @@ async function loginHandler(key) {
|
|
10
10
|
keyInfo = await RestClient.getApiKeyInformation(opts.apiUrl, key);
|
11
11
|
}
|
12
12
|
catch (e) {
|
13
|
-
if (e instanceof HttpError && e.response.status ===
|
13
|
+
if (e instanceof HttpError && e.response.status === 401) {
|
14
14
|
error("Couldn't log in: the API key you provided is invalid.");
|
15
15
|
process.exit(1);
|
16
16
|
}
|
package/dist/commands/pull.js
CHANGED
@@ -1,21 +1,33 @@
|
|
1
1
|
import { Command, Option } from 'commander';
|
2
2
|
import { unzipBuffer } from '../utils/zip.js';
|
3
3
|
import { overwriteDir } from '../utils/overwriteDir.js';
|
4
|
-
import { loading, success } from '../utils/logger.js';
|
4
|
+
import { error, loading, success } from '../utils/logger.js';
|
5
|
+
import { HttpError } from '../client/errors.js';
|
5
6
|
async function fetchZipBlob(opts) {
|
6
7
|
return opts.client.export.export({
|
7
8
|
format: opts.format,
|
8
9
|
languages: opts.languages,
|
9
10
|
filterState: opts.states,
|
10
11
|
structureDelimiter: opts.delimiter,
|
12
|
+
filterNamespace: opts.namespaces,
|
11
13
|
});
|
12
14
|
}
|
13
15
|
async function pullHandler(path) {
|
14
16
|
const opts = this.optsWithGlobals();
|
15
17
|
await overwriteDir(path, opts.overwrite);
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
try {
|
19
|
+
const zipBlob = await loading('Fetching strings from Tolgee...', fetchZipBlob(opts));
|
20
|
+
await loading('Extracting strings...', unzipBuffer(zipBlob, path));
|
21
|
+
success('Done!');
|
22
|
+
}
|
23
|
+
catch (e) {
|
24
|
+
if (e instanceof HttpError && e.response.status === 400) {
|
25
|
+
const res = await e.response.json();
|
26
|
+
error(`Please check if your parameters, including namespaces, are configured correctly. Tolgee responded with: ${res.code}`);
|
27
|
+
return;
|
28
|
+
}
|
29
|
+
throw e;
|
30
|
+
}
|
19
31
|
}
|
20
32
|
export default new Command()
|
21
33
|
.name('pull')
|
@@ -32,5 +44,6 @@ export default new Command()
|
|
32
44
|
.addOption(new Option('-d, --delimiter', 'Structure delimiter to use. By default, Tolgee interprets `.` as a nested structure. You can change the delimiter, or disable structure formatting by not specifying any value to the option')
|
33
45
|
.default('.')
|
34
46
|
.argParser((v) => v || ''))
|
47
|
+
.addOption(new Option('-n, --namespaces <namespaces...>', 'List of namespaces to pull. Defaults to all namespaces'))
|
35
48
|
.option('-o, --overwrite', 'Whether to automatically overwrite existing files. BE CAREFUL, THIS WILL WIPE *ALL* THE CONTENTS OF THE TARGET FOLDER. If unspecified, the user will be prompted interactively, or the command will fail when in non-interactive')
|
36
49
|
.action(pullHandler);
|
package/dist/config/tolgeerc.js
CHANGED
@@ -49,7 +49,7 @@ function parseConfig(rc) {
|
|
49
49
|
if (typeof rc.delimiter !== 'string' && rc.delimiter !== null) {
|
50
50
|
throw new Error('Invalid config: delimiter is not a string');
|
51
51
|
}
|
52
|
-
cfg.delimiter = rc.delimiter ||
|
52
|
+
cfg.delimiter = rc.delimiter || '';
|
53
53
|
}
|
54
54
|
return cfg;
|
55
55
|
}
|
package/dist/constants.js
CHANGED
@@ -8,4 +8,4 @@ export const USER_AGENT = `Tolgee-CLI/${VERSION} (+https://github.com/tolgee/tol
|
|
8
8
|
export const DEFAULT_API_URL = new URL('https://app.tolgee.io');
|
9
9
|
export const API_KEY_PAT_PREFIX = 'tgpat_';
|
10
10
|
export const API_KEY_PAK_PREFIX = 'tgpak_';
|
11
|
-
export const SDKS = ['react'];
|
11
|
+
export const SDKS = ['react', 'vue', 'svelte'];
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import { extname } from 'path';
|
2
2
|
import { interpret } from 'xstate';
|
3
3
|
import reactExtractorMachine from './machines/react.js';
|
4
|
+
import vueExtractorMachine from './machines/vue/extract.js';
|
4
5
|
import svelteExtractorMachine from './machines/svelte.js';
|
5
6
|
import commentsExtractorMachine from './machines/comments.js';
|
7
|
+
import vueSfcProcessor from './processors/vueSfc.js';
|
6
8
|
import tokenizer from './tokenizer.js';
|
7
9
|
const REACT_EXTS = [
|
8
10
|
'.js',
|
@@ -14,6 +16,7 @@ const REACT_EXTS = [
|
|
14
16
|
'.jsx',
|
15
17
|
'.tsx',
|
16
18
|
];
|
19
|
+
const VUE_EXTS = REACT_EXTS;
|
17
20
|
const ALL_EXTS = [
|
18
21
|
'.js',
|
19
22
|
'.mjs',
|
@@ -25,11 +28,13 @@ const ALL_EXTS = [
|
|
25
28
|
'.tsx',
|
26
29
|
'.svelte',
|
27
30
|
];
|
28
|
-
function pickMachine(code,
|
29
|
-
const ext = extname(fileName);
|
31
|
+
function pickMachine(code, ext) {
|
30
32
|
if (REACT_EXTS.includes(ext) && code.includes('@tolgee/react')) {
|
31
33
|
return reactExtractorMachine;
|
32
34
|
}
|
35
|
+
if (VUE_EXTS.includes(ext) && code.includes('@tolgee/vue')) {
|
36
|
+
return vueExtractorMachine;
|
37
|
+
}
|
33
38
|
if (ext === '.svelte' && code.includes('@tolgee/svelte')) {
|
34
39
|
return svelteExtractorMachine;
|
35
40
|
}
|
@@ -40,7 +45,15 @@ function pickMachine(code, fileName) {
|
|
40
45
|
return null;
|
41
46
|
}
|
42
47
|
export default async function extractor(code, fileName) {
|
43
|
-
const
|
48
|
+
const ext = extname(fileName);
|
49
|
+
if (ext === '.vue' &&
|
50
|
+
(code.includes('$t') ||
|
51
|
+
code.includes('@tolgee/vue') ||
|
52
|
+
code.includes('@tolgee-key') ||
|
53
|
+
code.includes('@tolgee-ignore'))) {
|
54
|
+
return vueSfcProcessor(code, fileName);
|
55
|
+
}
|
56
|
+
const machineSpec = pickMachine(code, ext);
|
44
57
|
if (!machineSpec) {
|
45
58
|
return { warnings: [], keys: [] };
|
46
59
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { createMachine, assign, send, forwardTo } from 'xstate';
|
2
|
+
import translateCallMachine from './shared/translateCall.js';
|
2
3
|
import propertiesMachine from './shared/properties.js';
|
3
4
|
import commentsService from './shared/comments.js';
|
4
5
|
const VOID_KEY = { keyName: '', line: -1 };
|
@@ -456,111 +457,38 @@ export default createMachine({
|
|
456
457
|
},
|
457
458
|
},
|
458
459
|
call: {
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
{
|
464
|
-
target: 'idle',
|
465
|
-
actions: 'dynamicOptions',
|
466
|
-
cond: (ctx) => !!ctx.key.keyName,
|
467
|
-
},
|
460
|
+
invoke: {
|
461
|
+
id: 'tCall',
|
462
|
+
src: translateCallMachine,
|
463
|
+
onDone: [
|
468
464
|
{
|
469
465
|
target: 'idle',
|
470
466
|
actions: 'dynamicKeyName',
|
471
|
-
|
472
|
-
],
|
473
|
-
'punctuation.definition.block.ts': {
|
474
|
-
target: 'param_object',
|
475
|
-
cond: (_ctx, evt) => evt.token === '{',
|
476
|
-
},
|
477
|
-
'meta.brace.round.ts': {
|
478
|
-
target: 'idle',
|
479
|
-
cond: (_ctx, evt) => evt.token === ')',
|
480
|
-
actions: 'pushKey',
|
481
|
-
},
|
482
|
-
},
|
483
|
-
},
|
484
|
-
param_string: {
|
485
|
-
on: {
|
486
|
-
'*': [
|
487
|
-
{
|
488
|
-
target: 'param_end',
|
489
|
-
actions: ['storeKeyName', 'storeKeyCurrentNamespace'],
|
490
|
-
cond: (ctx) => !ctx.key.keyName,
|
491
|
-
},
|
492
|
-
{
|
493
|
-
target: 'param_end',
|
494
|
-
actions: ['storeKeyDefault', 'storeKeyCurrentNamespace'],
|
495
|
-
cond: (ctx) => !!ctx.key.keyName,
|
496
|
-
},
|
497
|
-
],
|
498
|
-
},
|
499
|
-
},
|
500
|
-
param_end: {
|
501
|
-
on: {
|
502
|
-
'punctuation.separator.comma.ts': 'call',
|
503
|
-
'punctuation.definition.template-expression.begin.ts': [
|
504
|
-
{
|
505
|
-
target: 'param_end_warn',
|
506
|
-
actions: 'dynamicKeyDefault',
|
507
|
-
cond: (ctx) => !!ctx.key.defaultValue,
|
467
|
+
cond: (_, evt) => evt.data.keyName === false,
|
508
468
|
},
|
509
469
|
{
|
510
470
|
target: 'idle',
|
511
|
-
actions: '
|
512
|
-
|
513
|
-
],
|
514
|
-
'keyword.operator.arithmetic.ts': [
|
515
|
-
{
|
516
|
-
target: 'param_end_warn',
|
517
|
-
actions: 'dynamicKeyDefault',
|
518
|
-
cond: (ctx) => !!ctx.key.defaultValue,
|
471
|
+
actions: 'dynamicNamespace',
|
472
|
+
cond: (_, evt) => evt.data.namespace === false,
|
519
473
|
},
|
520
474
|
{
|
521
475
|
target: 'idle',
|
522
|
-
actions: '
|
476
|
+
actions: 'dynamicOptions',
|
477
|
+
cond: (_, evt) => evt.data.dynamicOptions,
|
523
478
|
},
|
524
|
-
],
|
525
|
-
'meta.brace.round.ts': {
|
526
|
-
target: 'idle',
|
527
|
-
cond: (_ctx, evt) => evt.token === ')',
|
528
|
-
actions: 'pushKey',
|
529
|
-
},
|
530
|
-
},
|
531
|
-
},
|
532
|
-
param_end_warn: {
|
533
|
-
on: {
|
534
|
-
'punctuation.separator.comma.ts': 'call',
|
535
|
-
'meta.brace.round.ts': {
|
536
|
-
target: 'idle',
|
537
|
-
cond: (_ctx, evt) => evt.token === ')',
|
538
|
-
actions: 'pushKey',
|
539
|
-
},
|
540
|
-
},
|
541
|
-
},
|
542
|
-
param_object: {
|
543
|
-
invoke: {
|
544
|
-
id: 'propertiesMachine',
|
545
|
-
src: propertiesMachine,
|
546
|
-
data: {
|
547
|
-
depth: 1,
|
548
|
-
},
|
549
|
-
onDone: [
|
550
479
|
{
|
551
480
|
target: 'idle',
|
552
|
-
|
553
|
-
cond: 'isPropertiesDataDynamic',
|
481
|
+
cond: (_, evt) => !evt.data.keyName,
|
554
482
|
},
|
555
483
|
{
|
556
484
|
target: 'idle',
|
557
|
-
actions:
|
485
|
+
actions: 'consumeTranslateCall',
|
558
486
|
},
|
559
487
|
],
|
560
488
|
},
|
561
489
|
on: {
|
562
490
|
'*': {
|
563
|
-
actions: forwardTo('
|
491
|
+
actions: forwardTo('tCall'),
|
564
492
|
},
|
565
493
|
},
|
566
494
|
},
|
@@ -613,6 +541,43 @@ export default createMachine({
|
|
613
541
|
{ warning: 'W_DYNAMIC_NAMESPACE', line: ctx.line },
|
614
542
|
],
|
615
543
|
}),
|
544
|
+
consumeTranslateCall: assign({
|
545
|
+
warnings: (ctx, evt) => {
|
546
|
+
const utNamespace = ctx.hooks.length
|
547
|
+
? ctx.hooks[ctx.hooks.length - 1].namespace
|
548
|
+
: undefined;
|
549
|
+
if (!evt.data.namespace && utNamespace === false) {
|
550
|
+
return [
|
551
|
+
...ctx.warnings,
|
552
|
+
{ warning: 'W_UNRESOLVABLE_NAMESPACE', line: ctx.line },
|
553
|
+
];
|
554
|
+
}
|
555
|
+
if (evt.data.defaultValue === false) {
|
556
|
+
return [
|
557
|
+
...ctx.warnings,
|
558
|
+
{ warning: 'W_DYNAMIC_DEFAULT_VALUE', line: ctx.line },
|
559
|
+
];
|
560
|
+
}
|
561
|
+
return ctx.warnings;
|
562
|
+
},
|
563
|
+
keys: (ctx, evt) => {
|
564
|
+
const utNamespace = ctx.hooks.length
|
565
|
+
? ctx.hooks[ctx.hooks.length - 1].namespace
|
566
|
+
: undefined;
|
567
|
+
const ns = evt.data.namespace === null ? utNamespace : evt.data.namespace;
|
568
|
+
if (!evt.data.keyName || ns === false)
|
569
|
+
return ctx.keys;
|
570
|
+
return [
|
571
|
+
...ctx.keys,
|
572
|
+
{
|
573
|
+
keyName: evt.data.keyName,
|
574
|
+
namespace: ns || undefined,
|
575
|
+
defaultValue: evt.data.defaultValue || undefined,
|
576
|
+
line: ctx.line,
|
577
|
+
},
|
578
|
+
];
|
579
|
+
},
|
580
|
+
}),
|
616
581
|
consumeParameters: assign({
|
617
582
|
key: (ctx, evt) => ({
|
618
583
|
// We don't want the key and default value to be overridable
|
@@ -643,7 +608,7 @@ export default createMachine({
|
|
643
608
|
line: ctx.line,
|
644
609
|
},
|
645
610
|
],
|
646
|
-
key:
|
611
|
+
key: VOID_KEY,
|
647
612
|
}),
|
648
613
|
appendChildren: assign({
|
649
614
|
children: (ctx, evt) => (ctx.children ?? '') + evt.token,
|
@@ -662,20 +627,19 @@ export default createMachine({
|
|
662
627
|
storeKeyDefault: assign({
|
663
628
|
key: (ctx, evt) => ({ ...ctx.key, defaultValue: evt.token }),
|
664
629
|
}),
|
665
|
-
storeKeyCurrentNamespace: assign({
|
666
|
-
key: (ctx, _evt) => ({
|
667
|
-
...ctx.key,
|
668
|
-
namespace: ctx.hooks.length
|
669
|
-
? ctx.hooks[ctx.hooks.length - 1].namespace
|
670
|
-
: undefined,
|
671
|
-
}),
|
672
|
-
}),
|
673
630
|
dynamicKeyName: assign({
|
674
631
|
warnings: (ctx, _evt) => [
|
675
632
|
...ctx.warnings,
|
676
633
|
{ warning: 'W_DYNAMIC_KEY', line: ctx.line },
|
677
634
|
],
|
678
|
-
key:
|
635
|
+
key: VOID_KEY,
|
636
|
+
}),
|
637
|
+
dynamicNamespace: assign({
|
638
|
+
warnings: (ctx, _evt) => [
|
639
|
+
...ctx.warnings,
|
640
|
+
{ warning: 'W_DYNAMIC_NAMESPACE', line: ctx.line },
|
641
|
+
],
|
642
|
+
key: VOID_KEY,
|
679
643
|
}),
|
680
644
|
dynamicKeyDefault: assign({
|
681
645
|
key: (ctx, _evt) => ({ ...ctx.key, defaultValue: undefined }),
|
@@ -685,7 +649,7 @@ export default createMachine({
|
|
685
649
|
],
|
686
650
|
}),
|
687
651
|
dynamicOptions: assign({
|
688
|
-
key:
|
652
|
+
key: VOID_KEY,
|
689
653
|
warnings: (ctx, _evt) => [
|
690
654
|
...ctx.warnings,
|
691
655
|
{ warning: 'W_DYNAMIC_OPTIONS', line: ctx.line },
|
@@ -704,14 +668,6 @@ export default createMachine({
|
|
704
668
|
],
|
705
669
|
}),
|
706
670
|
pushKey: assign({
|
707
|
-
warnings: (ctx, _evt) => {
|
708
|
-
if (!ctx.key.keyName || ctx.key.namespace !== false)
|
709
|
-
return ctx.warnings;
|
710
|
-
return [
|
711
|
-
...ctx.warnings,
|
712
|
-
{ warning: 'W_UNRESOLVABLE_NAMESPACE', line: ctx.line },
|
713
|
-
];
|
714
|
-
},
|
715
671
|
keys: (ctx, _evt) => {
|
716
672
|
if (!ctx.key.keyName || ctx.key.namespace === false)
|
717
673
|
return ctx.keys;
|
@@ -8,6 +8,7 @@ export default createMachine({
|
|
8
8
|
property: null,
|
9
9
|
depth: 0,
|
10
10
|
static: false,
|
11
|
+
nextDynamic: false,
|
11
12
|
keyName: null,
|
12
13
|
defaultValue: null,
|
13
14
|
namespace: null,
|
@@ -47,6 +48,37 @@ export default createMachine({
|
|
47
48
|
'punctuation.separator.key-value.svelte': {
|
48
49
|
target: 'value',
|
49
50
|
},
|
51
|
+
// Vue
|
52
|
+
'punctuation.attribute-shorthand.event.html.vue': [
|
53
|
+
{
|
54
|
+
cond: (_, evt) => evt.token === '@',
|
55
|
+
actions: ['markPropertyAsDynamic', 'markNextPropertyAsDynamic'],
|
56
|
+
},
|
57
|
+
],
|
58
|
+
'entity.other.attribute-name.html.vue': [
|
59
|
+
{
|
60
|
+
cond: (ctx) => ctx.nextDynamic,
|
61
|
+
actions: 'markImmediatePropertyAsDynamic',
|
62
|
+
},
|
63
|
+
{
|
64
|
+
actions: [
|
65
|
+
'markPropertyAsDynamic',
|
66
|
+
'unmarkAsStatic',
|
67
|
+
'storePropertyType',
|
68
|
+
],
|
69
|
+
},
|
70
|
+
],
|
71
|
+
'punctuation.separator.key-value.html.vue': {
|
72
|
+
target: 'value',
|
73
|
+
},
|
74
|
+
'entity.other.attribute-name.html': [
|
75
|
+
{
|
76
|
+
actions: ['markPropertyAsDynamic', 'storePropertyType'],
|
77
|
+
},
|
78
|
+
],
|
79
|
+
'punctuation.separator.key-value.html': {
|
80
|
+
target: 'value',
|
81
|
+
},
|
50
82
|
},
|
51
83
|
},
|
52
84
|
complex_key: {
|
@@ -76,6 +108,7 @@ export default createMachine({
|
|
76
108
|
'punctuation.definition.string.template.begin.ts': 'value_string',
|
77
109
|
'punctuation.definition.string.begin.svelte': 'value_string',
|
78
110
|
'punctuation.definition.string.template.begin.svelte': 'value_string',
|
111
|
+
'punctuation.definition.string.begin.html': 'value_string',
|
79
112
|
// Variable
|
80
113
|
'variable.other.readwrite.ts': {
|
81
114
|
target: 'idle',
|
@@ -98,6 +131,15 @@ export default createMachine({
|
|
98
131
|
'unmarkAsStatic',
|
99
132
|
],
|
100
133
|
},
|
134
|
+
// Vue
|
135
|
+
'string.unquoted.html': {
|
136
|
+
target: 'idle',
|
137
|
+
actions: [
|
138
|
+
'storePropertyValue',
|
139
|
+
'clearPropertyType',
|
140
|
+
'unmarkAsStatic',
|
141
|
+
],
|
142
|
+
},
|
101
143
|
// Value end
|
102
144
|
'punctuation.separator.comma.ts': {
|
103
145
|
target: 'idle',
|
@@ -137,6 +179,10 @@ export default createMachine({
|
|
137
179
|
target: 'idle',
|
138
180
|
actions: ['storeEmptyPropertyValue', 'clearPropertyType'],
|
139
181
|
},
|
182
|
+
'punctuation.definition.string.end.html': {
|
183
|
+
target: 'idle',
|
184
|
+
actions: ['storeEmptyPropertyValue', 'clearPropertyType'],
|
185
|
+
},
|
140
186
|
'*': [
|
141
187
|
{
|
142
188
|
target: 'idle',
|
@@ -186,6 +232,15 @@ export default createMachine({
|
|
186
232
|
target: 'idle',
|
187
233
|
actions: 'clearPropertyType',
|
188
234
|
},
|
235
|
+
// Vue
|
236
|
+
'punctuation.definition.string.end.html.vue': {
|
237
|
+
target: 'idle',
|
238
|
+
actions: 'clearPropertyType',
|
239
|
+
},
|
240
|
+
'punctuation.definition.string.end.html': {
|
241
|
+
target: 'idle',
|
242
|
+
actions: 'clearPropertyType',
|
243
|
+
},
|
189
244
|
},
|
190
245
|
},
|
191
246
|
end: {
|
@@ -221,15 +276,27 @@ export default createMachine({
|
|
221
276
|
target: 'end',
|
222
277
|
actions: 'markPropertyAsDynamic',
|
223
278
|
},
|
279
|
+
'punctuation.definition.tag.end.html.vue': {
|
280
|
+
target: 'end',
|
281
|
+
actions: 'markPropertyAsDynamic',
|
282
|
+
},
|
283
|
+
'punctuation.definition.tag.end.html': {
|
284
|
+
target: 'end',
|
285
|
+
actions: 'markPropertyAsDynamic',
|
286
|
+
},
|
224
287
|
},
|
225
288
|
}, {
|
226
289
|
guards: {
|
227
290
|
isOpenCurly: (_ctx, evt) => evt.token === '{' &&
|
228
291
|
!evt.scopes.includes('meta.embedded.expression.tsx') &&
|
229
|
-
!evt.scopes.includes('meta.embedded.expression.svelte')
|
292
|
+
!evt.scopes.includes('meta.embedded.expression.svelte') &&
|
293
|
+
(!evt.scopes.includes('source.ts.embedded.html.vue') ||
|
294
|
+
evt.scopes.includes('expression.embedded.vue')),
|
230
295
|
isCloseCurly: (_ctx, evt) => evt.token === '}' &&
|
231
296
|
!evt.scopes.includes('meta.embedded.expression.tsx') &&
|
232
|
-
!evt.scopes.includes('meta.embedded.expression.svelte')
|
297
|
+
!evt.scopes.includes('meta.embedded.expression.svelte') &&
|
298
|
+
(!evt.scopes.includes('source.ts.embedded.html.vue') ||
|
299
|
+
evt.scopes.includes('expression.embedded.vue')),
|
233
300
|
isFinalCloseCurly: (ctx, evt) => evt.token === '}' && ctx.depth === 1,
|
234
301
|
isOpenSquare: (_ctx, evt) => evt.token === '[',
|
235
302
|
isCloseSquare: (_ctx, evt) => evt.token === ']',
|
@@ -256,7 +323,11 @@ export default createMachine({
|
|
256
323
|
defaultValue: (ctx) => ctx.property === 'defaultValue' ? '' : ctx.defaultValue,
|
257
324
|
namespace: (ctx) => (ctx.property === 'ns' ? '' : ctx.namespace),
|
258
325
|
}),
|
326
|
+
markNextPropertyAsDynamic: assign({
|
327
|
+
nextDynamic: true,
|
328
|
+
}),
|
259
329
|
markPropertyAsDynamic: assign({
|
330
|
+
nextDynamic: false,
|
260
331
|
keyName: (ctx, _evt) => ctx.property === 'key' || ctx.property === 'keyName'
|
261
332
|
? false
|
262
333
|
: ctx.keyName,
|
@@ -264,6 +335,7 @@ export default createMachine({
|
|
264
335
|
namespace: (ctx, _evt) => ctx.property === 'ns' ? false : ctx.namespace,
|
265
336
|
}),
|
266
337
|
markImmediatePropertyAsDynamic: assign({
|
338
|
+
nextDynamic: false,
|
267
339
|
keyName: (ctx, evt) => evt.token === 'key' || evt.token === 'keyName' ? false : ctx.keyName,
|
268
340
|
defaultValue: (ctx, evt) => evt.token === 'defaultValue' ? false : ctx.defaultValue,
|
269
341
|
namespace: (ctx, evt) => (evt.token === 'ns' ? false : ctx.namespace),
|
@@ -275,10 +347,10 @@ export default createMachine({
|
|
275
347
|
depth: (ctx, _evt) => ctx.depth - 1,
|
276
348
|
}),
|
277
349
|
markAsStatic: assign({
|
278
|
-
static:
|
350
|
+
static: true,
|
279
351
|
}),
|
280
352
|
unmarkAsStatic: assign({
|
281
|
-
static:
|
353
|
+
static: false,
|
282
354
|
}),
|
283
355
|
},
|
284
356
|
});
|
@@ -0,0 +1,141 @@
|
|
1
|
+
// This machine is responsible for extracting data from
|
2
|
+
// calls to `t`. It is shared across multiple machines since
|
3
|
+
// all t functions share the same signature.
|
4
|
+
import { createMachine, assign, forwardTo } from 'xstate';
|
5
|
+
import propertiesMachine from './properties.js';
|
6
|
+
export default createMachine({
|
7
|
+
predictableActionArguments: true,
|
8
|
+
id: 'tCall',
|
9
|
+
initial: 'idle',
|
10
|
+
context: {
|
11
|
+
keyName: null,
|
12
|
+
defaultValue: null,
|
13
|
+
namespace: null,
|
14
|
+
dynamicOptions: false,
|
15
|
+
},
|
16
|
+
states: {
|
17
|
+
idle: {
|
18
|
+
on: {
|
19
|
+
'punctuation.definition.string.begin.ts': 'string',
|
20
|
+
'punctuation.definition.string.template.begin.ts': 'string',
|
21
|
+
'variable.other.readwrite.ts': [
|
22
|
+
{
|
23
|
+
target: 'done',
|
24
|
+
actions: 'dynamicOptions',
|
25
|
+
cond: (ctx) => !!ctx.keyName,
|
26
|
+
},
|
27
|
+
{
|
28
|
+
target: 'done',
|
29
|
+
actions: 'dynamicKeyName',
|
30
|
+
},
|
31
|
+
],
|
32
|
+
'punctuation.definition.block.ts': {
|
33
|
+
target: 'object',
|
34
|
+
cond: (_ctx, evt) => evt.token === '{',
|
35
|
+
},
|
36
|
+
'meta.brace.round.ts': {
|
37
|
+
target: 'done',
|
38
|
+
cond: (_ctx, evt) => evt.token === ')',
|
39
|
+
},
|
40
|
+
},
|
41
|
+
},
|
42
|
+
string: {
|
43
|
+
on: {
|
44
|
+
'*': [
|
45
|
+
{
|
46
|
+
target: 'string_end',
|
47
|
+
actions: 'storeKeyName',
|
48
|
+
cond: (ctx) => !ctx.keyName,
|
49
|
+
},
|
50
|
+
{
|
51
|
+
target: 'string_end',
|
52
|
+
actions: 'storeDefaultValue',
|
53
|
+
cond: (ctx) => !!ctx.keyName,
|
54
|
+
},
|
55
|
+
],
|
56
|
+
},
|
57
|
+
},
|
58
|
+
string_end: {
|
59
|
+
on: {
|
60
|
+
'punctuation.separator.comma.ts': 'idle',
|
61
|
+
'punctuation.definition.template-expression.begin.ts': [
|
62
|
+
{
|
63
|
+
target: 'string_end_warn',
|
64
|
+
actions: 'dynamicDefaultValue',
|
65
|
+
cond: (ctx) => !!ctx.defaultValue,
|
66
|
+
},
|
67
|
+
{
|
68
|
+
target: 'done',
|
69
|
+
actions: 'dynamicKeyName',
|
70
|
+
},
|
71
|
+
],
|
72
|
+
'keyword.operator.arithmetic.ts': [
|
73
|
+
{
|
74
|
+
target: 'string_end_warn',
|
75
|
+
actions: 'dynamicDefaultValue',
|
76
|
+
cond: (ctx) => !!ctx.defaultValue,
|
77
|
+
},
|
78
|
+
{
|
79
|
+
target: 'done',
|
80
|
+
actions: 'dynamicKeyName',
|
81
|
+
},
|
82
|
+
],
|
83
|
+
'meta.brace.round.ts': {
|
84
|
+
target: 'done',
|
85
|
+
cond: (_ctx, evt) => evt.token === ')',
|
86
|
+
},
|
87
|
+
},
|
88
|
+
},
|
89
|
+
string_end_warn: {
|
90
|
+
on: {
|
91
|
+
'punctuation.separator.comma.ts': 'idle',
|
92
|
+
'meta.brace.round.ts': {
|
93
|
+
target: 'done',
|
94
|
+
cond: (_ctx, evt) => evt.token === ')',
|
95
|
+
},
|
96
|
+
},
|
97
|
+
},
|
98
|
+
object: {
|
99
|
+
invoke: {
|
100
|
+
id: 'propertiesMachine',
|
101
|
+
src: propertiesMachine,
|
102
|
+
data: {
|
103
|
+
depth: 1,
|
104
|
+
},
|
105
|
+
onDone: {
|
106
|
+
target: 'done',
|
107
|
+
actions: 'consumeParameters',
|
108
|
+
},
|
109
|
+
},
|
110
|
+
on: {
|
111
|
+
'*': {
|
112
|
+
actions: forwardTo('propertiesMachine'),
|
113
|
+
},
|
114
|
+
},
|
115
|
+
},
|
116
|
+
done: { type: 'final', data: (ctx) => ctx },
|
117
|
+
},
|
118
|
+
}, {
|
119
|
+
actions: {
|
120
|
+
storeKeyName: assign({
|
121
|
+
keyName: (_, evt) => evt.token,
|
122
|
+
}),
|
123
|
+
storeDefaultValue: assign({
|
124
|
+
defaultValue: (_, evt) => evt.token,
|
125
|
+
}),
|
126
|
+
consumeParameters: assign({
|
127
|
+
keyName: (ctx, evt) => ctx.keyName === null ? evt.data.keyName : ctx.keyName,
|
128
|
+
namespace: (ctx, evt) => ctx.namespace === null ? evt.data.namespace : ctx.namespace,
|
129
|
+
defaultValue: (ctx, evt) => ctx.defaultValue === null ? evt.data.defaultValue : ctx.defaultValue,
|
130
|
+
}),
|
131
|
+
dynamicKeyName: assign({
|
132
|
+
keyName: () => false,
|
133
|
+
}),
|
134
|
+
dynamicDefaultValue: assign({
|
135
|
+
defaultValue: () => false,
|
136
|
+
}),
|
137
|
+
dynamicOptions: assign({
|
138
|
+
dynamicOptions: () => true,
|
139
|
+
}),
|
140
|
+
},
|
141
|
+
});
|