@prestack/thread 0.0.2 → 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.
- package/CHANGELOG.md +98 -0
- package/dist/core/{asking.d.ts → answers.d.ts} +6 -14
- package/dist/core/{asking.js → answers.js} +13 -332
- package/dist/core/{asking.ts → answers.ts} +14 -357
- package/dist/core/attach.js +2 -2
- package/dist/core/attach.ts +2 -3
- package/dist/core/chain.js +4 -11
- package/dist/core/chain.ts +4 -3
- package/dist/core/client.d.ts +57 -0
- package/dist/core/client.js +186 -0
- package/dist/core/client.ts +227 -0
- package/dist/core/descend.d.ts +2 -0
- package/dist/core/descend.js +109 -16
- package/dist/core/descend.ts +120 -16
- package/dist/core/files.d.ts +45 -0
- package/dist/core/files.js +95 -0
- package/dist/core/files.ts +137 -0
- package/dist/core/init.d.ts +1 -0
- package/dist/core/init.js +10 -2
- package/dist/core/init.ts +8 -2
- package/dist/core/invoked.js +1 -1
- package/dist/core/invoked.ts +1 -1
- package/dist/core/rows.d.ts +2 -0
- package/dist/core/rows.js +65 -0
- package/dist/core/rows.ts +58 -0
- package/dist/core/tree.js +1 -1
- package/dist/core/tree.ts +1 -1
- package/dist/derivation/attach.js +0 -12
- package/dist/derivation/attach.ts +0 -12
- package/dist/derivation/generators/build.js +8 -7
- package/dist/derivation/generators/build.ts +8 -7
- package/dist/derivation/generators/release.d.ts +1 -1
- package/dist/derivation/generators/release.js +15 -23
- package/dist/derivation/generators/release.ts +15 -15
- package/dist/integrations/attach.js +1 -19
- package/dist/integrations/attach.ts +1 -19
- package/dist/integrations/generators/read.js +2 -2
- package/dist/integrations/generators/read.ts +4 -4
- package/dist/integrations/generators/vault.js +4 -12
- package/dist/integrations/generators/vault.ts +4 -4
- package/dist/integrations/module.js +5 -3
- package/dist/integrations/module.ts +5 -3
- package/dist/integrations/vault.js +5 -5
- package/dist/integrations/vault.ts +5 -5
- package/dist/integrity/attach.js +0 -12
- package/dist/integrity/attach.ts +0 -12
- package/dist/integrity/check-threads.js +1 -1
- package/dist/integrity/check-threads.ts +1 -1
- package/dist/integrity/constraint.d.ts +11 -2
- package/dist/integrity/constraint.js +163 -20
- package/dist/integrity/constraint.ts +174 -22
- package/dist/integrity/generators/compiler.js +1 -1
- package/dist/integrity/generators/compiler.ts +1 -1
- package/dist/integrity/generators/gate.js +8 -16
- package/dist/integrity/generators/gate.ts +8 -7
- package/dist/integrity/generators/publish.js +14 -26
- package/dist/integrity/generators/publish.ts +14 -17
- package/dist/integrity/generators/trial.d.ts +2 -2
- package/dist/integrity/generators/trial.js +108 -50
- package/dist/integrity/generators/trial.ts +107 -48
- package/dist/integrity/lint.js +3 -3
- package/dist/integrity/lint.ts +3 -3
- package/dist/integrity/lsp/diagnostics.js +1 -1
- package/dist/integrity/lsp/diagnostics.ts +1 -1
- package/dist/integrity/lsp/lint.js +1 -1
- package/dist/integrity/lsp/lint.ts +1 -1
- package/dist/integrity/slopnator.d.ts +1 -14
- package/dist/integrity/slopnator.js +8 -40
- package/dist/integrity/slopnator.ts +9 -51
- package/dist/integrity/slopnators/sl_broken_lineage.js +4 -2
- package/dist/integrity/slopnators/sl_broken_lineage.ts +4 -2
- package/dist/integrity/slopnators/sl_declared_elsewhere.js +24 -3
- package/dist/integrity/slopnators/sl_declared_elsewhere.ts +24 -3
- package/dist/integrity/slopnators/sl_derived_drift.js +10 -4
- package/dist/integrity/slopnators/sl_derived_drift.ts +10 -4
- package/dist/integrity/slopnators/sl_inert_island.js +7 -13
- package/dist/integrity/slopnators/sl_inert_island.ts +7 -16
- package/dist/integrity/slopnators/sl_inert_slopnator.js +8 -8
- package/dist/integrity/slopnators/sl_inert_slopnator.ts +8 -8
- package/dist/integrity/slopnators/sl_missing_row.js +14 -9
- package/dist/integrity/slopnators/sl_missing_row.ts +14 -10
- package/dist/integrity/slopnators/sl_no_child_process.js +8 -8
- package/dist/integrity/slopnators/sl_no_child_process.ts +8 -8
- package/dist/integrity/slopnators/sl_no_import_cycle.js +1 -1
- package/dist/integrity/slopnators/sl_no_import_cycle.ts +1 -1
- package/dist/integrity/slopnators/sl_no_such_command.js +20 -5
- package/dist/integrity/slopnators/sl_no_such_command.ts +22 -5
- package/dist/integrity/slopnators/sl_only_takes_a_literal.js +8 -8
- package/dist/integrity/slopnators/sl_only_takes_a_literal.ts +8 -8
- package/dist/integrity/slopnators/sl_stale_path.js +91 -18
- package/dist/integrity/slopnators/sl_stale_path.ts +97 -18
- package/dist/integrity/slopnators/sl_twice_meant.js +25 -2
- package/dist/integrity/slopnators/sl_twice_meant.ts +28 -2
- package/dist/integrity/slopnators/sl_twice_parented.js +26 -5
- package/dist/integrity/slopnators/sl_twice_parented.ts +26 -5
- package/dist/integrity/slopnators/sl_undeclared_node.js +18 -2
- package/dist/integrity/slopnators/sl_undeclared_node.ts +18 -2
- package/dist/integrity/slopnators/sl_undeclared_operation.js +3 -1
- package/dist/integrity/slopnators/sl_undeclared_operation.ts +3 -1
- package/dist/integrity/slopnators/sl_undeclared_variant.js +6 -2
- package/dist/integrity/slopnators/sl_undeclared_variant.ts +6 -2
- package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -4
- package/dist/integrity/slopnators/sl_ungoverned_island.ts +3 -4
- package/dist/integrity/slopnators/sl_unkept_rows.js +1 -1
- package/dist/integrity/slopnators/sl_unkept_rows.ts +1 -1
- package/dist/integrity/slopnators/sl_unpaired_member.js +13 -8
- package/dist/integrity/slopnators/sl_unpaired_member.ts +16 -8
- package/dist/integrity/slopnators/sl_unpaired_slopnator.js +16 -3
- package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +16 -3
- package/dist/integrity/slopnators/sl_unthreaded.d.ts +1 -0
- package/dist/integrity/slopnators/sl_unthreaded.js +18 -10
- package/dist/integrity/slopnators/sl_unthreaded.ts +19 -11
- package/dist/integrity/slopnators/sl_untranslated_key.js +1 -1
- package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -1
- package/dist/integrity/slopnators/sl_unversioned.js +16 -2
- package/dist/integrity/slopnators/sl_unversioned.ts +16 -2
- package/dist/integrity/sweep.js +17 -3
- package/dist/integrity/sweep.ts +20 -3
- package/dist/knowledge/attach.js +0 -6
- package/dist/knowledge/attach.ts +0 -6
- package/dist/knowledge/generators/docsgen.js +12 -3
- package/dist/knowledge/generators/docsgen.ts +12 -2
- package/dist/knowledge/generators/glossary.js +1 -1
- package/dist/knowledge/generators/glossary.ts +1 -1
- package/dist/operations/attach.js +2 -26
- package/dist/operations/attach.ts +2 -27
- package/dist/operations/dispatch.js +2 -3
- package/dist/operations/dispatch.ts +2 -3
- package/dist/operations/generators/capability.js +4 -7
- package/dist/operations/generators/capability.ts +3 -6
- package/dist/operations/generators/compile.js +8 -13
- package/dist/operations/generators/compile.ts +8 -4
- package/dist/operations/generators/permits.js +4 -13
- package/dist/operations/generators/permits.ts +3 -3
- package/dist/operations/generators/seed.js +5 -2
- package/dist/operations/generators/seed.ts +6 -2
- package/dist/operations/generators/trial.js +10 -10
- package/dist/operations/generators/trial.ts +10 -10
- package/dist/operations/http.js +4 -1
- package/dist/operations/http.ts +6 -1
- package/package.json +2 -2
- package/dist/core/cli.d.ts +0 -2
- package/dist/core/cli.js +0 -1761
- package/dist/core/cli.ts +0 -2004
- package/dist/core/generators/meta.d.ts +0 -2
- package/dist/core/generators/meta.js +0 -829
- package/dist/core/generators/meta.ts +0 -1006
- package/dist/derivation/generators/derivation.d.ts +0 -3
- package/dist/derivation/generators/derivation.js +0 -273
- package/dist/derivation/generators/derivation.ts +0 -347
- package/dist/derivation/makers/release.d.ts +0 -1
- package/dist/derivation/makers/release.js +0 -107
- package/dist/derivation/makers/release.ts +0 -135
- package/dist/integrations/generators/secret.d.ts +0 -1
- package/dist/integrations/generators/secret.js +0 -233
- package/dist/integrations/generators/secret.ts +0 -289
- package/dist/integrations/generators/target.d.ts +0 -1
- package/dist/integrations/generators/target.js +0 -775
- package/dist/integrations/generators/target.ts +0 -944
- package/dist/integrity/generators/rule.d.ts +0 -2
- package/dist/integrity/generators/rule.js +0 -213
- package/dist/integrity/generators/rule.ts +0 -271
- package/dist/integrity/generators/seal.d.ts +0 -4
- package/dist/integrity/generators/seal.js +0 -101
- package/dist/integrity/generators/seal.ts +0 -117
- package/dist/integrity/sealed.d.ts +0 -1
- package/dist/integrity/sealed.js +0 -56
- package/dist/integrity/sealed.ts +0 -56
- package/dist/knowledge/generators/skills.d.ts +0 -1
- package/dist/knowledge/generators/skills.js +0 -222
- package/dist/knowledge/generators/skills.ts +0 -263
- package/dist/operations/generators/grant.d.ts +0 -1
- package/dist/operations/generators/grant.js +0 -267
- package/dist/operations/generators/grant.ts +0 -336
- package/dist/operations/generators/operation.d.ts +0 -1
- package/dist/operations/generators/operation.js +0 -811
- package/dist/operations/generators/operation.ts +0 -972
- package/dist/operations/makers/capability.d.ts +0 -1
- package/dist/operations/makers/capability.js +0 -117
- package/dist/operations/makers/capability.ts +0 -166
- package/dist/operations/makers/trial.d.ts +0 -1
- package/dist/operations/makers/trial.js +0 -413
- package/dist/operations/makers/trial.ts +0 -520
package/dist/core/rows.ts
CHANGED
|
@@ -252,6 +252,64 @@ function stated(node: ts.ObjectLiteralExpression, field: string): Bounds | undef
|
|
|
252
252
|
|
|
253
253
|
export const quoted = (one: string): string => `'${one.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n')}'`
|
|
254
254
|
|
|
255
|
+
const UNREAD = Symbol.for('thread.unread')
|
|
256
|
+
|
|
257
|
+
function valued(node: ts.Expression): unknown {
|
|
258
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text
|
|
259
|
+
if (ts.isNumericLiteral(node)) return Number(node.text)
|
|
260
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword) return true
|
|
261
|
+
if (node.kind === ts.SyntaxKind.FalseKeyword) return false
|
|
262
|
+
if (node.kind === ts.SyntaxKind.NullKeyword) return null
|
|
263
|
+
if (ts.isAsExpression(node) || ts.isSatisfiesExpression(node) || ts.isParenthesizedExpression(node)) return valued(node.expression)
|
|
264
|
+
if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.MinusToken) {
|
|
265
|
+
const held = valued(node.operand)
|
|
266
|
+
return typeof held === 'number' ? -held : UNREAD
|
|
267
|
+
}
|
|
268
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
269
|
+
const held: unknown[] = []
|
|
270
|
+
for (const one of node.elements) {
|
|
271
|
+
const each = valued(one)
|
|
272
|
+
if (each === UNREAD) return UNREAD
|
|
273
|
+
held.push(each)
|
|
274
|
+
}
|
|
275
|
+
return held
|
|
276
|
+
}
|
|
277
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
278
|
+
const held: Record<string, unknown> = {}
|
|
279
|
+
for (const one of node.properties) {
|
|
280
|
+
if (!ts.isPropertyAssignment(one)) return UNREAD
|
|
281
|
+
const key = keyed(one)
|
|
282
|
+
if (key === undefined) return UNREAD
|
|
283
|
+
const each = valued(one.initializer)
|
|
284
|
+
if (each === UNREAD) return UNREAD
|
|
285
|
+
held[key] = each
|
|
286
|
+
}
|
|
287
|
+
return held
|
|
288
|
+
}
|
|
289
|
+
return UNREAD
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function taken(text: string): readonly (readonly [string, unknown])[] {
|
|
293
|
+
const found: (readonly [string, unknown])[] = []
|
|
294
|
+
walk(tree(text), (node) => {
|
|
295
|
+
if (!ts.isVariableDeclaration(node) || node.initializer === undefined || !ts.isIdentifier(node.name)) return
|
|
296
|
+
found.push([node.name.text, valued(node.initializer)])
|
|
297
|
+
})
|
|
298
|
+
return found
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export function valuesIn(text: string): Readonly<Record<string, unknown>> {
|
|
302
|
+
const found: Record<string, unknown> = {}
|
|
303
|
+
for (const [name, held] of taken(text)) {
|
|
304
|
+
if (held !== UNREAD) found[name] = held
|
|
305
|
+
}
|
|
306
|
+
return found
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export function unread(text: string): readonly string[] {
|
|
310
|
+
return taken(text).filter(([, held]) => held === UNREAD).map(([name]) => name)
|
|
311
|
+
}
|
|
312
|
+
|
|
255
313
|
export const STATED = ['at', 'describes', 'version']
|
|
256
314
|
|
|
257
315
|
export function reconciled(held: string, source: string, fields: readonly string[]): string {
|
package/dist/core/tree.js
CHANGED
package/dist/core/tree.ts
CHANGED
|
@@ -39,18 +39,6 @@ const SHIPPED = [
|
|
|
39
39
|
id: 'release-generator',
|
|
40
40
|
source: " {\n id: 'release-generator',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/release.js',\n describes: 'The writer of what a host reads to run this app — it derives the config from what the app already declares, its own build and start commands and the names of every secret it says it must be given, and refuses to write while this app installs a package of this framework as a dependency, because what a host runs may hold nothing of the scaffolding that assembled it.',\n version: 1,\n by: 'thread release',\n runs: 'thread release --check',\n },",
|
|
41
41
|
},
|
|
42
|
-
{
|
|
43
|
-
into: 'derivation.ts',
|
|
44
|
-
list: 'GENERATORS',
|
|
45
|
-
id: 'release-noun',
|
|
46
|
-
source: " {\n id: 'release-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/makers/release.js',\n describes: 'The command that declares where this app goes when it leaves your machine. It writes the row saying where this app goes and nothing else, because everything the config needs is already declared somewhere and asking for it again would be the app’s own facts typed a second time.',\n version: 1,\n by: 'thread create release',\n },",
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
into: 'derivation.ts',
|
|
50
|
-
list: 'GENERATORS',
|
|
51
|
-
id: 'generator-noun',
|
|
52
|
-
source: " {\n id: 'generator-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/derivation.js',\n describes: 'Declares a generator this app derives a file with. `thread create generator` asks what it is, where its file goes and the command that writes it, then writes the row and seeds the file beside it — so a generator arrives through the same wizard as everything else, and the command it names exists from that moment because the CLI reads every `by:` the tree states.',\n version: 1,\n by: 'thread create generator',\n },",
|
|
53
|
-
},
|
|
54
42
|
];
|
|
55
43
|
export const ATTACH = {
|
|
56
44
|
attaches: SEEDED.attaches,
|
|
@@ -46,18 +46,6 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
|
|
|
46
46
|
id: 'release-generator',
|
|
47
47
|
source: " {\n id: 'release-generator',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/release.js',\n describes: 'The writer of what a host reads to run this app — it derives the config from what the app already declares, its own build and start commands and the names of every secret it says it must be given, and refuses to write while this app installs a package of this framework as a dependency, because what a host runs may hold nothing of the scaffolding that assembled it.',\n version: 1,\n by: 'thread release',\n runs: 'thread release --check',\n },",
|
|
48
48
|
},
|
|
49
|
-
{
|
|
50
|
-
into: 'derivation.ts',
|
|
51
|
-
list: 'GENERATORS',
|
|
52
|
-
id: 'release-noun',
|
|
53
|
-
source: " {\n id: 'release-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/makers/release.js',\n describes: 'The command that declares where this app goes when it leaves your machine. It writes the row saying where this app goes and nothing else, because everything the config needs is already declared somewhere and asking for it again would be the app’s own facts typed a second time.',\n version: 1,\n by: 'thread create release',\n },",
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
into: 'derivation.ts',
|
|
57
|
-
list: 'GENERATORS',
|
|
58
|
-
id: 'generator-noun',
|
|
59
|
-
source: " {\n id: 'generator-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/derivation.js',\n describes: 'Declares a generator this app derives a file with. `thread create generator` asks what it is, where its file goes and the command that writes it, then writes the row and seeds the file beside it — so a generator arrives through the same wizard as everything else, and the command it names exists from that moment because the CLI reads every `by:` the tree states.',\n version: 1,\n by: 'thread create generator',\n },",
|
|
60
|
-
},
|
|
61
49
|
]
|
|
62
50
|
export const ATTACH: Attaching = {
|
|
63
51
|
attaches: SEEDED.attaches,
|
|
@@ -6,13 +6,14 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
10
9
|
import { relative, resolve } from 'node:path';
|
|
11
10
|
import { argv, stderr, stdout } from 'node:process';
|
|
12
11
|
import { pathToFileURL } from 'node:url';
|
|
13
12
|
import { build } from 'esbuild';
|
|
14
13
|
import { descend, reached } from "../../core/descend.js";
|
|
14
|
+
import { existsSync, readFileSync } from "../../core/files.js";
|
|
15
15
|
import { exit, invoked } from "../../core/invoked.js";
|
|
16
|
+
import { valuesIn } from "../../core/rows.js";
|
|
16
17
|
import { findTree } from "../../core/tree.js";
|
|
17
18
|
import { servesBrowser } from "../../integrations/target.js";
|
|
18
19
|
const TREE = findTree();
|
|
@@ -57,23 +58,23 @@ const JSX = /\.(c|m)?(t|j)sx$/;
|
|
|
57
58
|
function browsing(entry) {
|
|
58
59
|
return JSX.test(entry);
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
+
function sheet(file, list) {
|
|
61
62
|
const path = resolve(ROOT, `${TREE.name}/${file}`);
|
|
62
63
|
if (!existsSync(path))
|
|
63
64
|
return [];
|
|
64
65
|
try {
|
|
65
|
-
const held = (
|
|
66
|
+
const held = valuesIn(readFileSync(path, 'utf8'));
|
|
66
67
|
return held[list] ?? [];
|
|
67
68
|
}
|
|
68
69
|
catch {
|
|
69
70
|
return [];
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
const targets =
|
|
73
|
+
function withheld(pass) {
|
|
74
|
+
const targets = sheet('targets.ts', 'TARGETS');
|
|
74
75
|
if (targets.length === 0)
|
|
75
76
|
return new Map();
|
|
76
|
-
const secrets =
|
|
77
|
+
const secrets = sheet('secrets.ts', 'SECRETS');
|
|
77
78
|
const because = new Map();
|
|
78
79
|
for (const one of targets) {
|
|
79
80
|
const said = servesBrowser(one, secrets);
|
|
@@ -184,7 +185,7 @@ async function main() {
|
|
|
184
185
|
exit(1);
|
|
185
186
|
}
|
|
186
187
|
const forBrowser = browsing(entry);
|
|
187
|
-
const refusals = forBrowser ?
|
|
188
|
+
const refusals = forBrowser ? withheld(pass) : new Map();
|
|
188
189
|
const held = await build({
|
|
189
190
|
entryPoints: [resolve(ROOT, entry)],
|
|
190
191
|
bundle: true,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
2
1
|
import { relative, resolve } from 'node:path'
|
|
3
2
|
import { argv, stderr, stdout } from 'node:process'
|
|
4
3
|
import { pathToFileURL } from 'node:url'
|
|
@@ -6,7 +5,9 @@ import { pathToFileURL } from 'node:url'
|
|
|
6
5
|
import { build } from 'esbuild'
|
|
7
6
|
|
|
8
7
|
import { descend, reached, type Pass } from '../../core/descend.ts'
|
|
8
|
+
import { existsSync, readFileSync } from '../../core/files.ts'
|
|
9
9
|
import { exit, invoked } from '../../core/invoked.ts'
|
|
10
|
+
import { valuesIn } from '../../core/rows.ts'
|
|
10
11
|
import { findTree } from '../../core/tree.ts'
|
|
11
12
|
import type { Secret } from '../../integrations/secret.ts'
|
|
12
13
|
import { servesBrowser, type Target } from '../../integrations/target.ts'
|
|
@@ -59,21 +60,21 @@ function browsing(entry: string): boolean {
|
|
|
59
60
|
return JSX.test(entry)
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
function sheet<T>(file: string, list: string): readonly T[] {
|
|
63
64
|
const path = resolve(ROOT, `${TREE.name}/${file}`)
|
|
64
65
|
if (!existsSync(path)) return []
|
|
65
66
|
try {
|
|
66
|
-
const held = (
|
|
67
|
+
const held = valuesIn(readFileSync(path, 'utf8')) as Record<string, readonly T[] | undefined>
|
|
67
68
|
return held[list] ?? []
|
|
68
69
|
} catch {
|
|
69
70
|
return []
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
const targets =
|
|
74
|
+
function withheld(pass: Pass): ReadonlyMap<string, string> {
|
|
75
|
+
const targets = sheet<Target>('targets.ts', 'TARGETS')
|
|
75
76
|
if (targets.length === 0) return new Map()
|
|
76
|
-
const secrets =
|
|
77
|
+
const secrets = sheet<Secret>('secrets.ts', 'SECRETS')
|
|
77
78
|
|
|
78
79
|
const because = new Map<string, string>()
|
|
79
80
|
for (const one of targets) {
|
|
@@ -193,7 +194,7 @@ async function main(): Promise<void> {
|
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
const forBrowser = browsing(entry)
|
|
196
|
-
const refusals = forBrowser ?
|
|
197
|
+
const refusals = forBrowser ? withheld(pass) : new Map<string, string>()
|
|
197
198
|
|
|
198
199
|
const held = await build({
|
|
199
200
|
entryPoints: [resolve(ROOT, entry)],
|
|
@@ -1,41 +1,33 @@
|
|
|
1
|
-
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
1
|
import { join } from 'node:path';
|
|
11
2
|
import { argv, stderr, stdout } from 'node:process';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
3
|
+
import { marked, wordsIn } from "../../core/answers.js";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
|
|
14
5
|
import { exit, invoked } from "../../core/invoked.js";
|
|
6
|
+
import { valuesIn } from "../../core/rows.js";
|
|
15
7
|
import { ours } from "../../core/scope.js";
|
|
16
8
|
import { findTree, inTree } from "../../core/tree.js";
|
|
17
9
|
import { CHECKED_BY, KINDS, LISTENS, SAID, WRITES, WRITTEN_BY, kindOf } from "../release.js";
|
|
18
10
|
const TREE = findTree();
|
|
19
11
|
const MANIFEST = 'package.json';
|
|
20
12
|
const mark = (one) => marked([one.id ?? '', one.at ?? '']);
|
|
21
|
-
|
|
13
|
+
function releases() {
|
|
22
14
|
const at = inTree(TREE, 'derivation.ts');
|
|
23
15
|
if (!existsSync(at))
|
|
24
16
|
return [];
|
|
25
17
|
try {
|
|
26
|
-
const held = (
|
|
18
|
+
const held = valuesIn(readFileSync(at, 'utf8'));
|
|
27
19
|
return held.DERIVATION?.derives ?? [];
|
|
28
20
|
}
|
|
29
21
|
catch {
|
|
30
22
|
return [];
|
|
31
23
|
}
|
|
32
24
|
}
|
|
33
|
-
|
|
25
|
+
function named() {
|
|
34
26
|
const at = inTree(TREE, 'secrets.ts');
|
|
35
27
|
if (!existsSync(at))
|
|
36
28
|
return [];
|
|
37
29
|
try {
|
|
38
|
-
const held = (
|
|
30
|
+
const held = valuesIn(readFileSync(at, 'utf8'));
|
|
39
31
|
return (held.SECRETS ?? []).map((one) => one.id.toUpperCase()).sort();
|
|
40
32
|
}
|
|
41
33
|
catch {
|
|
@@ -94,10 +86,10 @@ function compose(id, secrets) {
|
|
|
94
86
|
'',
|
|
95
87
|
].join('\n');
|
|
96
88
|
}
|
|
97
|
-
|
|
89
|
+
function made() {
|
|
98
90
|
const found = new Map();
|
|
99
|
-
const rows =
|
|
100
|
-
const secrets =
|
|
91
|
+
const rows = releases();
|
|
92
|
+
const secrets = named();
|
|
101
93
|
const { build, start } = scripted();
|
|
102
94
|
for (const one of rows) {
|
|
103
95
|
const id = one.id;
|
|
@@ -121,8 +113,8 @@ function installed() {
|
|
|
121
113
|
const held = JSON.parse(readFileSync(at, 'utf8'));
|
|
122
114
|
return Object.keys(held.dependencies ?? {}).filter((one) => ours(one)).sort();
|
|
123
115
|
}
|
|
124
|
-
|
|
125
|
-
const rows =
|
|
116
|
+
function run() {
|
|
117
|
+
const rows = releases();
|
|
126
118
|
if (rows.length === 0) {
|
|
127
119
|
stdout.write(`release: this app declares no release, so there is nowhere for it to go yet. Declare one with ` +
|
|
128
120
|
`\`thread create release\` — it is ${KINDS.join(' or ')}, and the prefix on its id says which.\n`);
|
|
@@ -151,7 +143,7 @@ async function run() {
|
|
|
151
143
|
}
|
|
152
144
|
return 0;
|
|
153
145
|
}
|
|
154
|
-
const files =
|
|
146
|
+
const files = made();
|
|
155
147
|
const checking = argv.includes('--check');
|
|
156
148
|
const shipped = installed();
|
|
157
149
|
if (shipped.length > 0) {
|
|
@@ -185,9 +177,9 @@ async function run() {
|
|
|
185
177
|
for (const [at, text] of files)
|
|
186
178
|
writeFileSync(join(TREE.at, at), text, 'utf8');
|
|
187
179
|
stdout.write(`release: wrote ${[...files.keys()].join(', ')} — built and started by what this app's own manifest ` +
|
|
188
|
-
`declares, listening on ${String(LISTENS)}, naming ${String(
|
|
180
|
+
`declares, listening on ${String(LISTENS)}, naming ${String(named().length)} secret(s) and holding none of them.\n`);
|
|
189
181
|
return 0;
|
|
190
182
|
}
|
|
191
183
|
if (invoked(import.meta.url))
|
|
192
|
-
exit(
|
|
184
|
+
exit(run());
|
|
193
185
|
export { CHECKED_BY, WRITES, made };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
1
|
import { join } from 'node:path'
|
|
3
2
|
import { argv, stderr, stdout } from 'node:process'
|
|
4
|
-
import { pathToFileURL } from 'node:url'
|
|
5
3
|
|
|
6
|
-
import { marked, wordsIn } from '../../core/
|
|
4
|
+
import { marked, wordsIn } from '../../core/answers.ts'
|
|
5
|
+
import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
|
|
7
6
|
import { exit, invoked } from '../../core/invoked.ts'
|
|
7
|
+
import { valuesIn } from '../../core/rows.ts'
|
|
8
8
|
import { ours } from '../../core/scope.ts'
|
|
9
9
|
import { findTree, inTree } from '../../core/tree.ts'
|
|
10
10
|
|
|
@@ -21,22 +21,22 @@ interface Row {
|
|
|
21
21
|
|
|
22
22
|
const mark = (one: Row): string => marked([one.id ?? '', one.at ?? ''])
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
function releases(): readonly Row[] {
|
|
25
25
|
const at = inTree(TREE, 'derivation.ts')
|
|
26
26
|
if (!existsSync(at)) return []
|
|
27
27
|
try {
|
|
28
|
-
const held = (
|
|
28
|
+
const held = valuesIn(readFileSync(at, 'utf8')) as { DERIVATION?: { readonly derives?: readonly Row[] } }
|
|
29
29
|
return held.DERIVATION?.derives ?? []
|
|
30
30
|
} catch {
|
|
31
31
|
return []
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
function named(): readonly string[] {
|
|
36
36
|
const at = inTree(TREE, 'secrets.ts')
|
|
37
37
|
if (!existsSync(at)) return []
|
|
38
38
|
try {
|
|
39
|
-
const held = (
|
|
39
|
+
const held = valuesIn(readFileSync(at, 'utf8')) as { SECRETS?: readonly { readonly id: string }[] }
|
|
40
40
|
return (held.SECRETS ?? []).map((one) => one.id.toUpperCase()).sort()
|
|
41
41
|
} catch {
|
|
42
42
|
return []
|
|
@@ -100,10 +100,10 @@ function compose(id: string, secrets: readonly string[]): string {
|
|
|
100
100
|
].join('\n')
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
function made(): ReadonlyMap<string, string> {
|
|
104
104
|
const found = new Map<string, string>()
|
|
105
|
-
const rows =
|
|
106
|
-
const secrets =
|
|
105
|
+
const rows = releases()
|
|
106
|
+
const secrets = named()
|
|
107
107
|
const { build, start } = scripted()
|
|
108
108
|
|
|
109
109
|
for (const one of rows) {
|
|
@@ -128,8 +128,8 @@ function installed(): readonly string[] {
|
|
|
128
128
|
return Object.keys(held.dependencies ?? {}).filter((one) => ours(one)).sort()
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
const rows =
|
|
131
|
+
function run(): number {
|
|
132
|
+
const rows = releases()
|
|
133
133
|
if (rows.length === 0) {
|
|
134
134
|
stdout.write(
|
|
135
135
|
`release: this app declares no release, so there is nowhere for it to go yet. Declare one with ` +
|
|
@@ -164,7 +164,7 @@ async function run(): Promise<number> {
|
|
|
164
164
|
return 0
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
const files =
|
|
167
|
+
const files = made()
|
|
168
168
|
const checking = argv.includes('--check')
|
|
169
169
|
|
|
170
170
|
const shipped = installed()
|
|
@@ -203,11 +203,11 @@ async function run(): Promise<number> {
|
|
|
203
203
|
for (const [at, text] of files) writeFileSync(join(TREE.at, at), text, 'utf8')
|
|
204
204
|
stdout.write(
|
|
205
205
|
`release: wrote ${[...files.keys()].join(', ')} — built and started by what this app's own manifest ` +
|
|
206
|
-
`declares, listening on ${String(LISTENS)}, naming ${String(
|
|
206
|
+
`declares, listening on ${String(LISTENS)}, naming ${String(named().length)} secret(s) and holding none of them.\n`,
|
|
207
207
|
)
|
|
208
208
|
return 0
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
if (invoked(import.meta.url)) exit(
|
|
211
|
+
if (invoked(import.meta.url)) exit(run())
|
|
212
212
|
|
|
213
213
|
export { CHECKED_BY, WRITES, made }
|
|
@@ -82,7 +82,7 @@ const OWN = [
|
|
|
82
82
|
},
|
|
83
83
|
];
|
|
84
84
|
const SEEDED = {
|
|
85
|
-
attaches: ['@prestack/thread/derivation/attach'],
|
|
85
|
+
attaches: ['@prestack/thread/derivation/attach', '@prestack/thread/knowledge/attach'],
|
|
86
86
|
id: 'integrations',
|
|
87
87
|
declares: [
|
|
88
88
|
' {',
|
|
@@ -94,18 +94,6 @@ const SEEDED = {
|
|
|
94
94
|
].join('\n'),
|
|
95
95
|
};
|
|
96
96
|
const SHIPPED = [
|
|
97
|
-
{
|
|
98
|
-
into: 'derivation.ts',
|
|
99
|
-
list: 'GENERATORS',
|
|
100
|
-
id: 'target-generator',
|
|
101
|
-
source: " {\n id: 'target-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that declares a place this app reaches. Asked for nothing it lists every target already here with what it accepts and what it requires, every way a target may be reached and what each way can hold, and every secret this app declares. It then asks what the place is called and how it is reached, puts the prefix on the id, asks which secret is its address and which go into a header, and writes the row — so a target arrives declared with its credential named rather than with an environment variable typed into whatever needed it.',\n version: 1,\n by: 'thread create target',\n },",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
into: 'derivation.ts',
|
|
105
|
-
list: 'GENERATORS',
|
|
106
|
-
id: 'secret-generator',
|
|
107
|
-
source: " {\n id: 'secret-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/secret.js',\n describes: 'The command that declares a value this app must be given, and the only thing that ever takes one. It asks what the secret is for and who may hold it, puts `sec_` or `pub_` on the id accordingly, and writes the row. Then it asks a person for the value, with the terminal\\'s echo off, and seals it into the store beside the tree under a key it generates and never prints. The value goes from the keyboard into the sealed store and nowhere else: not into the row, not into the output, not into whatever transcript is being kept of the session that ran it.',\n version: 1,\n by: 'thread create secret',\n },",
|
|
108
|
-
},
|
|
109
97
|
{
|
|
110
98
|
into: 'derivation.ts',
|
|
111
99
|
list: 'GENERATORS',
|
|
@@ -118,12 +106,6 @@ const SHIPPED = [
|
|
|
118
106
|
id: 'inspect-generator',
|
|
119
107
|
source: " {\n id: 'inspect-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/read.js',\n describes: 'The one command for reading what this app declares. Asked for nothing it prints every sheet and what each holds; asked for a word it prints every row whose id or sentence carries it. It reads the tree rather than the files, which is the whole reason it exists: a row is a nested TypeScript literal and a search over lines answers questions about text while the questions people actually ask are about rows.',\n version: 1,\n by: 'thread inspect',\n },",
|
|
120
108
|
},
|
|
121
|
-
{
|
|
122
|
-
into: 'derivation.ts',
|
|
123
|
-
list: 'GENERATORS',
|
|
124
|
-
id: 'call-noun',
|
|
125
|
-
source: " {\n id: 'call-noun',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that makes an already-declared call happen. `thread run call <id>` asks for whatever its path leaves to be filled in — `{like_this}` — by name, and for a call that writes (POST, PUT, PATCH) a JSON body, then resolves the target\\'s address and every credential it requires through the vault at the moment of the call and never before. Nothing here ever names a vendor: a call already states its target, its method and its path, and which one runs is read off its own id, exactly as `thread run trial` reads an operation\\'s.',\n version: 1,\n by: 'thread run call',\n },",
|
|
126
|
-
},
|
|
127
109
|
];
|
|
128
110
|
export const ATTACH = {
|
|
129
111
|
attaches: SEEDED.attaches,
|
|
@@ -107,7 +107,7 @@ const OWN: readonly { readonly into: string; readonly list: string; readonly id:
|
|
|
107
107
|
]
|
|
108
108
|
|
|
109
109
|
const SEEDED = {
|
|
110
|
-
attaches: ['@prestack/thread/derivation/attach'] as const,
|
|
110
|
+
attaches: ['@prestack/thread/derivation/attach', '@prestack/thread/knowledge/attach'] as const,
|
|
111
111
|
id: 'integrations',
|
|
112
112
|
declares: [
|
|
113
113
|
' {',
|
|
@@ -120,18 +120,6 @@ const SEEDED = {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
const SHIPPED: readonly { readonly into: string; readonly list: string; readonly id: string; readonly source: string }[] = [
|
|
123
|
-
{
|
|
124
|
-
into: 'derivation.ts',
|
|
125
|
-
list: 'GENERATORS',
|
|
126
|
-
id: 'target-generator',
|
|
127
|
-
source: " {\n id: 'target-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that declares a place this app reaches. Asked for nothing it lists every target already here with what it accepts and what it requires, every way a target may be reached and what each way can hold, and every secret this app declares. It then asks what the place is called and how it is reached, puts the prefix on the id, asks which secret is its address and which go into a header, and writes the row — so a target arrives declared with its credential named rather than with an environment variable typed into whatever needed it.',\n version: 1,\n by: 'thread create target',\n },",
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
into: 'derivation.ts',
|
|
131
|
-
list: 'GENERATORS',
|
|
132
|
-
id: 'secret-generator',
|
|
133
|
-
source: " {\n id: 'secret-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/secret.js',\n describes: 'The command that declares a value this app must be given, and the only thing that ever takes one. It asks what the secret is for and who may hold it, puts `sec_` or `pub_` on the id accordingly, and writes the row. Then it asks a person for the value, with the terminal\\'s echo off, and seals it into the store beside the tree under a key it generates and never prints. The value goes from the keyboard into the sealed store and nowhere else: not into the row, not into the output, not into whatever transcript is being kept of the session that ran it.',\n version: 1,\n by: 'thread create secret',\n },",
|
|
134
|
-
},
|
|
135
123
|
{
|
|
136
124
|
into: 'derivation.ts',
|
|
137
125
|
list: 'GENERATORS',
|
|
@@ -144,12 +132,6 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
|
|
|
144
132
|
id: 'inspect-generator',
|
|
145
133
|
source: " {\n id: 'inspect-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/read.js',\n describes: 'The one command for reading what this app declares. Asked for nothing it prints every sheet and what each holds; asked for a word it prints every row whose id or sentence carries it. It reads the tree rather than the files, which is the whole reason it exists: a row is a nested TypeScript literal and a search over lines answers questions about text while the questions people actually ask are about rows.',\n version: 1,\n by: 'thread inspect',\n },",
|
|
146
134
|
},
|
|
147
|
-
{
|
|
148
|
-
into: 'derivation.ts',
|
|
149
|
-
list: 'GENERATORS',
|
|
150
|
-
id: 'call-noun',
|
|
151
|
-
source: " {\n id: 'call-noun',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that makes an already-declared call happen. `thread run call <id>` asks for whatever its path leaves to be filled in — `{like_this}` — by name, and for a call that writes (POST, PUT, PATCH) a JSON body, then resolves the target\\'s address and every credential it requires through the vault at the moment of the call and never before. Nothing here ever names a vendor: a call already states its target, its method and its path, and which one runs is read off its own id, exactly as `thread run trial` reads an operation\\'s.',\n version: 1,\n by: 'thread run call',\n },",
|
|
152
|
-
},
|
|
153
135
|
]
|
|
154
136
|
export const ATTACH: Attaching = {
|
|
155
137
|
attaches: SEEDED.attaches,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { stdout } from 'node:process';
|
|
2
2
|
import { exit } from "../../core/invoked.js";
|
|
3
|
-
import { wordsIn } from "../../core/
|
|
3
|
+
import { TYPED, wordsIn } from "../../core/answers.js";
|
|
4
4
|
import { descend } from "../../core/descend.js";
|
|
5
5
|
const words = wordsIn([]);
|
|
6
6
|
const looking = words.join(' ').trim().toLowerCase();
|
|
@@ -43,7 +43,7 @@ if (looking === '') {
|
|
|
43
43
|
out.push(` ${String(held.length).padStart(4)} ${file}`);
|
|
44
44
|
}
|
|
45
45
|
out.unshift(`${String(files.length)} sheet(s) in this tree, and what each holds:`, '');
|
|
46
|
-
out.push('', 'Name a word to read the rows themselves — every row whose id, sentence, path, command or', 'requirement carries it, each with what it means:', '',
|
|
46
|
+
out.push('', 'Name a word to read the rows themselves — every row whose id, sentence, path, command or', 'requirement carries it, each with what it means:', '', ` ${TYPED} inspect element`, ` ${TYPED} inspect variant`, ` ${TYPED} inspect <any word above, or any word this tree coins>`, '');
|
|
47
47
|
stdout.write(`${out.join('\n')}\n`);
|
|
48
48
|
stdout.write(`read: ${String(rows)} row(s) across ${String(pass.declarations)} declaration(s), ` +
|
|
49
49
|
`and ${String(pass.findings.length)} finding(s) the gate would report.\n`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { stdout } from 'node:process'
|
|
2
2
|
|
|
3
3
|
import { exit } from '../../core/invoked.ts'
|
|
4
|
-
import { wordsIn } from '../../core/
|
|
4
|
+
import { TYPED, wordsIn } from '../../core/answers.ts'
|
|
5
5
|
import { descend, type Row } from '../../core/descend.ts'
|
|
6
6
|
|
|
7
7
|
const words = wordsIn([])
|
|
@@ -63,9 +63,9 @@ if (looking === '') {
|
|
|
63
63
|
'Name a word to read the rows themselves — every row whose id, sentence, path, command or',
|
|
64
64
|
'requirement carries it, each with what it means:',
|
|
65
65
|
'',
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
` ${TYPED} inspect element`,
|
|
67
|
+
` ${TYPED} inspect variant`,
|
|
68
|
+
` ${TYPED} inspect <any word above, or any word this tree coins>`,
|
|
69
69
|
'',
|
|
70
70
|
)
|
|
71
71
|
stdout.write(`${out.join('\n')}\n`)
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
|
|
2
|
+
import { valuesIn } from "../../core/rows.js";
|
|
10
3
|
import { dirname, join, relative } from 'node:path';
|
|
11
4
|
import { argv, stderr, stdout } from 'node:process';
|
|
12
5
|
import { fileURLToPath } from 'node:url';
|
|
@@ -31,7 +24,7 @@ function refuse(because) {
|
|
|
31
24
|
}
|
|
32
25
|
let secrets = [];
|
|
33
26
|
try {
|
|
34
|
-
const taken = (
|
|
27
|
+
const taken = valuesIn(readFileSync(from));
|
|
35
28
|
secrets = taken.SECRETS ?? [];
|
|
36
29
|
}
|
|
37
30
|
catch {
|
|
@@ -80,7 +73,7 @@ async function taken(file, list) {
|
|
|
80
73
|
if (!existsSync(at))
|
|
81
74
|
return [];
|
|
82
75
|
try {
|
|
83
|
-
const held = (
|
|
76
|
+
const held = valuesIn(readFileSync(at));
|
|
84
77
|
return held[list] ?? [];
|
|
85
78
|
}
|
|
86
79
|
catch {
|
|
@@ -187,7 +180,6 @@ if (existsSync(path) && readFileSync(path, 'utf8') === SOURCE) {
|
|
|
187
180
|
stdout.write(`vault: ${AT} is already yours — it opens ${opening}, read off ${here(from)} as they are declared.\n`);
|
|
188
181
|
exit(0);
|
|
189
182
|
}
|
|
190
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
191
183
|
writeFileSync(path, SOURCE, 'utf8');
|
|
192
184
|
stdout.write(`vault: wrote ${AT} — what opens a secret's value at the moment of use.\n` +
|
|
193
185
|
` It opens the values sealed under ${SEALED_AT} for the secrets declared in ${here(from)}, and refuses every other name.\n` +
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
|
|
2
|
+
import { valuesIn } from '../../core/rows.ts'
|
|
2
3
|
import { dirname, join, relative } from 'node:path'
|
|
3
4
|
import { argv, stderr, stdout } from 'node:process'
|
|
4
5
|
import { fileURLToPath } from 'node:url'
|
|
@@ -36,7 +37,7 @@ function refuse(because: string): never {
|
|
|
36
37
|
|
|
37
38
|
let secrets: readonly Secret[] = []
|
|
38
39
|
try {
|
|
39
|
-
const taken = (
|
|
40
|
+
const taken = valuesIn(readFileSync(from)) as { SECRETS?: readonly Secret[] }
|
|
40
41
|
secrets = taken.SECRETS ?? []
|
|
41
42
|
} catch {
|
|
42
43
|
refuse(`${here(from)} could not be read. Attach \`${packageOf('integrations')}\` first — an app states its secrets there.`)
|
|
@@ -86,7 +87,7 @@ async function taken<T>(file: string, list: string): Promise<readonly T[]> {
|
|
|
86
87
|
const at = inTree(TREE, file)
|
|
87
88
|
if (!existsSync(at)) return []
|
|
88
89
|
try {
|
|
89
|
-
const held = (
|
|
90
|
+
const held = valuesIn(readFileSync(at)) as Record<string, readonly T[] | undefined>
|
|
90
91
|
return held[list] ?? []
|
|
91
92
|
} catch {
|
|
92
93
|
return []
|
|
@@ -201,7 +202,6 @@ if (existsSync(path) && readFileSync(path, 'utf8') === SOURCE) {
|
|
|
201
202
|
exit(0)
|
|
202
203
|
}
|
|
203
204
|
|
|
204
|
-
mkdirSync(dirname(path), { recursive: true })
|
|
205
205
|
writeFileSync(path, SOURCE, 'utf8')
|
|
206
206
|
stdout.write(
|
|
207
207
|
`vault: wrote ${AT} — what opens a secret's value at the moment of use.\n` +
|
|
@@ -8,8 +8,10 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
8
8
|
};
|
|
9
9
|
import { spawnSync } from 'node:child_process';
|
|
10
10
|
import { argv, stderr, stdout } from 'node:process';
|
|
11
|
-
import { answer, asking, given,
|
|
11
|
+
import { answer, asking, given, unasked, wordsIn } from "../core/answers.js";
|
|
12
|
+
import { readFileSync } from "../core/files.js";
|
|
12
13
|
import { exit } from "../core/invoked.js";
|
|
14
|
+
import { valuesIn } from "../core/rows.js";
|
|
13
15
|
import { findTree, inTree } from "../core/tree.js";
|
|
14
16
|
import { REACH, reachOf } from "./target.js";
|
|
15
17
|
import { opened } from "./vault.js";
|
|
@@ -34,7 +36,7 @@ export async function ran(name) {
|
|
|
34
36
|
const tree = findTree();
|
|
35
37
|
let targets = [];
|
|
36
38
|
try {
|
|
37
|
-
const taken = (
|
|
39
|
+
const taken = valuesIn(readFileSync(inTree(tree, 'targets.ts')));
|
|
38
40
|
targets = taken.TARGETS ?? [];
|
|
39
41
|
}
|
|
40
42
|
catch {
|
|
@@ -79,7 +81,7 @@ export async function run(declared) {
|
|
|
79
81
|
return refuse(`\`${method}\` is not a method path — one name, or names joined by dots, e.g. \`customers.list\``);
|
|
80
82
|
}
|
|
81
83
|
const piped = given();
|
|
82
|
-
|
|
84
|
+
unasked(piped, TAKES, `\`thread run ${declared.name} ${method}\``);
|
|
83
85
|
const { ask, shut } = asking(piped);
|
|
84
86
|
const typed = (piped.length > 0
|
|
85
87
|
? (answer(piped, TAKES[0] ?? 'args') ?? '')
|