Переглянути джерело

feat(build-ts-package): staking app and insights hub work great with the dual publish

benduran 3 тижнів тому
батько
коміт
85abbd0898

+ 4 - 1
packages/build-ts-package/src/build-ts-package.js

@@ -15,6 +15,7 @@ import {
   AVAILABLE_PLATFORMS,
   compileTs,
 } from "./compile-ts.js";
+import { injectExtraExports } from "./inject-extra-exports.js";
 
 /**
  * builds a typescript package, using tsdown and its Node-friendly API
@@ -267,7 +268,9 @@ export async function buildTsPackage(argv = process.argv) {
   }
 
   pjson.exports["./package.json"] = "./package.json";
-  await fs.writeFile(pjsonPath, JSON.stringify(pjson, null, 2), "utf8");
+  const injected = injectExtraExports(pjson);
+
+  await fs.writeFile(pjsonPath, JSON.stringify(injected, null, 2), "utf8");
 }
 
 await buildTsPackage();

+ 24 - 8
packages/build-ts-package/src/compile-ts.js

@@ -96,6 +96,13 @@ export async function compileTs({
             cwd,
             jsc: {
               target: "esnext",
+              transform: {
+                react: {
+                  // React 17+ support.
+                  // if you're on a legacy version, sorry
+                  runtime: 'automatic',
+                },
+              },
             },
             module: {
               outFileExtension: "js",
@@ -146,20 +153,29 @@ export async function compileTs({
       contents = contents.replace(esmRegex, (full, _q1, imp1, _q2, imp2) => {
         const importPath = imp1 || imp2;
         const resolveImport = createResolver(absFp);
-        const { resolved } = resolveImport(importPath);
+        const { resolved, resolvedRelative } = resolveImport(importPath);
 
         if (!resolved.startsWith(outDir)) return full;
 
         // Compute the new path:
         // - If the specifier has an extension, replace it.
         // - If it doesn't, append the desired extension.
-        const ext = path.extname(importPath);
-        const newPath = ext
-          ? importPath.replace(ext, outExtension)
-          : `${importPath}${outExtension}`;
-
-        // Replace only inside the matched statement to avoid accidental global replacements.
-        return full.replace(importPath, newPath);
+        const ext = path.extname(resolvedRelative);
+        let newPath = ext
+          ? resolvedRelative.replace(ext, outExtension)
+          : `${resolvedRelative}${outExtension}`;
+
+        if (!newPath.startsWith('.') && !newPath.startsWith('/')) {
+          newPath = `./${newPath}`;
+        }
+
+        if (/\.jsx?/.test(resolved)) {
+          // Replace only inside the matched statement to avoid accidental global replacements.
+          const out = full.replace(importPath, newPath);
+
+          return out;
+        }
+        return full;
       });
 
       await fs.writeFile(absFp, contents, "utf8");

+ 39 - 0
packages/build-ts-package/src/inject-extra-exports.js

@@ -0,0 +1,39 @@
+/**
+ * @typedef {import('type-fest').PackageJson} PackageJson
+ */
+
+import { Logger } from './logger.js';
+
+/**
+ * @typedef {Object} Config
+ * @property {PackageJson['exports']} [extraExports=undefined]
+ */
+
+/**
+ * @typedef {Object} PackageJsonWithPossibleConfig
+ * @property {Config} build-ts-package
+ */
+
+/**
+ * takes the package.json blob and smears some additional
+ * export statements into the existing block, if avaialble
+ * 
+ * @param {PackageJson & PackageJsonWithPossibleConfig} pjson 
+ */
+export function injectExtraExports(pjson) {
+  const config = pjson['build-ts-package'];
+
+  if (!config?.extraExports) return pjson;
+
+  Logger.info('config.extraExports', JSON.stringify(config.extraExports));
+
+  return {
+    ...pjson,
+    exports: {
+      // @ts-expect-error - type mismatch between type-fest and here
+      ...pjson.exports,
+      // @ts-expect-error - type mismatch between type-fest and here
+      ...config.extraExports,
+    },
+  };
+}

+ 8 - 4
packages/build-ts-package/src/resolve-import-path.js

@@ -1,4 +1,3 @@
-// resolver.js
 import { createRequire } from "module";
 import path from "path";
 import { pathToFileURL } from "url";
@@ -6,7 +5,7 @@ import { pathToFileURL } from "url";
 /**
  * Create a resolver bound to the directory of a given file path.
  * @param {string} absFilePath - Absolute path to the file you read.
- * @returns {(specifier: string) => { resolved: string, hadExtension: boolean }}
+ * @returns {(specifier: string) => { hadExtension: boolean; resolved: string; resolvedRelative: string; }}
  */
 export function createResolver(absFilePath) {
   const absDir = path.dirname(absFilePath);
@@ -20,11 +19,16 @@ export function createResolver(absFilePath) {
     // Try Node's resolution first (handles bare specifiers, exports fields, node_modules, etc.)
     try {
       const resolved = require.resolve(specifier);
-      return { resolved, hadExtension };
+
+      const resolvedRelative = path.relative(absDir, resolved);
+      
+      return { resolved, resolvedRelative, hadExtension };
     } catch {
       // Fallback for simple relative specifiers; preserves original extension or lack thereof
       const resolved = path.resolve(absDir, specifier);
-      return { resolved, hadExtension };
+
+      const resolvedRelative = path.relative(absDir, resolved);
+      return { resolved, resolvedRelative, hadExtension };
     }
   };
 }

+ 11 - 1
packages/component-library/package.json

@@ -380,6 +380,16 @@
       "default": "./dist/useQueryParamsPagination/index.js",
       "types": "./dist/useQueryParamsPagination/index.d.ts"
     },
-    "./package.json": "./package.json"
+    "./package.json": "./package.json",
+    "./theme": {
+      "default": "./dist/theme.scss"
+    }
+  },
+  "build-ts-package": {
+    "extraExports": {
+      "./theme": {
+        "default": "./dist/theme.scss"
+      }
+    }
   }
 }