@prestack/thread 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/dist/core/{asking.d.ts → answers.d.ts} +6 -14
  3. package/dist/core/{asking.js → answers.js} +13 -332
  4. package/dist/core/{asking.ts → answers.ts} +14 -357
  5. package/dist/core/attach.js +2 -2
  6. package/dist/core/attach.ts +2 -3
  7. package/dist/core/chain.js +4 -11
  8. package/dist/core/chain.ts +4 -3
  9. package/dist/core/client.d.ts +57 -0
  10. package/dist/core/client.js +186 -0
  11. package/dist/core/client.ts +227 -0
  12. package/dist/core/descend.d.ts +2 -0
  13. package/dist/core/descend.js +109 -16
  14. package/dist/core/descend.ts +120 -16
  15. package/dist/core/files.d.ts +45 -0
  16. package/dist/core/files.js +95 -0
  17. package/dist/core/files.ts +137 -0
  18. package/dist/core/init.d.ts +1 -0
  19. package/dist/core/init.js +10 -2
  20. package/dist/core/init.ts +8 -2
  21. package/dist/core/invoked.js +1 -1
  22. package/dist/core/invoked.ts +1 -1
  23. package/dist/core/rows.d.ts +2 -0
  24. package/dist/core/rows.js +65 -0
  25. package/dist/core/rows.ts +58 -0
  26. package/dist/core/tree.js +1 -1
  27. package/dist/core/tree.ts +1 -1
  28. package/dist/derivation/attach.js +0 -12
  29. package/dist/derivation/attach.ts +0 -12
  30. package/dist/derivation/generators/build.js +8 -7
  31. package/dist/derivation/generators/build.ts +8 -7
  32. package/dist/derivation/generators/release.d.ts +1 -1
  33. package/dist/derivation/generators/release.js +15 -23
  34. package/dist/derivation/generators/release.ts +15 -15
  35. package/dist/integrations/attach.js +1 -19
  36. package/dist/integrations/attach.ts +1 -19
  37. package/dist/integrations/generators/read.js +2 -2
  38. package/dist/integrations/generators/read.ts +4 -4
  39. package/dist/integrations/generators/vault.js +4 -12
  40. package/dist/integrations/generators/vault.ts +4 -4
  41. package/dist/integrations/module.js +5 -3
  42. package/dist/integrations/module.ts +5 -3
  43. package/dist/integrations/vault.js +5 -5
  44. package/dist/integrations/vault.ts +5 -5
  45. package/dist/integrity/attach.js +0 -12
  46. package/dist/integrity/attach.ts +0 -12
  47. package/dist/integrity/check-threads.js +1 -1
  48. package/dist/integrity/check-threads.ts +1 -1
  49. package/dist/integrity/constraint.d.ts +11 -2
  50. package/dist/integrity/constraint.js +163 -20
  51. package/dist/integrity/constraint.ts +174 -22
  52. package/dist/integrity/generators/compiler.js +1 -1
  53. package/dist/integrity/generators/compiler.ts +1 -1
  54. package/dist/integrity/generators/gate.js +8 -16
  55. package/dist/integrity/generators/gate.ts +8 -7
  56. package/dist/integrity/generators/publish.js +14 -26
  57. package/dist/integrity/generators/publish.ts +14 -17
  58. package/dist/integrity/generators/trial.d.ts +2 -2
  59. package/dist/integrity/generators/trial.js +108 -50
  60. package/dist/integrity/generators/trial.ts +107 -48
  61. package/dist/integrity/lint.js +3 -3
  62. package/dist/integrity/lint.ts +3 -3
  63. package/dist/integrity/lsp/diagnostics.js +1 -1
  64. package/dist/integrity/lsp/diagnostics.ts +1 -1
  65. package/dist/integrity/lsp/lint.js +1 -1
  66. package/dist/integrity/lsp/lint.ts +1 -1
  67. package/dist/integrity/slopnator.d.ts +1 -14
  68. package/dist/integrity/slopnator.js +8 -40
  69. package/dist/integrity/slopnator.ts +9 -51
  70. package/dist/integrity/slopnators/sl_broken_lineage.js +4 -2
  71. package/dist/integrity/slopnators/sl_broken_lineage.ts +4 -2
  72. package/dist/integrity/slopnators/sl_declared_elsewhere.js +24 -3
  73. package/dist/integrity/slopnators/sl_declared_elsewhere.ts +24 -3
  74. package/dist/integrity/slopnators/sl_derived_drift.js +10 -4
  75. package/dist/integrity/slopnators/sl_derived_drift.ts +10 -4
  76. package/dist/integrity/slopnators/sl_inert_island.js +7 -13
  77. package/dist/integrity/slopnators/sl_inert_island.ts +7 -16
  78. package/dist/integrity/slopnators/sl_inert_slopnator.js +8 -8
  79. package/dist/integrity/slopnators/sl_inert_slopnator.ts +8 -8
  80. package/dist/integrity/slopnators/sl_missing_row.js +14 -9
  81. package/dist/integrity/slopnators/sl_missing_row.ts +14 -10
  82. package/dist/integrity/slopnators/sl_no_child_process.js +8 -8
  83. package/dist/integrity/slopnators/sl_no_child_process.ts +8 -8
  84. package/dist/integrity/slopnators/sl_no_import_cycle.js +1 -1
  85. package/dist/integrity/slopnators/sl_no_import_cycle.ts +1 -1
  86. package/dist/integrity/slopnators/sl_no_such_command.js +20 -5
  87. package/dist/integrity/slopnators/sl_no_such_command.ts +22 -5
  88. package/dist/integrity/slopnators/sl_only_takes_a_literal.js +8 -8
  89. package/dist/integrity/slopnators/sl_only_takes_a_literal.ts +8 -8
  90. package/dist/integrity/slopnators/sl_stale_path.js +91 -18
  91. package/dist/integrity/slopnators/sl_stale_path.ts +97 -18
  92. package/dist/integrity/slopnators/sl_twice_meant.js +25 -2
  93. package/dist/integrity/slopnators/sl_twice_meant.ts +28 -2
  94. package/dist/integrity/slopnators/sl_twice_parented.js +26 -5
  95. package/dist/integrity/slopnators/sl_twice_parented.ts +26 -5
  96. package/dist/integrity/slopnators/sl_undeclared_node.js +18 -2
  97. package/dist/integrity/slopnators/sl_undeclared_node.ts +18 -2
  98. package/dist/integrity/slopnators/sl_undeclared_operation.js +3 -1
  99. package/dist/integrity/slopnators/sl_undeclared_operation.ts +3 -1
  100. package/dist/integrity/slopnators/sl_undeclared_variant.js +6 -2
  101. package/dist/integrity/slopnators/sl_undeclared_variant.ts +6 -2
  102. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -4
  103. package/dist/integrity/slopnators/sl_ungoverned_island.ts +3 -4
  104. package/dist/integrity/slopnators/sl_unkept_rows.js +1 -1
  105. package/dist/integrity/slopnators/sl_unkept_rows.ts +1 -1
  106. package/dist/integrity/slopnators/sl_unpaired_member.js +13 -8
  107. package/dist/integrity/slopnators/sl_unpaired_member.ts +16 -8
  108. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +16 -3
  109. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +16 -3
  110. package/dist/integrity/slopnators/sl_unthreaded.d.ts +1 -0
  111. package/dist/integrity/slopnators/sl_unthreaded.js +18 -10
  112. package/dist/integrity/slopnators/sl_unthreaded.ts +19 -11
  113. package/dist/integrity/slopnators/sl_untranslated_key.js +1 -1
  114. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -1
  115. package/dist/integrity/slopnators/sl_unversioned.js +16 -2
  116. package/dist/integrity/slopnators/sl_unversioned.ts +16 -2
  117. package/dist/integrity/sweep.js +17 -3
  118. package/dist/integrity/sweep.ts +20 -3
  119. package/dist/knowledge/attach.js +0 -6
  120. package/dist/knowledge/attach.ts +0 -6
  121. package/dist/knowledge/generators/docsgen.js +12 -3
  122. package/dist/knowledge/generators/docsgen.ts +12 -2
  123. package/dist/knowledge/generators/glossary.js +1 -1
  124. package/dist/knowledge/generators/glossary.ts +1 -1
  125. package/dist/operations/attach.js +2 -26
  126. package/dist/operations/attach.ts +2 -27
  127. package/dist/operations/dispatch.js +2 -3
  128. package/dist/operations/dispatch.ts +2 -3
  129. package/dist/operations/generators/capability.js +4 -7
  130. package/dist/operations/generators/capability.ts +3 -6
  131. package/dist/operations/generators/compile.js +8 -13
  132. package/dist/operations/generators/compile.ts +8 -4
  133. package/dist/operations/generators/permits.js +4 -13
  134. package/dist/operations/generators/permits.ts +3 -3
  135. package/dist/operations/generators/seed.js +5 -2
  136. package/dist/operations/generators/seed.ts +6 -2
  137. package/dist/operations/generators/trial.js +10 -10
  138. package/dist/operations/generators/trial.ts +10 -10
  139. package/dist/operations/http.js +4 -1
  140. package/dist/operations/http.ts +6 -1
  141. package/package.json +2 -2
  142. package/dist/core/cli.d.ts +0 -2
  143. package/dist/core/cli.js +0 -1761
  144. package/dist/core/cli.ts +0 -2004
  145. package/dist/core/generators/meta.d.ts +0 -2
  146. package/dist/core/generators/meta.js +0 -829
  147. package/dist/core/generators/meta.ts +0 -1006
  148. package/dist/derivation/generators/derivation.d.ts +0 -3
  149. package/dist/derivation/generators/derivation.js +0 -273
  150. package/dist/derivation/generators/derivation.ts +0 -347
  151. package/dist/derivation/makers/release.d.ts +0 -1
  152. package/dist/derivation/makers/release.js +0 -107
  153. package/dist/derivation/makers/release.ts +0 -135
  154. package/dist/integrations/generators/secret.d.ts +0 -1
  155. package/dist/integrations/generators/secret.js +0 -233
  156. package/dist/integrations/generators/secret.ts +0 -289
  157. package/dist/integrations/generators/target.d.ts +0 -1
  158. package/dist/integrations/generators/target.js +0 -775
  159. package/dist/integrations/generators/target.ts +0 -944
  160. package/dist/integrity/generators/rule.d.ts +0 -2
  161. package/dist/integrity/generators/rule.js +0 -213
  162. package/dist/integrity/generators/rule.ts +0 -271
  163. package/dist/integrity/generators/seal.d.ts +0 -4
  164. package/dist/integrity/generators/seal.js +0 -101
  165. package/dist/integrity/generators/seal.ts +0 -117
  166. package/dist/integrity/sealed.d.ts +0 -1
  167. package/dist/integrity/sealed.js +0 -56
  168. package/dist/integrity/sealed.ts +0 -56
  169. package/dist/knowledge/generators/skills.d.ts +0 -1
  170. package/dist/knowledge/generators/skills.js +0 -222
  171. package/dist/knowledge/generators/skills.ts +0 -263
  172. package/dist/operations/generators/grant.d.ts +0 -1
  173. package/dist/operations/generators/grant.js +0 -267
  174. package/dist/operations/generators/grant.ts +0 -336
  175. package/dist/operations/generators/operation.d.ts +0 -1
  176. package/dist/operations/generators/operation.js +0 -811
  177. package/dist/operations/generators/operation.ts +0 -972
  178. package/dist/operations/makers/capability.d.ts +0 -1
  179. package/dist/operations/makers/capability.js +0 -117
  180. package/dist/operations/makers/capability.ts +0 -166
  181. package/dist/operations/makers/trial.d.ts +0 -1
  182. package/dist/operations/makers/trial.js +0 -413
  183. package/dist/operations/makers/trial.ts +0 -520
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
1
+ import { existsSync, readFileSync, readdirSync, statSync } from "../../core/files.js";
2
2
  import { join } from 'node:path';
