@cleartrip/frontguard 0.3.2 → 0.3.3

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.
package/README.md CHANGED
@@ -27,7 +27,7 @@ npx frontguard init
27
27
 
28
28
  This does three things:
29
29
 
30
- - **Creates `frontguard.config.js`** with all available options as commented examples
30
+ - **Creates `frontguard.config.mjs`** (ESM) with all available options as commented examples — works even when `package.json` is not `"type": "module"`
31
31
  - **Creates `pull_request_template.md`** with AI disclosure checkboxes
32
32
  - **Merges the FrontGuard step** into your existing `bitbucket-pipelines.yml` (or creates one if missing)
33
33
 
@@ -35,7 +35,7 @@ This does three things:
35
35
 
36
36
  ### 3. Configure
37
37
 
38
- Open `frontguard.config.js` and uncomment the checks you want. Every option is documented inline.
38
+ Open `frontguard.config.mjs` and uncomment the checks you want. Every option is documented inline.
39
39
 
40
40
  ### 4. Set Up CI
41
41
 
@@ -95,7 +95,7 @@ The bundle check supports multiple strategies for extracting the size metric:
95
95
 
96
96
  **Next.js (auto-detected):**
97
97
  ```js
98
- // frontguard.config.js — no strategy override needed
98
+ // frontguard.config.mjs — no strategy override needed
99
99
  bundle: {
100
100
  buildCommand: 'yarn build',
101
101
  maxDeltaBytes: 50_000,
@@ -122,7 +122,25 @@ Commit this to your base branch. FrontGuard compares the current build against i
122
122
 
123
123
  ## Configuration
124
124
 
125
- All configuration lives in `frontguard.config.js` at your project root:
125
+ FrontGuard loads the first file that exists, in order: **`frontguard.config.mjs`** **`frontguard.config.cjs`** **`frontguard.config.js`**.
126
+
127
+ - **`.mjs`** — ESM (`import` / `export default`). Use this in CommonJS-only repos (no `"type": "module"` needed). **Recommended.**
128
+ - **`.cjs`** — CommonJS without importing the package (plain object merges like `defineConfig`):
129
+
130
+ ```js
131
+ // frontguard.config.cjs
132
+ module.exports = {
133
+ checks: {
134
+ bundle: { buildCommand: 'yarn build:prod', bundleSizeStrategy: 'next' },
135
+ },
136
+ }
137
+ ```
138
+
139
+ - **`.js`** — Only reliable as ESM if your `package.json` has `"type": "module"`; otherwise Node may refuse to load it (you will see an ESM warning and defaults will apply).
140
+
141
+ **CI / monorepos:** Run `frontguard` with `cwd` set to the app root that contains `package.json` and the config file. **Git:** If you see `fatal: Needed a single revision`, increase clone depth or fetch the PR destination branch (e.g. `git fetch origin main:refs/remotes/origin/main`) so diff and baseline reads can resolve `origin/<branch>`.
142
+
143
+ All configuration lives in one of those files at your project root (same directory you run `frontguard` from):
126
144
 
127
145
  ```js
128
146
  import { defineConfig } from '@cleartrip/frontguard'
@@ -235,7 +253,7 @@ These features are **implemented in code but turned off by default** so day-to-d
235
253
 
236
254
  When you are ready to try them:
237
255
 
238
- 1. Set `checks.aiAssistedReview.enabled: true` for static heuristics on `@frontguard-ai` regions or AI-disclosed PRs (see `frontguard.config.js` comments).
256
+ 1. Set `checks.aiAssistedReview.enabled: true` for static heuristics on `@frontguard-ai` regions or AI-disclosed PRs (see `frontguard.config.mjs` comments).
239
257
  2. Set `checks.llm.enabled: true` and choose `provider: 'ollama' | 'openai' | 'anthropic'` for automated review text.
240
258
 
241
259
  **PR template:** The init flow still adds an **AI disclosure** section to `pull_request_template.md` for human reviewers. With AI-assisted review off, that disclosure is recorded as an info finding and does not enable extra static checks until you opt in.
package/dist/cli.js CHANGED
@@ -2768,12 +2768,20 @@ function findEndOfLastSection(lines, pipelinesIdx) {
2768
2768
  }
