afv-library/samples/ui-bundle-template-app-react-sample-b2x/scripts/sf-project-setup.mjs
svc-idee-bot 9a0712528a
chore: sync React samples from npm (#280)
Co-authored-by: Hemant Singh Bisht <hsinghbisht@salesforce.com>
2026-06-03 12:43:28 +05:30

104 lines
3.6 KiB
JavaScript

#!/usr/bin/env node
/**
* Run from SFDX project root: install dependencies, build, and launch the dev server
* for the UI bundle in force-app/main/default/uiBundles/.
*
* Usage: npm run sf-project-setup
* (from the directory that contains force-app/ and sfdx-project.json)
*/
import { spawnSync } from 'node:child_process';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { readdirSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, '..');
/**
* npm strips .gitignore from published packages — generate them on first run.
* Templates are stored in scripts/gitignore-templates.json (generated at build
* time from the actual .gitignore files). The JSON may not exist in git-cloned
* distributions where .gitignore is already present, so loading is best-effort.
*/
function loadGitignoreTemplates() {
const templatesPath = resolve(__dirname, 'gitignore-templates.json');
if (!existsSync(templatesPath)) return null;
try {
return JSON.parse(readFileSync(templatesPath, 'utf8'));
} catch {
return null;
}
}
function ensureGitignore(dir, content) {
if (!content) return;
const gitignorePath = resolve(dir, '.gitignore');
if (!existsSync(gitignorePath)) {
writeFileSync(gitignorePath, content, 'utf8');
console.log(`Created .gitignore in ${dir}`);
}
}
function resolveUIBundlesDir() {
const sfdxPath = resolve(ROOT, 'sfdx-project.json');
if (!existsSync(sfdxPath)) {
console.error('Error: sfdx-project.json not found at project root.');
process.exit(1);
}
const sfdxProject = JSON.parse(readFileSync(sfdxPath, 'utf8'));
const pkgDir = sfdxProject?.packageDirectories?.[0]?.path;
if (!pkgDir) {
console.error('Error: No packageDirectories[].path found in sfdx-project.json.');
process.exit(1);
}
return resolve(ROOT, pkgDir, 'main', 'default', 'uiBundles');
}
function discoverUIBundleDir() {
const uiBundlesDir = resolveUIBundlesDir();
if (!existsSync(uiBundlesDir)) {
console.error(`Error: uiBundles directory not found: ${uiBundlesDir}`);
process.exit(1);
}
const entries = readdirSync(uiBundlesDir, { withFileTypes: true });
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith('.'));
if (dirs.length === 0) {
console.error(`Error: No UI bundle folder found under ${uiBundlesDir}`);
process.exit(1);
}
if (dirs.length > 1) {
console.log(`Multiple UI bundles found; using first: ${dirs[0].name}`);
}
return resolve(uiBundlesDir, dirs[0].name);
}
function run(label, cmd, args, opts) {
console.log(`\n--- ${label} ---\n`);
const result = spawnSync(cmd, args, { stdio: 'inherit', ...opts });
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
// Ensure .gitignore files exist (npm strips them from published packages).
const gitignoreTemplates = loadGitignoreTemplates();
if (gitignoreTemplates) {
ensureGitignore(ROOT, gitignoreTemplates.sfdx);
const bundlesDir = resolveUIBundlesDir();
if (existsSync(bundlesDir)) {
for (const entry of readdirSync(bundlesDir, { withFileTypes: true })) {
if (entry.isDirectory() && !entry.name.startsWith('.')) {
ensureGitignore(resolve(bundlesDir, entry.name), gitignoreTemplates.webapp);
}
}
}
}
const uiBundleDir = discoverUIBundleDir();
console.log('SFDX project root:', ROOT);
console.log('UI bundle directory:', uiBundleDir);
run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir });
run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir });