Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .husky/pre-commit
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1 @@
npx lint-staged --config lint-staged.config.js
npx blocks internal-lint
106 changes: 106 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env node

/*global console*/

import { execSync } from 'child_process';
import path from 'path';
import fs from 'fs';
import process from 'process';
import { fileURLToPath } from 'url';
import { createRequire } from 'module';

const require = createRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// --- Path Resolution ---
const userAppRoot = process.cwd();
const engineRoot = path.resolve(__dirname, '..');
const internalModulesPath = path.resolve(engineRoot, 'node_modules');
const internalBinPath = path.resolve(internalModulesPath, '.bin');

// Safely find binary paths for the internal tools
const getBinPath = (pkgName, binSubPath) => {
try {
const pkgRoot = path.dirname(require.resolve(`${pkgName}/package.json`));
return path.join(pkgRoot, binSubPath);
} catch {
return path.resolve(internalBinPath, pkgName);
}
};

const huskyBin = getBinPath('husky', 'bin.js');
const lintStagedBin = getBinPath('lint-staged', 'bin/lint-staged.js');

const command = process.argv[2];

// ---------------------------------------------------------
// COMMAND: setup-git
// ---------------------------------------------------------
if (command === 'setup-git') {
console.log('🐶 Setting up @build-in-blocks git hooks...');

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 41 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement
try {
execSync(`node "${huskyBin}"`, { stdio: 'inherit' });
const preCommitPath = path.join(userAppRoot, '.husky/pre-commit');

// Use 'npx blocks' to ensure portability in the User App
const hookContent = 'npx blocks internal-lint';

fs.writeFileSync(preCommitPath, hookContent, { mode: 0o755 });

console.log('✅ Git hooks integrated successfully.');

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 51 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement
} catch {
console.error('❌ Git hook setup failed.');

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (24.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (20.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (22.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (25.x)

Unexpected console statement

Check warning on line 53 in bin/cli.js

View workflow job for this annotation

GitHub Actions / validate (23.x)

Unexpected console statement
}
}

// ---------------------------------------------------------
// COMMAND: internal-lint
// ---------------------------------------------------------
if (command === 'internal-lint') {
const configPath = path.resolve(engineRoot, 'configs/lint-staged.config.mjs');
try {
// Detect the correct PATH key (Windows compatibility)
const pathKey =
process.platform === 'win32'
? Object.keys(process.env).find((k) => k.toUpperCase() === 'PATH') ||
'PATH'
: 'PATH';

const env = {
...process.env,
[pathKey]: `${internalBinPath}${path.delimiter}${process.env[pathKey]}`,
NODE_PATH: internalModulesPath,
NODE_OPTIONS: '--no-warnings',
};

execSync(`node "${lintStagedBin}" --config "${configPath}"`, {
stdio: 'inherit',
cwd: userAppRoot,
env,
});
} catch {
process.exit(1);
}
}

// if (command === 'internal-lint') {
// const lintStagedConfig = path.resolve(engineRoot, 'configs/lint-staged.config.mjs');

// try {
// const env = {
// ...process.env,
// PATH: `${internalBinPath}${path.delimiter}${process.env.PATH}`,
// // We tell Node to look in the engine's node_modules
// // when the User App's config tries to resolve its imports.
// NODE_PATH: internalModulesPath,
// };

// execSync(`node ${lintStagedBin} --config ${lintStagedConfig}`, {
// stdio: 'inherit',
// env
// });
// } catch (e) {
// process.exit(1);
// }
// }
19 changes: 19 additions & 0 deletions configs/eslint.helper.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

import { createRequire } from 'module';
import blocksDevSetupBaseConfig from '../eslint.config.mjs';

const require = createRequire(import.meta.url);

// Dynamic Discovery: Find ESLint wherever the package manager put it
const eslintConfigPath = require.resolve('eslint/config');
const { defineConfig } = require(eslintConfigPath);

export { defineConfig, blocksDevSetupBaseConfig };



// dev.setup/configs/eslint.helper.mjs
// import { defineConfig } from 'eslint/config';
// import blocksDevSetupBaseConfig from '../eslint.config.mjs';

// export { defineConfig, blocksDevSetupBaseConfig };
23 changes: 23 additions & 0 deletions configs/lint-staged.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

import { createRequire } from 'module';
import path from 'path';

const require = createRequire(import.meta.url);
const resolveBin = (pkgName, binRelativePath) => {
const pkgRoot = path.dirname(require.resolve(`${pkgName}/package.json`));
return `node ${path.join(pkgRoot, binRelativePath)}`;
};

const eslint = resolveBin('eslint', 'bin/eslint.js');
const prettier = resolveBin('prettier', 'bin/prettier.cjs');

export default {
'*.{mjs,js,ts}': [
// We use absolute paths to binaries to avoid ENOENT
`${eslint} --fix --no-warn-ignored`,
`${prettier} --write`
],
'*.{html,css,scss}': [
`${prettier} --write`
]
};
4 changes: 3 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';
import eslintConfigPrettier from 'eslint-config-prettier/flat';

export default defineConfig(
const blocksDevSetupBaseConfig = defineConfig(
eslint.configs.recommended,
tseslint.configs.recommended,
tseslint.configs.stylistic,
Expand All @@ -19,3 +19,5 @@ export default defineConfig(
},
eslintConfigPrettier,
);

export default blocksDevSetupBaseConfig;
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@
"type": "module",
"main": "eslint.config.mjs",
"bin": {
"blocks": "./bin/cli.js",
"husky-ls-config-init": "bin/user-app.husky.lint-staged.js",
"internal-husky-ls-init": "bin/internal.husky.lint-staged.js"
},
"exports": {
".": "./eslint.config.mjs",
"./prettier": "./prettier.config.mjs"
"./prettier": "./prettier.config.mjs",
"./config": "./configs/eslint.helper.mjs"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"eslint:lint": "eslint .",
"prettier:format": "prettier --write \"**/*.{js,ts,css,html}\"",
"prepare": "husky"
"prepare": "node ./bin/cli.js setup-git"
},
"dependencies": {
"@eslint/js": "^10.0.1",
Expand Down
Loading