2769
2769
  async function initFrontGuard(cwd) {
2770
2770
  const actions = [];
2771
- const cfgPath = path6.join(cwd, "frontguard.config.js");
2772
- if (!await fileExists(cfgPath)) {
2771
+ const cfgCandidates = [
2772
+ "frontguard.config.mjs",
2773
+ "frontguard.config.js",
2774
+ "frontguard.config.cjs"
2775
+ ];
2776
+ const cfgPath = path6.join(cwd, "frontguard.config.mjs");
2777
+ const hasAny = await Promise.all(
2778
+ cfgCandidates.map((n3) => fileExists(path6.join(cwd, n3)))
2779
+ ).then((xs) => xs.some(Boolean));
2780
+ if (!hasAny) {
2773
2781
  await fs.writeFile(cfgPath, CONFIG_TEMPLATE, "utf8");
2774
- actions.push("created frontguard.config.js");
2782
+ actions.push("created frontguard.config.mjs");
2775
2783
  } else {
2776
- actions.push("frontguard.config.js already exists (skipped)");
2784
+ actions.push("frontguard config already exists (.mjs / .js / .cjs) \u2014 skipped");
2777
2785
  }
2778
2786
  const prTplPath = path6.join(cwd, "pull_request_template.md");
2779
2787
  if (!await fileExists(prTplPath)) {
@@ -3154,9 +3162,9 @@ function migrateLegacyConfigKeys(config) {
3154
3162
 
3155
3163
  // src/config/load.ts
3156
3164
  var CONFIG_NAMES = [
3157
- "frontguard.config.js",
3158
3165
  "frontguard.config.mjs",
3159
- "frontguard.config.cjs"
3166
+ "frontguard.config.cjs",
3167
+ "frontguard.config.js"
3160
3168
  ];
3161
3169
  async function importConfig(absolutePath) {
3162
3170
  const url = pathToFileURL(absolutePath).href;
@@ -3192,6 +3200,7 @@ async function loadExtendsLayer(cwd, spec) {
3192
3200
  }
3193
3201
  async function loadConfig(cwd) {
3194
3202
  let userFile = null;
3203
+ const loadErrors = [];
3195
3204
  for (const name of CONFIG_NAMES) {
3196
3205
  const full = path6.join(cwd, name);
3197
3206
  if (!fs2.existsSync(full)) continue;
@@ -3199,7 +3208,9 @@ async function loadConfig(cwd) {
3199
3208
  const mod = await importConfig(full);
3200
3209
  userFile = normalizeExport(mod);
3201
3210
  break;
3202
- } catch {
3211
+ } catch (e3) {
3212
+ const msg = e3 instanceof Error ? e3.message : String(e3);
3213
+ loadErrors.push(`${name}: ${msg}`);
3203
3214
  continue;
3204
3215
  }
3205
3216
  }
@@ -3208,6 +3219,21 @@ async function loadConfig(cwd) {
3208
3219
  migrateLegacyConfigKeys(orgLayer);
3209
3220
  if (userFile) migrateLegacyConfigKeys(userFile);
3210
3221
  const user = userFile ? stripExtends(userFile) : {};
3222
+ if (!userFile) {
3223
+ if (loadErrors.length > 0) {
3224
+ g.stderr.write(
3225
+ `FrontGuard: config file(s) exist under ${path6.resolve(cwd)} but failed to load:
3226
+ ${loadErrors.map((l3) => ` \u2022 ${l3}`).join("\n")}
3227
+ Common fix: use frontguard.config.mjs (ESM, no package.json "type" required), or frontguard.config.cjs with require(). See README.
3228
+ `
3229
+ );
3230
+ } else {
3231
+ g.stderr.write(
3232
+ `FrontGuard: no ${CONFIG_NAMES.join(", ")} found under ${path6.resolve(cwd)} \u2014 using built-in defaults only (e.g. checks.bundle.buildCommand defaults to "npm run build"). Add a config file or run from the directory that contains it.
3233
+ `
3234
+ );
3235
+ }
3236
+ }
3211
3237
  const base = structuredClone(defaultConfig);
3212
3238
  const withOrg = defu2(orgLayer, base);
3213
3239
  return defu2(user, withOrg);
@@ -6891,7 +6917,7 @@ function formatMarkdown(p2) {
6891
6917
  );
6892
6918
  sb.push("");
6893
6919
  sb.push(
6894
- "_Configure checks in `frontguard.config.js` \xB7 [Shields.io](https://shields.io) badge images load in Bitbucket PR comments (HTML tags like `<details>` are not supported there)._"
6920
+ "_Configure checks in `frontguard.config.mjs` (or `.cjs` / `.js`) \xB7 [Shields.io](https://shields.io) badge images load in Bitbucket PR comments (HTML tags like `<details>` are not supported there)._"
6895
6921
  );
6896
6922
  return sb.join("\n");
6897
6923
  }
@@ -7419,7 +7445,7 @@ var init2 = defineCommand({
7419
7445
  `);
7420
7446
  }
7421
7447
  g.stdout.write(
7422
- "\nNext steps:\n 1. Review frontguard.config.js \u2014 uncomment and tune the checks you need\n 2. Review bitbucket-pipelines.yml \u2014 check the merged FrontGuard step\n 3. Set BITBUCKET_ACCESS_TOKEN as a secured variable in your repo\n 4. Install the package: yarn add -D @cleartrip/frontguard\n\n"
7448
+ "\nNext steps:\n 1. Review frontguard.config.mjs \u2014 uncomment and tune the checks you need\n 2. Review bitbucket-pipelines.yml \u2014 check the merged FrontGuard step\n 3. Set BITBUCKET_ACCESS_TOKEN as a secured variable in your repo\n 4. Install the package: yarn add -D @cleartrip/frontguard\n\n"
7423
7449
  );
7424
7450
  }
7425
7451
  });