@goodbones/core 0.1.0-beta.2 → 0.1.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/build/dts/core/graph.d.ts +1 -0
  2. package/build/dts/core/graph.d.ts.map +1 -1
  3. package/build/dts/domain/manifest-location.d.ts +2 -0
  4. package/build/dts/domain/manifest-location.d.ts.map +1 -1
  5. package/build/dts/index.d.ts +6 -4
  6. package/build/dts/index.d.ts.map +1 -1
  7. package/build/dts/infrastructure/manifest-file.d.ts +1 -0
  8. package/build/dts/infrastructure/manifest-file.d.ts.map +1 -1
  9. package/build/dts/infrastructure/manifest-include.d.ts +16 -0
  10. package/build/dts/infrastructure/manifest-include.d.ts.map +1 -0
  11. package/build/dts/infrastructure/walk.d.ts +6 -0
  12. package/build/dts/infrastructure/walk.d.ts.map +1 -1
  13. package/build/dts/manifest/infer.d.ts +55 -0
  14. package/build/dts/manifest/infer.d.ts.map +1 -0
  15. package/build/dts/manifest/json-schema.d.ts +2 -0
  16. package/build/dts/manifest/json-schema.d.ts.map +1 -1
  17. package/build/dts/manifest/manifest.d.ts +1 -1
  18. package/build/dts/manifest/manifest.d.ts.map +1 -1
  19. package/build/dts/ports/language.d.ts +2 -0
  20. package/build/dts/ports/language.d.ts.map +1 -1
  21. package/build/esm/core/graph.js +8 -0
  22. package/build/esm/core/graph.js.map +1 -1
  23. package/build/esm/domain/manifest-location.js +16 -1
  24. package/build/esm/domain/manifest-location.js.map +1 -1
  25. package/build/esm/index.js +6 -3
  26. package/build/esm/index.js.map +1 -1
  27. package/build/esm/infrastructure/manifest-file.js +31 -17
  28. package/build/esm/infrastructure/manifest-file.js.map +1 -1
  29. package/build/esm/infrastructure/manifest-include.js +187 -0
  30. package/build/esm/infrastructure/manifest-include.js.map +1 -0
  31. package/build/esm/infrastructure/walk.js +57 -1
  32. package/build/esm/infrastructure/walk.js.map +1 -1
  33. package/build/esm/manifest/infer.js +455 -0
  34. package/build/esm/manifest/infer.js.map +1 -0
  35. package/build/esm/manifest/json-schema.js +72 -17
  36. package/build/esm/manifest/json-schema.js.map +1 -1
  37. package/build/esm/manifest/manifest.js +7 -18
  38. package/build/esm/manifest/manifest.js.map +1 -1
  39. package/package.json +1 -1
  40. package/schema/architecture-node.schema.json +1518 -0
  41. package/schema/architecture.schema.json +1102 -691
  42. package/src/core/graph.ts +12 -0
  43. package/src/domain/manifest-location.ts +22 -0
  44. package/src/index.ts +33 -2
  45. package/src/infrastructure/manifest-file.ts +37 -17
  46. package/src/infrastructure/manifest-include.ts +318 -0
  47. package/src/infrastructure/walk.ts +70 -1
  48. package/src/manifest/infer.ts +643 -0
  49. package/src/manifest/json-schema.ts +83 -18
  50. package/src/manifest/manifest.ts +11 -20
  51. package/src/ports/language.ts +11 -0
@@ -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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"}
@@ -1,4 +1,4 @@
1
- import { readdirSync, statSync } from "node:fs";
1
+ import { existsSync, readdirSync, 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
@@ -42,4 +42,60 @@ export const listSourceFiles = (repoRoot, roots, languages) => {
42
42
  }
43
43
  return found.sort();
44
44
  };
45
+ // The packages under (and above) `roots`: every folder holding one of the
46
+ // languages' marker files, the walk roots' own ancestors included, so a walk
47
+ // rooted at `src/` still finds the `package.json` beside it. Sorted by path.
48
+ export const listPackageRoots = (repoRoot, roots, languages) => {
49
+ const markers = languages.flatMap((language) => language.packageMarkers);
50
+ const sourceRoots = languages.flatMap((language) => language.sourceRoots);
51
+ if (markers.length === 0)
52
+ return [];
53
+ const isDirectory = (absolute) => {
54
+ try {
55
+ return statSync(absolute).isDirectory();
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ };
61
+ const relative = (absolute) => path.relative(repoRoot, absolute).replaceAll(path.sep, "/");
62
+ const found = new Map();
63
+ const consider = (absolute) => {
64
+ const key = relative(absolute);
65
+ if (found.has(key))
66
+ return;
67
+ if (!markers.some((marker) => existsSync(path.join(absolute, marker))))
68
+ return;
69
+ const source = sourceRoots.find((name) => isDirectory(path.join(absolute, name)));
70
+ found.set(key, {
71
+ root: key,
72
+ source: source === undefined ? null : relative(path.join(absolute, source)),
73
+ });
74
+ };
75
+ const walk = (absolute) => {
76
+ consider(absolute);
77
+ for (const entry of readdirSync(absolute)) {
78
+ if (SKIPPED.has(entry))
79
+ continue;
80
+ const child = path.join(absolute, entry);
81
+ if (isDirectory(child))
82
+ walk(child);
83
+ }
84
+ };
85
+ const top = path.resolve(repoRoot);
86
+ for (const root of roots) {
87
+ let absolute = path.resolve(repoRoot, root);
88
+ if (!isDirectory(absolute))
89
+ absolute = path.dirname(absolute);
90
+ walk(absolute);
91
+ // The ancestors, up to the repository: a package is as often above the
92
+ // walk root as inside it.
93
+ for (let above = absolute; above.startsWith(top); above = path.dirname(above)) {
94
+ consider(above);
95
+ if (above === top)
96
+ break;
97
+ }
98
+ }
99
+ return [...found.values()].sort((a, b) => a.root.localeCompare(b.root));
100
+ };
45
101
  //# 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;AAChD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,+EAA+E;AAC/E,6EAA6E;AAC7E,yDAAyD;AACzD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,cAAc;IACd,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,kBAAkB;IAClB,UAAU;CACX,CAAC,CAAC;AAMH,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,QAAgB,EAChB,KAA4B,EAC5B,SAAwC,EACjB,EAAE;IACzB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAW,EAAE,CAC1C,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzF,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAQ,EAAE;QACtC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAC;iBAC1C,IAAI,QAAQ,CAAC,KAAK,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;YAChD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAC"}
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../src/infrastructure/walk.ts"],"names":[],"mappings":"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"}