@knighted/module 1.0.0-rc.4 → 1.0.0-rc.5

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.
@@ -627,6 +627,11 @@ const format = async (src, ast, opts) => {
627
627
  const isValidExportName = name => /^[$A-Z_a-z][$\w]*$/.test(name);
628
628
  const asExportName = name => isValidExportName(name) ? name : JSON.stringify(name);
629
629
  const accessProp = name => isValidExportName(name) ? `${_exports.exportsRename}.${name}` : `${_exports.exportsRename}[${JSON.stringify(name)}]`;
630
+ const exportValueFor = name => {
631
+ if (name === '__dirname') return 'import.meta.dirname';
632
+ if (name === '__filename') return 'import.meta.filename';
633
+ return name;
634
+ };
630
635
  const tempNameFor = name => {
631
636
  const sanitized = name.replace(/[^$\w]/g, '_') || 'value';
632
637
  const safe = /^[0-9]/.test(sanitized) ? `_${sanitized}` : sanitized;
@@ -645,7 +650,14 @@ const format = async (src, ast, opts) => {
645
650
  const defaultEntry = exportTable.get('default');
646
651
  if (defaultEntry) {
647
652
  const def = defaultEntry.fromIdentifier ?? _exports.exportsRename;
648
- lines.push(`export default ${def};`);
653
+ const defExpr = exportValueFor(def);
654
+ if (defExpr !== def) {
655
+ const temp = tempNameFor(def);
656
+ lines.push(`const ${temp} = ${defExpr};`);
657
+ lines.push(`export default ${temp};`);
658
+ } else {
659
+ lines.push(`export default ${defExpr};`);
660
+ }
649
661
  }
650
662
  for (const [key, entry] of exportTable) {
651
663
  if (key === 'default') continue;
@@ -653,7 +665,14 @@ const format = async (src, ast, opts) => {
653
665
  warnOnce(`cjs-string-export:${key}`, `Synthesized string-literal export '${key}'. Some tooling may require bracket access to use it.`);
654
666
  }
655
667
  if (entry.fromIdentifier) {
656
- lines.push(`export { ${entry.fromIdentifier} as ${asExportName(key)} };`);
668
+ const resolved = exportValueFor(entry.fromIdentifier);
669
+ if (resolved !== entry.fromIdentifier) {
670
+ const temp = tempNameFor(entry.fromIdentifier);
671
+ lines.push(`const ${temp} = ${resolved};`);
672
+ lines.push(`export { ${temp} as ${asExportName(key)} };`);
673
+ } else {
674
+ lines.push(`export { ${resolved} as ${asExportName(key)} };`);
675
+ }
657
676
  } else {
658
677
  const temp = tempNameFor(key);
659
678
  lines.push(`const ${temp} = ${accessProp(key)};`);
package/dist/format.js CHANGED
@@ -620,6 +620,11 @@ const format = async (src, ast, opts) => {
620
620
  const isValidExportName = name => /^[$A-Z_a-z][$\w]*$/.test(name);
621
621
  const asExportName = name => isValidExportName(name) ? name : JSON.stringify(name);
622
622
  const accessProp = name => isValidExportName(name) ? `${exportsRename}.${name}` : `${exportsRename}[${JSON.stringify(name)}]`;
623
+ const exportValueFor = name => {
624
+ if (name === '__dirname') return 'import.meta.dirname';
625
+ if (name === '__filename') return 'import.meta.filename';
626
+ return name;
627
+ };
623
628
  const tempNameFor = name => {
624
629
  const sanitized = name.replace(/[^$\w]/g, '_') || 'value';
625
630
  const safe = /^[0-9]/.test(sanitized) ? `_${sanitized}` : sanitized;
@@ -638,7 +643,14 @@ const format = async (src, ast, opts) => {
638
643
  const defaultEntry = exportTable.get('default');
639
644
  if (defaultEntry) {
640
645
  const def = defaultEntry.fromIdentifier ?? exportsRename;
641
- lines.push(`export default ${def};`);
646
+ const defExpr = exportValueFor(def);
647
+ if (defExpr !== def) {
648
+ const temp = tempNameFor(def);
649
+ lines.push(`const ${temp} = ${defExpr};`);
650
+ lines.push(`export default ${temp};`);
651
+ } else {
652
+ lines.push(`export default ${defExpr};`);
653
+ }
642
654
  }
643
655
  for (const [key, entry] of exportTable) {
644
656
  if (key === 'default') continue;
@@ -646,7 +658,14 @@ const format = async (src, ast, opts) => {
646
658
  warnOnce(`cjs-string-export:${key}`, `Synthesized string-literal export '${key}'. Some tooling may require bracket access to use it.`);
647
659
  }
648
660
  if (entry.fromIdentifier) {
649
- lines.push(`export { ${entry.fromIdentifier} as ${asExportName(key)} };`);
661
+ const resolved = exportValueFor(entry.fromIdentifier);
662
+ if (resolved !== entry.fromIdentifier) {
663
+ const temp = tempNameFor(entry.fromIdentifier);
664
+ lines.push(`const ${temp} = ${resolved};`);
665
+ lines.push(`export { ${temp} as ${asExportName(key)} };`);
666
+ } else {
667
+ lines.push(`export { ${resolved} as ${asExportName(key)} };`);
668
+ }
650
669
  } else {
651
670
  const temp = tempNameFor(key);
652
671
  lines.push(`const ${temp} = ${accessProp(key)};`);
@@ -4,6 +4,10 @@ import type { FormatterOptions } from '../types.cjs';
4
4
  type MemberExpressionExtras = {
5
5
  onRequireResolve?: () => void;
6
6
  requireResolveName?: string;
7
+ onDiagnostic?: (code: string, message: string, loc?: {
8
+ start: number;
9
+ end: number;
10
+ }) => void;
7
11
  };
8
12
  export declare const memberExpression: (node: MemberExpression, parent: Node | null, src: MagicString, options: FormatterOptions, shadowed?: Set<string>, extras?: MemberExpressionExtras) => void;
9
13
  export {};
package/dist/types.d.cts CHANGED
@@ -34,11 +34,25 @@ export type ModuleOptions = {
34
34
  cjsDefault?: 'module-exports' | 'auto' | 'none';
35
35
  /** Handling for top-level await constructs. */
36
36
  topLevelAwait?: 'error' | 'wrap' | 'preserve';
37
+ /** Optional diagnostics sink for warnings/errors emitted during transform. */
38
+ diagnostics?: (diag: Diagnostic) => void;
39
+ /** Optional source file path used for diagnostics context. */
40
+ filePath?: string;
37
41
  /** Output directory or file path when writing. */
38
42
  out?: string;
39
43
  /** Overwrite input files instead of writing to out. */
40
44
  inPlace?: boolean;
41
45
  };
46
+ export type Diagnostic = {
47
+ level: 'warning' | 'error';
48
+ code: string;
49
+ message: string;
50
+ filePath?: string;
51
+ loc?: {
52
+ start: number;
53
+ end: number;
54
+ };
55
+ };
42
56
  export type SpannedNode = Node & Span;
43
57
  export type ExportsMeta = {
44
58
  hasExportsBeenReassigned: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@knighted/module",
3
- "version": "1.0.0-rc.4",
4
- "description": "Transforms differences between ES modules and CommonJS.",
3
+ "version": "1.0.0-rc.5",
4
+ "description": "Bidirectional transform for ES modules and CommonJS.",
5
5
  "type": "module",
6
6
  "main": "dist/module.js",
7
7
  "exports": {
@@ -44,13 +44,12 @@
44
44
  "postpack": "node scripts/restoreImportsToSrc.js"
45
45
  },
46
46
  "keywords": [
47
- "transform",
48
- "es module",
47
+ "esm",
49
48
  "commonjs",
50
- "require",
51
- "require.resolve",
52
- "import.meta.url",
53
- "import.meta.dirname",
49
+ "transform",
50
+ "cjs-to-esm",
51
+ "esm-to-cjs",
52
+ "import.meta",
54
53
  "__dirname",
55
54
  "__filename"
56
55
  ],