Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/build-next-bricks/bin/copy-jsx-d-ts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env node
import { existsSync } from "node:fs";
import { copyFile } from "node:fs/promises";
import path from "node:path";

const packageDir = process.cwd();
const jsxDtsSrc = path.join(packageDir, "src", "jsx.d.ts");
const jsxDtsDestDir = path.join(packageDir, "dist-types");
const jsxDtsDest = path.join(jsxDtsDestDir, "jsx.d.ts");

async function copyJsxDts() {
try {
if (!existsSync(jsxDtsSrc)) {
console.log(`Source file ${jsxDtsSrc} does not exist. Skipping copy.`);
return;
}

await copyFile(jsxDtsSrc, jsxDtsDest);
console.log(`Copied ${jsxDtsSrc} to ${jsxDtsDest}`);
} catch (error) {
console.error("Error copying jsx.d.ts:", error);
process.exit(1);
}
}

copyJsxDts();
3 changes: 2 additions & 1 deletion packages/build-next-bricks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"bin": {
"build-next-bricks": "./bin/build-next-bricks.js",
"pre-build-next-bricks": "./bin/pre-build-next-bricks.js",
"post-build-next-bricks": "./bin/post-build-next-bricks.js"
"post-build-next-bricks": "./bin/post-build-next-bricks.js",
"copy-jsx-d-ts": "./bin/copy-jsx-d-ts.js"
},
"files": [
"bin",
Expand Down
56 changes: 56 additions & 0 deletions packages/yo/src/plopfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,62 @@ export default function (
path: "bricks/{{pkgName}}/docs/{{>lastTagName}}.md",
templateFile: "templates/brick.md.hbs",
},
async function updateJsxDts(answers) {
const jsxDtsFile = path.join(
bricksDir,
answers.pkgName,
"src/jsx.d.ts"
);
/** @type {string} */
let jsxDtsContent;
if (!existsSync(jsxDtsFile)) {
// jsxDtsContent = `import type { DetailedHTMLProps, HTMLAttributes } from "react"`;
const jsxDtsTemplateFile = path.join(
__dirname,
"templates/bricks/src/jsx.d.ts.hbs"
);
jsxDtsContent = await readFile(jsxDtsTemplateFile, "utf-8");
} else {
jsxDtsContent = await readFile(jsxDtsFile, "utf-8");
}
const tagName = plop.renderString(
"{{getTagName brickType pkgName brickName false false}}",
answers
);
const className = plop.renderString(
"{{pascalCase (getTagName brickType pkgName brickName true true)}}",
answers
);
const propName = `${className}Props`;
const importStatement = `import type { ${className}, ${propName} } from "./${answers.brickName}";`;
const definitionProp = ` "${tagName}": DetailedHTMLProps<HTMLAttributes<${className}>, ${className}> & ${propName};`;

/** @type {[RegExp, string][]} */
const replacementPatterns = [
[
/(\r?\n)(\r?\n)?(declare global )/,
`$1${importStatement}$1$2$3`,
],
[
// eslint-disable-next-line no-regex-spaces
/(\r?\n)( \}\r?\n \}\r?\n\}\r?\n)$/,
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern uses hard-coded spaces (4 spaces, 2 spaces) which is fragile and will break if the template's indentation changes. Consider using \s* for flexible whitespace matching or extracting the expected structure as a constant with documentation explaining the pattern.

Suggested change
/(\r?\n)( \}\r?\n \}\r?\n\}\r?\n)$/,
/(\r?\n)(\s*\}\r?\n\s*\}\r?\n\}\r?\n)$/,

Copilot uses AI. Check for mistakes.
`$1${definitionProp}$1$2`,
],
];

for (const [pattern, replacement] of replacementPatterns) {
const newJsxDts = jsxDtsContent.replace(pattern, replacement);
if (newJsxDts === jsxDtsContent) {
throw new Error(
`Failed to add definition in jsx.d.ts for ${tagName}.`
);
}
jsxDtsContent = newJsxDts;
}

await writeFile(jsxDtsFile, jsxDtsContent);
return `Updated jsx.d.ts to include ${tagName} definition.`;
},
async function modifyCommonBricksJson(answers) {
if (answers.brickType === "common") {
const realBrickName = `eo-${answers.brickName}`;
Expand Down
4 changes: 3 additions & 1 deletion packages/yo/src/templates/bricks/package.json.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
"dist-types",
"docs"
],
"types": "dist-types/jsx.d.ts",
"exports": {
"./package.json": "./package.json",
"./dist/bricks.json": "./dist/bricks.json",
"./dist/manifest.json": "./dist/manifest.json",
".": "./dist-types/jsx.d.ts",
"./*": {
"types": "./dist-types/*/index.d.ts"
}
Expand All @@ -23,7 +25,7 @@
"start": "cross-env NODE_ENV=development build-next-bricks --watch",
"build": "npm run build:main && npm run build:types",
"build:main": "cross-env NODE_ENV=production build-next-bricks",
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist-types --project tsconfig.json",
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist-types --project tsconfig.json && copy-jsx-d-ts",
"build:manifest": "cross-env NODE_ENV=production build-next-bricks --manifest-only",
"test": "cross-env NODE_ENV='test' test-next",
"test:ci": "cross-env NODE_ENV='test' CI=true test-next",
Expand Down
9 changes: 9 additions & 0 deletions packages/yo/src/templates/bricks/src/jsx.d.ts.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { DetailedHTMLProps, HTMLAttributes } from "react";

declare global {
namespace JSX {
interface IntrinsicElements {
// Extend with brick definitions here
}
}
}
Loading