babel-plugin-formatjs 10.3.25 → 10.3.26
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/BUILD +90 -0
- package/CHANGELOG.md +1139 -0
- package/LICENSE.md +0 -0
- package/README.md +0 -0
- package/global.d.ts +0 -0
- package/index.ts +88 -0
- package/integration-tests/BUILD +21 -0
- package/integration-tests/package.json +5 -0
- package/integration-tests/vue/fixtures/App.vue +19 -0
- package/integration-tests/vue/fixtures/app.js +6 -0
- package/integration-tests/vue/integration.test.ts +62 -0
- package/package.json +5 -4
- package/tests/__snapshots__/index.test.ts.snap +1246 -0
- package/tests/fixtures/2663.js +3 -0
- package/tests/fixtures/FormattedMessage.js +14 -0
- package/tests/fixtures/additionalComponentNames.js +15 -0
- package/tests/fixtures/additionalFunctionNames.js +23 -0
- package/tests/fixtures/ast.js +45 -0
- package/tests/fixtures/defineMessage.js +57 -0
- package/tests/fixtures/defineMessages.js +49 -0
- package/tests/fixtures/descriptionsAsObjects.js +18 -0
- package/tests/fixtures/empty.js +8 -0
- package/tests/fixtures/extractFromFormatMessageCall.js +47 -0
- package/tests/fixtures/extractFromFormatMessageCallStateless.js +46 -0
- package/tests/fixtures/extractSourceLocation.js +8 -0
- package/tests/fixtures/formatMessageCall.js +38 -0
- package/tests/fixtures/icuSyntax.js +18 -0
- package/tests/fixtures/idInterpolationPattern.js +40 -0
- package/tests/fixtures/inline.js +26 -0
- package/tests/fixtures/overrideIdFn.js +48 -0
- package/tests/fixtures/preserveWhitespace.js +79 -0
- package/tests/fixtures/removeDefaultMessage.js +36 -0
- package/tests/fixtures/skipExtractionFormattedMessage.js +12 -0
- package/tests/fixtures/templateLiteral.js +21 -0
- package/tests/index.test.ts +221 -0
- package/tsconfig.json +5 -0
- package/types.ts +46 -0
- package/utils.ts +226 -0
- package/visitors/call-expression.ts +208 -0
- package/visitors/jsx-opening-element.ts +147 -0
- package/index.d.ts +0 -10
- package/index.d.ts.map +0 -1
- package/index.js +0 -74
- package/types.d.ts +0 -31
- package/types.d.ts.map +0 -1
- package/types.js +0 -2
- package/utils.d.ts +0 -34
- package/utils.d.ts.map +0 -1
- package/utils.js +0 -155
- package/visitors/call-expression.d.ts +0 -6
- package/visitors/call-expression.d.ts.map +0 -1
- package/visitors/call-expression.js +0 -127
- package/visitors/jsx-opening-element.d.ts +0 -6
- package/visitors/jsx-opening-element.d.ts.map +0 -1
- package/visitors/jsx-opening-element.js +0 -89
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {NodePath, PluginPass} from '@babel/core'
|
|
2
|
+
|
|
3
|
+
import {Options, State} from '../types'
|
|
4
|
+
import * as t from '@babel/types'
|
|
5
|
+
import {VisitNodeFunction} from '@babel/traverse'
|
|
6
|
+
import {parse} from '@formatjs/icu-messageformat-parser'
|
|
7
|
+
import {
|
|
8
|
+
createMessageDescriptor,
|
|
9
|
+
evaluateMessageDescriptor,
|
|
10
|
+
getMessageDescriptorKey,
|
|
11
|
+
storeMessage,
|
|
12
|
+
tagAsExtracted,
|
|
13
|
+
wasExtracted,
|
|
14
|
+
} from '../utils'
|
|
15
|
+
|
|
16
|
+
export const visitor: VisitNodeFunction<
|
|
17
|
+
PluginPass & State,
|
|
18
|
+
t.JSXOpeningElement
|
|
19
|
+
> = function (
|
|
20
|
+
path,
|
|
21
|
+
{
|
|
22
|
+
opts,
|
|
23
|
+
file: {
|
|
24
|
+
opts: {filename},
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
) {
|
|
28
|
+
const {
|
|
29
|
+
removeDefaultMessage,
|
|
30
|
+
idInterpolationPattern,
|
|
31
|
+
overrideIdFn,
|
|
32
|
+
ast,
|
|
33
|
+
preserveWhitespace,
|
|
34
|
+
} = opts as Options
|
|
35
|
+
|
|
36
|
+
const {componentNames, messages} = this
|
|
37
|
+
if (wasExtracted(path)) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const name = path.get('name')
|
|
42
|
+
|
|
43
|
+
if (!componentNames.find(n => name.isJSXIdentifier({name: n}))) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const attributes = path
|
|
48
|
+
.get('attributes')
|
|
49
|
+
.filter(attr => attr.isJSXAttribute())
|
|
50
|
+
|
|
51
|
+
const descriptorPath = createMessageDescriptor(
|
|
52
|
+
attributes.map(attr => [
|
|
53
|
+
attr.get('name') as NodePath<t.JSXIdentifier>,
|
|
54
|
+
attr.get('value') as
|
|
55
|
+
| NodePath<t.StringLiteral>
|
|
56
|
+
| NodePath<t.JSXExpressionContainer>,
|
|
57
|
+
])
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
// In order for a default message to be extracted when
|
|
61
|
+
// declaring a JSX element, it must be done with standard
|
|
62
|
+
// `key=value` attributes. But it's completely valid to
|
|
63
|
+
// write `<FormattedMessage {...descriptor} />`, because it will be
|
|
64
|
+
// skipped here and extracted elsewhere. The descriptor will
|
|
65
|
+
// be extracted only (storeMessage) if a `defaultMessage` prop.
|
|
66
|
+
if (!descriptorPath.defaultMessage) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Evaluate the Message Descriptor values in a JSX
|
|
71
|
+
// context, then store it.
|
|
72
|
+
const descriptor = evaluateMessageDescriptor(
|
|
73
|
+
descriptorPath,
|
|
74
|
+
true,
|
|
75
|
+
filename || undefined,
|
|
76
|
+
idInterpolationPattern,
|
|
77
|
+
overrideIdFn,
|
|
78
|
+
preserveWhitespace
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
storeMessage(
|
|
82
|
+
descriptor,
|
|
83
|
+
path,
|
|
84
|
+
opts as Options,
|
|
85
|
+
filename || undefined,
|
|
86
|
+
messages
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
let idAttr: NodePath<t.JSXAttribute> | undefined
|
|
90
|
+
let descriptionAttr: NodePath<t.JSXAttribute> | undefined
|
|
91
|
+
let defaultMessageAttr: NodePath<t.JSXAttribute> | undefined
|
|
92
|
+
const firstAttr = attributes[0]
|
|
93
|
+
for (const attr of attributes) {
|
|
94
|
+
if (!attr.isJSXAttribute()) {
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
switch (
|
|
98
|
+
getMessageDescriptorKey((attr as NodePath<t.JSXAttribute>).get('name'))
|
|
99
|
+
) {
|
|
100
|
+
case 'description':
|
|
101
|
+
descriptionAttr = attr
|
|
102
|
+
break
|
|
103
|
+
case 'defaultMessage':
|
|
104
|
+
defaultMessageAttr = attr
|
|
105
|
+
break
|
|
106
|
+
case 'id':
|
|
107
|
+
idAttr = attr
|
|
108
|
+
break
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Insert ID before removing node to prevent null node insertBefore
|
|
113
|
+
if (overrideIdFn || (descriptor.id && idInterpolationPattern)) {
|
|
114
|
+
if (idAttr) {
|
|
115
|
+
idAttr.get('value').replaceWith(t.stringLiteral(descriptor.id))
|
|
116
|
+
} else if (firstAttr) {
|
|
117
|
+
firstAttr.insertBefore(
|
|
118
|
+
t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(descriptor.id))
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (descriptionAttr) {
|
|
124
|
+
descriptionAttr.remove()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (defaultMessageAttr) {
|
|
128
|
+
if (removeDefaultMessage) {
|
|
129
|
+
defaultMessageAttr.remove()
|
|
130
|
+
} else if (ast && descriptor.defaultMessage) {
|
|
131
|
+
defaultMessageAttr
|
|
132
|
+
.get('value')
|
|
133
|
+
.replaceWith(t.jsxExpressionContainer(t.nullLiteral()))
|
|
134
|
+
const valueAttr = defaultMessageAttr.get(
|
|
135
|
+
'value'
|
|
136
|
+
) as NodePath<t.JSXExpressionContainer>
|
|
137
|
+
valueAttr
|
|
138
|
+
.get('expression')
|
|
139
|
+
.replaceWithSourceString(
|
|
140
|
+
JSON.stringify(parse(descriptor.defaultMessage))
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Tag the AST node so we don't try to extract it twice.
|
|
146
|
+
tagAsExtracted(path)
|
|
147
|
+
}
|
package/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { PluginObj, PluginPass } from '@babel/core';
|
|
2
|
-
import { ExtractedMessageDescriptor, Options } from './types';
|
|
3
|
-
export declare type ExtractionResult<M = Record<string, string>> = {
|
|
4
|
-
messages: ExtractedMessageDescriptor[];
|
|
5
|
-
meta: M;
|
|
6
|
-
};
|
|
7
|
-
export declare const DEFAULT_ID_INTERPOLATION_PATTERN = "[sha512:contenthash:base64:6]";
|
|
8
|
-
declare const _default: (api: object, options: Options | null | undefined, dirname: string) => PluginObj<PluginPass>;
|
|
9
|
-
export default _default;
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/babel-plugin-formatjs/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAE,UAAU,EAAC,MAAM,aAAa,CAAA;AAEjD,OAAO,EAAC,0BAA0B,EAAE,OAAO,EAAQ,MAAM,SAAS,CAAA;AAIlE,oBAAY,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;IACzD,QAAQ,EAAE,0BAA0B,EAAE,CAAA;IACtC,IAAI,EAAE,CAAC,CAAA;CACR,CAAA;AAED,eAAO,MAAM,gCAAgC,kCAAkC,CAAA;;AAG/E,wBAwEE"}
|
package/index.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_ID_INTERPOLATION_PATTERN = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var helper_plugin_utils_1 = require("@babel/helper-plugin-utils");
|
|
6
|
-
var plugin_syntax_jsx_1 = (0, tslib_1.__importDefault)(require("@babel/plugin-syntax-jsx"));
|
|
7
|
-
var jsx_opening_element_1 = require("./visitors/jsx-opening-element");
|
|
8
|
-
var call_expression_1 = require("./visitors/call-expression");
|
|
9
|
-
exports.DEFAULT_ID_INTERPOLATION_PATTERN = '[sha512:contenthash:base64:6]';
|
|
10
|
-
// @ts-expect-error PluginPass doesn't allow custom state but it actually does
|
|
11
|
-
exports.default = (0, helper_plugin_utils_1.declare)(function (api, options) {
|
|
12
|
-
api.assertVersion(7);
|
|
13
|
-
if (!options.idInterpolationPattern) {
|
|
14
|
-
options.idInterpolationPattern = exports.DEFAULT_ID_INTERPOLATION_PATTERN;
|
|
15
|
-
}
|
|
16
|
-
var pragma = options.pragma;
|
|
17
|
-
var componentNames = new Set(options.additionalComponentNames);
|
|
18
|
-
componentNames.add('FormattedMessage');
|
|
19
|
-
var functionNames = new Set(options.additionalFunctionNames);
|
|
20
|
-
functionNames.add('formatMessage');
|
|
21
|
-
// Vue
|
|
22
|
-
functionNames.add('$formatMessage');
|
|
23
|
-
return {
|
|
24
|
-
inherits: plugin_syntax_jsx_1.default,
|
|
25
|
-
pre: function () {
|
|
26
|
-
this.componentNames = Array.from(componentNames);
|
|
27
|
-
this.functionNames = Array.from(functionNames);
|
|
28
|
-
},
|
|
29
|
-
visitor: {
|
|
30
|
-
Program: {
|
|
31
|
-
enter: function (path) {
|
|
32
|
-
var _this = this;
|
|
33
|
-
this.messages = [];
|
|
34
|
-
this.meta = {};
|
|
35
|
-
if (!pragma) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
for (var _i = 0, _a = path.node.body; _i < _a.length; _i++) {
|
|
39
|
-
var leadingComments = _a[_i].leadingComments;
|
|
40
|
-
if (!leadingComments) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
var pragmaLineNode = leadingComments.find(function (c) {
|
|
44
|
-
return c.value.includes(pragma);
|
|
45
|
-
});
|
|
46
|
-
if (!pragmaLineNode) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
pragmaLineNode.value
|
|
50
|
-
.split(pragma)[1]
|
|
51
|
-
.trim()
|
|
52
|
-
.split(/\s+/g)
|
|
53
|
-
.forEach(function (kv) {
|
|
54
|
-
var _a = kv.split(':'), k = _a[0], v = _a[1];
|
|
55
|
-
_this.meta[k] = v;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
exit: function (_, _a) {
|
|
60
|
-
var _opts = _a.opts, filename = _a.file.opts.filename;
|
|
61
|
-
var opts = _opts;
|
|
62
|
-
if (typeof (opts === null || opts === void 0 ? void 0 : opts.onMetaExtracted) === 'function') {
|
|
63
|
-
opts.onMetaExtracted(filename || '', this.meta);
|
|
64
|
-
}
|
|
65
|
-
if (typeof (opts === null || opts === void 0 ? void 0 : opts.onMsgExtracted) === 'function') {
|
|
66
|
-
opts.onMsgExtracted(filename || '', this.messages);
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
JSXOpeningElement: jsx_opening_element_1.visitor,
|
|
71
|
-
CallExpression: call_expression_1.visitor,
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
});
|
package/types.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { NodePath } from '@babel/core';
|
|
2
|
-
import { JSXExpressionContainer, SourceLocation, StringLiteral } from '@babel/types';
|
|
3
|
-
export interface MessageDescriptor {
|
|
4
|
-
id: string;
|
|
5
|
-
defaultMessage?: string;
|
|
6
|
-
description?: string;
|
|
7
|
-
}
|
|
8
|
-
export interface State {
|
|
9
|
-
messages: ExtractedMessageDescriptor[];
|
|
10
|
-
meta: Record<string, string>;
|
|
11
|
-
componentNames: string[];
|
|
12
|
-
functionNames: string[];
|
|
13
|
-
}
|
|
14
|
-
export declare type ExtractedMessageDescriptor = MessageDescriptor & Partial<SourceLocation> & {
|
|
15
|
-
file?: string;
|
|
16
|
-
};
|
|
17
|
-
export declare type MessageDescriptorPath = Record<keyof MessageDescriptor, NodePath<StringLiteral> | NodePath<JSXExpressionContainer> | undefined>;
|
|
18
|
-
export interface Options {
|
|
19
|
-
overrideIdFn?: (id?: string, defaultMessage?: string, description?: string, filePath?: string) => string;
|
|
20
|
-
onMsgExtracted?: (filePath: string, msgs: MessageDescriptor[]) => void;
|
|
21
|
-
onMetaExtracted?: (filePath: string, meta: Record<string, string>) => void;
|
|
22
|
-
idInterpolationPattern?: string;
|
|
23
|
-
removeDefaultMessage?: boolean;
|
|
24
|
-
additionalComponentNames?: string[];
|
|
25
|
-
additionalFunctionNames?: string[];
|
|
26
|
-
pragma?: string;
|
|
27
|
-
extractSourceLocation?: boolean;
|
|
28
|
-
ast?: boolean;
|
|
29
|
-
preserveWhitespace?: boolean;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=types.d.ts.map
|
package/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/babel-plugin-formatjs/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AACpC,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,aAAa,EACd,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,0BAA0B,EAAE,CAAA;IACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,oBAAY,0BAA0B,GAAG,iBAAiB,GACxD,OAAO,CAAC,cAAc,CAAC,GAAG;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAC,CAAA;AAE3C,oBAAY,qBAAqB,GAAG,MAAM,CACxC,MAAM,iBAAiB,EACvB,QAAQ,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,sBAAsB,CAAC,GAAG,SAAS,CACvE,CAAA;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,CAAC,EAAE,CACb,EAAE,CAAC,EAAE,MAAM,EACX,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAA;IACX,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAA;IACtE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAA;IAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;IACnC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B"}
|
package/types.js
DELETED
package/utils.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as t from '@babel/types';
|
|
2
|
-
import { Options, ExtractedMessageDescriptor, MessageDescriptor, MessageDescriptorPath } from './types';
|
|
3
|
-
import { NodePath } from '@babel/core';
|
|
4
|
-
export declare function getMessageDescriptorKey(path: NodePath<any>): string;
|
|
5
|
-
export declare function createMessageDescriptor(propPaths: [
|
|
6
|
-
NodePath<t.JSXIdentifier> | NodePath<t.Identifier>,
|
|
7
|
-
NodePath<t.StringLiteral> | NodePath<t.JSXExpressionContainer>
|
|
8
|
-
][]): MessageDescriptorPath;
|
|
9
|
-
export declare function evaluateMessageDescriptor(descriptorPath: MessageDescriptorPath, isJSXSource: boolean | undefined, filename: string | undefined, idInterpolationPattern?: string, overrideIdFn?: Options['overrideIdFn'], preserveWhitespace?: Options['preserveWhitespace']): MessageDescriptor;
|
|
10
|
-
/**
|
|
11
|
-
* Tag a node as extracted
|
|
12
|
-
* Store this in the node itself so that multiple passes work. Specifically
|
|
13
|
-
* if we remove `description` in the 1st pass, 2nd pass will fail since
|
|
14
|
-
* it expect `description` to be there.
|
|
15
|
-
* HACK: We store this in the node instance since this persists across
|
|
16
|
-
* multiple plugin runs
|
|
17
|
-
* @param path
|
|
18
|
-
*/
|
|
19
|
-
export declare function tagAsExtracted(path: NodePath<any>): void;
|
|
20
|
-
/**
|
|
21
|
-
* Check if a node was extracted
|
|
22
|
-
* @param path
|
|
23
|
-
*/
|
|
24
|
-
export declare function wasExtracted(path: NodePath<any>): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Store a message in our global messages
|
|
27
|
-
* @param messageDescriptor
|
|
28
|
-
* @param path
|
|
29
|
-
* @param opts
|
|
30
|
-
* @param filename
|
|
31
|
-
* @param messages
|
|
32
|
-
*/
|
|
33
|
-
export declare function storeMessage({ id, description, defaultMessage }: MessageDescriptor, path: NodePath<any>, { extractSourceLocation }: Options, filename: string | undefined, messages: ExtractedMessageDescriptor[]): void;
|
|
34
|
-
//# sourceMappingURL=utils.d.ts.map
|
package/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../packages/babel-plugin-formatjs/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAIjC,OAAO,EACL,OAAO,EACP,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAmBpC,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,UAM1D;AA0BD,wBAAgB,uBAAuB,CACrC,SAAS,EAAE;IACT,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;IAClD,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC;CAC/D,EAAE,GACF,qBAAqB,CAmBvB;AAED,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,qBAAqB,EACrC,WAAW,qBAAQ,EACnB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,sBAAsB,CAAC,EAAE,MAAM,EAC/B,YAAY,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,qBAqCnD;AA6CD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,QAEjD;AACD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,WAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,EAAC,EAAE,EAAE,WAAW,EAAE,cAAc,EAAC,EAAE,iBAAiB,EACpD,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EACnB,EAAC,qBAAqB,EAAC,EAAE,OAAO,EAEhC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,0BAA0B,EAAE,QAgBvC"}
|
package/utils.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storeMessage = exports.wasExtracted = exports.tagAsExtracted = exports.evaluateMessageDescriptor = exports.createMessageDescriptor = exports.getMessageDescriptorKey = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
6
|
-
var ts_transformer_1 = require("@formatjs/ts-transformer");
|
|
7
|
-
var DESCRIPTOR_PROPS = new Set([
|
|
8
|
-
'id',
|
|
9
|
-
'description',
|
|
10
|
-
'defaultMessage',
|
|
11
|
-
]);
|
|
12
|
-
function evaluatePath(path) {
|
|
13
|
-
var evaluated = path.evaluate();
|
|
14
|
-
if (evaluated.confident) {
|
|
15
|
-
return evaluated.value;
|
|
16
|
-
}
|
|
17
|
-
throw path.buildCodeFrameError('[React Intl] Messages must be statically evaluate-able for extraction.');
|
|
18
|
-
}
|
|
19
|
-
function getMessageDescriptorKey(path) {
|
|
20
|
-
if (path.isIdentifier() || path.isJSXIdentifier()) {
|
|
21
|
-
return path.node.name;
|
|
22
|
-
}
|
|
23
|
-
return evaluatePath(path);
|
|
24
|
-
}
|
|
25
|
-
exports.getMessageDescriptorKey = getMessageDescriptorKey;
|
|
26
|
-
function getMessageDescriptorValue(path, isMessageNode) {
|
|
27
|
-
if (!path) {
|
|
28
|
-
return '';
|
|
29
|
-
}
|
|
30
|
-
if (path.isJSXExpressionContainer()) {
|
|
31
|
-
// If this is already compiled, no need to recompiled it
|
|
32
|
-
if (isMessageNode && path.get('expression').isArrayExpression()) {
|
|
33
|
-
return '';
|
|
34
|
-
}
|
|
35
|
-
path = path.get('expression');
|
|
36
|
-
}
|
|
37
|
-
// Always trim the Message Descriptor values.
|
|
38
|
-
var descriptorValue = evaluatePath(path);
|
|
39
|
-
return descriptorValue;
|
|
40
|
-
}
|
|
41
|
-
function createMessageDescriptor(propPaths) {
|
|
42
|
-
return propPaths.reduce(function (hash, _a) {
|
|
43
|
-
var keyPath = _a[0], valuePath = _a[1];
|
|
44
|
-
var key = getMessageDescriptorKey(keyPath);
|
|
45
|
-
if (DESCRIPTOR_PROPS.has(key)) {
|
|
46
|
-
hash[key] = valuePath;
|
|
47
|
-
}
|
|
48
|
-
return hash;
|
|
49
|
-
}, {
|
|
50
|
-
id: undefined,
|
|
51
|
-
defaultMessage: undefined,
|
|
52
|
-
description: undefined,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
exports.createMessageDescriptor = createMessageDescriptor;
|
|
56
|
-
function evaluateMessageDescriptor(descriptorPath, isJSXSource, filename, idInterpolationPattern, overrideIdFn, preserveWhitespace) {
|
|
57
|
-
if (isJSXSource === void 0) { isJSXSource = false; }
|
|
58
|
-
var id = getMessageDescriptorValue(descriptorPath.id);
|
|
59
|
-
var defaultMessage = getICUMessageValue(descriptorPath.defaultMessage, {
|
|
60
|
-
isJSXSource: isJSXSource,
|
|
61
|
-
}, preserveWhitespace);
|
|
62
|
-
var description = getMessageDescriptorValue(descriptorPath.description);
|
|
63
|
-
if (overrideIdFn) {
|
|
64
|
-
id = overrideIdFn(id, defaultMessage, description, filename);
|
|
65
|
-
}
|
|
66
|
-
else if (!id && idInterpolationPattern && defaultMessage) {
|
|
67
|
-
id = (0, ts_transformer_1.interpolateName)({ resourcePath: filename }, idInterpolationPattern, {
|
|
68
|
-
content: description
|
|
69
|
-
? "".concat(defaultMessage, "#").concat(description)
|
|
70
|
-
: defaultMessage,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
var descriptor = {
|
|
74
|
-
id: id,
|
|
75
|
-
};
|
|
76
|
-
if (description) {
|
|
77
|
-
descriptor.description = description;
|
|
78
|
-
}
|
|
79
|
-
if (defaultMessage) {
|
|
80
|
-
descriptor.defaultMessage = defaultMessage;
|
|
81
|
-
}
|
|
82
|
-
return descriptor;
|
|
83
|
-
}
|
|
84
|
-
exports.evaluateMessageDescriptor = evaluateMessageDescriptor;
|
|
85
|
-
function getICUMessageValue(messagePath, _a, preserveWhitespace) {
|
|
86
|
-
var _b = _a === void 0 ? {} : _a, _c = _b.isJSXSource, isJSXSource = _c === void 0 ? false : _c;
|
|
87
|
-
if (!messagePath) {
|
|
88
|
-
return '';
|
|
89
|
-
}
|
|
90
|
-
var message = getMessageDescriptorValue(messagePath, true);
|
|
91
|
-
if (!preserveWhitespace) {
|
|
92
|
-
message = message.trim().replace(/\s+/gm, ' ');
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
(0, icu_messageformat_parser_1.parse)(message);
|
|
96
|
-
}
|
|
97
|
-
catch (parseError) {
|
|
98
|
-
if (isJSXSource &&
|
|
99
|
-
messagePath.isLiteral() &&
|
|
100
|
-
message.indexOf('\\\\') >= 0) {
|
|
101
|
-
throw messagePath.buildCodeFrameError('[React Intl] Message failed to parse. ' +
|
|
102
|
-
'It looks like `\\`s were used for escaping, ' +
|
|
103
|
-
"this won't work with JSX string literals. " +
|
|
104
|
-
'Wrap with `{}`. ' +
|
|
105
|
-
'See: http://facebook.github.io/react/docs/jsx-gotchas.html');
|
|
106
|
-
}
|
|
107
|
-
throw messagePath.buildCodeFrameError('[React Intl] Message failed to parse. ' +
|
|
108
|
-
'See: https://formatjs.io/docs/core-concepts/icu-syntax' +
|
|
109
|
-
"\n".concat(parseError));
|
|
110
|
-
}
|
|
111
|
-
return message;
|
|
112
|
-
}
|
|
113
|
-
var EXTRACTED = Symbol('FormatJSExtracted');
|
|
114
|
-
/**
|
|
115
|
-
* Tag a node as extracted
|
|
116
|
-
* Store this in the node itself so that multiple passes work. Specifically
|
|
117
|
-
* if we remove `description` in the 1st pass, 2nd pass will fail since
|
|
118
|
-
* it expect `description` to be there.
|
|
119
|
-
* HACK: We store this in the node instance since this persists across
|
|
120
|
-
* multiple plugin runs
|
|
121
|
-
* @param path
|
|
122
|
-
*/
|
|
123
|
-
function tagAsExtracted(path) {
|
|
124
|
-
path.node[EXTRACTED] = true;
|
|
125
|
-
}
|
|
126
|
-
exports.tagAsExtracted = tagAsExtracted;
|
|
127
|
-
/**
|
|
128
|
-
* Check if a node was extracted
|
|
129
|
-
* @param path
|
|
130
|
-
*/
|
|
131
|
-
function wasExtracted(path) {
|
|
132
|
-
return !!path.node[EXTRACTED];
|
|
133
|
-
}
|
|
134
|
-
exports.wasExtracted = wasExtracted;
|
|
135
|
-
/**
|
|
136
|
-
* Store a message in our global messages
|
|
137
|
-
* @param messageDescriptor
|
|
138
|
-
* @param path
|
|
139
|
-
* @param opts
|
|
140
|
-
* @param filename
|
|
141
|
-
* @param messages
|
|
142
|
-
*/
|
|
143
|
-
function storeMessage(_a, path, _b, filename, messages) {
|
|
144
|
-
var id = _a.id, description = _a.description, defaultMessage = _a.defaultMessage;
|
|
145
|
-
var extractSourceLocation = _b.extractSourceLocation;
|
|
146
|
-
if (!id && !defaultMessage) {
|
|
147
|
-
throw path.buildCodeFrameError('[React Intl] Message Descriptors require an `id` or `defaultMessage`.');
|
|
148
|
-
}
|
|
149
|
-
var loc = {};
|
|
150
|
-
if (extractSourceLocation) {
|
|
151
|
-
loc = (0, tslib_1.__assign)({ file: filename }, path.node.loc);
|
|
152
|
-
}
|
|
153
|
-
messages.push((0, tslib_1.__assign)({ id: id, description: description, defaultMessage: defaultMessage }, loc));
|
|
154
|
-
}
|
|
155
|
-
exports.storeMessage = storeMessage;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { PluginPass } from '@babel/core';
|
|
2
|
-
import * as t from '@babel/types';
|
|
3
|
-
import { State } from '../types';
|
|
4
|
-
import { VisitNodeFunction } from '@babel/traverse';
|
|
5
|
-
export declare const visitor: VisitNodeFunction<PluginPass & State, t.CallExpression>;
|
|
6
|
-
//# sourceMappingURL=call-expression.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"call-expression.d.ts","sourceRoot":"","sources":["../../../../../../packages/babel-plugin-formatjs/visitors/call-expression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AACjC,OAAO,EAAU,KAAK,EAAC,MAAM,UAAU,CAAA;AACvC,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAA;AAoDjD,eAAO,MAAM,OAAO,EAAE,iBAAiB,CAAC,UAAU,GAAG,KAAK,EAAE,CAAC,CAAC,cAAc,CAwJzE,CAAA"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.visitor = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var t = (0, tslib_1.__importStar)(require("@babel/types"));
|
|
6
|
-
var utils_1 = require("../utils");
|
|
7
|
-
var icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
8
|
-
function assertObjectExpression(path, callee) {
|
|
9
|
-
if (!path || !path.isObjectExpression()) {
|
|
10
|
-
throw path.buildCodeFrameError("[React Intl] `".concat(callee.get('property').node.name, "()` must be called with an object expression with values that are React Intl Message Descriptors, also defined as object expressions."));
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
function isFormatMessageCall(callee, functionNames) {
|
|
14
|
-
if (functionNames.find(function (name) { return callee.isIdentifier({ name: name }); })) {
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
if (callee.isMemberExpression()) {
|
|
18
|
-
var property_1 = callee.get('property');
|
|
19
|
-
return !!functionNames.find(function (name) { return property_1.isIdentifier({ name: name }); });
|
|
20
|
-
}
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
function getMessagesObjectFromExpression(nodePath) {
|
|
24
|
-
var currentPath = nodePath;
|
|
25
|
-
while (t.isTSAsExpression(currentPath.node) ||
|
|
26
|
-
t.isTSTypeAssertion(currentPath.node) ||
|
|
27
|
-
t.isTypeCastExpression(currentPath.node)) {
|
|
28
|
-
currentPath = currentPath.get('expression');
|
|
29
|
-
}
|
|
30
|
-
return currentPath;
|
|
31
|
-
}
|
|
32
|
-
var visitor = function (path, _a) {
|
|
33
|
-
var opts = _a.opts, filename = _a.file.opts.filename;
|
|
34
|
-
var _b = opts, overrideIdFn = _b.overrideIdFn, idInterpolationPattern = _b.idInterpolationPattern, removeDefaultMessage = _b.removeDefaultMessage, ast = _b.ast, preserveWhitespace = _b.preserveWhitespace;
|
|
35
|
-
if ((0, utils_1.wasExtracted)(path)) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
var _c = this, messages = _c.messages, functionNames = _c.functionNames;
|
|
39
|
-
var callee = path.get('callee');
|
|
40
|
-
var args = path.get('arguments');
|
|
41
|
-
/**
|
|
42
|
-
* Process MessageDescriptor
|
|
43
|
-
* @param messageDescriptor Message Descriptor
|
|
44
|
-
*/
|
|
45
|
-
function processMessageObject(messageDescriptor) {
|
|
46
|
-
var _a, _b;
|
|
47
|
-
assertObjectExpression(messageDescriptor, callee);
|
|
48
|
-
var properties = messageDescriptor.get('properties');
|
|
49
|
-
var descriptorPath = (0, utils_1.createMessageDescriptor)(properties.map(function (prop) {
|
|
50
|
-
return [prop.get('key'), prop.get('value')];
|
|
51
|
-
}));
|
|
52
|
-
// If the message is already compiled, don't re-compile it
|
|
53
|
-
if ((_a = descriptorPath.defaultMessage) === null || _a === void 0 ? void 0 : _a.isArrayExpression()) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
// Evaluate the Message Descriptor values, then store it.
|
|
57
|
-
var descriptor = (0, utils_1.evaluateMessageDescriptor)(descriptorPath, false, filename || undefined, idInterpolationPattern, overrideIdFn, preserveWhitespace);
|
|
58
|
-
(0, utils_1.storeMessage)(descriptor, messageDescriptor, opts, filename || undefined, messages);
|
|
59
|
-
var firstProp = properties[0];
|
|
60
|
-
var defaultMessageProp = properties.find(function (prop) {
|
|
61
|
-
var keyProp = prop.get('key');
|
|
62
|
-
return (keyProp.isIdentifier({ name: 'defaultMessage' }) ||
|
|
63
|
-
keyProp.isStringLiteral({ value: 'defaultMessage' }));
|
|
64
|
-
});
|
|
65
|
-
var idProp = properties.find(function (prop) {
|
|
66
|
-
var keyProp = prop.get('key');
|
|
67
|
-
return (keyProp.isIdentifier({ name: 'id' }) ||
|
|
68
|
-
keyProp.isStringLiteral({ value: 'id' }));
|
|
69
|
-
});
|
|
70
|
-
// Insert ID potentially 1st before removing nodes
|
|
71
|
-
if (idProp) {
|
|
72
|
-
idProp.get('value').replaceWith(t.stringLiteral(descriptor.id));
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
firstProp.insertBefore(t.objectProperty(t.identifier('id'), t.stringLiteral(descriptor.id)));
|
|
76
|
-
}
|
|
77
|
-
// Remove description
|
|
78
|
-
(_b = properties
|
|
79
|
-
.find(function (prop) {
|
|
80
|
-
var keyProp = prop.get('key');
|
|
81
|
-
return (keyProp.isIdentifier({ name: 'description' }) ||
|
|
82
|
-
keyProp.isStringLiteral({ value: 'description' }));
|
|
83
|
-
})) === null || _b === void 0 ? void 0 : _b.remove();
|
|
84
|
-
// Pre-parse or remove defaultMessage
|
|
85
|
-
if (defaultMessageProp) {
|
|
86
|
-
if (removeDefaultMessage) {
|
|
87
|
-
defaultMessageProp === null || defaultMessageProp === void 0 ? void 0 : defaultMessageProp.remove();
|
|
88
|
-
}
|
|
89
|
-
else if (descriptor.defaultMessage) {
|
|
90
|
-
var valueProp = defaultMessageProp.get('value');
|
|
91
|
-
if (ast) {
|
|
92
|
-
valueProp.replaceWithSourceString(JSON.stringify((0, icu_messageformat_parser_1.parse)(descriptor.defaultMessage)));
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
valueProp.replaceWith(t.stringLiteral(descriptor.defaultMessage));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
(0, utils_1.tagAsExtracted)(path);
|
|
100
|
-
}
|
|
101
|
-
// Check that this is `defineMessages` call
|
|
102
|
-
if (callee.isIdentifier({ name: 'defineMessages' }) ||
|
|
103
|
-
callee.isIdentifier({ name: 'defineMessage' })) {
|
|
104
|
-
var firstArgument = args[0];
|
|
105
|
-
var messagesObj = getMessagesObjectFromExpression(firstArgument);
|
|
106
|
-
assertObjectExpression(messagesObj, callee);
|
|
107
|
-
if (callee.isIdentifier({ name: 'defineMessage' })) {
|
|
108
|
-
processMessageObject(messagesObj);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
var properties = messagesObj.get('properties');
|
|
112
|
-
if (Array.isArray(properties)) {
|
|
113
|
-
properties
|
|
114
|
-
.map(function (prop) { return prop.get('value'); })
|
|
115
|
-
.forEach(processMessageObject);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Check that this is `intl.formatMessage` call
|
|
120
|
-
if (isFormatMessageCall(callee, functionNames)) {
|
|
121
|
-
var messageDescriptor = args[0];
|
|
122
|
-
if (messageDescriptor.isObjectExpression()) {
|
|
123
|
-
processMessageObject(messageDescriptor);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
exports.visitor = visitor;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { PluginPass } from '@babel/core';
|
|
2
|
-
import { State } from '../types';
|
|
3
|
-
import * as t from '@babel/types';
|
|
4
|
-
import { VisitNodeFunction } from '@babel/traverse';
|
|
5
|
-
export declare const visitor: VisitNodeFunction<PluginPass & State, t.JSXOpeningElement>;
|
|
6
|
-
//# sourceMappingURL=jsx-opening-element.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-opening-element.d.ts","sourceRoot":"","sources":["../../../../../../packages/babel-plugin-formatjs/visitors/jsx-opening-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAC,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAU,KAAK,EAAC,MAAM,UAAU,CAAA;AACvC,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AACjC,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAA;AAWjD,eAAO,MAAM,OAAO,EAAE,iBAAiB,CACrC,UAAU,GAAG,KAAK,EAClB,CAAC,CAAC,iBAAiB,CAiIpB,CAAA"}
|