@intlify/bundle-utils 9.0.0 → 11.0.0-beta.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/lib/index.cjs CHANGED
@@ -5,9 +5,10 @@ const shared = require('@intlify/shared');
5
5
  const sourceMapJs = require('source-map-js');
6
6
  const messageCompiler = require('@intlify/message-compiler');
7
7
  const yamlEslintParser = require('yaml-eslint-parser');
8
- const acorn = require('acorn');
9
8
  const escodegen = require('escodegen');
10
9
  const estreeWalker = require('estree-walker');
10
+ const acorn = require('acorn');
11
+ const core = require('@babel/core');
11
12
  const module$1 = require('node:module');
12
13
 
13
14
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -749,6 +750,8 @@ function _generate$1(generator, node, options = {}) {
749
750
  return codeMaps;
750
751
  }
751
752
 
753
+ class DynamicResourceError extends Error {
754
+ }
752
755
  function generate(targetSource, {
753
756
  type = "plain",
754
757
  filename = "vue-i18n-loader.js",
@@ -759,13 +762,14 @@ function generate(targetSource, {
759
762
  env = "development",
760
763
  forceStringify = false,
761
764
  onError = void 0,
765
+ onWarn = void 0,
762
766
  strictMessage = true,
763
767
  escapeHtml = false,
764
768
  allowDynamic = false,
765
769
  jit = false
766
770
  }) {
767
771
  const target = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource;
768
- const value = target;
772
+ let value = target;
769
773
  const options = {
770
774
  type,
771
775
  source: value,
@@ -777,11 +781,28 @@ function generate(targetSource, {
777
781
  filename,
778
782
  forceStringify,
779
783
  onError,
784
+ onWarn,
780
785
  strictMessage,
781
786
  escapeHtml,
782
787
  jit
783
788
  };
784
789
  const generator = createCodeGenerator(options);
790
+ if (options.filename && /.[c|m]?ts$/.test(options.filename)) {
791
+ const transformed = core.transform(value, {
792
+ filename: options.filename,
793
+ sourceMaps: options.sourceMap,
794
+ babelrc: false,
795
+ configFile: false,
796
+ browserslistConfigFile: false,
797
+ comments: false,
798
+ envName: "development",
799
+ presets: ["@babel/preset-typescript"]
800
+ });
801
+ if (transformed && transformed.code) {
802
+ value = transformed.code;
803
+ options.source = transformed.code;
804
+ }
805
+ }
785
806
  const ast = acorn.parse(value, {
786
807
  ecmaVersion: "latest",
787
808
  sourceType: "module",
@@ -790,11 +811,16 @@ function generate(targetSource, {
790
811
  });
791
812
  const exportResult = scanAst(ast);
792
813
  if (!allowDynamic) {
793
- if (!exportResult || exportResult !== "object") {
814
+ if (!exportResult) {
794
815
  throw new Error(
795
816
  `You need to define an object as the locale message with 'export default'.`
796
817
  );
797
818
  }
819
+ if (exportResult !== "object") {
820
+ throw new DynamicResourceError(
821
+ `You need to define an object as the locale message with 'export default'.`
822
+ );
823
+ }
798
824
  } else {
799
825
  if (!exportResult) {
800
826
  throw new Error(
@@ -822,22 +848,19 @@ function scanAst(ast) {
822
848
  if (ast.type !== "Program") {
823
849
  throw new Error("Invalid AST: does not have Program node");
824
850
  }
825
- let ret = false;
826
851
  for (const node of ast.body) {
827
- if (node.type === "ExportDefaultDeclaration") {
828
- if (node.declaration.type === "ObjectExpression") {
829
- ret = "object";
830
- break;
831
- } else if (node.declaration.type === "FunctionDeclaration") {
832
- ret = "function";
833
- break;
834
- } else if (node.declaration.type === "ArrowFunctionExpression") {
835
- ret = "arrow-function";
836
- break;
837
- }
852
+ if (node.type !== "ExportDefaultDeclaration")
853
+ continue;
854
+ switch (node.declaration.type) {
855
+ case "ObjectExpression":
856
+ return "object";
857
+ case "FunctionDeclaration":
858
+ return "function";
859
+ case "ArrowFunctionExpression":
860
+ return "arrow-function";
838
861
  }
839
862
  }
840
- return ret;
863
+ return false;
841
864
  }
842
865
  function _generate(generator, node, options = {}) {
843
866
  const propsCountStack = [];
@@ -849,6 +872,42 @@ function _generate(generator, node, options = {}) {
849
872
  const { type, sourceMap, isGlobal, locale, jit } = options;
850
873
  const codegenFn = jit ? generateResourceAst : generateMessageFunction;
851
874
  const componentNamespace = "_Component";
875
+ const variableDeclarations = [];
876
+ estreeWalker.walk(node, {
877
+ /**
878
+ * NOTE:
879
+ * force cast to Node of `estree-walker@3.x`,
880
+ * because `estree-walker@3.x` is not dual packages,
881
+ * so it's support only esm only ...
882
+ */
883
+ // @ts-ignore
884
+ enter(node2, _parent) {
885
+ if (_parent?.type != null)
886
+ this.skip();
887
+ switch (node2.type) {
888
+ case "ExportDefaultDeclaration":
889
+ this.skip();
890
+ break;
891
+ case "ImportDeclaration":
892
+ generator.push(options.source?.slice(node2.start, node2.end));
893
+ generator.newline();
894
+ break;
895
+ case "VariableDeclaration":
896
+ generator.push(options.source?.slice(node2.start, node2.end));
897
+ generator.newline();
898
+ variableDeclarations.push(
899
+ ...node2.declarations.map((x) => `\`${x.id.name}\``)
900
+ );
901
+ break;
902
+ }
903
+ }
904
+ });
905
+ if (variableDeclarations.length > 0) {
906
+ options?.onWarn?.(
907
+ `
908
+ Variable declarations are not optimized - found ${variableDeclarations.join(", ")}`
909
+ );
910
+ }
852
911
  estreeWalker.walk(node, {
853
912
  /**
854
913
  * NOTE:
@@ -858,20 +917,24 @@ function _generate(generator, node, options = {}) {
858
917
  */
859
918
  // @ts-ignore
860
919
  enter(node2, parent) {
920
+ if (parent?.type === "Program") {
921
+ switch (node2.type) {
922
+ case "ImportDeclaration":
923
+ case "VariableDeclaration":
924
+ case "VariableDeclarator":
925
+ this.skip();
926
+ }
927
+ }
861
928
  switch (node2.type) {
862
929
  case "Program":
863
930
  if (type === "plain") {
864
931
  generator.push(`const resource = `);
865
932
  } else if (type === "sfc") {
866
933
  const variableName = type === "sfc" ? !isGlobal ? "__i18n" : "__i18nGlobal" : "";
867
- const localeName = type === "sfc" ? locale != null ? locale : `""` : "";
868
- const exportSyntax = "export default";
869
- generator.push(`${exportSyntax} function (Component) {`);
934
+ const localeName = type === "sfc" ? locale ?? `""` : "";
935
+ generator.push(`export default function (Component) {`);
870
936
  generator.indent();
871
- const componentVariable = `Component`;
872
- generator.pushline(
873
- `const ${componentNamespace} = ${componentVariable}`
874
- );
937
+ generator.pushline(`const ${componentNamespace} = Component`);
875
938
  generator.pushline(
876
939
  `${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
877
940
  );
@@ -885,7 +948,7 @@ function _generate(generator, node, options = {}) {
885
948
  generator.push(`{`);
886
949
  generator.indent();
887
950
  propsCountStack.push(node2.properties.length);
888
- if (parent != null && parent.type === "ArrayExpression") {
951
+ if (parent?.type === "ArrayExpression") {
889
952
  const lastIndex = itemsCountStack.length - 1;
890
953
  const currentCount = parent.elements.length - itemsCountStack[lastIndex];
891
954
  pathStack.push(currentCount.toString());
@@ -893,50 +956,54 @@ function _generate(generator, node, options = {}) {
893
956
  }
894
957
  break;
895
958
  case "Property":
896
- if (parent != null && parent.type === "ObjectExpression") {
897
- if (node2 != null) {
898
- if (isJSONablePrimitiveLiteral(node2.value) && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
899
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
900
- if (node2.value.type === "Literal" && shared.isString(node2.value.value) || node2.value.type === "TemplateLiteral") {
901
- const value = getValue(node2.value);
902
- generator.push(`${JSON.stringify(name)}: `);
903
- pathStack.push(name);
904
- const { code, map } = codegenFn(value, options, pathStack);
905
- sourceMap && map != null && codeMaps.set(value, map);
906
- generator.push(`${code}`, node2.value, value);
907
- skipStack.push(false);
959
+ if (parent?.type === "ObjectExpression") {
960
+ if (isJSONablePrimitiveLiteral(node2.value) && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
961
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
962
+ if (node2.value.type === "Literal" && shared.isString(node2.value.value) || node2.value.type === "TemplateLiteral") {
963
+ const value = getValue(node2.value);
964
+ generator.push(`${JSON.stringify(name2)}: `);
965
+ pathStack.push(name2);
966
+ const { code, map } = codegenFn(value, options, pathStack);
967
+ sourceMap && map != null && codeMaps.set(value, map);
968
+ generator.push(`${code}`, node2.value, value);
969
+ skipStack.push(false);
970
+ } else {
971
+ const value = getValue(node2.value);
972
+ if (forceStringify) {
973
+ const strValue = JSON.stringify(value);
974
+ generator.push(`${JSON.stringify(name2)}: `);
975
+ pathStack.push(name2);
976
+ const { code, map } = codegenFn(strValue, options, pathStack);
977
+ sourceMap && map != null && codeMaps.set(strValue, map);
978
+ generator.push(`${code}`, node2.value, strValue);
908
979
  } else {
909
- const value = getValue(node2.value);
910
- if (forceStringify) {
911
- const strValue = JSON.stringify(value);
912
- generator.push(`${JSON.stringify(name)}: `);
913
- pathStack.push(name);
914
- const { code, map } = codegenFn(
915
- strValue,
916
- options,
917
- pathStack
918
- );
919
- sourceMap && map != null && codeMaps.set(strValue, map);
920
- generator.push(`${code}`, node2.value, strValue);
921
- } else {
922
- generator.push(
923
- `${JSON.stringify(name)}: ${JSON.stringify(value)}`
924
- );
925
- pathStack.push(name);
926
- }
927
- skipStack.push(false);
980
+ generator.push(
981
+ `${JSON.stringify(name2)}: ${JSON.stringify(value)}`
982
+ );
983
+ pathStack.push(name2);
928
984
  }
929
- } else if ((node2.value.type === "FunctionExpression" || node2.value.type === "ArrowFunctionExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
930
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
931
- generator.push(`${JSON.stringify(name)}: `);
932
- pathStack.push(name);
933
- const code = escodegen.generate(node2.value);
934
- generator.push(`${code}`, node2.value, code);
935
985
  skipStack.push(false);
936
- } else if ((node2.value.type === "ObjectExpression" || node2.value.type === "ArrayExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
937
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
938
- generator.push(`${JSON.stringify(name)}: `);
939
- pathStack.push(name);
986
+ }
987
+ } else if ((node2.value.type === "FunctionExpression" || node2.value.type === "ArrowFunctionExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
988
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
989
+ generator.push(`${JSON.stringify(name2)}: `);
990
+ pathStack.push(name2);
991
+ const code = escodegen.generate(node2.value, {
992
+ format: { compact: true }
993
+ });
994
+ generator.push(`${code}`, node2.value, code);
995
+ skipStack.push(false);
996
+ } else if ((node2.value.type === "ObjectExpression" || node2.value.type === "ArrayExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
997
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
998
+ generator.push(`${JSON.stringify(name2)}: `);
999
+ pathStack.push(name2);
1000
+ } else {
1001
+ const skipProperty = "regex" in node2.value;
1002
+ if (!skipProperty && node2.type === "Property") {
1003
+ const name2 = node2.key.type === "Identifier" && String(node2.key.name) || node2.key.type === "Literal" && String(node2.key.value);
1004
+ const name22 = node2.value.type === "Identifier" && String(node2.value.name) || node2.value.type === "Literal" && String(node2.value.value);
1005
+ generator.push(`${JSON.stringify(name2)}: ${name22 || name2}`);
1006
+ skipStack.push(false);
940
1007
  } else {
941
1008
  skipStack.push(true);
942
1009
  }
@@ -948,7 +1015,7 @@ function _generate(generator, node, options = {}) {
948
1015
  case "ArrayExpression":
949
1016
  generator.push(`[`);
950
1017
  generator.indent();
951
- if (parent != null && parent.type === "ArrayExpression") {
1018
+ if (parent?.type === "ArrayExpression") {
952
1019
  const lastIndex = itemsCountStack.length - 1;
953
1020
  const currentCount = parent.elements.length - itemsCountStack[lastIndex];
954
1021
  pathStack.push(currentCount.toString());
@@ -956,39 +1023,37 @@ function _generate(generator, node, options = {}) {
956
1023
  }
957
1024
  itemsCountStack.push(node2.elements.length);
958
1025
  break;
1026
+ case "SpreadElement":
1027
+ const name = node2.argument.type === "Identifier" && String(node2.argument.name) || node2.argument.type === "Literal" && String(node2.argument.value);
1028
+ generator.push(`...${name}`);
1029
+ break;
959
1030
  default:
960
- if (node2 != null && parent != null) {
961
- if (parent.type === "ArrayExpression") {
962
- const lastIndex = itemsCountStack.length - 1;
963
- const currentCount = parent.elements.length - itemsCountStack[lastIndex];
964
- pathStack.push(currentCount.toString());
965
- if (isJSONablePrimitiveLiteral(node2)) {
966
- if (node2.type === "Literal" && shared.isString(node2.value) || node2.type === "TemplateLiteral") {
967
- const value = getValue(node2);
968
- const { code, map } = codegenFn(value, options, pathStack);
969
- sourceMap && map != null && codeMaps.set(value, map);
970
- generator.push(`${code}`, node2, value);
1031
+ if (parent?.type === "ArrayExpression") {
1032
+ const lastIndex = itemsCountStack.length - 1;
1033
+ const currentCount = parent.elements.length - itemsCountStack[lastIndex];
1034
+ pathStack.push(currentCount.toString());
1035
+ if (isJSONablePrimitiveLiteral(node2)) {
1036
+ if (node2.type === "Literal" && shared.isString(node2.value) || node2.type === "TemplateLiteral") {
1037
+ const value = getValue(node2);
1038
+ const { code, map } = codegenFn(value, options, pathStack);
1039
+ sourceMap && map != null && codeMaps.set(value, map);
1040
+ generator.push(`${code}`, node2, value);
1041
+ } else {
1042
+ const value = getValue(node2);
1043
+ if (forceStringify) {
1044
+ const strValue = JSON.stringify(value);
1045
+ const { code, map } = codegenFn(strValue, options, pathStack);
1046
+ sourceMap && map != null && codeMaps.set(strValue, map);
1047
+ generator.push(`${code}`, node2, strValue);
971
1048
  } else {
972
- const value = getValue(node2);
973
- if (forceStringify) {
974
- const strValue = JSON.stringify(value);
975
- const { code, map } = codegenFn(
976
- strValue,
977
- options,
978
- pathStack
979
- );
980
- sourceMap && map != null && codeMaps.set(strValue, map);
981
- generator.push(`${code}`, node2, strValue);
982
- } else {
983
- generator.push(`${JSON.stringify(value)}`);
984
- }
1049
+ generator.push(`${JSON.stringify(value)}`);
985
1050
  }
986
- skipStack.push(false);
987
- } else {
988
- skipStack.push(true);
989
1051
  }
990
- itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
1052
+ skipStack.push(false);
1053
+ } else {
1054
+ skipStack.push(true);
991
1055
  }
1056
+ itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
992
1057
  }
993
1058
  break;
994
1059
  }
@@ -1021,15 +1086,17 @@ function _generate(generator, node, options = {}) {
1021
1086
  }
1022
1087
  generator.deindent();
1023
1088
  generator.push(`}`);
1024
- if (parent != null && parent.type === "ArrayExpression") {
1089
+ if (parent?.type === "ArrayExpression") {
1025
1090
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1026
1091
  pathStack.pop();
1027
- generator.pushline(`,`);
1092
+ if (!skipStack.pop()) {
1093
+ generator.pushline(`,`);
1094
+ }
1028
1095
  }
1029
1096
  }
1030
1097
  break;
1031
1098
  case "Property":
1032
- if (parent != null && parent.type === "ObjectExpression") {
1099
+ if (parent?.type === "ObjectExpression") {
1033
1100
  if (propsCountStack[propsCountStack.length - 1] !== 0) {
1034
1101
  pathStack.pop();
1035
1102
  if (!skipStack.pop()) {
@@ -1045,7 +1112,7 @@ function _generate(generator, node, options = {}) {
1045
1112
  }
1046
1113
  generator.deindent();
1047
1114
  generator.push(`]`);
1048
- if (parent != null && parent.type === "ArrayExpression") {
1115
+ if (parent?.type === "ArrayExpression") {
1049
1116
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1050
1117
  pathStack.pop();
1051
1118
  if (!skipStack.pop()) {
@@ -1055,16 +1122,12 @@ function _generate(generator, node, options = {}) {
1055
1122
  }
1056
1123
  break;
1057
1124
  case "Literal":
1058
- if (parent != null && parent.type === "ArrayExpression") {
1125
+ if (parent?.type === "ArrayExpression") {
1059
1126
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1060
1127
  pathStack.pop();
1061
- if (!skipStack.pop()) {
1062
- generator.pushline(`,`);
1063
- }
1064
- } else {
1065
- if (!skipStack.pop()) {
1066
- generator.pushline(`,`);
1067
- }
1128
+ }
1129
+ if (!skipStack.pop()) {
1130
+ generator.pushline(`,`);
1068
1131
  }
1069
1132
  }
1070
1133
  break;
@@ -1128,6 +1191,7 @@ function loadModule(moduleName, debug) {
1128
1191
  }
1129
1192
  }
1130
1193
 
1194
+ exports.DynamicResourceError = DynamicResourceError;
1131
1195
  exports.checkInstallPackage = checkInstallPackage;
1132
1196
  exports.generateJSON = generate$2;
1133
1197
  exports.generateJavaScript = generate;
package/lib/index.d.cts CHANGED
@@ -15,8 +15,6 @@ type DevEnv = 'development' | 'production';
15
15
  */
16
16
  interface CodeGenOptions {
17
17
  type?: 'plain' | 'sfc' | 'bare';
18
- legacy?: boolean;
19
- bridge?: boolean;
20
18
  exportESM?: boolean;
21
19
  onlyLocales?: string[];
22
20
  source?: string;
@@ -68,14 +66,16 @@ declare function generate$1(targetSource: string | Buffer, { type, onlyLocales,
68
66
  * Code generator for i18n js resource
69
67
  */
70
68
 
69
+ declare class DynamicResourceError extends Error {
70
+ }
71
71
  /**
72
72
  * @internal
73
73
  */
74
- declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
74
+ declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, onWarn, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
75
75
 
76
76
  type InstalledPackage = 'vue-i18n' | 'petite-vue-i18n';
77
77
  declare function checkInstallPackage(pkg: string, debug: Function): InstalledPackage;
78
78
  type VueI18nVersion = '9' | '10' | 'unknown' | '';
79
79
  declare function getVueI18nVersion(debug: Function, pkg?: string): VueI18nVersion;
80
80
 
81
- export { type CodeGenOptions, type CodeGenResult, type DevEnv, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
81
+ export { type CodeGenOptions, type CodeGenResult, type DevEnv, DynamicResourceError, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
package/lib/index.d.mts CHANGED
@@ -15,8 +15,6 @@ type DevEnv = 'development' | 'production';
15
15
  */
16
16
  interface CodeGenOptions {
17
17
  type?: 'plain' | 'sfc' | 'bare';
18
- legacy?: boolean;
19
- bridge?: boolean;
20
18
  exportESM?: boolean;
21
19
  onlyLocales?: string[];
22
20
  source?: string;
@@ -68,14 +66,16 @@ declare function generate$1(targetSource: string | Buffer, { type, onlyLocales,
68
66
  * Code generator for i18n js resource
69
67
  */
70
68
 
69
+ declare class DynamicResourceError extends Error {
70
+ }
71
71
  /**
72
72
  * @internal
73
73
  */
74
- declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
74
+ declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, onWarn, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
75
75
 
76
76
  type InstalledPackage = 'vue-i18n' | 'petite-vue-i18n';
77
77
  declare function checkInstallPackage(pkg: string, debug: Function): InstalledPackage;
78
78
  type VueI18nVersion = '9' | '10' | 'unknown' | '';
79
79
  declare function getVueI18nVersion(debug: Function, pkg?: string): VueI18nVersion;
80
80
 
81
- export { type CodeGenOptions, type CodeGenResult, type DevEnv, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
81
+ export { type CodeGenOptions, type CodeGenResult, type DevEnv, DynamicResourceError, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
package/lib/index.d.ts CHANGED
@@ -15,8 +15,6 @@ type DevEnv = 'development' | 'production';
15
15
  */
16
16
  interface CodeGenOptions {
17
17
  type?: 'plain' | 'sfc' | 'bare';
18
- legacy?: boolean;
19
- bridge?: boolean;
20
18
  exportESM?: boolean;
21
19
  onlyLocales?: string[];
22
20
  source?: string;
@@ -68,14 +66,16 @@ declare function generate$1(targetSource: string | Buffer, { type, onlyLocales,
68
66
  * Code generator for i18n js resource
69
67
  */
70
68
 
69
+ declare class DynamicResourceError extends Error {
70
+ }
71
71
  /**
72
72
  * @internal
73
73
  */
74
- declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
74
+ declare function generate(targetSource: string | Buffer, { type, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, onWarn, strictMessage, escapeHtml, allowDynamic, jit }: CodeGenOptions): CodeGenResult<Node>;
75
75
 
76
76
  type InstalledPackage = 'vue-i18n' | 'petite-vue-i18n';
77
77
  declare function checkInstallPackage(pkg: string, debug: Function): InstalledPackage;
78
78
  type VueI18nVersion = '9' | '10' | 'unknown' | '';
79
79
  declare function getVueI18nVersion(debug: Function, pkg?: string): VueI18nVersion;
80
80
 
81
- export { type CodeGenOptions, type CodeGenResult, type DevEnv, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
81
+ export { type CodeGenOptions, type CodeGenResult, type DevEnv, DynamicResourceError, type InstalledPackage, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
package/lib/index.mjs CHANGED
@@ -3,9 +3,10 @@ import { isBoolean, format, escapeHtml, friendlyJSONstringify, isString, isNumbe
3
3
  import { SourceMapGenerator, SourceMapConsumer } from 'source-map-js';
4
4
  import { LOCATION_STUB, detectHtmlTag, baseCompile } from '@intlify/message-compiler';
5
5
  import { parseYAML, getStaticYAMLValue, traverseNodes as traverseNodes$1 } from 'yaml-eslint-parser';
6
- import { parse } from 'acorn';
7
6
  import { generate as generate$3 } from 'escodegen';
8
7
  import { walk } from 'estree-walker';
8
+ import { parse } from 'acorn';
9
+ import { transform } from '@babel/core';
9
10
  import module from 'node:module';
10
11
 
11
12
  function createCodeGenerator(options = {
@@ -742,6 +743,8 @@ function _generate$1(generator, node, options = {}) {
742
743
  return codeMaps;
743
744
  }
744
745
 
746
+ class DynamicResourceError extends Error {
747
+ }
745
748
  function generate(targetSource, {
746
749
  type = "plain",
747
750
  filename = "vue-i18n-loader.js",
@@ -752,13 +755,14 @@ function generate(targetSource, {
752
755
  env = "development",
753
756
  forceStringify = false,
754
757
  onError = void 0,
758
+ onWarn = void 0,
755
759
  strictMessage = true,
756
760
  escapeHtml = false,
757
761
  allowDynamic = false,
758
762
  jit = false
759
763
  }) {
760
764
  const target = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource;
761
- const value = target;
765
+ let value = target;
762
766
  const options = {
763
767
  type,
764
768
  source: value,
@@ -770,11 +774,28 @@ function generate(targetSource, {
770
774
  filename,
771
775
  forceStringify,
772
776
  onError,
777
+ onWarn,
773
778
  strictMessage,
774
779
  escapeHtml,
775
780
  jit
776
781
  };
777
782
  const generator = createCodeGenerator(options);
783
+ if (options.filename && /.[c|m]?ts$/.test(options.filename)) {
784
+ const transformed = transform(value, {
785
+ filename: options.filename,
786
+ sourceMaps: options.sourceMap,
787
+ babelrc: false,
788
+ configFile: false,
789
+ browserslistConfigFile: false,
790
+ comments: false,
791
+ envName: "development",
792
+ presets: ["@babel/preset-typescript"]
793
+ });
794
+ if (transformed && transformed.code) {
795
+ value = transformed.code;
796
+ options.source = transformed.code;
797
+ }
798
+ }
778
799
  const ast = parse(value, {
779
800
  ecmaVersion: "latest",
780
801
  sourceType: "module",
@@ -783,11 +804,16 @@ function generate(targetSource, {
783
804
  });
784
805
  const exportResult = scanAst(ast);
785
806
  if (!allowDynamic) {
786
- if (!exportResult || exportResult !== "object") {
807
+ if (!exportResult) {
787
808
  throw new Error(
788
809
  `You need to define an object as the locale message with 'export default'.`
789
810
  );
790
811
  }
812
+ if (exportResult !== "object") {
813
+ throw new DynamicResourceError(
814
+ `You need to define an object as the locale message with 'export default'.`
815
+ );
816
+ }
791
817
  } else {
792
818
  if (!exportResult) {
793
819
  throw new Error(
@@ -815,22 +841,19 @@ function scanAst(ast) {
815
841
  if (ast.type !== "Program") {
816
842
  throw new Error("Invalid AST: does not have Program node");
817
843
  }
818
- let ret = false;
819
844
  for (const node of ast.body) {
820
- if (node.type === "ExportDefaultDeclaration") {
821
- if (node.declaration.type === "ObjectExpression") {
822
- ret = "object";
823
- break;
824
- } else if (node.declaration.type === "FunctionDeclaration") {
825
- ret = "function";
826
- break;
827
- } else if (node.declaration.type === "ArrowFunctionExpression") {
828
- ret = "arrow-function";
829
- break;
830
- }
845
+ if (node.type !== "ExportDefaultDeclaration")
846
+ continue;
847
+ switch (node.declaration.type) {
848
+ case "ObjectExpression":
849
+ return "object";
850
+ case "FunctionDeclaration":
851
+ return "function";
852
+ case "ArrowFunctionExpression":
853
+ return "arrow-function";
831
854
  }
832
855
  }
833
- return ret;
856
+ return false;
834
857
  }
835
858
  function _generate(generator, node, options = {}) {
836
859
  const propsCountStack = [];
@@ -842,6 +865,42 @@ function _generate(generator, node, options = {}) {
842
865
  const { type, sourceMap, isGlobal, locale, jit } = options;
843
866
  const codegenFn = jit ? generateResourceAst : generateMessageFunction;
844
867
  const componentNamespace = "_Component";
868
+ const variableDeclarations = [];
869
+ walk(node, {
870
+ /**
871
+ * NOTE:
872
+ * force cast to Node of `estree-walker@3.x`,
873
+ * because `estree-walker@3.x` is not dual packages,
874
+ * so it's support only esm only ...
875
+ */
876
+ // @ts-ignore
877
+ enter(node2, _parent) {
878
+ if (_parent?.type != null)
879
+ this.skip();
880
+ switch (node2.type) {
881
+ case "ExportDefaultDeclaration":
882
+ this.skip();
883
+ break;
884
+ case "ImportDeclaration":
885
+ generator.push(options.source?.slice(node2.start, node2.end));
886
+ generator.newline();
887
+ break;
888
+ case "VariableDeclaration":
889
+ generator.push(options.source?.slice(node2.start, node2.end));
890
+ generator.newline();
891
+ variableDeclarations.push(
892
+ ...node2.declarations.map((x) => `\`${x.id.name}\``)
893
+ );
894
+ break;
895
+ }
896
+ }
897
+ });
898
+ if (variableDeclarations.length > 0) {
899
+ options?.onWarn?.(
900
+ `
901
+ Variable declarations are not optimized - found ${variableDeclarations.join(", ")}`
902
+ );
903
+ }
845
904
  walk(node, {
846
905
  /**
847
906
  * NOTE:
@@ -851,20 +910,24 @@ function _generate(generator, node, options = {}) {
851
910
  */
852
911
  // @ts-ignore
853
912
  enter(node2, parent) {
913
+ if (parent?.type === "Program") {
914
+ switch (node2.type) {
915
+ case "ImportDeclaration":
916
+ case "VariableDeclaration":
917
+ case "VariableDeclarator":
918
+ this.skip();
919
+ }
920
+ }
854
921
  switch (node2.type) {
855
922
  case "Program":
856
923
  if (type === "plain") {
857
924
  generator.push(`const resource = `);
858
925
  } else if (type === "sfc") {
859
926
  const variableName = type === "sfc" ? !isGlobal ? "__i18n" : "__i18nGlobal" : "";
860
- const localeName = type === "sfc" ? locale != null ? locale : `""` : "";
861
- const exportSyntax = "export default";
862
- generator.push(`${exportSyntax} function (Component) {`);
927
+ const localeName = type === "sfc" ? locale ?? `""` : "";
928
+ generator.push(`export default function (Component) {`);
863
929
  generator.indent();
864
- const componentVariable = `Component`;
865
- generator.pushline(
866
- `const ${componentNamespace} = ${componentVariable}`
867
- );
930
+ generator.pushline(`const ${componentNamespace} = Component`);
868
931
  generator.pushline(
869
932
  `${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
870
933
  );
@@ -878,7 +941,7 @@ function _generate(generator, node, options = {}) {
878
941
  generator.push(`{`);
879
942
  generator.indent();
880
943
  propsCountStack.push(node2.properties.length);
881
- if (parent != null && parent.type === "ArrayExpression") {
944
+ if (parent?.type === "ArrayExpression") {
882
945
  const lastIndex = itemsCountStack.length - 1;
883
946
  const currentCount = parent.elements.length - itemsCountStack[lastIndex];
884
947
  pathStack.push(currentCount.toString());
@@ -886,50 +949,54 @@ function _generate(generator, node, options = {}) {
886
949
  }
887
950
  break;
888
951
  case "Property":
889
- if (parent != null && parent.type === "ObjectExpression") {
890
- if (node2 != null) {
891
- if (isJSONablePrimitiveLiteral(node2.value) && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
892
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
893
- if (node2.value.type === "Literal" && isString(node2.value.value) || node2.value.type === "TemplateLiteral") {
894
- const value = getValue(node2.value);
895
- generator.push(`${JSON.stringify(name)}: `);
896
- pathStack.push(name);
897
- const { code, map } = codegenFn(value, options, pathStack);
898
- sourceMap && map != null && codeMaps.set(value, map);
899
- generator.push(`${code}`, node2.value, value);
900
- skipStack.push(false);
952
+ if (parent?.type === "ObjectExpression") {
953
+ if (isJSONablePrimitiveLiteral(node2.value) && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
954
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
955
+ if (node2.value.type === "Literal" && isString(node2.value.value) || node2.value.type === "TemplateLiteral") {
956
+ const value = getValue(node2.value);
957
+ generator.push(`${JSON.stringify(name2)}: `);
958
+ pathStack.push(name2);
959
+ const { code, map } = codegenFn(value, options, pathStack);
960
+ sourceMap && map != null && codeMaps.set(value, map);
961
+ generator.push(`${code}`, node2.value, value);
962
+ skipStack.push(false);
963
+ } else {
964
+ const value = getValue(node2.value);
965
+ if (forceStringify) {
966
+ const strValue = JSON.stringify(value);
967
+ generator.push(`${JSON.stringify(name2)}: `);
968
+ pathStack.push(name2);
969
+ const { code, map } = codegenFn(strValue, options, pathStack);
970
+ sourceMap && map != null && codeMaps.set(strValue, map);
971
+ generator.push(`${code}`, node2.value, strValue);
901
972
  } else {
902
- const value = getValue(node2.value);
903
- if (forceStringify) {
904
- const strValue = JSON.stringify(value);
905
- generator.push(`${JSON.stringify(name)}: `);
906
- pathStack.push(name);
907
- const { code, map } = codegenFn(
908
- strValue,
909
- options,
910
- pathStack
911
- );
912
- sourceMap && map != null && codeMaps.set(strValue, map);
913
- generator.push(`${code}`, node2.value, strValue);
914
- } else {
915
- generator.push(
916
- `${JSON.stringify(name)}: ${JSON.stringify(value)}`
917
- );
918
- pathStack.push(name);
919
- }
920
- skipStack.push(false);
973
+ generator.push(
974
+ `${JSON.stringify(name2)}: ${JSON.stringify(value)}`
975
+ );
976
+ pathStack.push(name2);
921
977
  }
922
- } else if ((node2.value.type === "FunctionExpression" || node2.value.type === "ArrowFunctionExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
923
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
924
- generator.push(`${JSON.stringify(name)}: `);
925
- pathStack.push(name);
926
- const code = generate$3(node2.value);
927
- generator.push(`${code}`, node2.value, code);
928
978
  skipStack.push(false);
929
- } else if ((node2.value.type === "ObjectExpression" || node2.value.type === "ArrayExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
930
- const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
931
- generator.push(`${JSON.stringify(name)}: `);
932
- pathStack.push(name);
979
+ }
980
+ } else if ((node2.value.type === "FunctionExpression" || node2.value.type === "ArrowFunctionExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
981
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
982
+ generator.push(`${JSON.stringify(name2)}: `);
983
+ pathStack.push(name2);
984
+ const code = generate$3(node2.value, {
985
+ format: { compact: true }
986
+ });
987
+ generator.push(`${code}`, node2.value, code);
988
+ skipStack.push(false);
989
+ } else if ((node2.value.type === "ObjectExpression" || node2.value.type === "ArrayExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
990
+ const name2 = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
991
+ generator.push(`${JSON.stringify(name2)}: `);
992
+ pathStack.push(name2);
993
+ } else {
994
+ const skipProperty = "regex" in node2.value;
995
+ if (!skipProperty && node2.type === "Property") {
996
+ const name2 = node2.key.type === "Identifier" && String(node2.key.name) || node2.key.type === "Literal" && String(node2.key.value);
997
+ const name22 = node2.value.type === "Identifier" && String(node2.value.name) || node2.value.type === "Literal" && String(node2.value.value);
998
+ generator.push(`${JSON.stringify(name2)}: ${name22 || name2}`);
999
+ skipStack.push(false);
933
1000
  } else {
934
1001
  skipStack.push(true);
935
1002
  }
@@ -941,7 +1008,7 @@ function _generate(generator, node, options = {}) {
941
1008
  case "ArrayExpression":
942
1009
  generator.push(`[`);
943
1010
  generator.indent();
944
- if (parent != null && parent.type === "ArrayExpression") {
1011
+ if (parent?.type === "ArrayExpression") {
945
1012
  const lastIndex = itemsCountStack.length - 1;
946
1013
  const currentCount = parent.elements.length - itemsCountStack[lastIndex];
947
1014
  pathStack.push(currentCount.toString());
@@ -949,39 +1016,37 @@ function _generate(generator, node, options = {}) {
949
1016
  }
950
1017
  itemsCountStack.push(node2.elements.length);
951
1018
  break;
1019
+ case "SpreadElement":
1020
+ const name = node2.argument.type === "Identifier" && String(node2.argument.name) || node2.argument.type === "Literal" && String(node2.argument.value);
1021
+ generator.push(`...${name}`);
1022
+ break;
952
1023
  default:
953
- if (node2 != null && parent != null) {
954
- if (parent.type === "ArrayExpression") {
955
- const lastIndex = itemsCountStack.length - 1;
956
- const currentCount = parent.elements.length - itemsCountStack[lastIndex];
957
- pathStack.push(currentCount.toString());
958
- if (isJSONablePrimitiveLiteral(node2)) {
959
- if (node2.type === "Literal" && isString(node2.value) || node2.type === "TemplateLiteral") {
960
- const value = getValue(node2);
961
- const { code, map } = codegenFn(value, options, pathStack);
962
- sourceMap && map != null && codeMaps.set(value, map);
963
- generator.push(`${code}`, node2, value);
1024
+ if (parent?.type === "ArrayExpression") {
1025
+ const lastIndex = itemsCountStack.length - 1;
1026
+ const currentCount = parent.elements.length - itemsCountStack[lastIndex];
1027
+ pathStack.push(currentCount.toString());
1028
+ if (isJSONablePrimitiveLiteral(node2)) {
1029
+ if (node2.type === "Literal" && isString(node2.value) || node2.type === "TemplateLiteral") {
1030
+ const value = getValue(node2);
1031
+ const { code, map } = codegenFn(value, options, pathStack);
1032
+ sourceMap && map != null && codeMaps.set(value, map);
1033
+ generator.push(`${code}`, node2, value);
1034
+ } else {
1035
+ const value = getValue(node2);
1036
+ if (forceStringify) {
1037
+ const strValue = JSON.stringify(value);
1038
+ const { code, map } = codegenFn(strValue, options, pathStack);
1039
+ sourceMap && map != null && codeMaps.set(strValue, map);
1040
+ generator.push(`${code}`, node2, strValue);
964
1041
  } else {
965
- const value = getValue(node2);
966
- if (forceStringify) {
967
- const strValue = JSON.stringify(value);
968
- const { code, map } = codegenFn(
969
- strValue,
970
- options,
971
- pathStack
972
- );
973
- sourceMap && map != null && codeMaps.set(strValue, map);
974
- generator.push(`${code}`, node2, strValue);
975
- } else {
976
- generator.push(`${JSON.stringify(value)}`);
977
- }
1042
+ generator.push(`${JSON.stringify(value)}`);
978
1043
  }
979
- skipStack.push(false);
980
- } else {
981
- skipStack.push(true);
982
1044
  }
983
- itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
1045
+ skipStack.push(false);
1046
+ } else {
1047
+ skipStack.push(true);
984
1048
  }
1049
+ itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
985
1050
  }
986
1051
  break;
987
1052
  }
@@ -1014,15 +1079,17 @@ function _generate(generator, node, options = {}) {
1014
1079
  }
1015
1080
  generator.deindent();
1016
1081
  generator.push(`}`);
1017
- if (parent != null && parent.type === "ArrayExpression") {
1082
+ if (parent?.type === "ArrayExpression") {
1018
1083
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1019
1084
  pathStack.pop();
1020
- generator.pushline(`,`);
1085
+ if (!skipStack.pop()) {
1086
+ generator.pushline(`,`);
1087
+ }
1021
1088
  }
1022
1089
  }
1023
1090
  break;
1024
1091
  case "Property":
1025
- if (parent != null && parent.type === "ObjectExpression") {
1092
+ if (parent?.type === "ObjectExpression") {
1026
1093
  if (propsCountStack[propsCountStack.length - 1] !== 0) {
1027
1094
  pathStack.pop();
1028
1095
  if (!skipStack.pop()) {
@@ -1038,7 +1105,7 @@ function _generate(generator, node, options = {}) {
1038
1105
  }
1039
1106
  generator.deindent();
1040
1107
  generator.push(`]`);
1041
- if (parent != null && parent.type === "ArrayExpression") {
1108
+ if (parent?.type === "ArrayExpression") {
1042
1109
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1043
1110
  pathStack.pop();
1044
1111
  if (!skipStack.pop()) {
@@ -1048,16 +1115,12 @@ function _generate(generator, node, options = {}) {
1048
1115
  }
1049
1116
  break;
1050
1117
  case "Literal":
1051
- if (parent != null && parent.type === "ArrayExpression") {
1118
+ if (parent?.type === "ArrayExpression") {
1052
1119
  if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
1053
1120
  pathStack.pop();
1054
- if (!skipStack.pop()) {
1055
- generator.pushline(`,`);
1056
- }
1057
- } else {
1058
- if (!skipStack.pop()) {
1059
- generator.pushline(`,`);
1060
- }
1121
+ }
1122
+ if (!skipStack.pop()) {
1123
+ generator.pushline(`,`);
1061
1124
  }
1062
1125
  }
1063
1126
  break;
@@ -1121,4 +1184,4 @@ function loadModule(moduleName, debug) {
1121
1184
  }
1122
1185
  }
1123
1186
 
1124
- export { checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
1187
+ export { DynamicResourceError, checkInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@intlify/bundle-utils",
3
+ "type": "module",
3
4
  "description": "Bundle utilities for Intlify project",
4
- "version": "9.0.0",
5
+ "version": "11.0.0-beta.0",
5
6
  "author": {
6
7
  "name": "kazuya kawaguchi",
7
8
  "email": "kawakazu80@gmail.com"
@@ -18,6 +19,8 @@
18
19
  }
19
20
  },
20
21
  "dependencies": {
22
+ "@babel/core": "^7.26.10",
23
+ "@babel/preset-typescript": "^7.26.0",
21
24
  "@intlify/message-compiler": "next",
22
25
  "@intlify/shared": "next",
23
26
  "acorn": "^8.8.2",
@@ -29,6 +32,7 @@
29
32
  "yaml-eslint-parser": "^1.2.2"
30
33
  },
31
34
  "devDependencies": {
35
+ "@types/babel__core": "^7.20.5",
32
36
  "@types/escodegen": "^0.0.10",
33
37
  "@types/estree": "^1.0.0",
34
38
  "unbuild": "^2.0.0"
@@ -47,7 +51,6 @@
47
51
  "types": "lib/index.d.ts",
48
52
  "exports": {
49
53
  ".": {
50
- "types": "./lib/index.d.ts",
51
54
  "import": "./lib/index.mjs",
52
55
  "require": "./lib/index.cjs"
53
56
  },