@goodbones/core 0.1.0-beta.1 → 0.1.0-beta.11
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/build/dts/core/coverage.d.ts +20 -0
- package/build/dts/core/coverage.d.ts.map +1 -1
- package/build/dts/core/graph.d.ts +2 -0
- package/build/dts/core/graph.d.ts.map +1 -1
- package/build/dts/core/imports.d.ts +3 -1
- package/build/dts/core/imports.d.ts.map +1 -1
- package/build/dts/core/slack.d.ts +22 -0
- package/build/dts/core/slack.d.ts.map +1 -0
- package/build/dts/core/structure.d.ts +1 -0
- package/build/dts/core/structure.d.ts.map +1 -1
- package/build/dts/domain/architecture-config.d.ts +19 -3
- package/build/dts/domain/architecture-config.d.ts.map +1 -1
- package/build/dts/domain/architecture-error.d.ts +8 -0
- package/build/dts/domain/architecture-error.d.ts.map +1 -1
- package/build/dts/domain/facts.d.ts +1 -0
- package/build/dts/domain/facts.d.ts.map +1 -1
- package/build/dts/domain/manifest-location.d.ts +9 -0
- package/build/dts/domain/manifest-location.d.ts.map +1 -0
- package/build/dts/domain/snapshot.d.ts +356 -0
- package/build/dts/domain/snapshot.d.ts.map +1 -0
- package/build/dts/domain/violation.d.ts +1 -1
- package/build/dts/domain/violation.d.ts.map +1 -1
- package/build/dts/index.d.ts +22 -10
- package/build/dts/index.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-live.d.ts.map +1 -1
- package/build/dts/infrastructure/manifest-file.d.ts +11 -2
- package/build/dts/infrastructure/manifest-file.d.ts.map +1 -1
- package/build/dts/infrastructure/manifest-include.d.ts +16 -0
- package/build/dts/infrastructure/manifest-include.d.ts.map +1 -0
- package/build/dts/infrastructure/syntax-matcher-fake.d.ts +10 -0
- package/build/dts/infrastructure/syntax-matcher-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/walk.d.ts +12 -1
- package/build/dts/infrastructure/walk.d.ts.map +1 -1
- package/build/dts/load/extension.d.ts +33 -0
- package/build/dts/load/extension.d.ts.map +1 -0
- package/build/dts/load/policy.d.ts +10 -0
- package/build/dts/load/policy.d.ts.map +1 -1
- package/build/dts/manifest/compile.d.ts +11 -1
- package/build/dts/manifest/compile.d.ts.map +1 -1
- package/build/dts/manifest/expand.d.ts +27 -0
- package/build/dts/manifest/expand.d.ts.map +1 -0
- package/build/dts/manifest/extension.d.ts +8 -0
- package/build/dts/manifest/extension.d.ts.map +1 -0
- package/build/dts/manifest/glob.d.ts +1 -0
- package/build/dts/manifest/glob.d.ts.map +1 -1
- package/build/dts/manifest/infer.d.ts +55 -0
- package/build/dts/manifest/infer.d.ts.map +1 -0
- package/build/dts/manifest/json-schema.d.ts +14 -0
- package/build/dts/manifest/json-schema.d.ts.map +1 -0
- package/build/dts/manifest/manifest.d.ts +26 -1
- package/build/dts/manifest/manifest.d.ts.map +1 -1
- package/build/dts/ports/file-system.d.ts +1 -0
- package/build/dts/ports/file-system.d.ts.map +1 -1
- package/build/dts/ports/language.d.ts +4 -0
- package/build/dts/ports/language.d.ts.map +1 -1
- package/build/dts/ports/syntax-matcher.d.ts +21 -0
- package/build/dts/ports/syntax-matcher.d.ts.map +1 -0
- package/build/dts/testing.d.ts +1 -0
- package/build/dts/testing.d.ts.map +1 -1
- package/build/esm/core/coverage.js +107 -32
- package/build/esm/core/coverage.js.map +1 -1
- package/build/esm/core/graph.js +45 -0
- package/build/esm/core/graph.js.map +1 -1
- package/build/esm/core/imports.js +14 -9
- package/build/esm/core/imports.js.map +1 -1
- package/build/esm/core/slack.js +76 -0
- package/build/esm/core/slack.js.map +1 -0
- package/build/esm/core/structure.js +6 -3
- package/build/esm/core/structure.js.map +1 -1
- package/build/esm/domain/architecture-config.js +28 -4
- package/build/esm/domain/architecture-config.js.map +1 -1
- package/build/esm/domain/architecture-error.js +27 -0
- package/build/esm/domain/architecture-error.js.map +1 -1
- package/build/esm/domain/manifest-location.js +21 -0
- package/build/esm/domain/manifest-location.js.map +1 -0
- package/build/esm/domain/snapshot.js +181 -0
- package/build/esm/domain/snapshot.js.map +1 -0
- package/build/esm/domain/violation.js.map +1 -1
- package/build/esm/index.js +28 -9
- package/build/esm/index.js.map +1 -1
- package/build/esm/infrastructure/file-system-fake.js +10 -0
- package/build/esm/infrastructure/file-system-fake.js.map +1 -1
- package/build/esm/infrastructure/file-system-live.js +9 -1
- package/build/esm/infrastructure/file-system-live.js.map +1 -1
- package/build/esm/infrastructure/manifest-file.js +158 -7
- package/build/esm/infrastructure/manifest-file.js.map +1 -1
- package/build/esm/infrastructure/manifest-include.js +187 -0
- package/build/esm/infrastructure/manifest-include.js.map +1 -0
- package/build/esm/infrastructure/syntax-matcher-fake.js +33 -0
- package/build/esm/infrastructure/syntax-matcher-fake.js.map +1 -0
- package/build/esm/infrastructure/walk.js +106 -4
- package/build/esm/infrastructure/walk.js.map +1 -1
- package/build/esm/load/extension.js +2 -0
- package/build/esm/load/extension.js.map +1 -0
- package/build/esm/load/policy.js +49 -2
- package/build/esm/load/policy.js.map +1 -1
- package/build/esm/manifest/compile.js +50 -27
- package/build/esm/manifest/compile.js.map +1 -1
- package/build/esm/manifest/expand.js +116 -0
- package/build/esm/manifest/expand.js.map +1 -0
- package/build/esm/manifest/extension.js +2 -0
- package/build/esm/manifest/extension.js.map +1 -0
- package/build/esm/manifest/glob.js +3 -0
- package/build/esm/manifest/glob.js.map +1 -1
- package/build/esm/manifest/infer.js +455 -0
- package/build/esm/manifest/infer.js.map +1 -0
- package/build/esm/manifest/json-schema.js +169 -0
- package/build/esm/manifest/json-schema.js.map +1 -0
- package/build/esm/manifest/manifest.js +127 -5
- package/build/esm/manifest/manifest.js.map +1 -1
- package/build/esm/ports/syntax-matcher.js +12 -0
- package/build/esm/ports/syntax-matcher.js.map +1 -0
- package/build/esm/testing.js +1 -0
- package/build/esm/testing.js.map +1 -1
- package/package.json +9 -3
- package/schema/architecture-node.schema.json +1518 -0
- package/schema/architecture.schema.json +4498 -0
- package/schema/conformance.schema.json +1019 -0
- package/src/core/coverage.ts +164 -34
- package/src/core/graph.ts +48 -0
- package/src/core/imports.ts +29 -13
- package/src/core/slack.ts +135 -0
- package/src/core/structure.ts +15 -8
- package/src/domain/architecture-config.ts +31 -4
- package/src/domain/architecture-error.ts +30 -0
- package/src/domain/facts.ts +9 -4
- package/src/domain/manifest-location.ts +41 -0
- package/src/domain/snapshot.ts +402 -0
- package/src/domain/violation.ts +4 -1
- package/src/index.ts +149 -7
- package/src/infrastructure/file-system-fake.ts +12 -0
- package/src/infrastructure/file-system-live.ts +8 -1
- package/src/infrastructure/manifest-file.ts +204 -8
- package/src/infrastructure/manifest-include.ts +318 -0
- package/src/infrastructure/syntax-matcher-fake.ts +51 -0
- package/src/infrastructure/walk.ts +127 -3
- package/src/load/extension.ts +66 -0
- package/src/load/policy.ts +77 -2
- package/src/manifest/compile.ts +81 -30
- package/src/manifest/expand.ts +183 -0
- package/src/manifest/extension.ts +41 -0
- package/src/manifest/glob.ts +5 -0
- package/src/manifest/infer.ts +643 -0
- package/src/manifest/json-schema.ts +210 -0
- package/src/manifest/manifest.ts +206 -10
- package/src/ports/file-system.ts +3 -0
- package/src/ports/language.ts +17 -0
- package/src/ports/syntax-matcher.ts +42 -0
- package/src/testing.ts +1 -0
|
@@ -1,15 +1,166 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
1
3
|
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { isAlias, isMap, isScalar, isSeq, LineCounter, parseDocument, stringify, } from "yaml";
|
|
2
5
|
import { ConfigInvalid } from "../domain/architecture-error.js";
|
|
3
|
-
|
|
4
|
-
// The manifest, as the
|
|
5
|
-
//
|
|
6
|
-
//
|
|
6
|
+
import { expandIncludes } from "./manifest-include.js";
|
|
7
|
+
// The manifest, as the files on disk state it, before any decoding. A data
|
|
8
|
+
// file — YAML, or JSON, which YAML 1.2 contains — is what any host in any
|
|
9
|
+
// language can read, and is the form the docs are written in. A JavaScript
|
|
10
|
+
// module is the escape hatch a Node host alone honours: for a manifest
|
|
11
|
+
// generated from other data, and for what the ecosystem expects of a config
|
|
12
|
+
// file. Either may `include` further data files, so a monorepo's policy can
|
|
13
|
+
// live beside the packages it governs. Whichever it is, what comes out is one
|
|
14
|
+
// `unknown` value for the decoder, and, from the data formats, a way to turn
|
|
15
|
+
// a path in it back into a file and a line.
|
|
16
|
+
// In discovery order. A repository with none of these is told all four; one
|
|
17
|
+
// with more than one is refused, so nobody edits the wrong file for a week.
|
|
18
|
+
export const MANIFEST_FILENAMES = [
|
|
19
|
+
"architecture.yaml",
|
|
20
|
+
"architecture.yml",
|
|
21
|
+
"architecture.json",
|
|
22
|
+
"architecture.config.mjs",
|
|
23
|
+
];
|
|
24
|
+
export const findManifestFile = (repoRoot) => {
|
|
25
|
+
const present = MANIFEST_FILENAMES.filter((name) => existsSync(path.resolve(repoRoot, name)));
|
|
26
|
+
const [found] = present;
|
|
27
|
+
if (found === undefined) {
|
|
28
|
+
throw new ConfigInvalid({
|
|
29
|
+
configPath: repoRoot,
|
|
30
|
+
detail: `no architecture manifest found. Looked for ${MANIFEST_FILENAMES.join(", ")} ` +
|
|
31
|
+
`in this directory; \`architecture init\` writes a starter architecture.yaml.`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (present.length > 1) {
|
|
35
|
+
throw new ConfigInvalid({
|
|
36
|
+
configPath: repoRoot,
|
|
37
|
+
detail: `more than one architecture manifest is present (${present.join(", ")}), and only one ` +
|
|
38
|
+
`can be the policy. Delete the others, or name one with ARCHITECTURE_CONFIG.`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return path.resolve(repoRoot, found);
|
|
42
|
+
};
|
|
43
|
+
const extensionOf = (configPath) => path.extname(configPath).toLowerCase();
|
|
44
|
+
const isDataManifest = (configPath) => [".yaml", ".yml", ".json"].includes(extensionOf(configPath));
|
|
45
|
+
const isModuleManifest = (configPath) => [".mjs", ".js", ".cjs"].includes(extensionOf(configPath));
|
|
46
|
+
// Whichever form the root takes, an `include` in it names a data file, read
|
|
47
|
+
// by the same parser; the locator that comes back answers across every file.
|
|
7
48
|
export const readManifestFile = async (configPath) => {
|
|
49
|
+
const root = isDataManifest(configPath)
|
|
50
|
+
? parseDataFile(configPath)
|
|
51
|
+
: isModuleManifest(configPath)
|
|
52
|
+
? await readModule(configPath)
|
|
53
|
+
: undefined;
|
|
54
|
+
if (root === undefined) {
|
|
55
|
+
throw new ConfigInvalid({
|
|
56
|
+
configPath,
|
|
57
|
+
detail: "a manifest is a .yaml, .yml or .json file, or a .mjs/.js module — " +
|
|
58
|
+
`not ${JSON.stringify(path.basename(configPath))}.`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const assembled = expandIncludes(configPath, root, { exists: existsSync, read: parseDataFile });
|
|
62
|
+
return {
|
|
63
|
+
configPath,
|
|
64
|
+
manifest: assembled.value,
|
|
65
|
+
locate: assembled.locate,
|
|
66
|
+
files: assembled.files,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const readModule = async (configPath) => {
|
|
8
70
|
const module = await import(pathToFileURL(configPath).href).catch((cause) => {
|
|
9
71
|
throw new ConfigInvalid({ configPath, detail: String(cause) });
|
|
10
72
|
});
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
73
|
+
const value = typeof module === "object" && module !== null && "default" in module ? module.default : module;
|
|
74
|
+
return { value, locate: undefined };
|
|
75
|
+
};
|
|
76
|
+
// YAML 1.2 core schema, which is what a reader without a YAML background
|
|
77
|
+
// expects: `on` and `no` are strings, not booleans. Merge keys (`<<`) resolve,
|
|
78
|
+
// because the parser handles them before the manifest sees the document, and
|
|
79
|
+
// duplicate keys are refused rather than last-one-wins. A tag the parser does
|
|
80
|
+
// not know is refused too — a manifest is data, and a `!!js/function` in it
|
|
81
|
+
// would be a manifest only one runtime could read.
|
|
82
|
+
const parseDataFile = (configPath) => {
|
|
83
|
+
let text;
|
|
84
|
+
try {
|
|
85
|
+
text = readFileSync(configPath, "utf8");
|
|
86
|
+
}
|
|
87
|
+
catch (cause) {
|
|
88
|
+
throw new ConfigInvalid({ configPath, detail: String(cause) });
|
|
89
|
+
}
|
|
90
|
+
const lines = new LineCounter();
|
|
91
|
+
const document = parseDocument(text, {
|
|
92
|
+
merge: true,
|
|
93
|
+
uniqueKeys: true,
|
|
94
|
+
customTags: [],
|
|
95
|
+
lineCounter: lines,
|
|
96
|
+
// A JSON file is read by the same parser; strict JSON is valid YAML.
|
|
97
|
+
schema: "core",
|
|
98
|
+
});
|
|
99
|
+
const problems = [...document.errors, ...document.warnings];
|
|
100
|
+
if (problems.length > 0) {
|
|
101
|
+
const file = path.basename(configPath);
|
|
102
|
+
throw new ConfigInvalid({
|
|
103
|
+
configPath,
|
|
104
|
+
detail: "the manifest does not parse:\n" +
|
|
105
|
+
problems
|
|
106
|
+
.map((problem) => {
|
|
107
|
+
const [position] = problem.linePos ?? [];
|
|
108
|
+
const at = position === undefined
|
|
109
|
+
? ""
|
|
110
|
+
: `${file}:${String(position.line)}:${String(position.col)} `;
|
|
111
|
+
return ` ${at}${problem.code}: ${problem.message.split("\n")[0] ?? problem.message}`;
|
|
112
|
+
})
|
|
113
|
+
.join("\n"),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
value: document.toJS({ mapAsMap: false }),
|
|
118
|
+
locate: makeLocator(document, lines),
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
const keyMatches = (pair, segment) => isScalar(pair.key) && String(pair.key.value) === String(segment);
|
|
122
|
+
// Walks the document's own tree by the decoder's path and answers with the
|
|
123
|
+
// position of the deepest thing that exists along it. A map key is reported
|
|
124
|
+
// at the key, where the reader's eye lands; a sequence item at the item. A
|
|
125
|
+
// key merged in through `<<` lives in the fragment it came from, which the
|
|
126
|
+
// walk cannot see — the reader then gets the position of the map instead.
|
|
127
|
+
const makeLocator = (document, lines) => {
|
|
128
|
+
const positionOf = (node) => {
|
|
129
|
+
const offset = node?.range?.[0];
|
|
130
|
+
if (offset === undefined)
|
|
131
|
+
return null;
|
|
132
|
+
const { col, line } = lines.linePos(offset);
|
|
133
|
+
return { line, column: col };
|
|
134
|
+
};
|
|
135
|
+
const resolved = (node) => (isAlias(node) ? node.resolve(document) : node);
|
|
136
|
+
return (manifestPath) => {
|
|
137
|
+
let current = resolved(document.contents);
|
|
138
|
+
let position = positionOf(document.contents);
|
|
139
|
+
for (const segment of manifestPath) {
|
|
140
|
+
if (isMap(current)) {
|
|
141
|
+
const pair = current.items.find((one) => keyMatches(one, segment));
|
|
142
|
+
if (pair === undefined)
|
|
143
|
+
break;
|
|
144
|
+
position = positionOf(isScalar(pair.key) ? pair.key : null) ?? position;
|
|
145
|
+
current = resolved(pair.value);
|
|
146
|
+
}
|
|
147
|
+
else if (isSeq(current) && typeof segment === "number") {
|
|
148
|
+
const item = current.items[segment];
|
|
149
|
+
if (item === undefined)
|
|
150
|
+
break;
|
|
151
|
+
position = positionOf(item) ?? position;
|
|
152
|
+
current = resolved(item);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return position;
|
|
159
|
+
};
|
|
14
160
|
};
|
|
161
|
+
// The value as a YAML document, for `architecture migrate` and anything else
|
|
162
|
+
// that writes a manifest rather than reads one. Strings are quoted whenever
|
|
163
|
+
// the core schema would read them as something else, and a multi-line one —
|
|
164
|
+
// a probe source — becomes a block scalar.
|
|
165
|
+
export const formatManifestYaml = (manifest) => stringify(manifest, { lineWidth: 100, blockQuote: "literal", schema: "core" });
|
|
15
166
|
//# sourceMappingURL=manifest-file.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-file.js","sourceRoot":"","sources":["../../../src/infrastructure/manifest-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest-file.js","sourceRoot":"","sources":["../../../src/infrastructure/manifest-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { ConfigInvalid } from "../domain/architecture-error.js";
|
|
3
|
+
import { renderManifestPath, } from "../domain/manifest-location.js";
|
|
4
|
+
const INCLUDABLE = [".yaml", ".yml", ".json"];
|
|
5
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
const isInclude = (value) => isRecord(value) && "include" in value;
|
|
7
|
+
const isPrefix = (prefix, whole) => prefix.length <= whole.length && prefix.every((segment, index) => whole[index] === segment);
|
|
8
|
+
const makeLocator = (mounts) => {
|
|
9
|
+
if (!mounts.some((mount) => mount.locate !== undefined))
|
|
10
|
+
return undefined;
|
|
11
|
+
return (manifestPath) => {
|
|
12
|
+
const innermost = mounts
|
|
13
|
+
.filter((mount) => isPrefix(mount.at, manifestPath))
|
|
14
|
+
.sort((a, b) => a.at.length - b.at.length)
|
|
15
|
+
.at(-1);
|
|
16
|
+
if (innermost === undefined)
|
|
17
|
+
return null;
|
|
18
|
+
const found = innermost.locate?.([...innermost.origin, ...manifestPath.slice(innermost.at.length)]) ?? null;
|
|
19
|
+
if (found === null)
|
|
20
|
+
return null;
|
|
21
|
+
return innermost.label === undefined ? found : { ...found, file: innermost.label };
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export const expandIncludes = (rootPath, root, reader) => {
|
|
25
|
+
const rootDirectory = path.dirname(rootPath);
|
|
26
|
+
const labelOf = (file) => path.relative(rootDirectory, file).split(path.sep).join("/");
|
|
27
|
+
const nameOf = (source) => source.label ?? path.basename(rootPath);
|
|
28
|
+
const files = [rootPath];
|
|
29
|
+
const mounts = [{ at: [], origin: [], label: undefined, locate: root.locate }];
|
|
30
|
+
// Fragments hoisted out of included files, and the file each name came from.
|
|
31
|
+
const hoisted = {};
|
|
32
|
+
const definedIn = new Map();
|
|
33
|
+
const refuse = (source, origin, detail) => {
|
|
34
|
+
const position = source.locate?.(origin) ?? null;
|
|
35
|
+
const at = position === null
|
|
36
|
+
? ""
|
|
37
|
+
: `${nameOf(source)}:${String(position.line)}:${String(position.column)} `;
|
|
38
|
+
throw new ConfigInvalid({
|
|
39
|
+
configPath: rootPath,
|
|
40
|
+
detail: `the manifest does not include:\n ${at}${renderManifestPath(origin)}: ${detail}`,
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
// Checks a reference and reads the file it names. Nothing is placed yet:
|
|
44
|
+
// where the value lands depends on whether it is a list spliced into a list.
|
|
45
|
+
const open = (reference, origin, source) => {
|
|
46
|
+
const { include: specifier, ...rest } = reference;
|
|
47
|
+
if (typeof specifier !== "string") {
|
|
48
|
+
return refuse(source, origin, "`include` names a file, as a string.");
|
|
49
|
+
}
|
|
50
|
+
const shown = `\`include: ${JSON.stringify(specifier)}\``;
|
|
51
|
+
const beside = Object.keys(rest);
|
|
52
|
+
if (beside.length > 0) {
|
|
53
|
+
return refuse(source, origin, `${shown} stands alone: an included file is replaced whole, so there is nothing for ` +
|
|
54
|
+
`${beside.map((key) => `\`${key}\``).join(", ")} to override. ` +
|
|
55
|
+
`To override a fragment, put it under \`defs\` and \`use\` it.`);
|
|
56
|
+
}
|
|
57
|
+
const target = path.resolve(path.dirname(source.file), specifier);
|
|
58
|
+
if (!INCLUDABLE.includes(path.extname(target).toLowerCase())) {
|
|
59
|
+
return refuse(source, origin, `${shown} names a file that is not YAML or JSON. Only a data file can be included: ` +
|
|
60
|
+
`a module would make the manifest readable by one runtime only.`);
|
|
61
|
+
}
|
|
62
|
+
if (source.stack.includes(target)) {
|
|
63
|
+
return refuse(source, origin, `${shown} includes a file that is already being included: ` +
|
|
64
|
+
`${[...source.stack, target].map(labelOf).join(" → ")}.`);
|
|
65
|
+
}
|
|
66
|
+
if (!reader.exists(target)) {
|
|
67
|
+
return refuse(source, origin, `${shown} names a file that does not exist (looked for ${labelOf(target)}, ` +
|
|
68
|
+
`relative to ${nameOf(source)}).`);
|
|
69
|
+
}
|
|
70
|
+
const document = reader.read(target);
|
|
71
|
+
files.push(target);
|
|
72
|
+
return {
|
|
73
|
+
document,
|
|
74
|
+
source: {
|
|
75
|
+
file: target,
|
|
76
|
+
label: labelOf(target),
|
|
77
|
+
locate: document.locate,
|
|
78
|
+
stack: [...source.stack, target],
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
// Places an opened file at `at`, whole, and walks it so no reference is
|
|
83
|
+
// left inside. A top-level `defs` in the file joins the root's, and its
|
|
84
|
+
// `$schema` is for the editor — unless the file was included somewhere
|
|
85
|
+
// under `defs`, where it is a fragment or the map itself, and a key by
|
|
86
|
+
// either name is the author's.
|
|
87
|
+
const place = (opened, at) => {
|
|
88
|
+
const { document, source } = opened;
|
|
89
|
+
mounts.push({ at, origin: [], label: source.label, locate: source.locate });
|
|
90
|
+
if (!isRecord(document.value) || at[0] === "defs") {
|
|
91
|
+
return walk(document.value, at, [], source);
|
|
92
|
+
}
|
|
93
|
+
const { $schema: _schema, defs, ...body } = document.value;
|
|
94
|
+
if (defs !== undefined) {
|
|
95
|
+
if (!isRecord(defs)) {
|
|
96
|
+
return refuse(source, ["defs"], "`defs` must be a map of named fragments.");
|
|
97
|
+
}
|
|
98
|
+
for (const [name, fragment] of Object.entries(defs)) {
|
|
99
|
+
const already = definedIn.get(name);
|
|
100
|
+
if (already !== undefined) {
|
|
101
|
+
return refuse(source, ["defs", name], `\`defs.${name}\` is already defined in ${already}. Every file's \`defs\` share ` +
|
|
102
|
+
`one namespace; rename one of them.`);
|
|
103
|
+
}
|
|
104
|
+
definedIn.set(name, nameOf(source));
|
|
105
|
+
mounts.push({
|
|
106
|
+
at: ["defs", name],
|
|
107
|
+
origin: ["defs", name],
|
|
108
|
+
label: source.label,
|
|
109
|
+
locate: source.locate,
|
|
110
|
+
});
|
|
111
|
+
hoisted[name] = walk(fragment, ["defs", name], ["defs", name], source);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return walk(body, at, [], source);
|
|
115
|
+
};
|
|
116
|
+
// Appends each item of `list` to `items`. An include standing as an item
|
|
117
|
+
// whose file holds a list is spliced in, so a list can be split across
|
|
118
|
+
// files; an item that does not sit at the index it was written at is
|
|
119
|
+
// mounted on its own.
|
|
120
|
+
const append = (items, list, at, origin, source, spliced) => {
|
|
121
|
+
for (const [index, item] of list.entries()) {
|
|
122
|
+
const itemOrigin = [...origin, index];
|
|
123
|
+
const slot = [...at, items.length];
|
|
124
|
+
if (isInclude(item)) {
|
|
125
|
+
const opened = open(item, itemOrigin, source);
|
|
126
|
+
if (Array.isArray(opened.document.value)) {
|
|
127
|
+
append(items, opened.document.value, at, [], opened.source, true);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
items.push(place(opened, slot));
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (spliced || items.length !== index) {
|
|
135
|
+
mounts.push({ at: slot, origin: itemOrigin, label: source.label, locate: source.locate });
|
|
136
|
+
}
|
|
137
|
+
items.push(walk(item, slot, itemOrigin, source));
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const walk = (value, at, origin, source) => {
|
|
141
|
+
if (isInclude(value))
|
|
142
|
+
return place(open(value, origin, source), at);
|
|
143
|
+
if (Array.isArray(value)) {
|
|
144
|
+
const items = [];
|
|
145
|
+
append(items, value, at, origin, source, false);
|
|
146
|
+
return items;
|
|
147
|
+
}
|
|
148
|
+
if (isRecord(value)) {
|
|
149
|
+
const entries = {};
|
|
150
|
+
for (const [key, item] of Object.entries(value)) {
|
|
151
|
+
entries[key] = walk(item, [...at, key], [...origin, key], source);
|
|
152
|
+
}
|
|
153
|
+
return entries;
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
};
|
|
157
|
+
const rootSource = {
|
|
158
|
+
file: rootPath,
|
|
159
|
+
label: undefined,
|
|
160
|
+
locate: root.locate,
|
|
161
|
+
stack: [rootPath],
|
|
162
|
+
};
|
|
163
|
+
const value = walk(root.value, [], [], rootSource);
|
|
164
|
+
// Nothing was included: the value and the locator are the reader's own.
|
|
165
|
+
if (files.length === 1)
|
|
166
|
+
return { value, locate: root.locate, files };
|
|
167
|
+
const names = Object.keys(hoisted);
|
|
168
|
+
if (names.length === 0 || !isRecord(value)) {
|
|
169
|
+
return { value, locate: makeLocator(mounts), files };
|
|
170
|
+
}
|
|
171
|
+
const own = value.defs;
|
|
172
|
+
if (own !== undefined && !isRecord(own)) {
|
|
173
|
+
return refuse(rootSource, ["defs"], "`defs` must be a map of named fragments.");
|
|
174
|
+
}
|
|
175
|
+
for (const name of names) {
|
|
176
|
+
if (own !== undefined && name in own) {
|
|
177
|
+
return refuse(rootSource, ["defs", name], `\`defs.${name}\` is also defined in ${definedIn.get(name) ?? "an included file"}. ` +
|
|
178
|
+
`Every file's \`defs\` share one namespace; rename one of them.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
value: { ...value, defs: { ...(own ?? {}), ...hoisted } },
|
|
183
|
+
locate: makeLocator(mounts),
|
|
184
|
+
files,
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=manifest-include.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-include.js","sourceRoot":"","sources":["../../../src/infrastructure/manifest-include.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const ZERO = { line: 0, column: 0 };
|
|
2
|
+
// Keyed by the source text, as the extractor fake is: a core test states
|
|
3
|
+
// what a snippet's syntax yields and never the parse, which has its own
|
|
4
|
+
// tests in the matcher package. A text not staged parses to no matches; a
|
|
5
|
+
// file whose extension is not among `extensions` does not parse at all,
|
|
6
|
+
// which is the shape of a language with no matcher.
|
|
7
|
+
export const makeSyntaxMatcherFake = (staged, extensions = null) => ({
|
|
8
|
+
parse: (file, text) => {
|
|
9
|
+
if (extensions !== null && !extensions.some((extension) => file.endsWith(extension))) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const matches = staged[text] ?? [];
|
|
13
|
+
return {
|
|
14
|
+
// A staged match's line is what a position is anchored by.
|
|
15
|
+
anchorAt: (position) => matches.find((one) => one.line === position.line)?.anchor ?? null,
|
|
16
|
+
findAll: (rule) => {
|
|
17
|
+
const asked = JSON.stringify(rule);
|
|
18
|
+
return matches
|
|
19
|
+
.filter((one) => one.rule === undefined || JSON.stringify(one.rule) === asked)
|
|
20
|
+
.map((one) => ({
|
|
21
|
+
text: one.text,
|
|
22
|
+
captures: new Map(Object.entries(one.captures ?? {})),
|
|
23
|
+
range: {
|
|
24
|
+
start: one.line === undefined ? ZERO : { line: one.line, column: 0 },
|
|
25
|
+
end: one.line === undefined ? ZERO : { line: one.line, column: one.text.length },
|
|
26
|
+
},
|
|
27
|
+
anchor: one.anchor ?? null,
|
|
28
|
+
}));
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=syntax-matcher-fake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-matcher-fake.js","sourceRoot":"","sources":["../../../src/infrastructure/syntax-matcher-fake.ts"],"names":[],"mappings":"AAeA,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAEpC,yEAAyE;AACzE,wEAAwE;AACxE,0EAA0E;AAC1E,wEAAwE;AACxE,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,MAA4D,EAC5D,UAAU,GAAiC,IAAI,EAChC,EAAE,CAAC,CAAC;IACnB,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACpB,IAAI,UAAU,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YACrF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO;YACL,2DAA2D;YAC3D,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,IAAI;YACzF,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAChB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACnC,OAAO,OAAO;qBACX,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;qBAC7E,GAAG,CAAC,CAAC,GAAG,EAAe,EAAE,CAAC,CAAC;oBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;oBACrD,KAAK,EAAE;wBACL,KAAK,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE;wBACpE,GAAG,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE;qBACjF;oBACD,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI;iBAC3B,CAAC,CAAC,CAAC;YACR,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readdirSync, statSync } from "node:fs";
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
// Folders no policy is written about and no linter visits. These are the right
|
|
4
4
|
// defaults for any language on this host: a package store, build output, the
|
|
@@ -16,9 +16,11 @@ const SKIPPED = new Set([
|
|
|
16
16
|
// Which files count as source is the languages' to say: the extension set is
|
|
17
17
|
// the union of theirs, and so is the set of files to step over. A root that
|
|
18
18
|
// names a file is that file, whatever its extension — `architecture check
|
|
19
|
-
// <file>` is a reasonable thing to type.
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// <file>` is a reasonable thing to type. `widened` adds the extensions a
|
|
20
|
+
// campaign's scope names beyond the packs' — a file the pack cannot parse
|
|
21
|
+
// contributes no facts, and only a campaign that asked for it sees it.
|
|
22
|
+
export const listSourceFiles = (repoRoot, roots, languages, widened = []) => {
|
|
23
|
+
const extensions = new Set([...languages.flatMap((language) => language.extensions), ...widened]);
|
|
22
24
|
const ignored = languages.flatMap((language) => language.ignoredFiles);
|
|
23
25
|
const isSource = (entry) => extensions.has(path.extname(entry)) && !ignored.some((pattern) => pattern.test(entry));
|
|
24
26
|
const found = [];
|
|
@@ -42,4 +44,104 @@ export const listSourceFiles = (repoRoot, roots, languages) => {
|
|
|
42
44
|
}
|
|
43
45
|
return found.sort();
|
|
44
46
|
};
|
|
47
|
+
// The packages under (and above) `roots`: every folder holding one of the
|
|
48
|
+
// languages' marker files, the walk roots' own ancestors included, so a walk
|
|
49
|
+
// rooted at `src/` still finds the `package.json` beside it. Sorted by path.
|
|
50
|
+
export const listPackageRoots = (repoRoot, roots, languages) => {
|
|
51
|
+
const markers = languages.flatMap((language) => language.packageMarkers);
|
|
52
|
+
const sourceRoots = languages.flatMap((language) => language.sourceRoots);
|
|
53
|
+
if (markers.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const isDirectory = (absolute) => {
|
|
56
|
+
try {
|
|
57
|
+
return statSync(absolute).isDirectory();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const relative = (absolute) => path.relative(repoRoot, absolute).replaceAll(path.sep, "/");
|
|
64
|
+
const found = new Map();
|
|
65
|
+
const consider = (absolute) => {
|
|
66
|
+
const key = relative(absolute);
|
|
67
|
+
if (found.has(key))
|
|
68
|
+
return;
|
|
69
|
+
if (!markers.some((marker) => existsSync(path.join(absolute, marker))))
|
|
70
|
+
return;
|
|
71
|
+
const source = sourceRoots.find((name) => isDirectory(path.join(absolute, name)));
|
|
72
|
+
found.set(key, {
|
|
73
|
+
root: key,
|
|
74
|
+
source: source === undefined ? null : relative(path.join(absolute, source)),
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const walk = (absolute) => {
|
|
78
|
+
consider(absolute);
|
|
79
|
+
for (const entry of readdirSync(absolute)) {
|
|
80
|
+
if (SKIPPED.has(entry))
|
|
81
|
+
continue;
|
|
82
|
+
const child = path.join(absolute, entry);
|
|
83
|
+
if (isDirectory(child))
|
|
84
|
+
walk(child);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const top = path.resolve(repoRoot);
|
|
88
|
+
for (const root of roots) {
|
|
89
|
+
let absolute = path.resolve(repoRoot, root);
|
|
90
|
+
if (!isDirectory(absolute))
|
|
91
|
+
absolute = path.dirname(absolute);
|
|
92
|
+
walk(absolute);
|
|
93
|
+
// The ancestors, up to the repository: a package is as often above the
|
|
94
|
+
// walk root as inside it.
|
|
95
|
+
for (let above = absolute; above.startsWith(top); above = path.dirname(above)) {
|
|
96
|
+
consider(above);
|
|
97
|
+
if (above === top)
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return [...found.values()].sort((a, b) => a.root.localeCompare(b.root));
|
|
102
|
+
};
|
|
103
|
+
// The workspace's projects, for an `nx` perimeter: every folder under the
|
|
104
|
+
// roots holding a `project.json`, named by it — or, when it names nothing,
|
|
105
|
+
// by the `package.json` beside it, or the folder. Read from the files
|
|
106
|
+
// rather than from `nx graph`, so no process is spawned and a checkout
|
|
107
|
+
// without the workspace's tooling installed still has its sectors.
|
|
108
|
+
export const listWorkspaceProjects = (repoRoot, roots) => {
|
|
109
|
+
const found = [];
|
|
110
|
+
const nameIn = (absolute, file) => {
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(readFileSync(path.join(absolute, file), "utf8"));
|
|
113
|
+
const name = typeof parsed === "object" && parsed !== null
|
|
114
|
+
? parsed.name
|
|
115
|
+
: undefined;
|
|
116
|
+
return typeof name === "string" && name !== "" ? name : null;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const walk = (absolute) => {
|
|
123
|
+
if (existsSync(path.join(absolute, "project.json"))) {
|
|
124
|
+
const root = path.relative(repoRoot, absolute).replaceAll(path.sep, "/");
|
|
125
|
+
found.push({
|
|
126
|
+
name: nameIn(absolute, "project.json") ??
|
|
127
|
+
nameIn(absolute, "package.json") ??
|
|
128
|
+
path.basename(absolute),
|
|
129
|
+
root,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
for (const entry of readdirSync(absolute)) {
|
|
133
|
+
if (SKIPPED.has(entry))
|
|
134
|
+
continue;
|
|
135
|
+
const child = path.join(absolute, entry);
|
|
136
|
+
if (statSync(child).isDirectory())
|
|
137
|
+
walk(child);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
for (const root of roots) {
|
|
141
|
+
const absolute = path.resolve(repoRoot, root);
|
|
142
|
+
if (statSync(absolute).isDirectory())
|
|
143
|
+
walk(absolute);
|
|
144
|
+
}
|
|
145
|
+
return found.sort((a, b) => a.root.localeCompare(b.root));
|
|
146
|
+
};
|
|
45
147
|
//# sourceMappingURL=walk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../src/infrastructure/walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../src/infrastructure/walk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/load/extension.ts"],"names":[],"mappings":""}
|