@pbiplint/core 0.1.0
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/LICENSE +661 -0
- package/NOTICE +29 -0
- package/README.md +34 -0
- package/dist/engine/config.d.ts +33 -0
- package/dist/engine/config.d.ts.map +1 -0
- package/dist/engine/config.js +61 -0
- package/dist/engine/config.js.map +1 -0
- package/dist/engine/ignore.d.ts +8 -0
- package/dist/engine/ignore.d.ts.map +1 -0
- package/dist/engine/ignore.js +17 -0
- package/dist/engine/ignore.js.map +1 -0
- package/dist/engine/lint.d.ts +38 -0
- package/dist/engine/lint.d.ts.map +1 -0
- package/dist/engine/lint.js +33 -0
- package/dist/engine/lint.js.map +1 -0
- package/dist/engine/rank.d.ts +24 -0
- package/dist/engine/rank.d.ts.map +1 -0
- package/dist/engine/rank.js +38 -0
- package/dist/engine/rank.js.map +1 -0
- package/dist/engine/run.d.ts +21 -0
- package/dist/engine/run.d.ts.map +1 -0
- package/dist/engine/run.js +43 -0
- package/dist/engine/run.js.map +1 -0
- package/dist/format/index.d.ts +11 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +21 -0
- package/dist/format/index.js.map +1 -0
- package/dist/format/json.d.ts +4 -0
- package/dist/format/json.d.ts.map +1 -0
- package/dist/format/json.js +20 -0
- package/dist/format/json.js.map +1 -0
- package/dist/format/markdown.d.ts +4 -0
- package/dist/format/markdown.d.ts.map +1 -0
- package/dist/format/markdown.js +28 -0
- package/dist/format/markdown.js.map +1 -0
- package/dist/format/sarif.d.ts +4 -0
- package/dist/format/sarif.d.ts.map +1 -0
- package/dist/format/sarif.js +77 -0
- package/dist/format/sarif.js.map +1 -0
- package/dist/format/text.d.ts +31 -0
- package/dist/format/text.d.ts.map +1 -0
- package/dist/format/text.js +57 -0
- package/dist/format/text.js.map +1 -0
- package/dist/index/build.d.ts +11 -0
- package/dist/index/build.d.ts.map +1 -0
- package/dist/index/build.js +11 -0
- package/dist/index/build.js.map +1 -0
- package/dist/index/references.d.ts +37 -0
- package/dist/index/references.d.ts.map +1 -0
- package/dist/index/references.js +126 -0
- package/dist/index/references.js.map +1 -0
- package/dist/index/relationships.d.ts +10 -0
- package/dist/index/relationships.d.ts.map +1 -0
- package/dist/index/relationships.js +24 -0
- package/dist/index/relationships.js.map +1 -0
- package/dist/index/usage.d.ts +11 -0
- package/dist/index/usage.d.ts.map +1 -0
- package/dist/index/usage.js +25 -0
- package/dist/index/usage.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/model/build.d.ts +9 -0
- package/dist/model/build.d.ts.map +1 -0
- package/dist/model/build.js +282 -0
- package/dist/model/build.js.map +1 -0
- package/dist/model/names.d.ts +12 -0
- package/dist/model/names.d.ts.map +1 -0
- package/dist/model/names.js +21 -0
- package/dist/model/names.js.map +1 -0
- package/dist/model/types.d.ts +150 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +2 -0
- package/dist/model/types.js.map +1 -0
- package/dist/rules/helpers.d.ts +54 -0
- package/dist/rules/helpers.d.ts.map +1 -0
- package/dist/rules/helpers.js +189 -0
- package/dist/rules/helpers.js.map +1 -0
- package/dist/rules/index.d.ts +3 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +4 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/microsoft-bpa/bpa-rules.data.d.ts +12 -0
- package/dist/rules/microsoft-bpa/bpa-rules.data.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/bpa-rules.data.js +664 -0
- package/dist/rules/microsoft-bpa/bpa-rules.data.js.map +1 -0
- package/dist/rules/microsoft-bpa/columns.d.ts +14 -0
- package/dist/rules/microsoft-bpa/columns.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/columns.js +117 -0
- package/dist/rules/microsoft-bpa/columns.js.map +1 -0
- package/dist/rules/microsoft-bpa/define.d.ts +14 -0
- package/dist/rules/microsoft-bpa/define.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/define.js +75 -0
- package/dist/rules/microsoft-bpa/define.js.map +1 -0
- package/dist/rules/microsoft-bpa/dependencies.d.ts +11 -0
- package/dist/rules/microsoft-bpa/dependencies.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/dependencies.js +56 -0
- package/dist/rules/microsoft-bpa/dependencies.js.map +1 -0
- package/dist/rules/microsoft-bpa/index.d.ts +4 -0
- package/dist/rules/microsoft-bpa/index.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/index.js +20 -0
- package/dist/rules/microsoft-bpa/index.js.map +1 -0
- package/dist/rules/microsoft-bpa/live-model.d.ts +3 -0
- package/dist/rules/microsoft-bpa/live-model.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/live-model.js +10 -0
- package/dist/rules/microsoft-bpa/live-model.js.map +1 -0
- package/dist/rules/microsoft-bpa/measures.d.ts +15 -0
- package/dist/rules/microsoft-bpa/measures.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/measures.js +69 -0
- package/dist/rules/microsoft-bpa/measures.js.map +1 -0
- package/dist/rules/microsoft-bpa/naming.d.ts +14 -0
- package/dist/rules/microsoft-bpa/naming.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/naming.js +47 -0
- package/dist/rules/microsoft-bpa/naming.js.map +1 -0
- package/dist/rules/microsoft-bpa/relationships.d.ts +14 -0
- package/dist/rules/microsoft-bpa/relationships.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/relationships.js +97 -0
- package/dist/rules/microsoft-bpa/relationships.js.map +1 -0
- package/dist/rules/microsoft-bpa/tables.d.ts +16 -0
- package/dist/rules/microsoft-bpa/tables.d.ts.map +1 -0
- package/dist/rules/microsoft-bpa/tables.js +147 -0
- package/dist/rules/microsoft-bpa/tables.js.map +1 -0
- package/dist/rules/parse-issue.d.ts +4 -0
- package/dist/rules/parse-issue.d.ts.map +1 -0
- package/dist/rules/parse-issue.js +19 -0
- package/dist/rules/parse-issue.js.map +1 -0
- package/dist/rules/rule-summaries.data.d.ts +3 -0
- package/dist/rules/rule-summaries.data.d.ts.map +1 -0
- package/dist/rules/rule-summaries.data.js +78 -0
- package/dist/rules/rule-summaries.data.js.map +1 -0
- package/dist/rules/types.d.ts +42 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +15 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/tmdl/parse.d.ts +7 -0
- package/dist/tmdl/parse.d.ts.map +1 -0
- package/dist/tmdl/parse.js +196 -0
- package/dist/tmdl/parse.js.map +1 -0
- package/dist/tmdl/quote.d.ts +5 -0
- package/dist/tmdl/quote.d.ts.map +1 -0
- package/dist/tmdl/quote.js +15 -0
- package/dist/tmdl/quote.js.map +1 -0
- package/dist/tmdl/types.d.ts +32 -0
- package/dist/tmdl/types.d.ts.map +1 -0
- package/dist/tmdl/types.js +2 -0
- package/dist/tmdl/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -0
- package/src/engine/config.ts +91 -0
- package/src/engine/ignore.ts +18 -0
- package/src/engine/lint.ts +79 -0
- package/src/engine/rank.ts +67 -0
- package/src/engine/run.ts +67 -0
- package/src/format/index.ts +37 -0
- package/src/format/json.ts +22 -0
- package/src/format/markdown.ts +37 -0
- package/src/format/sarif.ts +85 -0
- package/src/format/text.ts +90 -0
- package/src/index/build.ts +18 -0
- package/src/index/references.ts +170 -0
- package/src/index/relationships.ts +33 -0
- package/src/index/usage.ts +33 -0
- package/src/index.ts +80 -0
- package/src/model/build.ts +306 -0
- package/src/model/names.ts +31 -0
- package/src/model/types.ts +165 -0
- package/src/rules/helpers.ts +223 -0
- package/src/rules/index.ts +5 -0
- package/src/rules/microsoft-bpa/bpa-rules.data.ts +782 -0
- package/src/rules/microsoft-bpa/columns.ts +192 -0
- package/src/rules/microsoft-bpa/define.ts +84 -0
- package/src/rules/microsoft-bpa/dependencies.ts +95 -0
- package/src/rules/microsoft-bpa/index.ts +22 -0
- package/src/rules/microsoft-bpa/live-model.ts +10 -0
- package/src/rules/microsoft-bpa/measures.ts +143 -0
- package/src/rules/microsoft-bpa/naming.ts +104 -0
- package/src/rules/microsoft-bpa/relationships.ts +189 -0
- package/src/rules/microsoft-bpa/tables.ts +249 -0
- package/src/rules/parse-issue.ts +23 -0
- package/src/rules/rule-summaries.data.ts +144 -0
- package/src/rules/types.ts +87 -0
- package/src/tmdl/parse.ts +194 -0
- package/src/tmdl/quote.ts +15 -0
- package/src/tmdl/types.ts +34 -0
- package/src/version.ts +2 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { defaultRules } from "../rules/index.js";
|
|
2
|
+
import { VERSION } from "../version.js";
|
|
3
|
+
const LEVEL = {
|
|
4
|
+
3: "error",
|
|
5
|
+
2: "warning",
|
|
6
|
+
1: "note",
|
|
7
|
+
};
|
|
8
|
+
/** Rule summaries are Markdown with inline code; SARIF's plain-text slot gets them without the backticks. */
|
|
9
|
+
const plain = (markdown) => markdown.replace(/`/g, "");
|
|
10
|
+
export function formatSarif(result, options = {}) {
|
|
11
|
+
const byId = new Map((options.rules ?? defaultRules).map((r) => [r.id, r]));
|
|
12
|
+
// Code scanning resolves artifact URIs against the repository root, so the caller can prefix the
|
|
13
|
+
// model root's path. Finding locations themselves stay relative to the model root.
|
|
14
|
+
const prefix = options.pathPrefix ?? "";
|
|
15
|
+
// SARIF artifact URIs are URIs, so each path segment is percent-encoded: a model folder with a
|
|
16
|
+
// space in its name would otherwise produce a location code scanning cannot resolve.
|
|
17
|
+
const encodePath = (p) => p.split("/").map(encodeURIComponent).join("/");
|
|
18
|
+
const uri = (file) => encodePath(prefix ? `${prefix}/${file}` : file);
|
|
19
|
+
// GitHub renders help.markdown beside the alert and ignores helpUri, so the page link rides
|
|
20
|
+
// inside the help block as well.
|
|
21
|
+
const helpFor = (id, description, url) => options.help?.[id] ?? {
|
|
22
|
+
text: `${plain(description)}\n\nRead more: ${url}`,
|
|
23
|
+
markdown: `${description}\n\nRead more: ${url}`,
|
|
24
|
+
};
|
|
25
|
+
const rules = result.groups.map((g) => {
|
|
26
|
+
const full = byId.get(g.rule.id);
|
|
27
|
+
return {
|
|
28
|
+
id: g.rule.id,
|
|
29
|
+
name: g.rule.name,
|
|
30
|
+
shortDescription: { text: g.rule.name },
|
|
31
|
+
fullDescription: full
|
|
32
|
+
? { text: plain(full.description), markdown: full.description }
|
|
33
|
+
: { text: g.rule.name },
|
|
34
|
+
help: helpFor(g.rule.id, full?.description ?? g.rule.name, g.rule.url),
|
|
35
|
+
helpUri: g.rule.url,
|
|
36
|
+
defaultConfiguration: { level: LEVEL[g.rule.severity] },
|
|
37
|
+
properties: { category: g.rule.category },
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
const results = result.groups.flatMap((g, ruleIndex) => g.findings.map((f) => ({
|
|
41
|
+
ruleId: g.rule.id,
|
|
42
|
+
ruleIndex,
|
|
43
|
+
level: LEVEL[g.rule.severity],
|
|
44
|
+
message: { text: `${f.objectName}: ${g.rule.name}${f.detail ? ` (${f.detail})` : ""}` },
|
|
45
|
+
...(f.location
|
|
46
|
+
? {
|
|
47
|
+
locations: [
|
|
48
|
+
{
|
|
49
|
+
physicalLocation: {
|
|
50
|
+
artifactLocation: { uri: uri(f.location.file) },
|
|
51
|
+
region: { startLine: f.location.line },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
}
|
|
56
|
+
: {}),
|
|
57
|
+
})));
|
|
58
|
+
const doc = {
|
|
59
|
+
$schema: "https://json.schemastore.org/sarif-2.1.0.json",
|
|
60
|
+
version: "2.1.0",
|
|
61
|
+
runs: [
|
|
62
|
+
{
|
|
63
|
+
tool: {
|
|
64
|
+
driver: {
|
|
65
|
+
name: "pbiplint",
|
|
66
|
+
version: options.toolVersion ?? VERSION,
|
|
67
|
+
informationUri: "https://pbiplint.com",
|
|
68
|
+
rules,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
results,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
return JSON.stringify(doc, null, 2) + "\n";
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/format/sarif.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LintResult } from "../engine/lint.js";
|
|
2
|
+
import type { RankedGroup } from "../engine/rank.js";
|
|
3
|
+
import { type Finding } from "../rules/types.js";
|
|
4
|
+
/** Guidance for one rule in the two forms SARIF carries: plain text and Markdown. */
|
|
5
|
+
export interface RuleHelp {
|
|
6
|
+
text: string;
|
|
7
|
+
markdown: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FormatOptions {
|
|
10
|
+
toolVersion?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Help per rule id for the SARIF help block, which code scanning shows beside each alert.
|
|
13
|
+
* The CLI passes the rule pages' Why, How to fix, and Quirks sections. Without it the block
|
|
14
|
+
* falls back to the rule's description and page URL.
|
|
15
|
+
*/
|
|
16
|
+
help?: Readonly<Record<string, RuleHelp>>;
|
|
17
|
+
rules?: import("../rules/types.js").Rule[];
|
|
18
|
+
/**
|
|
19
|
+
* Posix path (forward slashes, no leading "./", no trailing slash) joined in front of each
|
|
20
|
+
* SARIF artifact URI so code scanning can resolve it from the repository root. The text, JSON,
|
|
21
|
+
* and markdown formats ignore it: their paths stay relative to the model root.
|
|
22
|
+
*/
|
|
23
|
+
pathPrefix?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const locationOf: (f: Finding) => string;
|
|
26
|
+
/** Summary sentence shared by the text and markdown formats. */
|
|
27
|
+
export declare function summaryLine(result: LintResult): string;
|
|
28
|
+
export declare function skippedLine(result: LintResult): string;
|
|
29
|
+
export declare const topGroups: (result: LintResult, n?: number) => RankedGroup[];
|
|
30
|
+
export declare function formatText(result: LintResult, _options?: FormatOptions): string;
|
|
31
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/format/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjE,qFAAqF;AACrF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAE,OAAO,mBAAmB,EAAE,IAAI,EAAE,CAAC;IAC3C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,eAAO,MAAM,UAAU,GAAI,GAAG,OAAO,KAAG,MACmB,CAAC;AAK5D,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAGtD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAStD;AAED,eAAO,MAAM,SAAS,GAAI,QAAQ,UAAU,EAAE,UAAK,KAAG,WAAW,EAA+B,CAAC;AAEjG,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,GAAE,aAAkB,GAAG,MAAM,CAmCnF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { SEVERITY_LABEL } from "../rules/types.js";
|
|
2
|
+
const SEVERITY_TAG = { 3: "ERROR", 2: "WARN ", 1: "INFO " };
|
|
3
|
+
export const locationOf = (f) => f.location ? `${f.location.file}:${f.location.line}` : "";
|
|
4
|
+
/** "1 rule", "2 rules". Nouns that do not take an s ("info") are written out by the caller. */
|
|
5
|
+
const plural = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
6
|
+
/** Summary sentence shared by the text and markdown formats. */
|
|
7
|
+
export function summaryLine(result) {
|
|
8
|
+
const s = result.summary;
|
|
9
|
+
return `${plural(s.findings, "finding")} (${plural(s.errors, "error")}, ${plural(s.warnings, "warning")}, ${s.infos} info) in ${plural(s.files, "file")}`;
|
|
10
|
+
}
|
|
11
|
+
export function skippedLine(result) {
|
|
12
|
+
const s = result.summary;
|
|
13
|
+
const live = s.rulesSkipped.filter((r) => r.reason === "needsLiveModel").length;
|
|
14
|
+
const disabled = s.rulesSkipped.filter((r) => r.reason === "disabled").length;
|
|
15
|
+
const parts = [`${plural(s.rulesRun, "rule")} run`];
|
|
16
|
+
if (live)
|
|
17
|
+
parts.push(`${plural(live, "rule")} skipped (need a live model)`);
|
|
18
|
+
if (disabled)
|
|
19
|
+
parts.push(`${plural(disabled, "rule")} disabled by config`);
|
|
20
|
+
if (s.ignored)
|
|
21
|
+
parts.push(`${plural(s.ignored, "finding")} ignored by annotation`);
|
|
22
|
+
return parts.join(", ");
|
|
23
|
+
}
|
|
24
|
+
export const topGroups = (result, n = 5) => result.groups.slice(0, n);
|
|
25
|
+
export function formatText(result, _options = {}) {
|
|
26
|
+
const out = [`pbiplint: ${summaryLine(result)}`, skippedLine(result), ""];
|
|
27
|
+
if (result.groups.length === 0) {
|
|
28
|
+
out.push("No findings.", "");
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
out.push("Fix these first:");
|
|
32
|
+
topGroups(result).forEach((g, i) => out.push(` ${i + 1}. ${g.rule.name} (${plural(g.findings.length, SEVERITY_LABEL[g.rule.severity])})`));
|
|
33
|
+
out.push("");
|
|
34
|
+
for (const g of result.groups) {
|
|
35
|
+
out.push(`${SEVERITY_TAG[g.rule.severity]} ${g.rule.name} ${g.rule.id} (${g.findings.length})`);
|
|
36
|
+
out.push(` ${g.rule.url}`);
|
|
37
|
+
// The location column is always emitted, empty or not, so a finding without a location never
|
|
38
|
+
// shifts its detail into the location column. Widths align within the group only.
|
|
39
|
+
const width = Math.max(...g.findings.map((f) => f.objectName.length));
|
|
40
|
+
const locWidth = Math.max(...g.findings.map((f) => locationOf(f).length));
|
|
41
|
+
for (const f of g.findings) {
|
|
42
|
+
const cols = [f.objectName.padEnd(width), locationOf(f).padEnd(locWidth), f.detail ?? ""];
|
|
43
|
+
out.push(` ${cols.join(" ")}`.trimEnd());
|
|
44
|
+
}
|
|
45
|
+
out.push("");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Rule crashes are always reported, including on a run where nothing else fired.
|
|
49
|
+
if (result.summary.ruleErrors.length) {
|
|
50
|
+
out.push("Rule errors (please report these):");
|
|
51
|
+
for (const e of result.summary.ruleErrors)
|
|
52
|
+
out.push(` ${e.id}: ${e.message}`);
|
|
53
|
+
out.push("");
|
|
54
|
+
}
|
|
55
|
+
return out.join("\n");
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/format/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Model } from "../model/types.js";
|
|
2
|
+
import { type ReferenceIndex } from "./references.js";
|
|
3
|
+
import { type RelationshipIndex } from "./relationships.js";
|
|
4
|
+
import { type UsageIndex } from "./usage.js";
|
|
5
|
+
export interface Indexes {
|
|
6
|
+
relationships: RelationshipIndex;
|
|
7
|
+
usage: UsageIndex;
|
|
8
|
+
references: ReferenceIndex;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildIndexes(model: Model): Indexes;
|
|
11
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/index/build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,iBAAiB,CAAC;IACjC,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAMlD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { buildReferenceIndex } from "./references.js";
|
|
2
|
+
import { buildRelationshipIndex } from "./relationships.js";
|
|
3
|
+
import { buildUsageIndex } from "./usage.js";
|
|
4
|
+
export function buildIndexes(model) {
|
|
5
|
+
return {
|
|
6
|
+
relationships: buildRelationshipIndex(model),
|
|
7
|
+
usage: buildUsageIndex(model),
|
|
8
|
+
references: buildReferenceIndex(model),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/index/build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAA0B,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAQ9D,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,OAAO;QACL,aAAa,EAAE,sBAAsB,CAAC,KAAK,CAAC;QAC5C,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;QAC7B,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC;KACvC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { CalculationItem, Column, Measure, Model, Table, TablePermission } from "../model/types.js";
|
|
2
|
+
export type RefOwnerKind = "measure" | "calculatedColumn" | "calculatedTable" | "tablePermission" | "calculationItem";
|
|
3
|
+
export interface DaxRef {
|
|
4
|
+
kind: "column" | "measure" | "unresolved";
|
|
5
|
+
/** Canonical table name of the resolved object. */
|
|
6
|
+
table?: string;
|
|
7
|
+
/** Canonical name of the resolved object, or the raw name when unresolved. */
|
|
8
|
+
name: string;
|
|
9
|
+
qualified: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface RefOwner {
|
|
12
|
+
kind: RefOwnerKind;
|
|
13
|
+
object: Measure | Column | Table | TablePermission | CalculationItem;
|
|
14
|
+
ownerTable?: Table;
|
|
15
|
+
expression: string;
|
|
16
|
+
refs: DaxRef[];
|
|
17
|
+
}
|
|
18
|
+
export interface ReferenceIndex {
|
|
19
|
+
owners: RefOwner[];
|
|
20
|
+
refsOf(object: object): DaxRef[];
|
|
21
|
+
columnReferencedBy(c: Column): RefOwner[];
|
|
22
|
+
measureReferencedBy(m: Measure): RefOwner[];
|
|
23
|
+
}
|
|
24
|
+
interface RawRef {
|
|
25
|
+
table?: string;
|
|
26
|
+
name: string;
|
|
27
|
+
qualified: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Regex approximation of DAX dependencies: qualified refs first, then bare refs whose `[` was not
|
|
31
|
+
* part of a qualified match. Strings and comments are not skipped; that is the upgrade path if a
|
|
32
|
+
* fixture ever breaks parity because of it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractRefs(expression: string): RawRef[];
|
|
35
|
+
export declare function buildReferenceIndex(model: Model): ReferenceIndex;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../../src/index/references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,OAAO,EACP,KAAK,EACL,KAAK,EACL,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,YAAY,GACtB,SAAS,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAE7F,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;IAC1C,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,eAAe,GAAG,eAAe,CAAC;IACrE,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC1C,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;CAC7C;AAED,UAAU,MAAM;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAQD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAaxD;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,CAkGhE"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// Qualified: 'Table Name'[Column] or TableName[Column]. Bare: [Name]. An unquoted table name may
|
|
2
|
+
// contain Unicode letters and digits (Año, Größe), so the identifier branch matches \p{L} and
|
|
3
|
+
// \p{N} rather than ASCII word characters.
|
|
4
|
+
const QUALIFIED = /(?:'((?:[^']|'')+)'\s*|([\p{L}_][\p{L}\p{N}_]*))\[([^\]]+)\]/gu;
|
|
5
|
+
const BARE = /\[([^\]]+)\]/g;
|
|
6
|
+
/**
|
|
7
|
+
* Regex approximation of DAX dependencies: qualified refs first, then bare refs whose `[` was not
|
|
8
|
+
* part of a qualified match. Strings and comments are not skipped; that is the upgrade path if a
|
|
9
|
+
* fixture ever breaks parity because of it.
|
|
10
|
+
*/
|
|
11
|
+
export function extractRefs(expression) {
|
|
12
|
+
const out = [];
|
|
13
|
+
const consumed = new Set();
|
|
14
|
+
for (const m of expression.matchAll(QUALIFIED)) {
|
|
15
|
+
const table = m[1] !== undefined ? m[1].replace(/''/g, "'") : m[2];
|
|
16
|
+
out.push({ table, name: m[3], qualified: true });
|
|
17
|
+
consumed.add(m.index + m[0].length - m[3].length - 2);
|
|
18
|
+
}
|
|
19
|
+
for (const m of expression.matchAll(BARE)) {
|
|
20
|
+
if (consumed.has(m.index))
|
|
21
|
+
continue;
|
|
22
|
+
out.push({ name: m[1], qualified: false });
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
const lower = (s) => s.toLowerCase();
|
|
27
|
+
const key = (table, name) => `${lower(table)} ${lower(name)}`;
|
|
28
|
+
export function buildReferenceIndex(model) {
|
|
29
|
+
const tables = new Map(model.tables.map((t) => [lower(t.name), t]));
|
|
30
|
+
const columns = new Map();
|
|
31
|
+
const measures = new Map();
|
|
32
|
+
for (const t of model.tables) {
|
|
33
|
+
for (const c of t.columns)
|
|
34
|
+
columns.set(key(t.name, c.name), c);
|
|
35
|
+
for (const m of t.measures)
|
|
36
|
+
measures.set(lower(m.name), m);
|
|
37
|
+
}
|
|
38
|
+
const columnOf = (t, name) => columns.get(key(t.name, name));
|
|
39
|
+
const resolve = (raw, ownerTable, ownerKind) => {
|
|
40
|
+
if (raw.qualified) {
|
|
41
|
+
const t = tables.get(lower(raw.table));
|
|
42
|
+
if (!t)
|
|
43
|
+
return { kind: "unresolved", table: raw.table, name: raw.name, qualified: true };
|
|
44
|
+
const col = columnOf(t, raw.name);
|
|
45
|
+
if (col)
|
|
46
|
+
return { kind: "column", table: t.name, name: col.name, qualified: true };
|
|
47
|
+
const meas = t.measures.find((m) => lower(m.name) === lower(raw.name));
|
|
48
|
+
if (meas)
|
|
49
|
+
return { kind: "measure", table: t.name, name: meas.name, qualified: true };
|
|
50
|
+
return { kind: "unresolved", table: raw.table, name: raw.name, qualified: true };
|
|
51
|
+
}
|
|
52
|
+
const meas = measures.get(lower(raw.name));
|
|
53
|
+
if (meas)
|
|
54
|
+
return { kind: "measure", table: meas.table.name, name: meas.name, qualified: false };
|
|
55
|
+
if (ownerKind === "calculationItem")
|
|
56
|
+
return { kind: "unresolved", name: raw.name, qualified: false };
|
|
57
|
+
if (ownerTable) {
|
|
58
|
+
const col = columnOf(ownerTable, raw.name);
|
|
59
|
+
if (col)
|
|
60
|
+
return { kind: "column", table: ownerTable.name, name: col.name, qualified: false };
|
|
61
|
+
}
|
|
62
|
+
for (const t of model.tables) {
|
|
63
|
+
const col = columnOf(t, raw.name);
|
|
64
|
+
if (col)
|
|
65
|
+
return { kind: "column", table: t.name, name: col.name, qualified: false };
|
|
66
|
+
}
|
|
67
|
+
return { kind: "unresolved", name: raw.name, qualified: false };
|
|
68
|
+
};
|
|
69
|
+
const owners = [];
|
|
70
|
+
const byObject = new Map();
|
|
71
|
+
const add = (kind, object, ownerTable, ...expressions) => {
|
|
72
|
+
const expression = expressions.filter((e) => e !== undefined).join("\n");
|
|
73
|
+
const owner = {
|
|
74
|
+
kind,
|
|
75
|
+
object,
|
|
76
|
+
ownerTable,
|
|
77
|
+
expression,
|
|
78
|
+
refs: extractRefs(expression).map((r) => resolve(r, ownerTable, kind)),
|
|
79
|
+
};
|
|
80
|
+
owners.push(owner);
|
|
81
|
+
byObject.set(object, owner);
|
|
82
|
+
};
|
|
83
|
+
for (const t of model.tables) {
|
|
84
|
+
for (const m of t.measures)
|
|
85
|
+
add("measure", m, t, m.expression, m.formatStringDefinition);
|
|
86
|
+
for (const c of t.columns)
|
|
87
|
+
if (c.kind === "calculated")
|
|
88
|
+
add("calculatedColumn", c, t, c.expression);
|
|
89
|
+
if (t.kind === "calculated")
|
|
90
|
+
add("calculatedTable", t, t, ...t.partitions.filter((p) => p.sourceType === "calculated").map((p) => p.source));
|
|
91
|
+
for (const item of t.calculationGroup?.items ?? [])
|
|
92
|
+
add("calculationItem", item, t, item.expression, item.formatStringDefinition);
|
|
93
|
+
}
|
|
94
|
+
for (const role of model.roles) {
|
|
95
|
+
for (const tp of role.tablePermissions)
|
|
96
|
+
if (tp.filter !== undefined)
|
|
97
|
+
add("tablePermission", tp, tables.get(lower(tp.table)), tp.filter);
|
|
98
|
+
}
|
|
99
|
+
const columnRefs = new Map();
|
|
100
|
+
const measureRefs = new Map();
|
|
101
|
+
for (const o of owners) {
|
|
102
|
+
for (const r of o.refs) {
|
|
103
|
+
if (r.kind === "column") {
|
|
104
|
+
const k = key(r.table, r.name);
|
|
105
|
+
const arr = columnRefs.get(k) ?? [];
|
|
106
|
+
if (!arr.includes(o))
|
|
107
|
+
arr.push(o);
|
|
108
|
+
columnRefs.set(k, arr);
|
|
109
|
+
}
|
|
110
|
+
else if (r.kind === "measure") {
|
|
111
|
+
const k = lower(r.name);
|
|
112
|
+
const arr = measureRefs.get(k) ?? [];
|
|
113
|
+
if (!arr.includes(o))
|
|
114
|
+
arr.push(o);
|
|
115
|
+
measureRefs.set(k, arr);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
owners,
|
|
121
|
+
refsOf: (object) => byObject.get(object)?.refs ?? [],
|
|
122
|
+
columnReferencedBy: (c) => columnRefs.get(key(c.table.name, c.name)) ?? [],
|
|
123
|
+
measureReferencedBy: (m) => measureRefs.get(lower(m.name)) ?? [],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"references.js","sourceRoot":"","sources":["../../src/index/references.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Model, Relationship } from "../model/types.js";
|
|
2
|
+
export interface RelationshipIndex {
|
|
3
|
+
all: Relationship[];
|
|
4
|
+
/** Relationships in which the column is the from-side or the to-side. */
|
|
5
|
+
forColumn(table: string, column: string): Relationship[];
|
|
6
|
+
/** Relationships in which the table is on either side. */
|
|
7
|
+
forTable(table: string): Relationship[];
|
|
8
|
+
}
|
|
9
|
+
export declare function buildRelationshipIndex(model: Model): RelationshipIndex;
|
|
10
|
+
//# sourceMappingURL=relationships.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/index/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IACzD,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CACzC;AAUD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,GAAG,iBAAiB,CActE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const key = (table, column) => `${table} ${column}`;
|
|
2
|
+
function push(map, k, r) {
|
|
3
|
+
const arr = map.get(k);
|
|
4
|
+
if (!arr)
|
|
5
|
+
map.set(k, [r]);
|
|
6
|
+
else if (!arr.includes(r))
|
|
7
|
+
arr.push(r);
|
|
8
|
+
}
|
|
9
|
+
export function buildRelationshipIndex(model) {
|
|
10
|
+
const byColumn = new Map();
|
|
11
|
+
const byTable = new Map();
|
|
12
|
+
for (const r of model.relationships) {
|
|
13
|
+
push(byColumn, key(r.fromTable, r.fromColumn), r);
|
|
14
|
+
push(byColumn, key(r.toTable, r.toColumn), r);
|
|
15
|
+
push(byTable, r.fromTable, r);
|
|
16
|
+
push(byTable, r.toTable, r);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
all: model.relationships,
|
|
20
|
+
forColumn: (table, column) => byColumn.get(key(table, column)) ?? [],
|
|
21
|
+
forTable: (table) => byTable.get(table) ?? [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=relationships.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/index/relationships.ts"],"names":[],"mappings":"AAUA,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,MAAc,EAAU,EAAE,CAAC,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;AAE5E,SAAS,IAAI,CAAC,GAAgC,EAAE,CAAS,EAAE,CAAe;IACxE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACrB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAY;IACjD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,aAAa;QACxB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE;QACpE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;KAC9C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Column, Model } from "../model/types.js";
|
|
2
|
+
export interface UsageIndex {
|
|
3
|
+
/** Another column in the same table sorts by this column. */
|
|
4
|
+
usedInSortBy(c: Column): boolean;
|
|
5
|
+
/** A hierarchy level in the same table uses this column. */
|
|
6
|
+
usedInHierarchies(c: Column): boolean;
|
|
7
|
+
/** A variation anywhere names this column as its default column. */
|
|
8
|
+
usedInVariations(c: Column): boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildUsageIndex(model: Model): UsageIndex;
|
|
11
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/index/usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,6DAA6D;IAC7D,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,4DAA4D;IAC5D,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC,oEAAoE;IACpE,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CAmBxD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const key = (table, column) => `${table} ${column}`;
|
|
2
|
+
export function buildUsageIndex(model) {
|
|
3
|
+
const sortTargets = new Set();
|
|
4
|
+
const levelColumns = new Set();
|
|
5
|
+
const variationDefaults = new Set();
|
|
6
|
+
for (const t of model.tables) {
|
|
7
|
+
for (const c of t.columns) {
|
|
8
|
+
if (c.sortByColumn !== undefined)
|
|
9
|
+
sortTargets.add(key(t.name, c.sortByColumn));
|
|
10
|
+
for (const v of c.variations)
|
|
11
|
+
if (v.defaultColumn)
|
|
12
|
+
variationDefaults.add(key(v.defaultColumn.table, v.defaultColumn.column));
|
|
13
|
+
}
|
|
14
|
+
for (const h of t.hierarchies)
|
|
15
|
+
for (const l of h.levels)
|
|
16
|
+
if (l.column !== undefined)
|
|
17
|
+
levelColumns.add(key(t.name, l.column));
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
usedInSortBy: (c) => sortTargets.has(key(c.table.name, c.name)),
|
|
21
|
+
usedInHierarchies: (c) => levelColumns.has(key(c.table.name, c.name)),
|
|
22
|
+
usedInVariations: (c) => variationDefaults.has(key(c.table.name, c.name)),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/index/usage.ts"],"names":[],"mappings":"AAWA,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,MAAc,EAAU,EAAE,CAAC,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;AAE5E,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS;gBAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAC/E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU;gBAC1B,IAAI,CAAC,CAAC,aAAa;oBACjB,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;YAC3B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;gBAAE,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;oBAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAClG,CAAC;IACD,OAAO;QACL,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACrE,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;KAC1E,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { VERSION } from "./version.js";
|
|
2
|
+
export { ConfigError, resolveConfig, SEVERITY_BY_NAME, type PbiplintConfig, type ResolvedConfig, type SeverityName, } from "./engine/config.js";
|
|
3
|
+
export { IGNORE_ANNOTATION, isIgnored } from "./engine/ignore.js";
|
|
4
|
+
export { lint, type LintFile, type LintOptions, type LintResult, type LintSummary, } from "./engine/lint.js";
|
|
5
|
+
export { effectiveSeverity, rank, summarizeRule, type RankedGroup, type RuleSummary, } from "./engine/rank.js";
|
|
6
|
+
export { runRules, type RuleError, type RunResult, type SkippedRule } from "./engine/run.js";
|
|
7
|
+
export { FORMATS, formatResult, formatJson, formatMarkdown, formatSarif, formatText, skippedLine, summaryLine, topGroups, type FormatName, type FormatOptions, type RuleHelp, } from "./format/index.js";
|
|
8
|
+
export { buildIndexes, type Indexes } from "./index/build.js";
|
|
9
|
+
export { extractRefs, type DaxRef, type RefOwner, type RefOwnerKind, type ReferenceIndex, } from "./index/references.js";
|
|
10
|
+
export type { RelationshipIndex } from "./index/relationships.js";
|
|
11
|
+
export type { UsageIndex } from "./index/usage.js";
|
|
12
|
+
export { buildModel, splitQualifiedName } from "./model/build.js";
|
|
13
|
+
export { columnRef, measureRef, relationshipName, RULE_URL_BASE, ruleUrl, slug, tableRef, } from "./model/names.js";
|
|
14
|
+
export type * from "./model/types.js";
|
|
15
|
+
export { allCalculationItems, allColumns, allMeasures, allPartitions, allTablePermissions, columnObjectType, finding, namedObjects, tableObjectType, } from "./rules/helpers.js";
|
|
16
|
+
export { defaultRules } from "./rules/index.js";
|
|
17
|
+
export { BPA_RULES, type BpaRuleMeta } from "./rules/microsoft-bpa/bpa-rules.data.js";
|
|
18
|
+
export { bpaRule, liveModelRule, mapScope } from "./rules/microsoft-bpa/define.js";
|
|
19
|
+
export { microsoftBpaRules } from "./rules/microsoft-bpa/index.js";
|
|
20
|
+
export { PARSE_ISSUE } from "./rules/parse-issue.js";
|
|
21
|
+
export * from "./rules/types.js";
|
|
22
|
+
export { parseTmdl } from "./tmdl/parse.js";
|
|
23
|
+
export { unquoteName, unquoteValue } from "./tmdl/quote.js";
|
|
24
|
+
export type { ParsedFile, ParseIssue, TmdlNode, TmdlNodeKind } from "./tmdl/types.js";
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EACL,IAAI,EACJ,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,IAAI,EACJ,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EACL,OAAO,EACP,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EACL,WAAW,EACX,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,mBAAmB,kBAAkB,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { VERSION } from "./version.js";
|
|
2
|
+
export { ConfigError, resolveConfig, SEVERITY_BY_NAME, } from "./engine/config.js";
|
|
3
|
+
export { IGNORE_ANNOTATION, isIgnored } from "./engine/ignore.js";
|
|
4
|
+
export { lint, } from "./engine/lint.js";
|
|
5
|
+
export { effectiveSeverity, rank, summarizeRule, } from "./engine/rank.js";
|
|
6
|
+
export { runRules } from "./engine/run.js";
|
|
7
|
+
export { FORMATS, formatResult, formatJson, formatMarkdown, formatSarif, formatText, skippedLine, summaryLine, topGroups, } from "./format/index.js";
|
|
8
|
+
export { buildIndexes } from "./index/build.js";
|
|
9
|
+
export { extractRefs, } from "./index/references.js";
|
|
10
|
+
export { buildModel, splitQualifiedName } from "./model/build.js";
|
|
11
|
+
export { columnRef, measureRef, relationshipName, RULE_URL_BASE, ruleUrl, slug, tableRef, } from "./model/names.js";
|
|
12
|
+
export { allCalculationItems, allColumns, allMeasures, allPartitions, allTablePermissions, columnObjectType, finding, namedObjects, tableObjectType, } from "./rules/helpers.js";
|
|
13
|
+
export { defaultRules } from "./rules/index.js";
|
|
14
|
+
export { BPA_RULES } from "./rules/microsoft-bpa/bpa-rules.data.js";
|
|
15
|
+
export { bpaRule, liveModelRule, mapScope } from "./rules/microsoft-bpa/define.js";
|
|
16
|
+
export { microsoftBpaRules } from "./rules/microsoft-bpa/index.js";
|
|
17
|
+
export { PARSE_ISSUE } from "./rules/parse-issue.js";
|
|
18
|
+
export * from "./rules/types.js";
|
|
19
|
+
export { parseTmdl } from "./tmdl/parse.js";
|
|
20
|
+
export { unquoteName, unquoteValue } from "./tmdl/quote.js";
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,WAAW,EACX,aAAa,EACb,gBAAgB,GAIjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EACL,IAAI,GAKL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,IAAI,EACJ,aAAa,GAGd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAoD,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EACL,OAAO,EACP,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,GAIV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAgB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EACL,WAAW,GAKZ,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ParsedFile } from "../tmdl/types.js";
|
|
2
|
+
import type { Model } from "./types.js";
|
|
3
|
+
/** Split `Table.Column` or `'Some Table'.'Some Column'` into its unquoted parts. */
|
|
4
|
+
export declare function splitQualifiedName(ref: string): {
|
|
5
|
+
table: string;
|
|
6
|
+
column: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildModel(files: ParsedFile[]): Model;
|
|
9
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/model/build.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAQV,KAAK,EAUN,MAAM,YAAY,CAAC;AA2BpB,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKjF;AAsLD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,KAAK,CAsErD"}
|