@swc/plugin-formatjs 3.2.1 → 3.2.3
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/CHANGELOG.md +12 -0
- package/README.md +12 -0
- package/package.json +1 -1
- package/src/lib.rs +1 -1
- package/swc_plugin_formatjs.wasm +0 -0
- package/Cargo.toml +0 -24
- package/__tests__/wasm.test.ts +0 -286
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -4,6 +4,18 @@ FormatJS SWC plugin, maintained by SWC team.
|
|
|
4
4
|
|
|
5
5
|
# @swc/plugin-formatjs
|
|
6
6
|
|
|
7
|
+
## 3.2.2
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 5ddbaeb: Update swc_core to v23
|
|
12
|
+
|
|
13
|
+
## 3.2.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 1abaa28: fix(formatjs): Sort description objects before serialization
|
|
18
|
+
|
|
7
19
|
## 3.2.0
|
|
8
20
|
|
|
9
21
|
### Minor Changes
|
package/package.json
CHANGED
package/src/lib.rs
CHANGED
|
@@ -16,7 +16,7 @@ pub fn process(mut program: Program, metadata: TransformPluginProgramMetadata) -
|
|
|
16
16
|
let plugin_options: FormatJSPluginOptions = if let Some(plugin_config) = plugin_config {
|
|
17
17
|
serde_json::from_str(&plugin_config).unwrap_or_else(|f| {
|
|
18
18
|
println!("Could not deserialize instrumentation option");
|
|
19
|
-
println!("{:#?}"
|
|
19
|
+
println!("{f:#?}");
|
|
20
20
|
Default::default()
|
|
21
21
|
})
|
|
22
22
|
} else {
|
package/swc_plugin_formatjs.wasm
CHANGED
|
Binary file
|
package/Cargo.toml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
authors = [
|
|
3
|
-
"OJ Kwon <kwon.ohjoong@gmail.com>",
|
|
4
|
-
"DongYoon Kang <kdy1997.dev@gmail.com>",
|
|
5
|
-
]
|
|
6
|
-
description = "formatjs plugin for SWC"
|
|
7
|
-
edition = { workspace = true }
|
|
8
|
-
license = { workspace = true }
|
|
9
|
-
name = "swc_plugin_formatjs"
|
|
10
|
-
publish = false
|
|
11
|
-
repository = { workspace = true }
|
|
12
|
-
version = "1.0.0"
|
|
13
|
-
|
|
14
|
-
[lib]
|
|
15
|
-
crate-type = ["cdylib"]
|
|
16
|
-
|
|
17
|
-
[dependencies]
|
|
18
|
-
serde = { workspace = true }
|
|
19
|
-
serde_json = { workspace = true }
|
|
20
|
-
swc_core = { workspace = true, features = [
|
|
21
|
-
"ecma_plugin_transform",
|
|
22
|
-
"ecma_ast_serde",
|
|
23
|
-
] }
|
|
24
|
-
swc_formatjs_transform = { path = "./transform", version = "4.0.0" }
|
package/__tests__/wasm.test.ts
DELETED
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { transform } from "@swc/core";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import url from "node:url";
|
|
5
|
-
|
|
6
|
-
const transformCode = async (code: string, options = {}) => {
|
|
7
|
-
const result = await transform(code, {
|
|
8
|
-
jsc: {
|
|
9
|
-
parser: {
|
|
10
|
-
syntax: "typescript",
|
|
11
|
-
tsx: true,
|
|
12
|
-
},
|
|
13
|
-
experimental: {
|
|
14
|
-
plugins: [
|
|
15
|
-
[
|
|
16
|
-
path.join(
|
|
17
|
-
path.dirname(url.fileURLToPath(import.meta.url)),
|
|
18
|
-
"..",
|
|
19
|
-
"swc_plugin_formatjs.wasm",
|
|
20
|
-
),
|
|
21
|
-
options,
|
|
22
|
-
],
|
|
23
|
-
],
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
return result.code;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
describe("formatjs swc plugin", () => {
|
|
31
|
-
it("should transform FormattedMessage component", async () => {
|
|
32
|
-
const input = `
|
|
33
|
-
import React from 'react';
|
|
34
|
-
import { FormattedMessage } from 'react-intl';
|
|
35
|
-
|
|
36
|
-
export function Greeting() {
|
|
37
|
-
return (
|
|
38
|
-
<FormattedMessage
|
|
39
|
-
defaultMessage="Hello, {name}!"
|
|
40
|
-
description="Greeting message"
|
|
41
|
-
/>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
`;
|
|
45
|
-
|
|
46
|
-
const output = await transformCode(input);
|
|
47
|
-
|
|
48
|
-
expect(output).toMatch(/id: \".+\"/);
|
|
49
|
-
expect(output).toMatch(/defaultMessage: "Hello, \{name\}!"/);
|
|
50
|
-
expect(output).not.toMatch(/description/);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("should transform defineMessage function", async () => {
|
|
54
|
-
const input = `
|
|
55
|
-
import { defineMessage } from 'react-intl';
|
|
56
|
-
|
|
57
|
-
const message = defineMessage({
|
|
58
|
-
defaultMessage: "Welcome to {site}",
|
|
59
|
-
description: "Welcome message"
|
|
60
|
-
});
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
const output = await transformCode(input);
|
|
64
|
-
|
|
65
|
-
expect(output).toMatch(/id: "[^"]+"/);
|
|
66
|
-
expect(output).toMatch(/defaultMessage: "Welcome to \{site\}"/);
|
|
67
|
-
expect(output).not.toMatch(/description/);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("should transform multiple messages in defineMessages", async () => {
|
|
71
|
-
const input = `
|
|
72
|
-
import { defineMessages } from 'react-intl';
|
|
73
|
-
|
|
74
|
-
const messages = defineMessages({
|
|
75
|
-
greeting: {
|
|
76
|
-
defaultMessage: "Hello",
|
|
77
|
-
description: "Greeting"
|
|
78
|
-
},
|
|
79
|
-
farewell: {
|
|
80
|
-
defaultMessage: "Goodbye",
|
|
81
|
-
description: "Farewell"
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
`;
|
|
85
|
-
|
|
86
|
-
const output = await transformCode(input);
|
|
87
|
-
|
|
88
|
-
const idMatches = output.match(/id:/g);
|
|
89
|
-
expect(idMatches).toHaveLength(2);
|
|
90
|
-
|
|
91
|
-
expect(output).toMatch(/defaultMessage: "Hello"/);
|
|
92
|
-
expect(output).toMatch(/defaultMessage: "Goodbye"/);
|
|
93
|
-
|
|
94
|
-
expect(output).not.toMatch(/description/);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should handle formatMessage calls", async () => {
|
|
98
|
-
const input = `
|
|
99
|
-
import { useIntl } from 'react-intl';
|
|
100
|
-
|
|
101
|
-
function MyComponent() {
|
|
102
|
-
const intl = useIntl();
|
|
103
|
-
return intl.formatMessage({
|
|
104
|
-
defaultMessage: "Click here",
|
|
105
|
-
description: "Button text"
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
`;
|
|
109
|
-
|
|
110
|
-
const output = await transformCode(input);
|
|
111
|
-
|
|
112
|
-
expect(output).toMatch(/id: "[^"]+"/);
|
|
113
|
-
expect(output).toMatch(/defaultMessage: "Click here"/);
|
|
114
|
-
expect(output).not.toMatch(/description/);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("should preserve whitespace when option is enabled", async () => {
|
|
118
|
-
const input = `
|
|
119
|
-
import { FormattedMessage } from 'react-intl';
|
|
120
|
-
|
|
121
|
-
export function Greeting() {
|
|
122
|
-
return (
|
|
123
|
-
<FormattedMessage
|
|
124
|
-
defaultMessage="Hello, {name}!"
|
|
125
|
-
description="Greeting message"
|
|
126
|
-
/>
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
`;
|
|
130
|
-
|
|
131
|
-
const output = await transformCode(input, {
|
|
132
|
-
preserve_whitespace: true,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
expect(output).toMatch(/defaultMessage: "Hello, {4}\{name\}!"/);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("should use custom id interpolation pattern", async () => {
|
|
139
|
-
const input = `
|
|
140
|
-
import { FormattedMessage } from 'react-intl';
|
|
141
|
-
|
|
142
|
-
export function Greeting() {
|
|
143
|
-
return (
|
|
144
|
-
<FormattedMessage
|
|
145
|
-
defaultMessage="Hello, {name}!"
|
|
146
|
-
description="Greeting message"
|
|
147
|
-
/>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
`;
|
|
151
|
-
|
|
152
|
-
const output = await transformCode(input, {
|
|
153
|
-
idInterpolationPattern: "[name]_[hash:base64:5]",
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
expect(output).toMatch(/id: "file_[a-zA-Z0-9]{5}"/);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it("should handle additional component names", async () => {
|
|
160
|
-
const input = `
|
|
161
|
-
import { CustomMessage } from './custom-intl';
|
|
162
|
-
|
|
163
|
-
export function Greeting() {
|
|
164
|
-
return (
|
|
165
|
-
<CustomMessage
|
|
166
|
-
defaultMessage="Hello, {name}!"
|
|
167
|
-
description="Greeting message"
|
|
168
|
-
/>
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
`;
|
|
172
|
-
|
|
173
|
-
const output = await transformCode(input, {
|
|
174
|
-
additionalComponentNames: ["CustomMessage"],
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
expect(output).toMatch(/id: "[^"]+"/);
|
|
178
|
-
expect(output).toMatch(/defaultMessage: "Hello, \{name\}!"/);
|
|
179
|
-
expect(output).not.toMatch(/description/);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("should be able to use sha1 and sha512 hashing in interpolation", async () => {
|
|
183
|
-
const input = `
|
|
184
|
-
import { FormattedMessage } from 'react-intl';
|
|
185
|
-
|
|
186
|
-
export function Greeting() {
|
|
187
|
-
return (
|
|
188
|
-
<FormattedMessage
|
|
189
|
-
defaultMessage="Hello!"
|
|
190
|
-
description="Greeting message"
|
|
191
|
-
/>
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
`;
|
|
195
|
-
|
|
196
|
-
const sha1output = await transformCode(input, {
|
|
197
|
-
idInterpolationPattern: "[sha1:contenthash:base64:6]",
|
|
198
|
-
});
|
|
199
|
-
const sha512output = await transformCode(input, {
|
|
200
|
-
idInterpolationPattern: "[sha512:contenthash:base64:6]",
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
expect(sha1output).toMatch(/id: "[a-zA-Z0-9]{6}"/);
|
|
204
|
-
expect(sha512output).toMatch(/id: "[a-zA-Z0-9]{6}"/);
|
|
205
|
-
expect(sha1output).not.toMatch(sha512output);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it("should be able to use object description", async () => {
|
|
209
|
-
const input = `
|
|
210
|
-
import { FormattedMessage } from 'react-intl';
|
|
211
|
-
|
|
212
|
-
export function Greeting() {
|
|
213
|
-
return (
|
|
214
|
-
<FormattedMessage
|
|
215
|
-
defaultMessage="Hello!"
|
|
216
|
-
description={{ text: "Greeting message" }}
|
|
217
|
-
/>
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
`;
|
|
221
|
-
|
|
222
|
-
console.log(input);
|
|
223
|
-
const output = await transformCode(input);
|
|
224
|
-
|
|
225
|
-
expect(output).toMatch(/id: "zL\/jyT\"/);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it("should generate same id even if order of keys is different in two description objects with same keys", async () => {
|
|
229
|
-
const input = `
|
|
230
|
-
import { FormattedMessage } from 'react-intl';
|
|
231
|
-
|
|
232
|
-
export function Greeting() {
|
|
233
|
-
return (
|
|
234
|
-
<FormattedMessage
|
|
235
|
-
defaultMessage="Hello!"
|
|
236
|
-
description={{ text: "Greeting message", image: "https://example.com/image.png" }}
|
|
237
|
-
/>
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
`;
|
|
241
|
-
|
|
242
|
-
const input2 = `
|
|
243
|
-
import { FormattedMessage } from 'react-intl';
|
|
244
|
-
|
|
245
|
-
export function Greeting() {
|
|
246
|
-
return (
|
|
247
|
-
<FormattedMessage
|
|
248
|
-
defaultMessage="Hello!"
|
|
249
|
-
description={{ image: "https://example.com/image.png", text: "Greeting message" }}
|
|
250
|
-
/>
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
`;
|
|
254
|
-
|
|
255
|
-
const output = await transformCode(input);
|
|
256
|
-
const output2 = await transformCode(input2);
|
|
257
|
-
|
|
258
|
-
expect(output).toMatch(output2);
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it("should be able to use different encodings in interpolation", async () => {
|
|
262
|
-
const input = `
|
|
263
|
-
import { FormattedMessage } from 'react-intl';
|
|
264
|
-
|
|
265
|
-
export function Greeting() {
|
|
266
|
-
return (
|
|
267
|
-
<FormattedMessage
|
|
268
|
-
defaultMessage="Hello, World!"
|
|
269
|
-
description="Greeting message"
|
|
270
|
-
/>
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
`;
|
|
274
|
-
|
|
275
|
-
const hexOutput = await transformCode(input, {
|
|
276
|
-
idInterpolationPattern: "[sha512:contenthash:hex:9]",
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
const base64UrlOutput = await transformCode(input, {
|
|
280
|
-
idInterpolationPattern: "[sha512:contenthash:base64url:12]",
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
expect(hexOutput).toMatch(/id: "[0-9a-f]{9}"/);
|
|
284
|
-
expect(base64UrlOutput).toMatch(/id: "[a-zA-Z0-9-_]{12}"/);
|
|
285
|
-
});
|
|
286
|
-
});
|