@tolgee/cli 2.0.4 → 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 (90) 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/sync/compare.js +2 -6
  5. package/dist/commands/sync/sync.js +1 -5
  6. package/dist/commands/tag.js +1 -5
  7. package/dist/config/tolgeerc.js +4 -6
  8. package/dist/extractor/extractor.js +40 -66
  9. package/dist/extractor/parser/extractComment.js +78 -0
  10. package/dist/extractor/parser/generalMapper.js +82 -0
  11. package/dist/extractor/parser/generateReport.js +161 -0
  12. package/dist/extractor/parser/iterator.js +37 -0
  13. package/dist/extractor/parser/mergerMachine.js +66 -0
  14. package/dist/extractor/parser/nodeUtils.js +21 -0
  15. package/dist/extractor/parser/parser.js +129 -0
  16. package/dist/extractor/parser/rules/tComponentGeneral.js +45 -0
  17. package/dist/extractor/parser/rules/tFunctionGeneral.js +41 -0
  18. package/dist/extractor/parser/rules/tNsSourceGeneral.js +36 -0
  19. package/dist/extractor/parser/tokenMergers/closingTagMerger.js +27 -0
  20. package/dist/extractor/parser/tokenMergers/commentsMerger.js +36 -0
  21. package/dist/extractor/parser/tokenMergers/stringMerger.js +50 -0
  22. package/dist/extractor/parser/tokenMergers/templateStringMerger.js +55 -0
  23. package/dist/extractor/parser/tokenMergers/typesAsMergerer.js +40 -0
  24. package/dist/extractor/parser/tokenMergers/typesCastMerger.js +28 -0
  25. package/dist/extractor/parser/tree/getTranslateProps.js +54 -0
  26. package/dist/extractor/parser/tree/getValue.js +17 -0
  27. package/dist/extractor/parser/tree/parseGeneral.js +51 -0
  28. package/dist/extractor/parser/tree/parseList.js +33 -0
  29. package/dist/extractor/parser/tree/parseObject.js +130 -0
  30. package/dist/extractor/parser/tree/parseProps.js +56 -0
  31. package/dist/extractor/parser/tree/parseTag.js +26 -0
  32. package/dist/extractor/parser/types.js +1 -0
  33. package/dist/extractor/parserReact/ParserReact.js +30 -0
  34. package/dist/extractor/parserReact/jsxMapper.js +24 -0
  35. package/dist/extractor/parserReact/rules/createElement.js +62 -0
  36. package/dist/extractor/parserReact/rules/tComponent.js +9 -0
  37. package/dist/extractor/parserReact/rules/tFunction.js +7 -0
  38. package/dist/extractor/parserReact/rules/useTranslate.js +7 -0
  39. package/dist/extractor/parserReact/tokenMergers/createElementMerger.js +35 -0
  40. package/dist/extractor/parserReact/tokenMergers/tComponentMerger.js +20 -0
  41. package/dist/extractor/parserReact/tokenMergers/tFunctionMerger.js +23 -0
  42. package/dist/extractor/parserReact/tokenMergers/useTranslateMerger.js +20 -0
  43. package/dist/extractor/parserSvelte/ParserSvelte.js +32 -0
  44. package/dist/extractor/parserSvelte/contextConstants.js +1 -0
  45. package/dist/extractor/parserSvelte/rules/scriptTag.js +26 -0
  46. package/dist/extractor/parserSvelte/rules/tComponent.js +9 -0
  47. package/dist/extractor/parserSvelte/rules/tFunction.js +7 -0
  48. package/dist/extractor/parserSvelte/rules/useTranslate.js +7 -0
  49. package/dist/extractor/parserSvelte/svelteMapper.js +39 -0
  50. package/dist/extractor/parserSvelte/svelteTreeTransform.js +38 -0
  51. package/dist/extractor/parserSvelte/tokenMergers/getTranslateMerger.js +20 -0
  52. package/dist/extractor/parserSvelte/tokenMergers/scriptTagMerger.js +20 -0
  53. package/dist/extractor/parserSvelte/tokenMergers/tComponentMerger.js +20 -0
  54. package/dist/extractor/parserSvelte/tokenMergers/tFunctionMerger.js +29 -0
  55. package/dist/extractor/parserVue/ParserVue.js +45 -0
  56. package/dist/extractor/parserVue/contextConstants.js +3 -0
  57. package/dist/extractor/parserVue/rules/exportDefaultObject.js +14 -0
  58. package/dist/extractor/parserVue/rules/globalTFunction.js +7 -0
  59. package/dist/extractor/parserVue/rules/scriptTag.js +31 -0
  60. package/dist/extractor/parserVue/rules/tComponent.js +9 -0
  61. package/dist/extractor/parserVue/rules/tFunction.js +7 -0
  62. package/dist/extractor/parserVue/rules/useTranslate.js +7 -0
  63. package/dist/extractor/parserVue/tokenMergers/exportDefaultObjectMerger.js +25 -0
  64. package/dist/extractor/parserVue/tokenMergers/globalTFunctionMerger.js +36 -0
  65. package/dist/extractor/parserVue/tokenMergers/scriptTagMerger.js +20 -0
  66. package/dist/extractor/parserVue/tokenMergers/tComponentMerger.js +20 -0
  67. package/dist/extractor/parserVue/tokenMergers/tFunctionMerger.js +37 -0
  68. package/dist/extractor/parserVue/tokenMergers/useTranslateMerger.js +20 -0
  69. package/dist/extractor/parserVue/vueMapper.js +51 -0
  70. package/dist/extractor/parserVue/vueTreeTransform.js +109 -0
  71. package/dist/extractor/runner.js +52 -4
  72. package/dist/extractor/visualizers/printTokens.js +7 -0
  73. package/dist/extractor/visualizers/tokensToString.js +28 -0
  74. package/dist/extractor/visualizers/visualizeRules.js +40 -0
  75. package/dist/extractor/warnings.js +4 -0
  76. package/dist/extractor/worker.js +10 -7
  77. package/dist/options.js +5 -0
  78. package/extractor.d.ts +8 -1
  79. package/package.json +2 -4
  80. package/schema.json +18 -6
  81. package/dist/client/internal/requester.js +0 -130
  82. package/dist/extractor/machines/comments.js +0 -78
  83. package/dist/extractor/machines/react.js +0 -705
  84. package/dist/extractor/machines/shared/comments.js +0 -79
  85. package/dist/extractor/machines/shared/properties.js +0 -380
  86. package/dist/extractor/machines/shared/translateCall.js +0 -141
  87. package/dist/extractor/machines/svelte.js +0 -429
  88. package/dist/extractor/machines/vue/decoder.js +0 -194
  89. package/dist/extractor/machines/vue/extract.js +0 -491
  90. package/dist/extractor/processors/vueSfc.js +0 -55