3
3
  import { ORGANISATION, ours } from "../../core/scope.js";
4
4
  import { findTree } from "../../core/tree.js";
@@ -9,7 +9,6 @@ import { findTree } from "../../core/tree.js";
9
9
  * plain Node could not resolve it, `load()` swallowed the failure, and all eight read from every
10
10
  * caller exactly like laws finding nothing. Nothing here imports anything but node builtins.
11
11
  */
12
- const ROOT = findTree().at;
13
12
  /** A node: a const annotated `Threaded`. */
14
13
  const NODE = /export\s+const\s+[A-Za-z_$][\w$]*\s*:\s*Threaded\b/;
15
14
  /**
@@ -95,8 +94,8 @@ function filesIn(dir) {
95
94
  }
96
95
  }
97
96
  /** Every installed thread package that ships nodes of its own. */
98
- function installed() {
99
- const at = join(ROOT, 'node_modules', ORGANISATION);
97
+ function installed(root) {
98
+ const at = join(root, 'node_modules', ORGANISATION);
100
99
  const found = [];
101
100
  for (const one of safely(at)) {
102
101
  const name = `${ORGANISATION}/${one}`;
@@ -125,8 +124,8 @@ function read(path) {
125
124
  }
126
125
  }
127
126
  export const slopnator = {
128
- checks: () => {
129
- const tree = findTree();
127
+ checks: (root) => {
128
+ const tree = findTree(root);
130
129
  /* Every id the tree holds, across every node in it. */
131
130
  const held = new Set();
132
131
  for (const path of filesIn(tree.dir))
@@ -146,7 +145,7 @@ export const slopnator = {
146
145
  wired.add(one[1] ?? '');
147
146
  }
148
147
  const found = [];
149
- for (const pkg of installed()) {
148
+ for (const pkg of installed(root)) {
150
149
  if (!wired.has(pkg.name))
151
150
  continue;
152
151
  for (const path of filesIn(pkg.src)) {
@@ -166,13 +165,19 @@ export const slopnator = {
166
165
  proves: {
167
166
  wrong: [
168
167
  {
169
- files: [{ at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [],\n}\n" }],
168
+ files: [
169
+ { at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n at: 'node_modules/@prestack/thread-probe/dist/foo.ts',\n },\n ],\n}\n" },
170
+ { at: 'node_modules/@prestack/thread-probe/dist/foo.ts', source: "export const PKG: Threaded = {\n declares: [\n {\n id: 'missing-thing',\n },\n ],\n}\n" },
171
+ ],
170
172
  at: '_threads/_probe_missing.ts',
171
173
  },
172
174
  ],
173
175
  right: [
174
176
  {
175
- files: [{ at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n id: 'colour',\n },\n ],\n}\n" }],
177
+ files: [
178
+ { at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n id: 'colour',\n },\n {\n id: 'missing-thing',\n },\n {\n at: 'node_modules/@prestack/thread-probe/dist/foo.ts',\n },\n ],\n}\n" },
179
+ { at: 'node_modules/@prestack/thread-probe/dist/foo.ts', source: "export const PKG: Threaded = {\n declares: [\n {\n id: 'missing-thing',\n },\n ],\n}\n" },
180
+ ],
176
181
  at: '_threads/_probe_missing.ts',
177
182
  },
178
183
  ],
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
1
+ import { existsSync, readFileSync, readdirSync, statSync } from '../../core/files.ts'
2
2
  import { join } from 'node:path'
3
3
 
4
4
  import type { Slopnator } from '../slopnator.ts'
@@ -13,8 +13,6 @@ import { findTree } from '../../core/tree.ts'
13
13
  * caller exactly like laws finding nothing. Nothing here imports anything but node builtins.
14
14
  */
15
15
 
16
- const ROOT = findTree().at
17
-
18
16
  /** A node: a const annotated `Threaded`. */
19
17
  const NODE = /export\s+const\s+[A-Za-z_$][\w$]*\s*:\s*Threaded\b/
20
18
 
@@ -99,8 +97,8 @@ function filesIn(dir: string): readonly string[] {
99
97
  }
100
98
 
101
99
  /** Every installed thread package that ships nodes of its own. */
102
- function installed(): readonly { readonly name: string; readonly src: string }[] {
103
- const at = join(ROOT, 'node_modules', ORGANISATION)
100
+ function installed(root: string): readonly { readonly name: string; readonly src: string }[] {
101
+ const at = join(root, 'node_modules', ORGANISATION)
104
102
  const found: { name: string; src: string }[] = []
105
103
  for (const one of safely(at)) {
106
104
  const name = `${ORGANISATION}/${one}`
@@ -128,8 +126,8 @@ function read(path: string): string {
128
126
  }
129
127
 
130
128
  export const slopnator: Slopnator = {
131
- checks: () => {
132
- const tree = findTree()
129
+ checks: (root) => {
130
+ const tree = findTree(root)
133
131
 
134
132
  /* Every id the tree holds, across every node in it. */
135
133
  const held = new Set<string>()
@@ -149,7 +147,7 @@ export const slopnator: Slopnator = {
149
147
  }
150
148
 
151
149
  const found: string[] = []
152
- for (const pkg of installed()) {
150
+ for (const pkg of installed(root)) {
153
151
  if (!wired.has(pkg.name)) continue
154
152
  for (const path of filesIn(pkg.src)) {
155
153
  const shipped = shippedIn(read(path))
@@ -168,13 +166,19 @@ export const slopnator: Slopnator = {
168
166
  proves: {
169
167
  wrong: [
170
168
  {
171
- files: [{ at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [],\n}\n" }],
169
+ files: [
170
+ { at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n at: 'node_modules/@prestack/thread-probe/dist/foo.ts',\n },\n ],\n}\n" },
171
+ { at: 'node_modules/@prestack/thread-probe/dist/foo.ts', source: "export const PKG: Threaded = {\n declares: [\n {\n id: 'missing-thing',\n },\n ],\n}\n" },
172
+ ],
172
173
  at: '_threads/_probe_missing.ts',
173
174
  },
174
175
  ],
175
176
  right: [
176
177
  {
177
- files: [{ at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n id: 'colour',\n },\n ],\n}\n" }],
178
+ files: [
179
+ { at: '_threads/_probe_missing.ts', source: "import type { Threaded } from '../../core/thread.ts'\n\nexport const M: Threaded = {\n declares: [\n {\n id: 'colour',\n },\n {\n id: 'missing-thing',\n },\n {\n at: 'node_modules/@prestack/thread-probe/dist/foo.ts',\n },\n ],\n}\n" },
180
+ { at: 'node_modules/@prestack/thread-probe/dist/foo.ts', source: "export const PKG: Threaded = {\n declares: [\n {\n id: 'missing-thing',\n },\n ],\n}\n" },
181
+ ],
178
182
  at: '_threads/_probe_missing.ts',
179
183
  },
180
184
  ],
@@ -21,40 +21,40 @@ export const slopnator = {
21
21
  {
22
22
  files: [
23
23
  {
24
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
24
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
25
25
  source: "import { spawnSync } from 'node:child_process'\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
26
26
  },
27
27
  ],
28
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
28
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
29
29
  },
30
30
  {
31
31
  files: [
32
32
  {
33
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
33
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
34
34
  source: "const held = await import('child_process')\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
35
35
  },
36
36
  ],
37
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
37
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
38
38
  },
39
39
  ],
40
40
  right: [
41
41
  {
42
42
  files: [
43
43
  {
44
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
44
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
45
45
  source: "import { readFileSync } from 'node:fs'\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
46
46
  },
47
47
  ],
48
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
48
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
49
49
  },
50
50
  {
51
51
  files: [
52
52
  {
53
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
53
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
54
54
  source: "export const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
55
55
  },
56
56
  ],
57
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
57
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
58
58
  },
59
59
  ],
60
60
  },
@@ -34,40 +34,40 @@ export const slopnator: Slopnator = {
34
34
  {
35
35
  files: [
36
36
  {
37
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
37
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
38
38
  source: "import { spawnSync } from 'node:child_process'\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
39
39
  },
40
40
  ],
41
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
41
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
42
42
  },
43
43
  {
44
44
  files: [
45
45
  {
46
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
46
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
47
47
  source: "const held = await import('child_process')\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
48
48
  },
49
49
  ],
50
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
50
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
51
51
  },
52
52
  ],
53
53
  right: [
54
54
  {
55
55
  files: [
56
56
  {
57
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
57
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
58
58
  source: "import { readFileSync } from 'node:fs'\nexport const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
59
59
  },
60
60
  ],
61
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
61
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
62
62
  },
63
63
  {
64
64
  files: [
65
65
  {
66
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
66
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
67
67
  source: "export const slopnator = { holds: () => false, proves: { wrong: ['a'], right: ['b'] } }\n",
68
68
  },
69
69
  ],
70
- at: 'packages/core/src/integrity/slopnators/sl_probe_spawn.ts',
70
+ at: 'thread/integrity/slopnators/sl_probe_spawn.ts',
71
71
  },
72
72
  ],
73
73
  },
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from 'node:fs';
1
+ import { existsSync, readFileSync } from "../../core/files.js";
2
2
  import { dirname, resolve } from 'node:path';
3
3
  import { findTree } from "../../core/tree.js";
4
4
  const ROOT = findTree().at;
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from 'node:fs'
1
+ import { existsSync, readFileSync } from '../../core/files.ts'
2
2
  import { dirname, resolve } from 'node:path'
3
3
 
4
4
  import type { Slopnator } from '../slopnator.ts'
@@ -1,4 +1,4 @@
1
- import { readFileSync } from 'node:fs';
1
+ import { readFileSync } from "../../core/files.js";
2
2
  import { resolve } from 'node:path';
3
3
  import { findTree } from "../../core/tree.js";
4
4
  const ROOT = findTree().at;
@@ -21,6 +21,9 @@ function scripts() {
21
21
  return new Set();
22
22
  }
23
23
  }
24
+ const HAS = [
25
+ { at: 'package.json', source: '{\n "scripts": {\n "typecheck": "tsc",\n "gate:generate": "node gate.mjs"\n }\n}\n' },
26
+ ];
24
27
  export const slopnator = {
25
28
  on: ['Property'],
26
29
  holds: (node) => {
@@ -42,12 +45,24 @@ export const slopnator = {
42
45
  },
43
46
  proves: {
44
47
  wrong: [
45
- "const M = {\n runs: 'pnpm nope:check',\n}",
46
- "const M = {\n by: 'pnpm also-not-a-script',\n}",
48
+ {
49
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n runs: 'pnpm nope:check',\n}\n" }],
50
+ at: 'threads/_probe_command.ts',
51
+ },
52
+ {
53
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n by: 'pnpm also-not-a-script',\n}\n" }],
54
+ at: 'threads/_probe_command.ts',
55
+ },
47
56
  ],
48
57
  right: [
49
- "const M = {\n runs: 'pnpm typecheck',\n}",
50
- "const M = {\n by: 'pnpm gate:generate',\n}",
58
+ {
59
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n runs: 'pnpm typecheck',\n}\n" }],
60
+ at: 'threads/_probe_command.ts',
61
+ },
62
+ {
63
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n by: 'pnpm gate:generate',\n}\n" }],
64
+ at: 'threads/_probe_command.ts',
65
+ },
51
66
  "const M = {\n runs: 'node scripts/_generated/gate.mjs',\n}",
52
67
  "const M = {\n describes: 'A sentence mentioning pnpm nope:check without naming it as a command.',\n}",
53
68
  ],
@@ -1,6 +1,7 @@
1
- import { readFileSync } from 'node:fs'
1
+ import { readFileSync } from '../../core/files.ts'
2
2
  import { resolve } from 'node:path'
3
3
 
4
+ import type { Sourced } from '../constraint.ts'
4
5
  import type { Slopnator } from '../slopnator.ts'
5
6
  import { findTree } from '../../core/tree.ts'
6
7
 
@@ -30,6 +31,10 @@ function scripts(): ReadonlySet<string> {
30
31
  }
31
32
  }
32
33
 
34
+ const HAS: readonly Sourced[] = [
35
+ { at: 'package.json', source: '{\n "scripts": {\n "typecheck": "tsc",\n "gate:generate": "node gate.mjs"\n }\n}\n' },
36
+ ]
37
+
33
38
  export const slopnator: Slopnator = {
34
39
  on: ['Property'],
35
40
  holds: (node) => {
@@ -51,12 +56,24 @@ export const slopnator: Slopnator = {
51
56
  },
52
57
  proves: {
53
58
  wrong: [
54
- "const M = {\n runs: 'pnpm nope:check',\n}",
55
- "const M = {\n by: 'pnpm also-not-a-script',\n}",
59
+ {
60
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n runs: 'pnpm nope:check',\n}\n" }],
61
+ at: 'threads/_probe_command.ts',
62
+ },
63
+ {
64
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n by: 'pnpm also-not-a-script',\n}\n" }],
65
+ at: 'threads/_probe_command.ts',
66
+ },
56
67
  ],
57
68
  right: [
58
- "const M = {\n runs: 'pnpm typecheck',\n}",
59
- "const M = {\n by: 'pnpm gate:generate',\n}",
69
+ {
70
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n runs: 'pnpm typecheck',\n}\n" }],
71
+ at: 'threads/_probe_command.ts',
72
+ },
73
+ {
74
+ files: [...HAS, { at: 'threads/_probe_command.ts', source: "const M = {\n by: 'pnpm gate:generate',\n}\n" }],
75
+ at: 'threads/_probe_command.ts',
76
+ },
60
77
  "const M = {\n runs: 'node scripts/_generated/gate.mjs',\n}",
61
78
  "const M = {\n describes: 'A sentence mentioning pnpm nope:check without naming it as a command.',\n}",
62
79
  ],
@@ -19,40 +19,40 @@ export const slopnator = {
19
19
  {
20
20
  files: [
21
21
  {
22
- at: 'packages/core/src/integrations/generators/probe.ts',
22
+ at: 'thread/integrations/generators/probe.ts',
23
23
  source: "only(piped, ['name', 'describes'], 'a thing')\n",
24
24
  },
25
25
  ],
26
- at: 'packages/core/src/integrations/generators/probe.ts',
26
+ at: 'thread/integrations/generators/probe.ts',
27
27
  },
28
28
  {
29
29
  files: [
30
30
  {
31
- at: 'packages/core/src/integrations/generators/probe.ts',
31
+ at: 'thread/integrations/generators/probe.ts',
32
32
  source: "only(one, ['stop', 'sets'], 'a stop')\n",
33
33
  },
34
34
  ],
35
- at: 'packages/core/src/integrations/generators/probe.ts',
35
+ at: 'thread/integrations/generators/probe.ts',
36
36
  },
37
37
  ],
38
38
  right: [
39
39
  {
40
40
  files: [
41
41
  {
42
- at: 'packages/core/src/integrations/generators/probe.ts',
42
+ at: 'thread/integrations/generators/probe.ts',
43
43
  source: "const TAKES = ASKS.map((one) => one.key)\nonly(piped, TAKES, 'a thing')\n",
44
44
  },
45
45
  ],
46
- at: 'packages/core/src/integrations/generators/probe.ts',
46
+ at: 'thread/integrations/generators/probe.ts',
47
47
  },
48
48
  {
49
49
  files: [
50
50
  {
51
- at: 'packages/core/src/integrations/generators/probe.ts',
51
+ at: 'thread/integrations/generators/probe.ts',
52
52
  source: "only(all, [...allowed, ...worded], 'a thing')\n",
53
53
  },
54
54
  ],
55
- at: 'packages/core/src/integrations/generators/probe.ts',
55
+ at: 'thread/integrations/generators/probe.ts',
56
56
  },
57
57
  ],
58
58
  },
@@ -23,40 +23,40 @@ export const slopnator: Slopnator = {
23
23
  {
24
24
  files: [
25
25
  {
26
- at: 'packages/core/src/integrations/generators/probe.ts',
26
+ at: 'thread/integrations/generators/probe.ts',
27
27
  source: "only(piped, ['name', 'describes'], 'a thing')\n",
28
28
  },
29
29
  ],
30
- at: 'packages/core/src/integrations/generators/probe.ts',
30
+ at: 'thread/integrations/generators/probe.ts',
31
31
  },
32
32
  {
33
33
  files: [
34
34
  {
35
- at: 'packages/core/src/integrations/generators/probe.ts',
35
+ at: 'thread/integrations/generators/probe.ts',
36
36
  source: "only(one, ['stop', 'sets'], 'a stop')\n",
37
37
  },
38
38
  ],
39
- at: 'packages/core/src/integrations/generators/probe.ts',
39
+ at: 'thread/integrations/generators/probe.ts',
40
40
  },
41
41
  ],
42
42
  right: [
43
43
  {
44
44
  files: [
45
45
  {
46
- at: 'packages/core/src/integrations/generators/probe.ts',
46
+ at: 'thread/integrations/generators/probe.ts',
47
47
  source: "const TAKES = ASKS.map((one) => one.key)\nonly(piped, TAKES, 'a thing')\n",
48
48
  },
49
49
  ],
50
- at: 'packages/core/src/integrations/generators/probe.ts',
50
+ at: 'thread/integrations/generators/probe.ts',
51
51
  },
52
52
  {
53
53
  files: [
54
54
  {
55
- at: 'packages/core/src/integrations/generators/probe.ts',
55
+ at: 'thread/integrations/generators/probe.ts',
56
56
  source: "only(all, [...allowed, ...worded], 'a thing')\n",
57
57
  },
58
58
  ],
59
- at: 'packages/core/src/integrations/generators/probe.ts',
59
+ at: 'thread/integrations/generators/probe.ts',
60
60
  },
61
61
  ],
62
62
  },
@@ -1,8 +1,10 @@
1
- import { existsSync, readdirSync, statSync } from 'node:fs';
1
+ import { existsSync, readdirSync, statSync } from "../../core/files.js";
2
2
  import { resolve } from 'node:path';
3
3
  import { descend } from "../../core/descend.js";
4
4
  import { findTree } from "../../core/tree.js";
5
5
  const ROOT = findTree().at;
6
+ const TREE = findTree().name;
7
+ const canonical = (at) => (at.startsWith('threads/') ? `${TREE}/${at.slice('threads/'.length)}` : at);
6
8
  const NAMES_A_FILE = /\.[a-z]{1,5}$/;
7
9
  /*
8
10
  * A FILE A GENERATOR WRITES IS ABSENT UNTIL THE GENERATOR HAS RUN, AND THAT IS NOT A STALE PATH.
@@ -46,46 +48,117 @@ const ours = () => {
46
48
  return new Set();
47
49
  }
48
50
  };
51
+ const named = (one) => one.key?.name ?? (typeof one.key?.value === 'string' ? one.key.value : undefined);
52
+ function proving(ancestors) {
53
+ for (let at = ancestors.length - 1; at >= 0; at -= 1) {
54
+ const held = ancestors[at];
55
+ if (held.type !== 'ObjectExpression')
56
+ continue;
57
+ const properties = held.properties ?? [];
58
+ const files = properties.some((one) => named(one) === 'files' && one.value?.type === 'ArrayExpression');
59
+ const where = properties.some((one) => named(one) === 'at' && one.value?.type === 'Literal');
60
+ if (files && where)
61
+ return true;
62
+ }
63
+ return false;
64
+ }
49
65
  export const slopnator = {
50
66
  on: ['Literal'],
51
- holds: (node) => {
67
+ holds: (node, held) => {
68
+ if (proving(held.ancestors()))
69
+ return false;
52
70
  const value = node.value;
53
71
  if (typeof value !== 'string' || !value.includes('/'))
54
72
  return false;
73
+ const path = canonical(value);
55
74
  const tops = ours();
56
- if (tops.size === 0 || !tops.has(value.split('/')[0] ?? ''))
75
+ if (tops.size === 0 || !tops.has(path.split('/')[0] ?? ''))
57
76
  return false;
58
- const brace = value.indexOf('{');
77
+ const brace = path.indexOf('{');
59
78
  if (brace !== -1) {
60
- const cut = value.lastIndexOf('/', brace);
61
- const dir = cut === -1 ? '.' : value.slice(0, cut);
79
+ const cut = path.lastIndexOf('/', brace);
80
+ const dir = cut === -1 ? '.' : path.slice(0, cut);
62
81
  if (statSync(resolve(ROOT, dir), { throwIfNoEntry: false })?.isDirectory() === true)
63
82
  return false;
64
83
  return `\`${value}\` writes into \`${dir}\`, which is not a directory on disk`;
65
84
  }
66
- if (!NAMES_A_FILE.test(value))
85
+ if (!NAMES_A_FILE.test(path))
67
86
  return false;
68
- if (existsSync(resolve(ROOT, value)))
87
+ if (existsSync(resolve(ROOT, path)))
69
88
  return false;
70
- if (derived.has(value))
89
+ if (derived.has(path))
71
90
  return false;
72
91
  return `\`${value}\` is not on disk`;
73
92
  },
74
93
  proves: {
75
94
  wrong: [
76
- "const at = 'threads/nope.ts'",
77
- "const at = 'scripts/gone.ts'",
78
- "const at = 'docs/nowhere/{page}.md'",
79
- "const at = 'migrations/gone.sql'",
80
- "const at = 'plans/gone.md'",
95
+ {
96
+ files: [
97
+ { at: 'threads/_probe_there.ts', source: 'export const THERE = 1\n' },
98
+ { at: 'probe.tsx', source: "const at = 'threads/nope.ts'\n" },
99
+ ],
100
+ at: 'probe.tsx',
101
+ },
102
+ {
103
+ files: [
104
+ { at: 'scripts/_probe_there.ts', source: 'export const THERE = 1\n' },
105
+ { at: 'probe.tsx', source: "const at = 'scripts/gone.ts'\n" },
106
+ ],
107
+ at: 'probe.tsx',
108
+ },
109
+ {
110
+ files: [
111
+ { at: 'docs/_probe_there.md', source: 'there\n' },
112
+ { at: 'probe.tsx', source: "const at = 'docs/nowhere/{page}.md'\n" },
113
+ ],
114
+ at: 'probe.tsx',
115
+ },
116
+ {
117
+ files: [
118
+ { at: 'migrations/_probe_there.sql', source: 'select 1;\n' },
119
+ { at: 'probe.tsx', source: "const at = 'migrations/gone.sql'\n" },
120
+ ],
121
+ at: 'probe.tsx',
122
+ },
123
+ {
124
+ files: [
125
+ { at: 'plans/_probe_there.md', source: 'there\n' },
126
+ { at: 'probe.tsx', source: "const at = 'plans/gone.md'\n" },
127
+ ],
128
+ at: 'probe.tsx',
129
+ },
81
130
  ],
82
131
  right: [
83
- "const at = 'packages/core/integrity/src/constraint.ts'",
84
- "const at = 'packages/core/integrity/src/lint.ts'",
85
- "const at = 'docs/reference/{page}.md'",
132
+ {
133
+ files: [
134
+ { at: 'packages/core/integrity/src/constraint.ts', source: 'export const CONSTRAINTS = []\n' },
135
+ { at: 'probe.tsx', source: "const at = 'packages/core/integrity/src/constraint.ts'\n" },
136
+ ],
137
+ at: 'probe.tsx',
138
+ },
139
+ {
140
+ files: [
141
+ { at: 'packages/core/integrity/src/lint.ts', source: 'export const plugin = {}\n' },
142
+ { at: 'probe.tsx', source: "const at = 'packages/core/integrity/src/lint.ts'\n" },
143
+ ],
144
+ at: 'probe.tsx',
145
+ },
146
+ {
147
+ files: [
148
+ { at: 'docs/reference/_probe_there.md', source: 'there\n' },
149
+ { at: 'probe.tsx', source: "const at = 'docs/reference/{page}.md'\n" },
150
+ ],
151
+ at: 'probe.tsx',
152
+ },
86
153
  "const at = 'threads/'",
87
154
  "const said = 'a sentence about packages/core/integrity/src/constraint.ts and nothing else'",
88
- "const at = 'app/layout.tsx'",
155
+ {
156
+ files: [
157
+ { at: 'app/_probe_there.tsx', source: 'export const THERE = 1\n' },
158
+ { at: 'probe.tsx', source: "const at = 'app/layout.tsx'\n" },
159
+ ],
160
+ at: 'probe.tsx',
161
+ },
89
162
  "const at = 'node_modules/thread/package.json'",
90
163
  ],
91
164
  },