1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.getExports = getExports;
|
7 | exports.renderExports = renderExports;
|
8 | function forError(item) {
|
9 | return typeof item === "string" ? item : `\n${JSON.stringify(item, null, " ")}\n`;
|
10 | }
|
11 | function splitCommand(command) {
|
12 | const result = command.split("|").map(item => item.split(" ")).reduce((acc, val) => acc.concat(val), []);
|
13 | for (const item of result) {
|
14 | if (!item) {
|
15 | throw new Error(`Invalid command "${item}" in "${command}" for exports. There must be only one separator: " ", or "|"`);
|
16 | }
|
17 | }
|
18 | return result;
|
19 | }
|
20 | function resolveExports(type, item) {
|
21 | let result;
|
22 | if (typeof item === "string") {
|
23 | const noWhitespaceItem = item.trim();
|
24 | if (noWhitespaceItem.length === 0) {
|
25 | throw new Error(`Invalid "${item}" value for export`);
|
26 | }
|
27 | const splittedItem = splitCommand(noWhitespaceItem);
|
28 | if (splittedItem.length > 3) {
|
29 | throw new Error(`Invalid "${item}" value for export`);
|
30 | }
|
31 | if (splittedItem.length === 1) {
|
32 | result = {
|
33 | syntax: type === "module" ? "named" : "multiple",
|
34 | name: splittedItem[0],
|
35 |
|
36 | alias: undefined
|
37 | };
|
38 | } else {
|
39 | result = {
|
40 | syntax: splittedItem[0],
|
41 | name: splittedItem[1],
|
42 | alias:
|
43 |
|
44 | typeof splittedItem[2] !== "undefined" ? splittedItem[2] : undefined
|
45 | };
|
46 | }
|
47 | } else {
|
48 | result = {
|
49 | syntax: type === "module" ? "named" : "multiple",
|
50 | ...item
|
51 | };
|
52 | }
|
53 | if (!["default", "named", "single", "multiple"].includes(result.syntax)) {
|
54 | throw new Error(`Unknown "${result.syntax}" syntax export in "${forError(item)}" value`);
|
55 | }
|
56 | if (["default", "single"].includes(result.syntax) && typeof result.alias !== "undefined") {
|
57 | throw new Error(`The "${result.syntax}" syntax can't have "${result.alias}" alias in "${forError(item)}" value`);
|
58 | }
|
59 | if (type === "commonjs") {
|
60 | if (result.syntax === "default" || result.syntax === "named") {
|
61 | throw new Error(`The "${type}" format can't be used with the "${result.syntax}" syntax export in "${forError(item)}" value`);
|
62 | }
|
63 | }
|
64 | if (type === "module") {
|
65 | if (result.syntax === "single" || result.syntax === "multiple") {
|
66 | throw new Error(`The "${type}" format can't be used with the "${result.syntax}" syntax export in "${forError(item)}" value`);
|
67 | }
|
68 | }
|
69 | return result;
|
70 | }
|
71 | function getIdentifiers(array) {
|
72 | return array.reduce((accumulator, item) => {
|
73 | if (typeof item.alias !== "undefined") {
|
74 | accumulator.push({
|
75 | type: "alias",
|
76 | value: item.alias
|
77 | });
|
78 | return accumulator;
|
79 | }
|
80 | accumulator.push({
|
81 | type: "name",
|
82 | value: item.name
|
83 | });
|
84 | return accumulator;
|
85 | }, []);
|
86 | }
|
87 | function getExports(type, exports) {
|
88 | let result;
|
89 | const exportItems = typeof exports === "string" && exports.includes(",") ? exports.split(",") : exports;
|
90 | if (Array.isArray(exportItems)) {
|
91 | result = exportItems.map(item => resolveExports(type, item));
|
92 | } else {
|
93 | result = [resolveExports(type, exportItems)];
|
94 | }
|
95 | const hasMultipleDefault = result.filter(({
|
96 | syntax
|
97 | }) => syntax === "default" || syntax === "single");
|
98 | if (hasMultipleDefault.length > 1) {
|
99 | throw new Error(`The "${type}" format can't have multiple "${type === "module" ? "default" : "single"}" exports in "\n${JSON.stringify(exports, null, " ")}\n" value`);
|
100 | }
|
101 | const identifiers = getIdentifiers(result);
|
102 | const duplicates = duplicateBy(identifiers, "value");
|
103 | if (duplicates.length > 0) {
|
104 | throw new Error(`Duplicate ${duplicates.map(identifier => `"${identifier.value}" (as "${identifier.type}")`).join(", ")} identifiers found in "\n${JSON.stringify(exports, null, " ")}\n" value`);
|
105 | }
|
106 | return result;
|
107 | }
|
108 | function duplicateBy(array, key) {
|
109 | return array.filter((a, aIndex) => array.filter((b, bIndex) => b[key] === a[key] && aIndex !== bIndex).length > 0);
|
110 | }
|
111 | function renderExports(loaderContext, type, exports) {
|
112 | let code = "";
|
113 | const defaultExport = exports.filter(({
|
114 | syntax
|
115 | }) => syntax === "default" || syntax === "single");
|
116 | const namedExports = exports.filter(({
|
117 | syntax
|
118 | }) => syntax === "named" || syntax === "multiple");
|
119 | if (defaultExport.length > 0) {
|
120 |
|
121 | switch (type) {
|
122 | case "commonjs":
|
123 | code += "module.exports = ";
|
124 | break;
|
125 | case "module":
|
126 | code += "export default ";
|
127 | break;
|
128 | }
|
129 | code += `${defaultExport[0].name};\n`;
|
130 | }
|
131 | if (namedExports.length > 0) {
|
132 |
|
133 | switch (type) {
|
134 | case "commonjs":
|
135 | code += "module.exports = {\n";
|
136 | break;
|
137 | case "module":
|
138 | code += "export {\n";
|
139 | break;
|
140 | }
|
141 | namedExports.forEach((namedExport, i) => {
|
142 | const needComma = i < namedExports.length - 1;
|
143 | const {
|
144 | name
|
145 | } = namedExport;
|
146 |
|
147 | const alias = namedExport.alias || undefined;
|
148 | code += ` ${type === "commonjs" ? alias ? `${JSON.stringify(alias)}: (${name})` : `${name}` : `${name}${alias ? ` as ${alias}` : ""}`}${needComma ? ",\n" : ""}`;
|
149 | });
|
150 | code += "\n};\n";
|
151 | }
|
152 | return code;
|
153 | } |
\ | No newline at end of file |