@@ -1,17 +1,65 @@
1
1
  import { glob } from 'glob';
2
+ import { extname } from 'path';
2
3
  import { callWorker } from './worker.js';
4
+ import { exitWithError } from '../utils/logger.js';
3
5
  export const NullNamespace = Symbol('namespace.null');
4
- export async function extractKeysFromFile(file, extractor) {
6
+ function parseVerbose(v) {
7
+ return Array.isArray(v) ? v : v ? [] : undefined;
8
+ }
9
+ export async function extractKeysFromFile(file, parserType, options, extractor) {
5
10
  return callWorker({
6
11
  extractor: extractor,
12
+ parserType,
7
13
  file: file,
14
+ options,
8
15
  });
9
16
  }
10
- export async function extractKeysOfFiles(filesPatterns, extractor) {
11
- const files = await glob(filesPatterns, { nodir: true });
17
+ export function findPossibleFrameworks(fileNames) {
18
+ const possibleFrameworks = [];
19
+ const extensions = new Set(fileNames.map((name) => extname(name)));
20
+ if (extensions.has('.jsx') || extensions.has('.tsx')) {
21
+ possibleFrameworks.push('react');
22
+ }
23
+ if (extensions.has('.vue')) {
24
+ possibleFrameworks.push('vue');
25
+ }
26
+ if (extensions.has('.svelte')) {
27
+ possibleFrameworks.push('svelte');
28
+ }
29
+ return possibleFrameworks;
30
+ }
31
+ function detectParserType(fileNames) {
32
+ const possibleFrameworks = findPossibleFrameworks(fileNames);
33
+ if (possibleFrameworks.length === 1) {
34
+ return possibleFrameworks[0];
35
+ }
36
+ else if (possibleFrameworks.length === 0) {
37
+ exitWithError("Couldn't detect which framework is used, use '--parser' or 'config.parser' option");
38
+ }
39
+ else {
40
+ exitWithError(`Detected multiple possible frameworks used (${possibleFrameworks.join(', ')}), use '--parser' or 'config.parser' options`);
41
+ }
42
+ }
43
+ export async function extractKeysOfFiles(opts) {
44
+ if (!opts.patterns?.length) {
45
+ exitWithError("Missing '--patterns' or 'config.patterns' option");
46
+ }
47
+ const files = await glob(opts.patterns, { nodir: true });
48
+ if (files.length === 0) {
49
+ exitWithError('No files were matched for extraction');
50
+ }
51
+ let parserType = opts.parser;
52
+ if (!parserType) {
53
+ parserType = detectParserType(files);
54
+ }
12
55
  const result = new Map();
56
+ const options = {
57
+ strictNamespace: Boolean(opts.strictNamespace),
58
+ defaultNamespace: opts.defaultNamespace,
59
+ verbose: parseVerbose(opts.verbose),
60
+ };
13
61
  await Promise.all(files.map(async (file) => {
14
- const keys = await extractKeysFromFile(file, extractor);
62
+ const keys = await extractKeysFromFile(file, parserType, options, opts.extractor);
15
63
  result.set(file, keys);
16
64
  }));
17
65
  return result;
@@ -0,0 +1,7 @@
1
+ export const tokensList = (tokens) => {
2
+ const result = [];
3
+ for (const t of tokens) {
4
+ result.push(`${JSON.stringify(t.token).padEnd(30)} ${t.type.padEnd(40)} ${t.customType ?? ''}`);
5
+ }
6
+ return result.join('\n');
7
+ };
@@ -0,0 +1,28 @@
1
+ import ansi from 'ansi-colors';
2
+ export function tokensToString(tokens, originalString, getColorizer) {
3
+ const result = [];
4
+ let lastIndex = 0;
5
+ let lastColorizer;
6
+ for (const token of tokens) {
7
+ const colorizer = getColorizer(token);
8
+ if (lastIndex < token.startIndex) {
9
+ if (colorizer === lastColorizer) {
10
+ result.push(colorizer(originalString.substring(lastIndex, token.startIndex)));
11
+ }
12
+ else {
13
+ result.push(ansi.grey(originalString.substring(lastIndex, token.startIndex)));
14
+ }
15
+ }
16
+ lastIndex = token.endIndex;
17
+ const fullText = originalString.substring(token.startIndex, token.endIndex);
18
+ result.push(getColorizer(token)(fullText));
19
+ }
20
+ if (lastIndex < originalString.length) {
21
+ result.push(originalString.substring(lastIndex, originalString.length));
22
+ }
23
+ return result
24
+ .join('')
25
+ .split('\n')
26
+ .map((line, index) => `${ansi.gray(String(index + 1).padEnd(3))}${line}`)
27
+ .join('\n');
28
+ }
@@ -0,0 +1,40 @@
1
+ import { tokensToString } from './tokensToString.js';
2
+ import ansi from 'ansi-colors';
3
+ const palette = [
4
+ ansi.blue,
5
+ ansi.red,
6
+ ansi.yellow,
7
+ ansi.bgBlue,
8
+ ansi.bgRed,
9
+ ansi.bgYellow,
10
+ ];
11
+ export const visualizeRules = (tokens, originalString) => {
12
+ let paletteIndex = 0;
13
+ const colors = {};
14
+ function getColor(rule) {
15
+ if (!colors[rule]) {
16
+ colors[rule] = palette[paletteIndex % palette.length];
17
+ paletteIndex += 1;
18
+ }
19
+ return colors[rule];
20
+ }
21
+ const colorized = tokensToString(tokens, originalString, (token) => {
22
+ if (token.customType) {
23
+ return getColor(token.customType);
24
+ }
25
+ else {
26
+ return ansi.white;
27
+ }
28
+ });
29
+ return (colorized +
30
+ '\n\n' +
31
+ Object.entries({
32
+ ...colors,
33
+ ...{
34
+ unknown: ansi.white,
35
+ ignored: ansi.grey,
36
+ },
37
+ })
38
+ .map(([rule, paint]) => paint(rule))
39
+ .join('\n'));
40
+ };
@@ -36,6 +36,10 @@ export const WarningMessages = {
36
36
  name: 'Vue setup function is a reference',
37
37
  description: 'The setup function must be directly defined on-site, and not be a reference to a previously defined function.',
38
38
  },
39
+ W_MISSING_T_SOURCE: {
40
+ name: 'Expected source of `t` function (useTranslate or getTranslate)',
41
+ description: "When used like this namespace can't be reliably detected so the warning is emitted, use `--no-strict-namespace` or `config.strictNamespace: false` if you don't use namespaces",
42
+ },
39
43
  };
40
44
  /**
41
45
  * Dumps warnings emitted during an extraction to stdout, with GitHub integration, and counts them.
@@ -10,15 +10,18 @@ const IS_TS_NODE = extname(import.meta.url) === '.ts';
10
10
  let loadedExtractor = Symbol('unloaded');
11
11
  let extractor;
12
12
  async function handleJob(args) {
13
- if (loadedExtractor !== args.extractor) {
14
- loadedExtractor = args.extractor;
15
- extractor = args.extractor
16
- ? await loadModule(args.extractor).then((mdl) => mdl.default)
17
- : internalExtractor;
18
- }
19
13
  const file = resolve(args.file);
20
14
  const code = await readFile(file, 'utf8');
21
- return extractor(code, file);
15
+ if (args.extractor) {
16
+ if (args.extractor !== loadedExtractor) {
17
+ loadedExtractor = args.extractor;
18
+ extractor = await loadModule(args.extractor).then((mdl) => mdl.default);
19
+ }
20
+ return extractor(code, file, args.options);
21
+ }
22
+ else {
23
+ return internalExtractor(code, file, args.parserType, args.options);
24
+ }
22
25
  }
23
26
  async function workerInit() {
24
27
  parentPort.on('message', (params) => {
package/dist/options.js CHANGED
@@ -56,3 +56,8 @@ export const FORMAT_OPT = new Option('--format <format>', 'Localization files fo
56
56
  'XLIFF_RUBY',
57
57
  ]);
58
58
  export const FILE_PATTERNS = new Option('-pt, --patterns <patterns...>', 'File glob patterns to include (hint: make sure to escape it in quotes, or your shell might attempt to unroll some tokens like *)');
59
+ export const STRICT_NAMESPACE = new Option('--strict-namespace').hideHelp(true);
60
+ export const STRICT_NAMESPACE_NEGATION = new Option('--no-strict-namespace', "No require namespace to be reachable, use if you don't use namespaces.");
61
+ export const DEFAULT_NAMESPACE = new Option('--default-namespace <namespace>', 'Default namespace used in extraction if not specified otherwise.');
62
+ export const PARSER = new Option('--parser <parser>', 'Override parser detection.').choices(['react', 'vue', 'svelte']);
63
+ export const VERBOSE = new Option('-v, --verbose [rules...]', 'Enable verbose logging. If you want more info to be logged pass an option.').choices(['extractor']);
package/extractor.d.ts CHANGED
@@ -12,7 +12,14 @@ export type Warning = {
12
12
  warning: string;
13
13
  line: number;
14
14
  };
15
- export type Extractor = (fileContents: string, fileName: string) => ExtractionResult[];
15
+ export type VerboseOption = 'extractor';
16
+ export type ExtractOptions = {
17
+ verbose?: VerboseOption[];
18
+ strictNamespace: boolean;
19
+ defaultNamespace: string | undefined;
20
+ };
21
+ export type ParserType = 'react' | 'vue' | 'svelte';
22
+ export type Extractor = (fileContents: string, fileName: string, options: ExtractOptions) => ExtractionResult;
16
23
  export type ExtractionResult = {
17
24
  keys: ExtractedKey[];
18
25
  warnings: Warning[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tolgee/cli",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "A tool to interact with the Tolgee Platform through CLI",
6
6
  "repository": {
@@ -18,7 +18,7 @@
18
18
  "test:package": "node scripts/validatePackage.js",
19
19
  "tolgee:start": "node scripts/startDocker.js",
20
20
  "tolgee:stop": "docker stop tolgee_cli_e2e",
21
- "lint": "eslint --ext .ts --ext .js --ext .cjs ./src ./scripts vitest.config.ts",
21
+ "eslint": "eslint --max-warnings 0 --ext .ts --ext .js --ext .cjs ./src ./scripts vitest.config.ts",
22
22
  "prettier": "prettier --write ./src ./scripts vitest.config.ts",
23
23
  "run-dev": "cross-env NODE_OPTIONS=\"--import=./scripts/registerTsNode.js\" node ./src/cli.ts",
24
24
  "schema": "openapi-typescript http://localhost:22222/v3/api-docs/All%20Internal%20-%20for%20Tolgee%20Web%20application --output src/client/internal/schema.generated.ts",
@@ -37,10 +37,8 @@
37
37
  "json5": "^2.2.3",
38
38
  "jsonschema": "^1.4.1",
39
39
  "openapi-fetch": "^0.9.7",
40
- "undici": "^5.22.1",
41
40
  "vscode-oniguruma": "^1.7.0",
42
41
  "vscode-textmate": "^9.0.0",
43
- "xstate": "^4.38.1",
44
42
  "yauzl": "^2.10.0"
45
43
  },
46
44
  "devDependencies": {
package/schema.json CHANGED
@@ -5,14 +5,17 @@
5
5
  "description": "Project ID. Only required when using a Personal Access Token.",
6
6
  "type": ["number", "string"]
7
7
  },
8
- "extractor": {
9
- "description": "A path to a custom extractor to use instead of the default one.",
10
- "type": "string"
11
- },
12
8
  "apiUrl": {
13
9
  "description": "The url of Tolgee API.",
14
10
  "type": "string"
15
11
  },
12
+ "format": {
13
+ "$ref": "#/$defs/format"
14
+ },
15
+ "extractor": {
16
+ "description": "A path to a custom extractor to use instead of the default one.",
17
+ "type": "string"
18
+ },
16
19
  "patterns": {
17
20
  "description": "File glob patterns to your source code, used for keys extraction.",
18
21
  "type": "array",
@@ -20,8 +23,17 @@
20
23
  "type": "string"
21
24
  }
22
25
  },
23
- "format": {
24
- "$ref": "#/$defs/format"
26
+ "strictNamespace": {
27
+ "description": "Require namespace to be reachable, turn off if you don't use namespaces. (Default: true)",
28
+ "type": "boolean"
29
+ },
30
+ "defaultNamespace": {
31
+ "description": "Default namespace used in extraction if not specified otherwise.",
32
+ "type": "string"
33
+ },
34
+ "parser": {
35
+ "description": "Override parser detection.",
36
+ "enum": ["react", "vue", "svelte"]
25
37
  },
26
38
  "push": {
27
39
  "type": "object",
@@ -1,130 +0,0 @@
1
- import { STATUS_CODES } from 'http';
2
- import { request } from 'undici';
3
- import FormData from 'form-data';
4
- import { debug } from '../../utils/logger.js';
5
- import { USER_AGENT } from '../../constants.js';
6
- export default class Requester {
7
- params;
8
- constructor(params) {
9
- this.params = params;
10
- }
11
- get projectUrl() {
12
- return `/v2/projects/${this.params.projectId}`;
13
- }
14
- /**
15
- * Performs an HTTP request to the API
16
- *
17
- * @param req Request data
18
- * @returns The response
19
- */
20
- async request(req) {
21
- const url = new URL(req.path, this.params.apiUrl);
22
- if (req.query) {
23
- for (const param in req.query) {
24
- if (param in req.query) {
25
- const val = req.query[param];
26
- if (val !== undefined) {
27
- if (Array.isArray(val)) {
28
- for (const v of val) {
29
- url.searchParams.append(param, String(v));
30
- }
31
- }
32
- else {
33
- url.searchParams.set(param, String(val));
34
- }
35
- }
36
- }
37
- }
38
- }
39
- const headers = {
40
- ...(req.headers || {}),
41
- 'user-agent': USER_AGENT,
42
- 'x-api-key': this.params.apiKey,
43
- };
44
- let body = undefined;
45
- if (req.body) {
46
- if (req.body instanceof FormData) {
47
- const header = `multipart/form-data; boundary=${req.body.getBoundary()}`;
48
- headers['content-type'] = header;
49
- body = req.body.getBuffer();
50
- }
51
- else {
52
- headers['content-type'] = 'application/json';
53
- body = JSON.stringify(req.body);
54
- }
55
- }
56
- debug(`[HTTP] Requesting: ${req.method} ${url}`);
57
- const response = await request(url, {
58
- method: req.method,
59
- headers: headers,
60
- body: body,
61
- headersTimeout: req.headersTimeout ?? 300_000,
62
- bodyTimeout: req.bodyTimeout ?? 300_000,
63
- });
64
- debug(`[HTTP] ${req.method} ${url} -> ${response.statusCode} ${STATUS_CODES[response.statusCode]}`);
65
- return response;
66
- }
67
- /**
68
- * Performs an HTTP request to the API and returns the result as a JSON object
69
- *
70
- * @param req Request data
71
- * @returns The response data
72
- */
73
- async requestJson(req) {
74
- return this.request(req).then((r) => r.body.json());
75
- }
76
- /**
77
- * Performs an HTTP request to the API and returns the result as a Blob
78
- *
79
- * @param req Request data
80
- * @returns The response blob
81
- */
82
- async requestBlob(req) {
83
- return this.request(req).then((r) => r.body.blob());
84
- }
85
- /**
86
- * Performs an HTTP request to the API.
87
- */
88
- async requestVoid(req) {
89
- await this.request(req);
90
- }
91
- /**
92
- * Performs an HTTP request to the API to a resource which is paginated.
93
- * The returned result is a view with helpers to get next (or previous) data.
94
- *
95
- * @param req Request data
96
- */
97
- async requestPaginatedResource(req) {
98
- const res = await this.requestJson(req);
99
- const _this = this;
100
- const view = {
101
- data: res._embedded,
102
- page: res.page,
103
- hasNext() {
104
- return !!res._links.next?.href;
105
- },
106
- hasPrevious() {
107
- return !!res._links.prev?.href;
108
- },
109
- async next() {
110
- if (!this.hasNext())
111
- return null;
112
- return _this.requestPaginatedResource({
113
- ...req,
114
- path: res._links.next.href,
115
- query: undefined,
116
- });
117
- },
118
- async previous() {
119
- if (!this.hasPrevious())
120
- return null;
121
- return _this.requestPaginatedResource({
122
- ...req,
123
- path: res._links.prev.href,
124
- query: undefined,
125
- });
126
- },
127
- };
128
- return view;
129
- }
130
- }
@@ -1,78 +0,0 @@
1
- import { createMachine, assign, send } from 'xstate';
2
- import commentsService from './shared/comments.js';
3
- export default createMachine({
4
- predictableActionArguments: true,
5
- id: 'commentsExtractor',
6
- context: {
7
- keys: [],
8
- warnings: [],
9
- },
10
- invoke: {
11
- id: 'comments',
12
- src: () => commentsService,
13
- },
14
- on: {
15
- // Service messages
16
- MAGIC_COMMENT: [
17
- {
18
- actions: 'warnUnusedIgnore',
19
- cond: (_ctx, evt) => evt.kind === 'ignore',
20
- },
21
- {
22
- actions: 'pushKey',
23
- cond: (_ctx, evt) => evt.kind === 'key',
24
- },
25
- ],
26
- WARNING: {
27
- actions: 'pushWarning',
28
- },
29
- // Code messages
30
- 'comment.line.double-slash.ts': {
31
- actions: send((_ctx, evt) => ({
32
- type: 'COMMENT',
33
- data: evt.token,
34
- line: evt.line,
35
- }), { to: 'comments' }),
36
- },
37
- 'comment.block.ts': {
38
- actions: send((_ctx, evt) => ({
39
- type: 'COMMENT',
40
- data: evt.token,
41
- line: evt.line,
42
- }), { to: 'comments' }),
43
- },
44
- 'comment.block.svelte': {
45
- actions: send((_ctx, evt) => ({
46
- type: 'COMMENT',
47
- data: evt.token,
48
- line: evt.line,
49
- }), { to: 'comments' }),
50
- },
51
- },
52
- }, {
53
- actions: {
54
- warnUnusedIgnore: assign({
55
- warnings: (ctx, evt) => [
56
- ...ctx.warnings,
57
- { warning: 'W_UNUSED_IGNORE', line: evt.line },
58
- ],
59
- }),
60
- pushKey: assign({
61
- keys: (ctx, evt) => [
62
- ...ctx.keys,
63
- {
64
- keyName: evt.keyName,
65
- namespace: evt.namespace,
66
- defaultValue: evt.defaultValue,
67
- line: evt.line,
68
- },
69
- ],
70
- }),
71
- pushWarning: assign({
72
- warnings: (ctx, evt) => [
73
- ...ctx.warnings,
74
- { warning: evt.kind, line: evt.line },
75
- ],
76
- }),
77
- },
78
- });