@prestack/thread 0.1.3 → 0.1.5
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/CHANGELOG.md +563 -0
- package/dist/core/actor.d.ts +1 -1
- package/dist/core/actor.js +5 -4
- package/dist/core/actor.ts +5 -4
- package/dist/core/attach.d.ts +0 -7
- package/dist/core/attach.js +38 -67
- package/dist/core/attach.ts +34 -80
- package/dist/core/chain.js +13 -17
- package/dist/core/chain.ts +11 -15
- package/dist/core/condition.d.ts +4 -4
- package/dist/core/condition.js +2 -2
- package/dist/core/descend.d.ts +4 -2
- package/dist/core/descend.js +91 -23
- package/dist/core/descend.ts +90 -21
- package/dist/core/errors/catalogue.d.ts +52 -0
- package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
- package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
- package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
- package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
- package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
- package/dist/core/errors/namespaces.d.ts +3 -0
- package/dist/core/errors/namespaces.js +15 -0
- package/dist/core/errors/namespaces.ts +19 -0
- package/dist/core/finding.js +2 -2
- package/dist/core/finding.ts +1 -2
- package/dist/core/init.d.ts +1 -1
- package/dist/core/init.js +51 -5
- package/dist/core/init.ts +58 -5
- package/dist/core/invoked.d.ts +1 -1
- package/dist/core/invoked.js +3 -1
- package/dist/core/invoked.ts +5 -2
- package/dist/core/round.js +36 -22
- package/dist/core/round.ts +26 -9
- package/dist/core/rows.d.ts +4 -0
- package/dist/core/rows.js +31 -2
- package/dist/core/rows.ts +33 -1
- package/dist/core/scope.d.ts +1 -0
- package/dist/core/scope.js +1 -0
- package/dist/core/scope.ts +2 -0
- package/dist/core/thread.d.ts +3 -3
- package/dist/core/tree.d.ts +4 -1
- package/dist/core/tree.js +26 -6
- package/dist/core/tree.ts +29 -6
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +3 -1
- package/dist/core/types.ts +2 -1
- package/dist/derivation/attach.js +3 -2
- package/dist/derivation/attach.ts +2 -1
- package/dist/derivation/generators/build.js +6 -6
- package/dist/derivation/generators/build.ts +1 -1
- package/dist/derivation/generators/check.js +1 -1
- package/dist/derivation/generators/determinism.js +1 -1
- package/dist/derivation/generators/release.js +60 -47
- package/dist/derivation/generators/release.ts +66 -43
- package/dist/derivation/release.d.ts +7 -3
- package/dist/derivation/release.js +14 -1
- package/dist/derivation/release.ts +22 -2
- package/dist/integrations/attach.d.ts +4 -0
- package/dist/integrations/attach.js +37 -56
- package/dist/integrations/attach.ts +54 -60
- package/dist/integrations/cli.d.ts +37 -0
- package/dist/integrations/cli.js +440 -0
- package/dist/integrations/cli.ts +543 -0
- package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -24
- package/dist/integrations/disk.js +435 -0
- package/dist/integrations/disk.ts +465 -0
- package/dist/integrations/generators/read.js +6 -6
- package/dist/integrations/generators/read.ts +4 -4
- package/dist/integrations/generators/vault.js +10 -11
- package/dist/integrations/generators/vault.ts +4 -5
- package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
- package/dist/integrations/https.js +170 -0
- package/dist/integrations/https.ts +216 -0
- package/dist/integrations/pglite.d.ts +26 -0
- package/dist/integrations/pglite.js +143 -0
- package/dist/integrations/pglite.ts +206 -0
- package/dist/integrations/secret.d.ts +8 -2
- package/dist/integrations/secret.js +3 -5
- package/dist/integrations/secret.ts +10 -6
- package/dist/integrations/target.d.ts +155 -14
- package/dist/integrations/target.js +171 -50
- package/dist/integrations/target.ts +377 -61
- package/dist/integrations/vault.d.ts +1 -0
- package/dist/integrations/vault.js +20 -5
- package/dist/integrations/vault.ts +17 -5
- package/dist/integrity/attach.js +8 -77
- package/dist/integrity/attach.ts +7 -76
- package/dist/integrity/check-threads.js +5 -5
- package/dist/integrity/check-threads.ts +2 -2
- package/dist/integrity/constraint.d.ts +0 -1
- package/dist/integrity/constraint.js +267 -366
- package/dist/integrity/constraint.ts +267 -375
- package/dist/integrity/generators/compiler.js +14 -17
- package/dist/integrity/generators/compiler.ts +10 -15
- package/dist/integrity/generators/gate.js +15 -15
- package/dist/integrity/generators/gate.ts +10 -10
- package/dist/integrity/generators/issues.js +7 -7
- package/dist/integrity/generators/publish.js +39 -57
- package/dist/integrity/generators/publish.ts +44 -55
- package/dist/integrity/generators/trial.d.ts +3 -3
- package/dist/integrity/generators/trial.js +133 -165
- package/dist/integrity/generators/trial.ts +145 -169
- package/dist/integrity/lint.js +9 -13
- package/dist/integrity/lint.ts +7 -10
- package/dist/integrity/lsp/bin.js +5 -4
- package/dist/integrity/lsp/bin.ts +3 -1
- package/dist/integrity/lsp/diagnostics.js +3 -3
- package/dist/integrity/lsp/diagnostics.ts +1 -1
- package/dist/integrity/lsp/lint.js +19 -30
- package/dist/integrity/lsp/lint.ts +16 -32
- package/dist/integrity/lsp/server.js +3 -3
- package/dist/integrity/slopnator.d.ts +3 -13
- package/dist/integrity/slopnator.js +59 -38
- package/dist/integrity/slopnator.ts +54 -38
- package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
- package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
- package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
- package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
- package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
- package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
- package/dist/integrity/slopnators/sl_inert_island.js +10 -8
- package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
- package/dist/integrity/slopnators/sl_missing_row.js +6 -51
- package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
- package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
- package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
- package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
- package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
- package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
- package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
- package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
- package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
- package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
- package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
- package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
- package/dist/integrity/slopnators/sl_stale_path.js +5 -22
- package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
- package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
- package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
- package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
- package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
- package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
- package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
- package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
- package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
- package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
- package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
- package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
- package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
- package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
- package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
- package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
- package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
- package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
- package/dist/integrity/slopnators/sl_underived_route.js +61 -0
- package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
- package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
- package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
- package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
- package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
- package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
- package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
- package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
- package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
- package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
- package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
- package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
- package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
- package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
- package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
- package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
- package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
- package/dist/integrity/slopnators/sl_unversioned.js +6 -4
- package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
- package/dist/integrity/sweep.d.ts +1 -0
- package/dist/integrity/sweep.js +105 -42
- package/dist/integrity/sweep.ts +115 -42
- package/dist/knowledge/attach.js +4 -3
- package/dist/knowledge/attach.ts +3 -2
- package/dist/knowledge/generators/docsgen.js +8 -6
- package/dist/knowledge/generators/docsgen.ts +4 -2
- package/dist/knowledge/generators/glossary.js +4 -4
- package/dist/knowledge/generators/glossary.ts +1 -1
- package/dist/operations/access.d.ts +23 -0
- package/dist/operations/access.js +28 -1
- package/dist/operations/access.ts +43 -0
- package/dist/operations/attach.js +33 -113
- package/dist/operations/attach.ts +51 -117
- package/dist/operations/capabilities.d.ts +14 -5
- package/dist/operations/capabilities.js +13 -4
- package/dist/operations/capabilities.ts +27 -8
- package/dist/operations/dispatch.d.ts +8 -2
- package/dist/operations/dispatch.js +128 -185
- package/dist/operations/dispatch.ts +138 -191
- package/dist/operations/error-results.d.ts +1 -1
- package/dist/operations/error-results.js +2 -2
- package/dist/operations/error-results.ts +2 -2
- package/dist/operations/generators/capability.d.ts +11 -1
- package/dist/operations/generators/capability.js +481 -224
- package/dist/operations/generators/capability.ts +562 -233
- package/dist/operations/generators/compile.js +66 -39
- package/dist/operations/generators/compile.ts +78 -39
- package/dist/operations/generators/permits.js +11 -12
- package/dist/operations/generators/permits.ts +3 -4
- package/dist/operations/generators/seed.d.ts +1 -0
- package/dist/operations/generators/seed.js +19 -17
- package/dist/operations/generators/seed.ts +22 -14
- package/dist/operations/generators/trial.d.ts +6 -8
- package/dist/operations/generators/trial.js +200 -70
- package/dist/operations/generators/trial.ts +230 -93
- package/dist/operations/nodes.d.ts +15 -16
- package/dist/operations/nodes.ts +16 -17
- package/dist/operations/operations.d.ts +40 -4
- package/dist/operations/operations.js +1 -0
- package/dist/operations/operations.ts +61 -4
- package/dist/operations/result.d.ts +2 -2
- package/dist/operations/result.ts +2 -2
- package/package.json +1 -4
- package/dist/core/answers.d.ts +0 -171
- package/dist/core/answers.js +0 -789
- package/dist/core/answers.ts +0 -999
- package/dist/core/client.d.ts +0 -63
- package/dist/core/client.js +0 -249
- package/dist/core/client.ts +0 -289
- package/dist/core/files.js +0 -171
- package/dist/core/files.ts +0 -222
- package/dist/integrations/module.d.ts +0 -6
- package/dist/integrations/module.js +0 -153
- package/dist/integrations/module.ts +0 -191
- package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
- package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
- package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
- package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
- package/dist/operations/cost.d.ts +0 -14
- package/dist/operations/cost.js +0 -37
- package/dist/operations/cost.ts +0 -58
- package/dist/operations/errors/errors.d.ts +0 -52
- package/dist/operations/http.js +0 -124
- package/dist/operations/http.ts +0 -169
- package/dist/operations/memory.d.ts +0 -104
- package/dist/operations/memory.js +0 -365
- package/dist/operations/memory.ts +0 -470
- package/dist/operations/metering.d.ts +0 -55
- package/dist/operations/metering.js +0 -247
- package/dist/operations/metering.ts +0 -328
- package/dist/operations/queue-policy.d.ts +0 -3
- package/dist/operations/queue-policy.js +0 -8
- package/dist/operations/queue-policy.ts +0 -10
- package/dist/operations/seams.d.ts +0 -239
- package/dist/operations/seams.js +0 -45
- package/dist/operations/seams.ts +0 -364
- package/dist/operations/store.d.ts +0 -14
- package/dist/operations/store.js +0 -1
- package/dist/operations/store.ts +0 -29
- /package/dist/{operations → core}/errors/classes.d.ts +0 -0
- /package/dist/{operations → core}/errors/classes.js +0 -0
- /package/dist/{operations → core}/errors/classes.ts +0 -0
- /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
- /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
package/dist/integrity/sweep.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { attached, existsSync, readFileSync, readdirSync } from
|
|
1
|
+
import { starts } from '../integrations/cli.js';
|
|
2
|
+
import { attached, existsSync, readFileSync, readdirSync } from '../integrations/disk.js';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { stdout } from 'node:process';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { exit, invoked } from "../core/invoked.js";
|
|
4
|
+
import { argv, stdout } from 'node:process';
|
|
5
|
+
import { runChecker } from '../core/finding.js';
|
|
6
|
+
import { exit, invoked } from '../core/invoked.js';
|
|
8
7
|
import { parser } from 'typescript-eslint';
|
|
9
|
-
import { CONSTRAINTS } from
|
|
10
|
-
import { NOT_WRITTEN, ROOT, governs, load, reads, rules, slopnatorName, sweeps, visits } from
|
|
11
|
-
import { deriveTrials, runTrials } from
|
|
8
|
+
import { CONSTRAINTS } from './constraint.js';
|
|
9
|
+
import { NOT_WRITTEN, ROOT, derivedHere, governs, load, proofsOf, reads, rules, slopnatorName, subject, sweeps, visits } from './slopnator.js';
|
|
10
|
+
import { crossed, deriveTrials, runTrials } from './generators/trial.js';
|
|
12
11
|
const PARSEABLE = /\.(ts|tsx|mts|cts|mjs|cjs|js|jsx)$/;
|
|
13
12
|
function tree(text) {
|
|
14
13
|
const read = (jsx) => parser.parseForESLint(text, {
|
|
@@ -57,6 +56,23 @@ export function visit(root, on, each) {
|
|
|
57
56
|
};
|
|
58
57
|
step(root);
|
|
59
58
|
}
|
|
59
|
+
const blank = (said) => said.replace(/[^\n]/g, ' ');
|
|
60
|
+
const sourcesIn = (one) => typeof one === 'string'
|
|
61
|
+
? [one]
|
|
62
|
+
: one.files.flatMap((each) => (typeof each.source === 'string' ? [each.source] : []));
|
|
63
|
+
function without(text, rule, slopnators) {
|
|
64
|
+
let said = text;
|
|
65
|
+
for (const proof of proofsOf(rule, slopnators).wrong) {
|
|
66
|
+
for (const source of sourcesIn(proof)) {
|
|
67
|
+
for (const one of [source, source.trim()]) {
|
|
68
|
+
if (one === '')
|
|
69
|
+
continue;
|
|
70
|
+
said = said.replaceAll(one, blank(one));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return said;
|
|
75
|
+
}
|
|
60
76
|
const ELSEWHERE = new Set(['node_modules', '.git']);
|
|
61
77
|
function ignoredIn(root) {
|
|
62
78
|
const at = join(root, '.gitignore');
|
|
@@ -67,28 +83,12 @@ function ignoredIn(root) {
|
|
|
67
83
|
.map((line) => line.trim().replace(/^\//, '').replace(/\/$/, ''))
|
|
68
84
|
.filter((line) => line !== '' && !line.startsWith('#') && !line.includes('*') && !line.startsWith('!')));
|
|
69
85
|
}
|
|
70
|
-
function authored() {
|
|
71
|
-
const found = new Set();
|
|
72
|
-
try {
|
|
73
|
-
for (const [at, threadings] of descend().threaded) {
|
|
74
|
-
if (threadings.some((one) => one.list === 'derives' && (one.row.by ?? one.row.runs) !== undefined))
|
|
75
|
-
found.add(at);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
}
|
|
80
|
-
return found;
|
|
81
|
-
}
|
|
82
86
|
export function tracked(root) {
|
|
83
|
-
const derived =
|
|
84
|
-
const mine = (one) =>
|
|
87
|
+
const derived = derivedHere();
|
|
88
|
+
const mine = (one) => derived?.has(one) !== true;
|
|
85
89
|
try {
|
|
86
|
-
const listed =
|
|
87
|
-
|
|
88
|
-
encoding: 'utf8',
|
|
89
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
90
|
-
})
|
|
91
|
-
.split('\n')
|
|
90
|
+
const listed = starts('git', ['ls-files', '--cached', '--others', '--exclude-standard'], { at: root })
|
|
91
|
+
.out.split('\n')
|
|
92
92
|
.filter(Boolean);
|
|
93
93
|
if (!attached() && listed.length > 0) {
|
|
94
94
|
return [...new Set(listed)].filter((one) => existsSync(join(root, one)) && mine(one)).sort();
|
|
@@ -123,10 +123,20 @@ export function sweep(root, all, slopnators, files) {
|
|
|
123
123
|
.filter((one) => one.slopnator !== undefined && visits(one.slopnator));
|
|
124
124
|
const findings = [];
|
|
125
125
|
let swept = 0;
|
|
126
|
+
const spent = new Map();
|
|
127
|
+
const timed = (rule, work) => {
|
|
128
|
+
const began = Date.now();
|
|
129
|
+
try {
|
|
130
|
+
return work();
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
spent.set(rule, (spent.get(rule) ?? 0) + Date.now() - began);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
126
136
|
const met = new Set();
|
|
127
137
|
for (const file of files) {
|
|
128
|
-
const reading = readers.filter((one) => governs(one.rule, file));
|
|
129
|
-
const walking = walkers.filter((one) => governs(one.rule, file));
|
|
138
|
+
const reading = readers.filter((one) => subject(one.rule) && governs(one.rule, file));
|
|
139
|
+
const walking = walkers.filter((one) => subject(one.rule) && governs(one.rule, file));
|
|
130
140
|
for (const one of reading)
|
|
131
141
|
met.add(one.rule.id);
|
|
132
142
|
for (const one of walking)
|
|
@@ -142,12 +152,12 @@ export function sweep(root, all, slopnators, files) {
|
|
|
142
152
|
}
|
|
143
153
|
swept += 1;
|
|
144
154
|
for (const { rule, slopnator } of reading) {
|
|
145
|
-
const held = slopnator.holds(undefined, {
|
|
155
|
+
const held = timed(rule.id, () => slopnator.holds(undefined, {
|
|
146
156
|
filename: file,
|
|
147
|
-
text,
|
|
157
|
+
text: without(text, rule, slopnators),
|
|
148
158
|
ancestors: () => [],
|
|
149
159
|
comments: () => [],
|
|
150
|
-
});
|
|
160
|
+
}));
|
|
151
161
|
if (held === false || held === NOT_WRITTEN)
|
|
152
162
|
continue;
|
|
153
163
|
findings.push({ rule: rule.id, file, found: typeof held === 'string' ? held : slopnatorName(rule.id) });
|
|
@@ -177,7 +187,7 @@ export function sweep(root, all, slopnators, files) {
|
|
|
177
187
|
});
|
|
178
188
|
continue;
|
|
179
189
|
}
|
|
180
|
-
visit(ast, on, (node, ancestors) => {
|
|
190
|
+
timed(rule.id, () => visit(ast, on, (node, ancestors) => {
|
|
181
191
|
const held = slopnator.holds(node, {
|
|
182
192
|
filename: file,
|
|
183
193
|
text,
|
|
@@ -187,14 +197,14 @@ export function sweep(root, all, slopnators, files) {
|
|
|
187
197
|
if (held === false || held === NOT_WRITTEN)
|
|
188
198
|
return;
|
|
189
199
|
findings.push({ rule: rule.id, file, found: typeof held === 'string' ? held : slopnatorName(rule.id) });
|
|
190
|
-
});
|
|
200
|
+
}));
|
|
191
201
|
}
|
|
192
202
|
}
|
|
193
203
|
for (const rule of all) {
|
|
194
204
|
const slopnator = slopnators.get(slopnatorName(rule.id));
|
|
195
205
|
if (slopnator === undefined || reads(slopnator))
|
|
196
206
|
continue;
|
|
197
|
-
for (const found of slopnator.checks(root))
|
|
207
|
+
for (const found of timed(rule.id, () => slopnator.checks(root)))
|
|
198
208
|
findings.push({ rule: rule.id, file: '', found });
|
|
199
209
|
}
|
|
200
210
|
const unrun = all.filter((rule) => slopnators.get(slopnatorName(rule.id)) === undefined).map((rule) => rule.id);
|
|
@@ -207,6 +217,7 @@ export function sweep(root, all, slopnators, files) {
|
|
|
207
217
|
unrun,
|
|
208
218
|
unmet,
|
|
209
219
|
linted,
|
|
220
|
+
spent,
|
|
210
221
|
rules: readers.length +
|
|
211
222
|
walkers.length +
|
|
212
223
|
all.filter((rule) => {
|
|
@@ -216,17 +227,54 @@ export function sweep(root, all, slopnators, files) {
|
|
|
216
227
|
};
|
|
217
228
|
}
|
|
218
229
|
if (invoked(import.meta.url)) {
|
|
219
|
-
const
|
|
230
|
+
const began = Date.now();
|
|
231
|
+
const declared = [...CONSTRAINTS, ...((await rules()) ?? [])];
|
|
232
|
+
let only;
|
|
233
|
+
let flagged = false;
|
|
234
|
+
for (const one of argv) {
|
|
235
|
+
if (flagged) {
|
|
236
|
+
only = one;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
if (one === '--only')
|
|
240
|
+
flagged = true;
|
|
241
|
+
}
|
|
242
|
+
let governing = [];
|
|
243
|
+
for (const one of declared) {
|
|
244
|
+
const id = one['id'];
|
|
245
|
+
if (only === undefined || id === only || slopnatorName(id) === only)
|
|
246
|
+
governing = [...governing, one];
|
|
247
|
+
}
|
|
248
|
+
if (governing[0] === undefined) {
|
|
249
|
+
runChecker('sweep', [
|
|
250
|
+
{
|
|
251
|
+
file: '',
|
|
252
|
+
detail: 'this tree declares no rule called ' + String(only),
|
|
253
|
+
instead: 'name a rule by its id, or by the slopnator beside it — `thread rules` lists both. Running all of them while ' +
|
|
254
|
+
'saying one was asked for is a green tick over a sweep nobody asked for, so nothing was swept',
|
|
255
|
+
},
|
|
256
|
+
], '');
|
|
257
|
+
exit(1);
|
|
258
|
+
}
|
|
220
259
|
const slopnators = await load(ROOT, governing);
|
|
221
260
|
const named = new Map(governing.map((rule) => [rule.id, rule]));
|
|
261
|
+
const loaded = Date.now();
|
|
222
262
|
const run = sweep(ROOT, governing, slopnators, tracked(ROOT));
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
const
|
|
263
|
+
const walked = Date.now();
|
|
264
|
+
const { default: plugin } = await import('./lint.js');
|
|
265
|
+
const derived = deriveTrials(governing, slopnators).trials;
|
|
266
|
+
const proving = runTrials(derived, governing, plugin.rules, parser, slopnators);
|
|
267
|
+
const proved = Date.now();
|
|
268
|
+
const crossing = new Map();
|
|
269
|
+
const unproven = [
|
|
270
|
+
...proving.outcomes.filter((one) => !one.passed),
|
|
271
|
+
...crossed(derived, declared, plugin.rules, parser, await load(ROOT, declared), crossing),
|
|
272
|
+
];
|
|
273
|
+
const done = Date.now();
|
|
226
274
|
const failing = new Map();
|
|
227
275
|
for (const one of unproven) {
|
|
228
276
|
const held = failing.get(one.rule) ?? [];
|
|
229
|
-
held.push(` ${one.failures.join('; ')}`);
|
|
277
|
+
held.push(` ${one.id} — ${one.failures.join('; ')}`);
|
|
230
278
|
failing.set(one.rule, held);
|
|
231
279
|
}
|
|
232
280
|
const warned = new Set();
|
|
@@ -268,6 +316,21 @@ if (invoked(import.meta.url)) {
|
|
|
268
316
|
`${String(run.linted.length)} of them reading a syntax tree, and ${String(proving.passed)} of ${String(proving.outcomes.length)} rule trial(s) passed, ${String(proving.measured)} measured` +
|
|
269
317
|
`${run.unrun.length === 0 ? '' : `, ${String(run.unrun.length)} that DID NOT RUN AT ALL`}` +
|
|
270
318
|
`${run.unmet.length === 0 ? '' : `, and ${String(run.unmet.length)} that governed no file here and so measured nothing: ${run.unmet.join(', ')}`}`);
|
|
319
|
+
const seconds = (ms) => String(Math.round(ms / 1000)) + ' s';
|
|
320
|
+
const slowest = (spent) => [...spent.entries()]
|
|
321
|
+
.sort((one, two) => two[1] - one[1])
|
|
322
|
+
.slice(0, 3)
|
|
323
|
+
.map(([rule, ms]) => rule + ' ' + seconds(ms))
|
|
324
|
+
.join(', ');
|
|
325
|
+
const own = new Map(run.spent);
|
|
326
|
+
for (const [rule, ms] of proving.spent)
|
|
327
|
+
own.set(rule, (own.get(rule) ?? 0) + ms);
|
|
328
|
+
stdout.write('sweep: it took ' + seconds(done - began) + '. Loading the rules took ' + seconds(loaded - began) +
|
|
329
|
+
', reading the files in this tree ' + seconds(walked - loaded) +
|
|
330
|
+
', running each rule on its own examples ' + seconds(proved - walked) +
|
|
331
|
+
', and holding what each rule recommends against every other rule ' + seconds(done - proved) +
|
|
332
|
+
'. Slowest on their own files and examples: ' + slowest(own) +
|
|
333
|
+
'. Slowest to hold against the rest: ' + slowest(crossing) + '.\n');
|
|
271
334
|
const forbidding = findings.length - run.findings.filter((one) => named.get(one.rule)?.severity === 'warning').length;
|
|
272
335
|
if (forbidding > 0)
|
|
273
336
|
exit(1);
|
package/dist/integrity/sweep.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { attached, existsSync, readFileSync, readdirSync } from '../
|
|
1
|
+
import { starts } from '../integrations/cli.ts'
|
|
2
|
+
import { attached, existsSync, readFileSync, readdirSync } from '../integrations/disk.ts'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
|
-
import { stdout } from 'node:process'
|
|
4
|
+
import { argv, stdout } from 'node:process'
|
|
5
5
|
import { pathToFileURL } from 'node:url'
|
|
6
6
|
|
|
7
|
-
import { descend } from '../core/descend.ts'
|
|
8
7
|
import { runChecker, type Finding } from '../core/finding.ts'
|
|
9
8
|
import { exit, invoked } from '../core/invoked.ts'
|
|
10
9
|
|
|
11
10
|
import { parser } from 'typescript-eslint'
|
|
12
11
|
|
|
13
|
-
import { CONSTRAINTS, type Constraint } from './constraint.ts'
|
|
14
|
-
import { NOT_WRITTEN, ROOT, governs, load, reads, rules, slopnatorName, sweeps, visits, type Reading, type Slopnator, type Spoken, type Visiting } from './slopnator.ts'
|
|
12
|
+
import { CONSTRAINTS, type Constraint, type Proof } from './constraint.ts'
|
|
13
|
+
import { NOT_WRITTEN, ROOT, derivedHere, governs, load, proofsOf, reads, rules, slopnatorName, subject, sweeps, visits, type Reading, type Slopnator, type Spoken, type Visiting } from './slopnator.ts'
|
|
15
14
|
import { ruleMessage } from './lint.ts'
|
|
16
|
-
import { deriveTrials, runTrials } from './generators/trial.ts'
|
|
15
|
+
import { crossed, deriveTrials, runTrials } from './generators/trial.ts'
|
|
17
16
|
|
|
18
17
|
const PARSEABLE = /\.(ts|tsx|mts|cts|mjs|cjs|js|jsx)$/
|
|
19
18
|
|
|
@@ -65,6 +64,26 @@ export function visit(root: Node, on: ReadonlySet<string>, each: (node: Node, an
|
|
|
65
64
|
step(root)
|
|
66
65
|
}
|
|
67
66
|
|
|
67
|
+
const blank = (said: string): string => said.replace(/[^\n]/g, ' ')
|
|
68
|
+
|
|
69
|
+
const sourcesIn = (one: Proof): readonly string[] =>
|
|
70
|
+
typeof one === 'string'
|
|
71
|
+
? [one]
|
|
72
|
+
: one.files.flatMap((each) => (typeof each.source === 'string' ? [each.source] : []))
|
|
73
|
+
|
|
74
|
+
function without(text: string, rule: Constraint, slopnators: ReadonlyMap<string, Slopnator>): string {
|
|
75
|
+
let said = text
|
|
76
|
+
for (const proof of proofsOf(rule, slopnators).wrong) {
|
|
77
|
+
for (const source of sourcesIn(proof)) {
|
|
78
|
+
for (const one of [source, source.trim()]) {
|
|
79
|
+
if (one === '') continue
|
|
80
|
+
said = said.replaceAll(one, blank(one))
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return said
|
|
85
|
+
}
|
|
86
|
+
|
|
68
87
|
export interface Caught {
|
|
69
88
|
readonly rule: string
|
|
70
89
|
readonly file: string
|
|
@@ -84,30 +103,14 @@ function ignoredIn(root: string): ReadonlySet<string> {
|
|
|
84
103
|
)
|
|
85
104
|
}
|
|
86
105
|
|
|
87
|
-
function authored(): ReadonlySet<string> {
|
|
88
|
-
const found = new Set<string>()
|
|
89
|
-
try {
|
|
90
|
-
for (const [at, threadings] of descend().threaded) {
|
|
91
|
-
if (threadings.some((one) => one.list === 'derives' && (one.row.by ?? one.row.runs) !== undefined)) found.add(at)
|
|
92
|
-
}
|
|
93
|
-
} catch {
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
return found
|
|
97
|
-
}
|
|
98
|
-
|
|
99
106
|
export function tracked(root: string): readonly string[] {
|
|
100
|
-
const derived =
|
|
101
|
-
const mine = (one: string): boolean =>
|
|
107
|
+
const derived = derivedHere()
|
|
108
|
+
const mine = (one: string): boolean => derived?.has(one) !== true
|
|
102
109
|
|
|
103
110
|
try {
|
|
104
111
|
|
|
105
|
-
const listed =
|
|
106
|
-
|
|
107
|
-
encoding: 'utf8',
|
|
108
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
109
|
-
})
|
|
110
|
-
.split('\n')
|
|
112
|
+
const listed = starts('git', ['ls-files', '--cached', '--others', '--exclude-standard'], { at: root })
|
|
113
|
+
.out.split('\n')
|
|
111
114
|
.filter(Boolean)
|
|
112
115
|
if (!attached() && listed.length > 0) {
|
|
113
116
|
return [...new Set(listed)].filter((one) => existsSync(join(root, one)) && mine(one)).sort()
|
|
@@ -146,6 +149,7 @@ export function sweep(
|
|
|
146
149
|
readonly unrun: readonly string[]
|
|
147
150
|
readonly unmet: readonly string[]
|
|
148
151
|
readonly linted: readonly string[]
|
|
152
|
+
readonly spent: ReadonlyMap<string, number>
|
|
149
153
|
} {
|
|
150
154
|
const readers = all
|
|
151
155
|
.map((rule) => ({ rule, slopnator: slopnators.get(slopnatorName(rule.id)) }))
|
|
@@ -157,12 +161,21 @@ export function sweep(
|
|
|
157
161
|
|
|
158
162
|
const findings: Caught[] = []
|
|
159
163
|
let swept = 0
|
|
164
|
+
const spent = new Map<string, number>()
|
|
165
|
+
const timed = <T>(rule: string, work: () => T): T => {
|
|
166
|
+
const began = Date.now()
|
|
167
|
+
try {
|
|
168
|
+
return work()
|
|
169
|
+
} finally {
|
|
170
|
+
spent.set(rule, (spent.get(rule) ?? 0) + Date.now() - began)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
160
173
|
|
|
161
174
|
const met = new Set<string>()
|
|
162
175
|
|
|
163
176
|
for (const file of files) {
|
|
164
|
-
const reading = readers.filter((one) => governs(one.rule, file))
|
|
165
|
-
const walking = walkers.filter((one) => governs(one.rule, file))
|
|
177
|
+
const reading = readers.filter((one) => subject(one.rule) && governs(one.rule, file))
|
|
178
|
+
const walking = walkers.filter((one) => subject(one.rule) && governs(one.rule, file))
|
|
166
179
|
for (const one of reading) met.add(one.rule.id)
|
|
167
180
|
for (const one of walking) met.add(one.rule.id)
|
|
168
181
|
if (reading.length === 0 && walking.length === 0) continue
|
|
@@ -176,12 +189,14 @@ export function sweep(
|
|
|
176
189
|
swept += 1
|
|
177
190
|
|
|
178
191
|
for (const { rule, slopnator } of reading) {
|
|
179
|
-
const held =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
192
|
+
const held = timed(rule.id, () =>
|
|
193
|
+
slopnator.holds(undefined, {
|
|
194
|
+
filename: file,
|
|
195
|
+
text: without(text, rule, slopnators),
|
|
196
|
+
ancestors: () => [],
|
|
197
|
+
comments: () => [],
|
|
198
|
+
}),
|
|
199
|
+
)
|
|
185
200
|
if (held === false || held === NOT_WRITTEN) continue
|
|
186
201
|
findings.push({ rule: rule.id, file, found: typeof held === 'string' ? held : slopnatorName(rule.id) })
|
|
187
202
|
}
|
|
@@ -213,7 +228,7 @@ export function sweep(
|
|
|
213
228
|
})
|
|
214
229
|
continue
|
|
215
230
|
}
|
|
216
|
-
visit(ast, on, (node, ancestors) => {
|
|
231
|
+
timed(rule.id, () => visit(ast, on, (node, ancestors) => {
|
|
217
232
|
const held = slopnator.holds(node, {
|
|
218
233
|
filename: file,
|
|
219
234
|
text,
|
|
@@ -222,14 +237,14 @@ export function sweep(
|
|
|
222
237
|
})
|
|
223
238
|
if (held === false || held === NOT_WRITTEN) return
|
|
224
239
|
findings.push({ rule: rule.id, file, found: typeof held === 'string' ? held : slopnatorName(rule.id) })
|
|
225
|
-
})
|
|
240
|
+
}))
|
|
226
241
|
}
|
|
227
242
|
}
|
|
228
243
|
|
|
229
244
|
for (const rule of all) {
|
|
230
245
|
const slopnator = slopnators.get(slopnatorName(rule.id))
|
|
231
246
|
if (slopnator === undefined || reads(slopnator)) continue
|
|
232
|
-
for (const found of slopnator.checks(root)) findings.push({ rule: rule.id, file: '', found })
|
|
247
|
+
for (const found of timed(rule.id, () => slopnator.checks(root))) findings.push({ rule: rule.id, file: '', found })
|
|
233
248
|
}
|
|
234
249
|
|
|
235
250
|
const unrun = all.filter((rule) => slopnators.get(slopnatorName(rule.id)) === undefined).map((rule) => rule.id)
|
|
@@ -243,6 +258,7 @@ export function sweep(
|
|
|
243
258
|
unrun,
|
|
244
259
|
unmet,
|
|
245
260
|
linted,
|
|
261
|
+
spent,
|
|
246
262
|
rules:
|
|
247
263
|
readers.length +
|
|
248
264
|
walkers.length +
|
|
@@ -254,19 +270,59 @@ export function sweep(
|
|
|
254
270
|
}
|
|
255
271
|
|
|
256
272
|
if (invoked(import.meta.url)) {
|
|
257
|
-
const
|
|
273
|
+
const began = Date.now()
|
|
274
|
+
const declared = [...CONSTRAINTS, ...((await rules()) ?? [])]
|
|
275
|
+
let only: string | undefined
|
|
276
|
+
let flagged = false
|
|
277
|
+
for (const one of argv) {
|
|
278
|
+
if (flagged) {
|
|
279
|
+
only = one
|
|
280
|
+
break
|
|
281
|
+
}
|
|
282
|
+
if (one === '--only') flagged = true
|
|
283
|
+
}
|
|
284
|
+
let governing: readonly Constraint[] = []
|
|
285
|
+
for (const one of declared) {
|
|
286
|
+
const id = one['id']
|
|
287
|
+
if (only === undefined || id === only || slopnatorName(id) === only) governing = [...governing, one]
|
|
288
|
+
}
|
|
289
|
+
if (governing[0] === undefined) {
|
|
290
|
+
runChecker(
|
|
291
|
+
'sweep',
|
|
292
|
+
[
|
|
293
|
+
{
|
|
294
|
+
file: '',
|
|
295
|
+
detail: 'this tree declares no rule called ' + String(only),
|
|
296
|
+
instead:
|
|
297
|
+
'name a rule by its id, or by the slopnator beside it — `thread rules` lists both. Running all of them while ' +
|
|
298
|
+
'saying one was asked for is a green tick over a sweep nobody asked for, so nothing was swept',
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
'',
|
|
302
|
+
)
|
|
303
|
+
exit(1)
|
|
304
|
+
}
|
|
258
305
|
const slopnators = await load(ROOT, governing)
|
|
259
306
|
const named = new Map(governing.map((rule) => [rule.id, rule]))
|
|
307
|
+
const loaded = Date.now()
|
|
260
308
|
const run = sweep(ROOT, governing, slopnators, tracked(ROOT))
|
|
309
|
+
const walked = Date.now()
|
|
261
310
|
|
|
262
311
|
const { default: plugin } = await import('./lint.ts')
|
|
263
|
-
const
|
|
264
|
-
const
|
|
312
|
+
const derived = deriveTrials(governing, slopnators).trials
|
|
313
|
+
const proving = runTrials(derived, governing, plugin.rules, parser, slopnators)
|
|
314
|
+
const proved = Date.now()
|
|
315
|
+
const crossing = new Map<string, number>()
|
|
316
|
+
const unproven = [
|
|
317
|
+
...proving.outcomes.filter((one) => !one.passed),
|
|
318
|
+
...crossed(derived, declared, plugin.rules, parser, await load(ROOT, declared), crossing),
|
|
319
|
+
]
|
|
320
|
+
const done = Date.now()
|
|
265
321
|
|
|
266
322
|
const failing = new Map<string, string[]>()
|
|
267
323
|
for (const one of unproven) {
|
|
268
324
|
const held = failing.get(one.rule) ?? []
|
|
269
|
-
held.push(` ${one.failures.join('; ')}`)
|
|
325
|
+
held.push(` ${one.id} — ${one.failures.join('; ')}`)
|
|
270
326
|
failing.set(one.rule, held)
|
|
271
327
|
}
|
|
272
328
|
|
|
@@ -315,6 +371,23 @@ if (invoked(import.meta.url)) {
|
|
|
315
371
|
`${run.unrun.length === 0 ? '' : `, ${String(run.unrun.length)} that DID NOT RUN AT ALL`}` +
|
|
316
372
|
`${run.unmet.length === 0 ? '' : `, and ${String(run.unmet.length)} that governed no file here and so measured nothing: ${run.unmet.join(', ')}`}`,
|
|
317
373
|
)
|
|
374
|
+
const seconds = (ms: number): string => String(Math.round(ms / 1000)) + ' s'
|
|
375
|
+
const slowest = (spent: ReadonlyMap<string, number>): string =>
|
|
376
|
+
[...spent.entries()]
|
|
377
|
+
.sort((one, two) => two[1] - one[1])
|
|
378
|
+
.slice(0, 3)
|
|
379
|
+
.map(([rule, ms]) => rule + ' ' + seconds(ms))
|
|
380
|
+
.join(', ')
|
|
381
|
+
const own = new Map(run.spent)
|
|
382
|
+
for (const [rule, ms] of proving.spent) own.set(rule, (own.get(rule) ?? 0) + ms)
|
|
383
|
+
stdout.write(
|
|
384
|
+
'sweep: it took ' + seconds(done - began) + '. Loading the rules took ' + seconds(loaded - began) +
|
|
385
|
+
', reading the files in this tree ' + seconds(walked - loaded) +
|
|
386
|
+
', running each rule on its own examples ' + seconds(proved - walked) +
|
|
387
|
+
', and holding what each rule recommends against every other rule ' + seconds(done - proved) +
|
|
388
|
+
'. Slowest on their own files and examples: ' + slowest(own) +
|
|
389
|
+
'. Slowest to hold against the rest: ' + slowest(crossing) + '.\n',
|
|
390
|
+
)
|
|
318
391
|
const forbidding = findings.length - run.findings.filter((one) => named.get(one.rule)?.severity === 'warning').length
|
|
319
392
|
if (forbidding > 0) exit(1)
|
|
320
393
|
if (warned.size > 0) {
|
package/dist/knowledge/attach.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SHAPED } from '../core/init.js';
|
|
2
|
+
import { quoted } from '../core/rows.js';
|
|
2
3
|
const DESCRIBES = 'The system that compiles what this repository holds into forms a reader can understand — the glossary first, and every later view of the tree computed rather than written.';
|
|
3
4
|
const CONCEPTS = 'Every word this framework means something specific by that no declaration coins — its own verbs and the fields they sit in, written by a person because nothing in the tree can state them, and read into the glossary with everything else.';
|
|
4
|
-
const CONCEPTS_SOURCE = `import type { Member } from '
|
|
5
|
+
const CONCEPTS_SOURCE = `import type { Member } from '${SHAPED}'
|
|
5
6
|
|
|
6
7
|
export interface Concept extends Member {
|
|
7
8
|
readonly avoid?: readonly string[]
|
|
@@ -288,7 +289,7 @@ export const ATTACH = {
|
|
|
288
289
|
{
|
|
289
290
|
file: 'knowledge.ts',
|
|
290
291
|
source: [
|
|
291
|
-
|
|
292
|
+
`import type { Threaded } from '${SHAPED}'`,
|
|
292
293
|
'',
|
|
293
294
|
'export const KNOWLEDGE: Threaded = {',
|
|
294
295
|
" id: 'knowledge',",
|
package/dist/knowledge/attach.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Attaching } from '../core/attach.ts'
|
|
2
2
|
|
|
3
|
+
import { SHAPED } from '../core/init.ts'
|
|
3
4
|
import { quoted } from '../core/rows.ts'
|
|
4
5
|
|
|
5
6
|
const DESCRIBES =
|
|
@@ -8,7 +9,7 @@ const DESCRIBES =
|
|
|
8
9
|
const CONCEPTS =
|
|
9
10
|
'Every word this framework means something specific by that no declaration coins — its own verbs and the fields they sit in, written by a person because nothing in the tree can state them, and read into the glossary with everything else.'
|
|
10
11
|
|
|
11
|
-
const CONCEPTS_SOURCE = `import type { Member } from '
|
|
12
|
+
const CONCEPTS_SOURCE = `import type { Member } from '${SHAPED}'
|
|
12
13
|
|
|
13
14
|
export interface Concept extends Member {
|
|
14
15
|
readonly avoid?: readonly string[]
|
|
@@ -298,7 +299,7 @@ export const ATTACH: Attaching = {
|
|
|
298
299
|
{
|
|
299
300
|
file: 'knowledge.ts',
|
|
300
301
|
source: [
|
|
301
|
-
|
|
302
|
+
`import type { Threaded } from '${SHAPED}'`,
|
|
302
303
|
'',
|
|
303
304
|
'export const KNOWLEDGE: Threaded = {',
|
|
304
305
|
" id: 'knowledge',",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.js';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { argv, stderr, stdout } from 'node:process';
|
|
4
|
-
import { exit } from
|
|
5
|
-
import { ROOT, descend } from
|
|
6
|
-
import { forbids, runChecker } from
|
|
7
|
-
import { agentInstructions } from
|
|
4
|
+
import { exit } from '../../core/invoked.js';
|
|
5
|
+
import { ROOT, descend } from '../../core/descend.js';
|
|
6
|
+
import { forbids, runChecker } from '../../core/finding.js';
|
|
7
|
+
import { agentInstructions } from '../../integrity/lint.js';
|
|
8
8
|
const AT = 'docs.md';
|
|
9
9
|
const CHECKING = argv.includes('--check');
|
|
10
10
|
const SHOWING = argv.includes('--show');
|
|
@@ -71,7 +71,9 @@ const line = (one) => {
|
|
|
71
71
|
].join('\n');
|
|
72
72
|
};
|
|
73
73
|
const words = [...pass.coined].sort(([one], [two]) => (one < two ? -1 : 1));
|
|
74
|
-
const
|
|
74
|
+
const threadedRows = new Set([...pass.threaded.values()].flat().map((one) => one.row));
|
|
75
|
+
const loose = [...pass.stated.values()].filter((one) => !threadedRows.has(one));
|
|
76
|
+
const commands = [...pass.derived.values(), ...[...under.values()].flat().map((one) => one.row), ...loose]
|
|
75
77
|
.filter((one) => text(one.by)?.startsWith('thread ') === true)
|
|
76
78
|
.reduce((found, one) => found.set(text(one.by), one), new Map());
|
|
77
79
|
const sections = [...under.keys()].sort();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from '../../
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.ts'
|
|
2
2
|
import { dirname, resolve } from 'node:path'
|
|
3
3
|
import { argv, stderr, stdout } from 'node:process'
|
|
4
4
|
|
|
@@ -96,7 +96,9 @@ const line = (one: { readonly list: string; readonly row: Row }): string => {
|
|
|
96
96
|
|
|
97
97
|
const words = [...pass.coined].sort(([one], [two]) => (one < two ? -1 : 1))
|
|
98
98
|
|
|
99
|
-
const
|
|
99
|
+
const threadedRows = new Set([...pass.threaded.values()].flat().map((one) => one.row))
|
|
100
|
+
const loose = [...pass.stated.values()].filter((one) => !threadedRows.has(one))
|
|
101
|
+
const commands = [...pass.derived.values(), ...[...under.values()].flat().map((one) => one.row), ...loose]
|
|
100
102
|
.filter((one) => text(one.by)?.startsWith('thread ') === true)
|
|
101
103
|
.reduce((found, one) => found.set(text(one.by) as string, one), new Map<string, Row>())
|
|
102
104
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.js';
|
|
2
2
|
import { dirname, relative, resolve } from 'node:path';
|
|
3
3
|
import { argv, stderr, stdout } from 'node:process';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { exit } from
|
|
6
|
-
import { ROOT, descend } from
|
|
7
|
-
import { forbids, runChecker } from
|
|
5
|
+
import { exit } from '../../core/invoked.js';
|
|
6
|
+
import { ROOT, descend } from '../../core/descend.js';
|
|
7
|
+
import { forbids, runChecker } from '../../core/finding.js';
|
|
8
8
|
function refuse(why) {
|
|
9
9
|
stderr.write(`glossary: ${why}\n`);
|
|
10
10
|
exit(1);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from '../../
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.ts'
|
|
2
2
|
import { dirname, relative, resolve } from 'node:path'
|
|
3
3
|
import { argv, stderr, stdout } from 'node:process'
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
@@ -13,6 +13,29 @@ export declare function declaredWords(entities: readonly {
|
|
|
13
13
|
};
|
|
14
14
|
}[], which: 'roles' | 'entitlements', everybody: string): readonly string[];
|
|
15
15
|
export declare function undeclared(answered: string, offers: readonly string[], which: 'roles' | 'entitlements'): string | undefined;
|
|
16
|
+
export interface Declaring {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly holds: readonly {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly options?: readonly string[];
|
|
21
|
+
}[];
|
|
22
|
+
readonly rows?: readonly Record<string, unknown>[];
|
|
23
|
+
readonly must?: readonly {
|
|
24
|
+
readonly unique?: readonly string[];
|
|
25
|
+
}[];
|
|
26
|
+
readonly actor?: {
|
|
27
|
+
readonly roles: string;
|
|
28
|
+
readonly entitlements?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface Caller {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly entity: string;
|
|
34
|
+
readonly roles: readonly string[];
|
|
35
|
+
readonly entitlements: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
export declare const keyIn: (one: Declaring) => string | undefined;
|
|
38
|
+
export declare const declaredCallers: (entities: readonly Declaring[]) => readonly Caller[];
|
|
16
39
|
export interface Grant extends Member {
|
|
17
40
|
readonly may: readonly string[];
|
|
18
41
|
readonly on?: string;
|