usedesign 0.2.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 +201 -0
- package/README.md +85 -0
- package/dist/checks.d.ts +29 -0
- package/dist/checks.js +0 -0
- package/dist/checks.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +131 -0
- package/dist/cli.js.map +1 -0
- package/dist/conformance.d.ts +8 -0
- package/dist/conformance.js +92 -0
- package/dist/conformance.js.map +1 -0
- package/dist/core.d.ts +52 -0
- package/dist/core.js +133 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/schema/config.schema.json +61 -0
- package/dist/schema/operation-card.schema.json +984 -0
- package/dist/schema/route-inventory.schema.json +51 -0
- package/dist/validate.d.ts +18 -0
- package/dist/validate.js +259 -0
- package/dist/validate.js.map +1 -0
- package/package.json +49 -0
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type Severity = "error" | "warning";
|
|
2
|
+
export declare class Finding {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly detail: string;
|
|
5
|
+
readonly severity: Severity;
|
|
6
|
+
constructor(code: string, detail: string, severity?: Severity);
|
|
7
|
+
toString(): string;
|
|
8
|
+
}
|
|
9
|
+
export declare const errors: (findings: Finding[]) => Finding[];
|
|
10
|
+
export declare const warnings: (findings: Finding[]) => Finding[];
|
|
11
|
+
export declare const codesOf: (findings: Finding[]) => string[];
|
|
12
|
+
/** A card's front matter, as parsed. Deliberately loose: the schema is what judges its shape. */
|
|
13
|
+
export type Card = Record<string, any>;
|
|
14
|
+
export interface Config {
|
|
15
|
+
usedesign_config?: number;
|
|
16
|
+
cards?: string[];
|
|
17
|
+
inventory?: string;
|
|
18
|
+
test_report?: string;
|
|
19
|
+
code_root?: string;
|
|
20
|
+
evidence_horizon_days?: number;
|
|
21
|
+
exclude?: {
|
|
22
|
+
path?: string;
|
|
23
|
+
method?: string;
|
|
24
|
+
reason?: string;
|
|
25
|
+
}[];
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Return the parsed YAML front matter, or null if the file has none.
|
|
30
|
+
*
|
|
31
|
+
* The delimiter search matches the Python prototype exactly — `\n---` after the opening fence —
|
|
32
|
+
* because two implementations disagreeing about where a card ends is the same class of defect
|
|
33
|
+
* this project exists to catch.
|
|
34
|
+
*/
|
|
35
|
+
export declare function frontMatter(path: string): Card | null;
|
|
36
|
+
export declare function loadConfig(path: string): {
|
|
37
|
+
config: Config;
|
|
38
|
+
base: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Expand a glob relative to `base`. Supports `*`, `?` and `**`; enough for `cards:` patterns and
|
|
42
|
+
* small enough to keep the tool dependency-light, which matters for something meant to be run
|
|
43
|
+
* with `npx` inside somebody else's CI.
|
|
44
|
+
*/
|
|
45
|
+
export declare function expandGlob(base: string, pattern: string): string[];
|
|
46
|
+
/** Every card the config points at, as [id, front matter]. */
|
|
47
|
+
export declare function loadCardFiles(config: Config, base: string): {
|
|
48
|
+
cards: [string, Card][];
|
|
49
|
+
findings: Finding[];
|
|
50
|
+
};
|
|
51
|
+
/** Collect `*.op.md` under the given files or directories. */
|
|
52
|
+
export declare function collectCards(paths: string[]): string[];
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared machinery: findings, front matter, config, and the small amount of path globbing the
|
|
3
|
+
* tool needs. Nothing here decides anything about a card — the rules live in `validate.ts` and
|
|
4
|
+
* `checks.ts`, so that a change to a rule never hides inside a helper.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
7
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
8
|
+
import { parse as parseYaml } from "yaml";
|
|
9
|
+
export class Finding {
|
|
10
|
+
code;
|
|
11
|
+
detail;
|
|
12
|
+
severity;
|
|
13
|
+
constructor(code, detail, severity = "error") {
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.detail = detail;
|
|
16
|
+
this.severity = severity;
|
|
17
|
+
}
|
|
18
|
+
toString() {
|
|
19
|
+
return `${this.code}: ${this.detail}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const errors = (findings) => findings.filter((f) => f.severity === "error");
|
|
23
|
+
export const warnings = (findings) => findings.filter((f) => f.severity === "warning");
|
|
24
|
+
export const codesOf = (findings) => [...new Set(findings.map((f) => f.code))].sort();
|
|
25
|
+
/**
|
|
26
|
+
* Return the parsed YAML front matter, or null if the file has none.
|
|
27
|
+
*
|
|
28
|
+
* The delimiter search matches the Python prototype exactly — `\n---` after the opening fence —
|
|
29
|
+
* because two implementations disagreeing about where a card ends is the same class of defect
|
|
30
|
+
* this project exists to catch.
|
|
31
|
+
*/
|
|
32
|
+
export function frontMatter(path) {
|
|
33
|
+
// Line endings and a byte-order mark must never decide whether a card parses. Left alone, a
|
|
34
|
+
// CRLF file hands the YAML parser a dangling carriage return after the closing fence, and a
|
|
35
|
+
// card written on Windows fails on a rule that has nothing to do with its content.
|
|
36
|
+
const text = readFileSync(path, "utf8").replace(/^/, "").replace(/\r\n/g, "\n");
|
|
37
|
+
if (!text.startsWith("---"))
|
|
38
|
+
return null;
|
|
39
|
+
const end = text.indexOf("\n---", 3);
|
|
40
|
+
if (end === -1)
|
|
41
|
+
return null;
|
|
42
|
+
const parsed = parseYaml(text.slice(3, end));
|
|
43
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
44
|
+
}
|
|
45
|
+
export function loadConfig(path) {
|
|
46
|
+
const config = parseYaml(readFileSync(path, "utf8"));
|
|
47
|
+
if (!config || typeof config !== "object" || config.usedesign_config !== 1) {
|
|
48
|
+
throw new Error(`${path}: not a usedesign config (expected \`usedesign_config: 1\`)`);
|
|
49
|
+
}
|
|
50
|
+
return { config, base: dirname(resolve(path)) };
|
|
51
|
+
}
|
|
52
|
+
/** Translate one glob segment into a regular expression. `*` and `?` do not cross a separator. */
|
|
53
|
+
function segmentToRegExp(segment) {
|
|
54
|
+
const escaped = segment.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/\\\\]*").replace(/\?/g, "[^/\\\\]");
|
|
55
|
+
return new RegExp(`^${escaped}$`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Expand a glob relative to `base`. Supports `*`, `?` and `**`; enough for `cards:` patterns and
|
|
59
|
+
* small enough to keep the tool dependency-light, which matters for something meant to be run
|
|
60
|
+
* with `npx` inside somebody else's CI.
|
|
61
|
+
*/
|
|
62
|
+
export function expandGlob(base, pattern) {
|
|
63
|
+
const segments = pattern.split(/[\\/]+/).filter((s) => s.length > 0);
|
|
64
|
+
let current = [resolve(base)];
|
|
65
|
+
for (const [index, segment] of segments.entries()) {
|
|
66
|
+
const last = index === segments.length - 1;
|
|
67
|
+
const next = [];
|
|
68
|
+
if (segment === "**") {
|
|
69
|
+
for (const dir of current) {
|
|
70
|
+
const stack = [dir];
|
|
71
|
+
while (stack.length) {
|
|
72
|
+
const here = stack.pop();
|
|
73
|
+
next.push(here);
|
|
74
|
+
if (!existsSync(here))
|
|
75
|
+
continue;
|
|
76
|
+
for (const entry of readdirSync(here, { withFileTypes: true })) {
|
|
77
|
+
if (entry.isDirectory())
|
|
78
|
+
stack.push(join(here, entry.name));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (segment === "." || segment === "..") {
|
|
84
|
+
next.push(...current.map((dir) => resolve(dir, segment)));
|
|
85
|
+
}
|
|
86
|
+
else if (!/[*?]/.test(segment)) {
|
|
87
|
+
next.push(...current.map((dir) => join(dir, segment)));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const matcher = segmentToRegExp(segment);
|
|
91
|
+
for (const dir of current) {
|
|
92
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory())
|
|
93
|
+
continue;
|
|
94
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
95
|
+
if (matcher.test(entry.name) && (last || entry.isDirectory()))
|
|
96
|
+
next.push(join(dir, entry.name));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
current = [...new Set(next)];
|
|
101
|
+
}
|
|
102
|
+
return current.filter((path) => existsSync(path) && statSync(path).isFile()).sort();
|
|
103
|
+
}
|
|
104
|
+
/** Every card the config points at, as [id, front matter]. */
|
|
105
|
+
export function loadCardFiles(config, base) {
|
|
106
|
+
const findings = [];
|
|
107
|
+
const files = new Set();
|
|
108
|
+
for (const pattern of config.cards ?? []) {
|
|
109
|
+
for (const file of expandGlob(base, pattern))
|
|
110
|
+
files.add(file);
|
|
111
|
+
}
|
|
112
|
+
if (files.size === 0)
|
|
113
|
+
findings.push(new Finding("no_cards_found", "the `cards` patterns matched nothing"));
|
|
114
|
+
const cards = [];
|
|
115
|
+
for (const path of [...files].sort()) {
|
|
116
|
+
const fm = frontMatter(path);
|
|
117
|
+
if (fm)
|
|
118
|
+
cards.push([String(fm["id"] ?? path.split(sep).pop()), fm]);
|
|
119
|
+
}
|
|
120
|
+
return { cards, findings };
|
|
121
|
+
}
|
|
122
|
+
/** Collect `*.op.md` under the given files or directories. */
|
|
123
|
+
export function collectCards(paths) {
|
|
124
|
+
const files = [];
|
|
125
|
+
for (const path of paths) {
|
|
126
|
+
if (existsSync(path) && statSync(path).isDirectory())
|
|
127
|
+
files.push(...expandGlob(path, "**/*.op.md"));
|
|
128
|
+
else
|
|
129
|
+
files.push(path);
|
|
130
|
+
}
|
|
131
|
+
return [...new Set(files)].sort();
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Library entry point — the same functions the CLI uses, for embedding in another tool. */
|
|
2
|
+
export { Finding, codesOf, errors, warnings, frontMatter, loadConfig, loadCardFiles, expandGlob, collectCards } from "./core.js";
|
|
3
|
+
export type { Card, Config, Severity } from "./core.js";
|
|
4
|
+
export { validate, validateSchema, schemaPathFor, MATURITY } from "./validate.js";
|
|
5
|
+
export { CHECKS, checkRoutes, checkCoverage, checkMaturity, normalise, findCases, evidencePaths } from "./checks.js";
|
|
6
|
+
export type { CheckResult, TestCase } from "./checks.js";
|
|
7
|
+
export { runCardCorpus, runChecksCorpus } from "./conformance.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Library entry point — the same functions the CLI uses, for embedding in another tool. */
|
|
2
|
+
export { Finding, codesOf, errors, warnings, frontMatter, loadConfig, loadCardFiles, expandGlob, collectCards } from "./core.js";
|
|
3
|
+
export { validate, validateSchema, schemaPathFor, MATURITY } from "./validate.js";
|
|
4
|
+
export { CHECKS, checkRoutes, checkCoverage, checkMaturity, normalise, findCases, evidencePaths } from "./checks.js";
|
|
5
|
+
export { runCardCorpus, runChecksCorpus } from "./conformance.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEjI,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAErH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/nistoc/usedesign/schema/config.schema.json",
|
|
4
|
+
"title": "usedesign.config.yaml",
|
|
5
|
+
"description": "The one configuration file of the project. Everything else is description. Lives at the root of the checked repository.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["usedesign_config", "cards"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"usedesign_config": { "const": 1 },
|
|
11
|
+
"cards": {
|
|
12
|
+
"type": "array",
|
|
13
|
+
"minItems": 1,
|
|
14
|
+
"items": { "type": "string" },
|
|
15
|
+
"description": "Glob patterns locating the operation cards."
|
|
16
|
+
},
|
|
17
|
+
"inventory": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Path to the route inventory (schema/route-inventory.schema.json). Without it, check 1 cannot run and is reported as not run — never as passed."
|
|
20
|
+
},
|
|
21
|
+
"code_root": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Root the `maturity_evidence.implemented` paths are resolved against. Without it, the path part of check 3 is reported as not run — never as passed."
|
|
24
|
+
},
|
|
25
|
+
"evidence_horizon_days": {
|
|
26
|
+
"type": "integer",
|
|
27
|
+
"minimum": 1,
|
|
28
|
+
"default": 180,
|
|
29
|
+
"description": "How long an unverifiable claim (a dated `deployed`) is accepted before it is reported as stale. Any number is wrong for somebody, which is why it is configurable."
|
|
30
|
+
},
|
|
31
|
+
"test_report": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Path to a JUnit XML report from the run being checked. Without it, check 2 cannot confirm that the tests a card names exist and pass, and is reported as not run — never as passed. Freshness is procedural: run the check in the same CI job as the suite. See design/step-coverage.md §6."
|
|
34
|
+
},
|
|
35
|
+
"exclude": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"description": "Routes that are deliberately not operations: health probes, metrics, generated documentation UI, static assets.",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"required": ["path", "reason"],
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"properties": {
|
|
43
|
+
"path": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Glob over the normalised path, e.g. '/health' or '/docs/**'."
|
|
46
|
+
},
|
|
47
|
+
"method": {
|
|
48
|
+
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
|
|
49
|
+
"description": "Optional. Omitted means every method."
|
|
50
|
+
},
|
|
51
|
+
"reason": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"minLength": 1,
|
|
54
|
+
"$comment": "Required, for the same reason a relaxed concurrency policy requires a rationale: an exclusion is a hole in the check, and a hole nobody had to justify is a hole nobody will revisit.",
|
|
55
|
+
"description": "Why this is not an operation."
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|