pbiplint 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/dist/pbiplint.mjs +16 -14
  2. package/package.json +2 -2
package/dist/pbiplint.mjs CHANGED
@@ -5,7 +5,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
5
5
  import { basename as basename2, dirname as dirname4, relative as relative2, resolve as resolve3 } from "node:path";
6
6
 
7
7
  // ../core/src/version.ts
8
- var VERSION = "0.1.0";
8
+ var VERSION = "0.1.1";
9
9
 
10
10
  // ../core/src/engine/config.ts
11
11
  var ConfigError = class extends Error {
@@ -2323,20 +2323,21 @@ function parseTmdl(file, text) {
2323
2323
  let pendingDescription = [];
2324
2324
  let descriptionLine = 0;
2325
2325
  let descriptionText = "";
2326
+ const orphanDescription = () => {
2327
+ issues.push({
2328
+ file,
2329
+ line: descriptionLine,
2330
+ text: descriptionText,
2331
+ reason: "description is not followed by a declaration"
2332
+ });
2333
+ pendingDescription = [];
2334
+ };
2326
2335
  let i = 0;
2327
2336
  while (i < lines.length) {
2328
2337
  const raw = lines[i];
2329
2338
  const lineNo = i + 1;
2330
2339
  if (raw.trim() === "") {
2331
- if (pendingDescription.length) {
2332
- issues.push({
2333
- file,
2334
- line: descriptionLine,
2335
- text: descriptionText,
2336
- reason: "description is not followed by a declaration"
2337
- });
2338
- pendingDescription = [];
2339
- }
2340
+ if (pendingDescription.length) orphanDescription();
2340
2341
  i++;
2341
2342
  continue;
2342
2343
  }
@@ -2390,7 +2391,7 @@ function parseTmdl(file, text) {
2390
2391
  j++;
2391
2392
  }
2392
2393
  if (j >= lines.length)
2393
- issues.push({ file, line: lineNo, text: raw, reason: "unterminated ``` fence" });
2394
+ issues.push({ file, line: lineNo, text: raw, reason: "unterminated code fence" });
2394
2395
  const boundary = j < lines.length ? leadingWs(lines[j]) : 0;
2395
2396
  i = j;
2396
2397
  return out.map((l) => l.slice(Math.min(boundary, leadingWs(l)))).join("\n");
@@ -2445,6 +2446,7 @@ function parseTmdl(file, text) {
2445
2446
  stack[indent] = node;
2446
2447
  i++;
2447
2448
  }
2449
+ if (pendingDescription.length) orphanDescription();
2448
2450
  return { file, roots, issues, lineCount: lines.length };
2449
2451
  }
2450
2452
 
@@ -3132,8 +3134,8 @@ Read more: https://pbiplint.com/rules/large-tables-should-be-partitioned`,
3132
3134
  markdown: "### Why it matters\n\nWith a default summarization, dragging the column onto a visual produces an implicit sum, and it is easy to sum something that should never be summed: a year, a unit price, a percentage, a key. The implicit measure also bypasses the format string and the logic of the real measures, so two visuals of the same thing disagree. With summarization off, the column lands on a visual as a category and the author reaches for a measure.\n\n### How to fix it\n\nIn Power BI Desktop, select the column and set Summarization to Don't summarize under Column tools. In the TMDL file the property is `summarizeBy: none`. Create explicit measures for the aggregations reports need.\n\n### Quirks\n\n- A column with no summarizeBy property is treated as Default, which is not None, so it is flagged.\n\nRead more: https://pbiplint.com/rules/numeric-column-summarize-by"
3133
3135
  },
3134
3136
  OBJECTS_SHOULD_NOT_START_OR_END_WITH_A_SPACE: {
3135
- text: 'Why it matters\n\nA leading or trailing space is invisible on screen but is part of the name, so "Sales " and "Sales" are two different objects to the engine. That is enough to break a DAX reference, a report visual binding, or a deployment that expects the trimmed name, and the error you get back will name an object that looks perfectly correct. Stray spaces almost always arrive by accident, pasted in or inherited from a source column name, so trimming them is safe and rarely breaks anything downstream. TRIM_OBJECT_NAMES makes the same check across more object types at a lower severity, so every finding here appears there as well.\n\nHow to fix it\n\nRename the object without the space in Power BI Desktop, which updates the visuals and DAX that reference it, or edit the name in the TMDL file.\n\nQuirks\n\n- Narrower scope than TRIM_OBJECT_NAMES: levels, roles, expressions, calculation items, calculated tables, and calculated table columns are not checked here.\n\nRead more: https://pbiplint.com/rules/objects-should-not-start-or-end-with-a-space',
3136
- markdown: '### Why it matters\n\nA leading or trailing space is invisible on screen but is part of the name, so "Sales " and "Sales" are two different objects to the engine. That is enough to break a DAX reference, a report visual binding, or a deployment that expects the trimmed name, and the error you get back will name an object that looks perfectly correct. Stray spaces almost always arrive by accident, pasted in or inherited from a source column name, so trimming them is safe and rarely breaks anything downstream. `TRIM_OBJECT_NAMES` makes the same check across more object types at a lower severity, so every finding here appears there as well.\n\n### How to fix it\n\nRename the object without the space in Power BI Desktop, which updates the visuals and DAX that reference it, or edit the name in the TMDL file.\n\n### Quirks\n\n- Narrower scope than `TRIM_OBJECT_NAMES`: levels, roles, expressions, calculation items, calculated tables, and calculated table columns are not checked here.\n\nRead more: https://pbiplint.com/rules/objects-should-not-start-or-end-with-a-space'
3137
+ text: 'Why it matters\n\nA leading or trailing space is invisible on screen but is part of the name, so "Sales " and "Sales" are two different objects to the engine. That is enough to break a DAX reference, a report visual binding, or a deployment that expects the trimmed name, and the error you get back will name an object that looks perfectly correct. Stray spaces almost always arrive by accident, pasted in or inherited from a source column name, so trimming them is safe and rarely breaks anything downstream. TRIM_OBJECT_NAMES makes the same check across more object types at a lower severity, so every finding here appears there as well.\n\nHow to fix it\n\nRename the object without the space in Power BI Desktop, which updates the visuals and DAX that reference it, or edit the name in the TMDL file.\n\nQuirks\n\n- Narrower scope than TRIM_OBJECT_NAMES: levels, roles, expressions, calculation items, calculated tables, and calculated table columns are not checked here.\n- In the browser, the "Choose a folder" button in Chrome and Edge does not list a file whose name begins or ends with a space, so a table file named that way is never read on that route and its findings are missing. Drag the folder onto the page, or use the command line, to read it.\n\nRead more: https://pbiplint.com/rules/objects-should-not-start-or-end-with-a-space',
3138
+ markdown: '### Why it matters\n\nA leading or trailing space is invisible on screen but is part of the name, so "Sales " and "Sales" are two different objects to the engine. That is enough to break a DAX reference, a report visual binding, or a deployment that expects the trimmed name, and the error you get back will name an object that looks perfectly correct. Stray spaces almost always arrive by accident, pasted in or inherited from a source column name, so trimming them is safe and rarely breaks anything downstream. `TRIM_OBJECT_NAMES` makes the same check across more object types at a lower severity, so every finding here appears there as well.\n\n### How to fix it\n\nRename the object without the space in Power BI Desktop, which updates the visuals and DAX that reference it, or edit the name in the TMDL file.\n\n### Quirks\n\n- Narrower scope than `TRIM_OBJECT_NAMES`: levels, roles, expressions, calculation items, calculated tables, and calculated table columns are not checked here.\n- In the browser, the "Choose a folder" button in Chrome and Edge does not list a file whose name begins or ends with a space, so a table file named that way is never read on that route and its findings are missing. Drag the folder onto the page, or use the command line, to read it.\n\nRead more: https://pbiplint.com/rules/objects-should-not-start-or-end-with-a-space'
3137
3139
  },
3138
3140
  OBJECTS_WITH_NO_DESCRIPTION: {
3139
3141
  text: "Why it matters\n\nThe description is the tooltip a report author sees when hovering a field in the field list, and it is the only place in the model to say what a measure counts, which currency a column is in, or which of two similar fields to use. Without it, every author works that out from the name, and gets it wrong at about the same rate. Descriptions also feed documentation tools, so the same sentence pays off twice.\n\nHow to fix it\n\nIn Power BI Desktop, open Model view, select the object, and type the Description in the Properties pane. In the TMDL file a description is one or more /// lines directly above the object. With hundreds of objects, Tabular Editor can paste descriptions into many objects at once; the TMDL comment lines need no other tool.\n\nQuirks\n\n- Visibility is the object's own isHidden flag: a visible column inside a hidden table is still reported.\n- A calculation group table is reported once, as a calculation group.\n\nRead more: https://pbiplint.com/rules/objects-with-no-description",
@@ -3288,7 +3290,7 @@ function resolveModel(input) {
3288
3290
  }
3289
3291
 
3290
3292
  // src/main.ts
3291
- var VERSION2 = true ? "0.1.0" : "0.0.0-dev";
3293
+ var VERSION2 = true ? "0.1.1" : "0.0.0-dev";
3292
3294
  function listRules() {
3293
3295
  const width = Math.max(...defaultRules.map((r) => r.id.length));
3294
3296
  return defaultRules.map(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pbiplint",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Lint Power BI semantic models (TMDL) for best-practice violations, with text, JSON, SARIF, and Markdown output. Nothing is uploaded.",
5
5
  "keywords": [
6
6
  "power-bi",
@@ -43,6 +43,6 @@
43
43
  "test:bundle": "node dist/pbiplint.mjs --sample --format json > /dev/null; test $? -eq 1"
44
44
  },
45
45
  "engines": {
46
- "node": ">=20"
46
+ "node": "^20.19.0 || >=22.12.0"
47
47
  }
48
48
  }