@kvman/kvbuilder 0.2.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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/api.d.ts +271 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +2 -0
- package/dist/api.js.map +1 -0
- package/dist/app/install-source.d.ts +3 -0
- package/dist/app/install-source.d.ts.map +1 -0
- package/dist/app/install-source.js +11 -0
- package/dist/app/install-source.js.map +1 -0
- package/dist/app/register-app-reads.d.ts +3 -0
- package/dist/app/register-app-reads.d.ts.map +1 -0
- package/dist/app/register-app-reads.js +36 -0
- package/dist/app/register-app-reads.js.map +1 -0
- package/dist/app/register-app.d.ts +3 -0
- package/dist/app/register-app.d.ts.map +1 -0
- package/dist/app/register-app.js +124 -0
- package/dist/app/register-app.js.map +1 -0
- package/dist/build/register-build.d.ts +3 -0
- package/dist/build/register-build.d.ts.map +1 -0
- package/dist/build/register-build.js +34 -0
- package/dist/build/register-build.js.map +1 -0
- package/dist/connectors/docs.d.ts +30 -0
- package/dist/connectors/docs.d.ts.map +1 -0
- package/dist/connectors/docs.js +18 -0
- package/dist/connectors/docs.js.map +1 -0
- package/dist/connectors/ext.d.ts +40 -0
- package/dist/connectors/ext.d.ts.map +1 -0
- package/dist/connectors/ext.js +13 -0
- package/dist/connectors/ext.js.map +1 -0
- package/dist/connectors/kvman.d.ts +113 -0
- package/dist/connectors/kvman.d.ts.map +1 -0
- package/dist/connectors/kvman.js +41 -0
- package/dist/connectors/kvman.js.map +1 -0
- package/dist/connectors/preset.d.ts +26 -0
- package/dist/connectors/preset.d.ts.map +1 -0
- package/dist/connectors/preset.js +11 -0
- package/dist/connectors/preset.js.map +1 -0
- package/dist/connectors/preview.d.ts +41 -0
- package/dist/connectors/preview.d.ts.map +1 -0
- package/dist/connectors/preview.js +14 -0
- package/dist/connectors/preview.js.map +1 -0
- package/dist/docs/guides.d.ts +54 -0
- package/dist/docs/guides.d.ts.map +1 -0
- package/dist/docs/guides.js +68 -0
- package/dist/docs/guides.js.map +1 -0
- package/dist/docs/own-docs.d.ts +5 -0
- package/dist/docs/own-docs.d.ts.map +1 -0
- package/dist/docs/own-docs.js +36 -0
- package/dist/docs/own-docs.js.map +1 -0
- package/dist/docs/pages.d.ts +18 -0
- package/dist/docs/pages.d.ts.map +1 -0
- package/dist/docs/pages.js +44 -0
- package/dist/docs/pages.js.map +1 -0
- package/dist/docs/register-docs.d.ts +3 -0
- package/dist/docs/register-docs.d.ts.map +1 -0
- package/dist/docs/register-docs.js +25 -0
- package/dist/docs/register-docs.js.map +1 -0
- package/dist/ext/ext-check.d.ts +8 -0
- package/dist/ext/ext-check.d.ts.map +1 -0
- package/dist/ext/ext-check.js +26 -0
- package/dist/ext/ext-check.js.map +1 -0
- package/dist/ext/ext-list.d.ts +8 -0
- package/dist/ext/ext-list.d.ts.map +1 -0
- package/dist/ext/ext-list.js +20 -0
- package/dist/ext/ext-list.js.map +1 -0
- package/dist/ext/ext-new.d.ts +15 -0
- package/dist/ext/ext-new.d.ts.map +1 -0
- package/dist/ext/ext-new.js +11 -0
- package/dist/ext/ext-new.js.map +1 -0
- package/dist/ext/findings.d.ts +12 -0
- package/dist/ext/findings.d.ts.map +1 -0
- package/dist/ext/findings.js +44 -0
- package/dist/ext/findings.js.map +1 -0
- package/dist/ext/register-ext.d.ts +3 -0
- package/dist/ext/register-ext.d.ts.map +1 -0
- package/dist/ext/register-ext.js +49 -0
- package/dist/ext/register-ext.js.map +1 -0
- package/dist/folders.d.ts +18 -0
- package/dist/folders.d.ts.map +1 -0
- package/dist/folders.js +53 -0
- package/dist/folders.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/job-options.d.ts +33 -0
- package/dist/job-options.d.ts.map +1 -0
- package/dist/job-options.js +13 -0
- package/dist/job-options.js.map +1 -0
- package/dist/preset/register-preset.d.ts +3 -0
- package/dist/preset/register-preset.d.ts.map +1 -0
- package/dist/preset/register-preset.js +55 -0
- package/dist/preset/register-preset.js.map +1 -0
- package/dist/preview/preview-call.d.ts +20 -0
- package/dist/preview/preview-call.d.ts.map +1 -0
- package/dist/preview/preview-call.js +39 -0
- package/dist/preview/preview-call.js.map +1 -0
- package/dist/preview/preview-start.d.ts +8 -0
- package/dist/preview/preview-start.d.ts.map +1 -0
- package/dist/preview/preview-start.js +103 -0
- package/dist/preview/preview-start.js.map +1 -0
- package/dist/preview/preview-state.d.ts +11 -0
- package/dist/preview/preview-state.d.ts.map +1 -0
- package/dist/preview/preview-state.js +18 -0
- package/dist/preview/preview-state.js.map +1 -0
- package/dist/preview/register-preview.d.ts +3 -0
- package/dist/preview/register-preview.d.ts.map +1 -0
- package/dist/preview/register-preview.js +75 -0
- package/dist/preview/register-preview.js.map +1 -0
- package/dist/problems.d.ts +8 -0
- package/dist/problems.d.ts.map +1 -0
- package/dist/problems.js +11 -0
- package/dist/problems.js.map +1 -0
- package/dist/program-command.d.ts +17 -0
- package/dist/program-command.d.ts.map +1 -0
- package/dist/program-command.js +12 -0
- package/dist/program-command.js.map +1 -0
- package/dist/query/register-app-query.d.ts +3 -0
- package/dist/query/register-app-query.d.ts.map +1 -0
- package/dist/query/register-app-query.js +39 -0
- package/dist/query/register-app-query.js.map +1 -0
- package/dist/register-with-kvcoder.d.ts +3 -0
- package/dist/register-with-kvcoder.d.ts.map +1 -0
- package/dist/register-with-kvcoder.js +20 -0
- package/dist/register-with-kvcoder.js.map +1 -0
- package/dist/run-bin.d.ts +31 -0
- package/dist/run-bin.d.ts.map +1 -0
- package/dist/run-bin.js +137 -0
- package/dist/run-bin.js.map +1 -0
- package/dist/run-program.d.ts +12 -0
- package/dist/run-program.d.ts.map +1 -0
- package/dist/run-program.js +49 -0
- package/dist/run-program.js.map +1 -0
- package/docs/building.md +154 -0
- package/docs/guide.md +34 -0
- package/locales/ar.json +12 -0
- package/locales/en.json +12 -0
- package/package.json +55 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from '@kvman/sdk';
|
|
2
|
+
import { getGuide, guideListSchema, guideSchema, listGuides } from "./guides.js";
|
|
3
|
+
import { registerOwnDocs } from "./own-docs.js";
|
|
4
|
+
// What the `docs` connector calls (plan 09 §9.1), and kvbuilder's own docs pair.
|
|
5
|
+
export function registerDocs(ctx) {
|
|
6
|
+
ctx.registerQuery('kvbuilder.guides.list', {
|
|
7
|
+
description: 'Lists the guides of kvman and the documentation pages of every installed extension that serves docs.',
|
|
8
|
+
public: true,
|
|
9
|
+
input: z.object({}),
|
|
10
|
+
output: guideListSchema,
|
|
11
|
+
handle: () => listGuides(ctx),
|
|
12
|
+
});
|
|
13
|
+
ctx.registerQuery('kvbuilder.guides.get', {
|
|
14
|
+
description: "Gives one guide of kvman, or one page of an installed extension's docs, as Markdown.",
|
|
15
|
+
public: true,
|
|
16
|
+
input: z.object({
|
|
17
|
+
extension: z.string().min(1).optional().describe('The extension package name, such as @kvman/kvwebui; leave it out (or kvman) for a built-in guide.'),
|
|
18
|
+
topic: z.string().describe('The page topic, such as sdk or views.'),
|
|
19
|
+
}),
|
|
20
|
+
output: guideSchema,
|
|
21
|
+
handle: (input) => getGuide(ctx, input),
|
|
22
|
+
});
|
|
23
|
+
registerOwnDocs(ctx);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=register-docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-docs.js","sourceRoot":"","sources":["../../src/docs/register-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,iFAAiF;AAEjF,MAAM,UAAU,YAAY,CAAC,GAAQ;IACnC,GAAG,CAAC,aAAa,CAAC,uBAAuB,EAAE;QACzC,WAAW,EAAE,sGAAsG;QACnH,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,eAAe;QACvB,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;KAC9B,CAAC,CAAC;IACH,GAAG,CAAC,aAAa,CAAC,sBAAsB,EAAE;QACxC,WAAW,EAAE,sFAAsF;QACnG,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;YACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mGAAmG,CAAC;YACrJ,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;SACpE,CAAC;QACF,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;KACxC,CAAC,CAAC;IACH,eAAe,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Finding } from './findings.ts';
|
|
2
|
+
export declare function checkProject(folder: string, signal: AbortSignal): Promise<Finding[]>;
|
|
3
|
+
export declare function testProject(folder: string, signal: AbortSignal): Promise<{
|
|
4
|
+
passed: boolean;
|
|
5
|
+
exitCode: number;
|
|
6
|
+
output: string;
|
|
7
|
+
}>;
|
|
8
|
+
//# sourceMappingURL=ext-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-check.d.ts","sourceRoot":"","sources":["../../src/ext/ext-check.ts"],"names":[],"mappings":"AACA,OAAO,EAAiD,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAe5F,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQ1F;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAGrI"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { lastLines, runProgram } from "../run-program.js";
|
|
2
|
+
import { checkFindings, outputTail, typeScriptFindings } from "./findings.js";
|
|
3
|
+
// `ext check` and `ext test` (plan 09 §9.1, ADR 0009, 117, 126): the project's own toolchain, run in its folder.
|
|
4
|
+
function checkFailed(run) {
|
|
5
|
+
return {
|
|
6
|
+
message: `npm run check failed with exit code ${String(run.exitCode)}:\n${lastLines(run.output)}`,
|
|
7
|
+
hint: 'Run npm install in the project, and keep its check script as kvman-check.',
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function typeScriptFailed(run) {
|
|
11
|
+
return { message: `npx tsc failed with exit code ${String(run.exitCode)}:\n${lastLines(run.output)}`, hint: 'Run npm install in the project, so its own TypeScript is there.' };
|
|
12
|
+
}
|
|
13
|
+
export async function checkProject(folder, signal) {
|
|
14
|
+
const typeScript = await runProgram('npx', ['tsc', '--noEmit', '--pretty', 'false'], folder, signal);
|
|
15
|
+
const typeFindings = typeScriptFindings(typeScript.stdout);
|
|
16
|
+
const check = await runProgram('npm', ['run', 'check', '--', '--json'], folder, signal);
|
|
17
|
+
return [
|
|
18
|
+
...(typeScript.exitCode !== 0 && typeFindings.length === 0 ? [typeScriptFailed(typeScript)] : typeFindings),
|
|
19
|
+
...(checkFindings(check.stdout) ?? [checkFailed(check)]),
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
export async function testProject(folder, signal) {
|
|
23
|
+
const run = await runProgram('npm', ['test'], folder, signal);
|
|
24
|
+
return { passed: run.exitCode === 0, exitCode: run.exitCode, output: outputTail(run.output) };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ext-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-check.js","sourceRoot":"","sources":["../../src/ext/ext-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAgB,MAAM,eAAe,CAAC;AAE5F,iHAAiH;AAEjH,SAAS,WAAW,CAAC,GAAe;IAClC,OAAO;QACL,OAAO,EAAE,uCAAuC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QACjG,IAAI,EAAE,2EAA2E;KAClF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAe;IACvC,OAAO,EAAE,OAAO,EAAE,iCAAiC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;AAClL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,MAAmB;IACpE,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrG,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxF,OAAO;QACL,GAAG,CAAC,UAAU,CAAC,QAAQ,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QAC3G,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,MAAmB;IACnE,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;AAChG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-list.d.ts","sourceRoot":"","sources":["../../src/ext/ext-list.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAa9F,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,EAAE,CAIlE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readdirSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { readProjectManifest, workspaceRelative } from "../folders.js";
|
|
4
|
+
function walk(workspaceFolder, folder, rows) {
|
|
5
|
+
const manifest = readProjectManifest(folder);
|
|
6
|
+
if (manifest !== undefined) {
|
|
7
|
+
rows.push({ folder: workspaceRelative(workspaceFolder, folder), name: manifest.name, namespace: manifest.namespace, version: manifest.version });
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
for (const entry of readdirSync(folder, { withFileTypes: true })) {
|
|
11
|
+
if (entry.isDirectory() && entry.name !== 'node_modules' && !entry.name.startsWith('.'))
|
|
12
|
+
walk(workspaceFolder, path.join(folder, entry.name), rows);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function listProjects(workspaceFolder) {
|
|
16
|
+
const rows = [];
|
|
17
|
+
walk(workspaceFolder, workspaceFolder, rows);
|
|
18
|
+
return rows.sort((a, b) => a.folder.localeCompare(b.folder));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ext-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-list.js","sourceRoot":"","sources":["../../src/ext/ext-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOvE,SAAS,IAAI,CAAC,eAAuB,EAAE,MAAc,EAAE,IAAkB;IACvE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACjJ,OAAO;IACT,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACtJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,eAAuB;IAClD,MAAM,IAAI,GAAiB,EAAE,CAAC;IAC9B,IAAI,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Ctx } from '@kvman/sdk';
|
|
2
|
+
export type NewProject = {
|
|
3
|
+
folder: string;
|
|
4
|
+
name: string;
|
|
5
|
+
namespace: string;
|
|
6
|
+
web: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type NewProjectInput = {
|
|
9
|
+
name: string;
|
|
10
|
+
namespace: string;
|
|
11
|
+
folder: string;
|
|
12
|
+
web: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function newProject(ctx: Ctx, workspaceFolder: string, input: NewProjectInput, signal: AbortSignal): Promise<NewProject>;
|
|
15
|
+
//# sourceMappingURL=ext-new.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-new.d.ts","sourceRoot":"","sources":["../../src/ext/ext-new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAOzC,MAAM,MAAM,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3F,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAIhG,wBAAsB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAKpI"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from '@kvman/sdk';
|
|
2
|
+
import { insideWorkspace, workspaceRelative } from "../folders.js";
|
|
3
|
+
import { binResult, runBin } from "../run-bin.js";
|
|
4
|
+
const newOutputSchema = z.object({ folder: z.string(), name: z.string(), namespace: z.string(), web: z.boolean() });
|
|
5
|
+
export async function newProject(ctx, workspaceFolder, input, signal) {
|
|
6
|
+
insideWorkspace(workspaceFolder, input.folder, 'folder');
|
|
7
|
+
const run = await runBin('kvman-new', [input.folder, '--name', input.name, '--namespace', input.namespace, ...(input.web ? ['--web'] : [])], workspaceFolder, signal);
|
|
8
|
+
const created = binResult(ctx.log, 'kvman-new', run, newOutputSchema);
|
|
9
|
+
return { folder: workspaceRelative(workspaceFolder, created.folder), name: created.name, namespace: created.namespace, web: created.web };
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ext-new.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-new.js","sourceRoot":"","sources":["../../src/ext/ext-new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AASlD,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAEpH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAQ,EAAE,eAAuB,EAAE,KAAsB,EAAE,MAAmB;IAC7G,eAAe,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;IACtK,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;IACtE,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;AAC5I,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Finding = {
|
|
2
|
+
file?: string;
|
|
3
|
+
message: string;
|
|
4
|
+
hint: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function typeScriptFindings(output: string): Finding[];
|
|
7
|
+
/** The findings `kvman-check --json` printed on its last line, or `undefined` when that line isn't its array. */
|
|
8
|
+
export declare function checkFindings(stdout: string): Finding[] | undefined;
|
|
9
|
+
export declare const outputTailLimit: number;
|
|
10
|
+
/** The last 30 KB of an output, marked when the start was cut. */
|
|
11
|
+
export declare function outputTail(output: string): string;
|
|
12
|
+
//# sourceMappingURL=findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../../src/ext/findings.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAQvE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAW5D;AAED,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,GAAG,SAAS,CAWnE;AAED,eAAO,MAAM,eAAe,QAAY,CAAC;AAEzC,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIjD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from '@kvman/sdk';
|
|
2
|
+
const findingsSchema = z.array(z.strictObject({ file: z.string().optional(), message: z.string(), hint: z.string() }));
|
|
3
|
+
const located = /^(.+)\((\d+),(\d+)\): (?:error|warning) (TS\d+): (.*)$/;
|
|
4
|
+
const global = /^(?:error|warning) (TS\d+): (.*)$/;
|
|
5
|
+
const typeHint = 'Fix the type error at that line, then run ext check again.';
|
|
6
|
+
export function typeScriptFindings(output) {
|
|
7
|
+
const findings = [];
|
|
8
|
+
for (const line of output.split(/\r?\n/)) {
|
|
9
|
+
const at = located.exec(line);
|
|
10
|
+
const anywhere = at === null ? global.exec(line) : null;
|
|
11
|
+
const last = findings.at(-1);
|
|
12
|
+
if (at !== null)
|
|
13
|
+
findings.push({ file: `${(at[1] ?? '').replaceAll('\\', '/')}:${at[2] ?? ''}:${at[3] ?? ''}`, message: `${at[4] ?? ''}: ${at[5] ?? ''}`, hint: typeHint });
|
|
14
|
+
else if (anywhere !== null)
|
|
15
|
+
findings.push({ message: `${anywhere[1] ?? ''}: ${anywhere[2] ?? ''}`, hint: typeHint });
|
|
16
|
+
else if (last !== undefined && /^\s+\S/.test(line))
|
|
17
|
+
last.message += `\n${line.trim()}`;
|
|
18
|
+
}
|
|
19
|
+
return findings;
|
|
20
|
+
}
|
|
21
|
+
/** The findings `kvman-check --json` printed on its last line, or `undefined` when that line isn't its array. */
|
|
22
|
+
export function checkFindings(stdout) {
|
|
23
|
+
const lastLine = stdout.trimEnd().split('\n').at(-1) ?? '';
|
|
24
|
+
let parsed;
|
|
25
|
+
try {
|
|
26
|
+
parsed = JSON.parse(lastLine);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof SyntaxError)
|
|
30
|
+
return undefined;
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
const findings = findingsSchema.safeParse(parsed);
|
|
34
|
+
return findings.success ? findings.data.map(({ file, message, hint }) => (file === undefined ? { message, hint } : { file, message, hint })) : undefined;
|
|
35
|
+
}
|
|
36
|
+
export const outputTailLimit = 30 * 1024;
|
|
37
|
+
/** The last 30 KB of an output, marked when the start was cut. */
|
|
38
|
+
export function outputTail(output) {
|
|
39
|
+
const bytes = Buffer.from(output, 'utf8');
|
|
40
|
+
if (bytes.length <= outputTailLimit)
|
|
41
|
+
return output;
|
|
42
|
+
return `[… the first ${String(bytes.length - outputTailLimit)} bytes were cut …]\n${bytes.subarray(bytes.length - outputTailLimit).toString('utf8')}`;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.js","sourceRoot":"","sources":["../../src/ext/findings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-ext.d.ts","sourceRoot":"","sources":["../../src/ext/register-ext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAmB7E,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAgC1C"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { namespaceSchema, packageNameSchema, z } from '@kvman/sdk';
|
|
2
|
+
import { projectAt } from "../folders.js";
|
|
3
|
+
import { jobOptions } from "../job-options.js";
|
|
4
|
+
import { checkProject, testProject } from "./ext-check.js";
|
|
5
|
+
import { listProjects } from "./ext-list.js";
|
|
6
|
+
import { newProject } from "./ext-new.js";
|
|
7
|
+
// The `ext` connector's commands (plan 09 §9.1): scaffold, list, check, and test extension projects in the workspace.
|
|
8
|
+
const folderInput = z.object({ folder: z.string().min(1).describe('The project folder, relative to the workspace folder.') });
|
|
9
|
+
const findingSchema = z.object({ file: z.string().optional(), message: z.string(), hint: z.string() });
|
|
10
|
+
const newInput = z.object({
|
|
11
|
+
name: packageNameSchema.describe('The npm package name, such as notes or @me/notes.'),
|
|
12
|
+
namespace: namespaceSchema.refine((namespace) => namespace !== 'kernel', 'kernel is the kernel\'s own namespace.').describe('The namespace every name starts with, such as notes.'),
|
|
13
|
+
folder: z.string().min(1).describe('The new or empty folder to write it in, relative to the workspace folder.'),
|
|
14
|
+
web: z.boolean().optional().describe('Whether to add a Vue custom component and its build.'),
|
|
15
|
+
});
|
|
16
|
+
export function registerExt(ctx) {
|
|
17
|
+
ctx.registerCommand('kvbuilder.ext.new', {
|
|
18
|
+
description: 'Scaffolds an extension project and runs npm install in it.',
|
|
19
|
+
public: true,
|
|
20
|
+
...jobOptions['kvbuilder.ext.new'],
|
|
21
|
+
input: newInput,
|
|
22
|
+
output: z.object({ folder: z.string(), name: z.string(), namespace: z.string(), web: z.boolean() }),
|
|
23
|
+
handle: (input) => newProject(ctx, ctx.job.workspace.path, { name: input.name, namespace: input.namespace, folder: input.folder, web: input.web ?? false }, ctx.job.signal),
|
|
24
|
+
});
|
|
25
|
+
ctx.registerQuery('kvbuilder.ext.list', {
|
|
26
|
+
description: 'Lists the extension projects in the workspace folder.',
|
|
27
|
+
public: true,
|
|
28
|
+
input: z.object({}),
|
|
29
|
+
output: z.array(z.object({ folder: z.string(), name: z.string(), namespace: z.string(), version: z.string() })),
|
|
30
|
+
handle: () => listProjects(ctx.job.workspace.path),
|
|
31
|
+
});
|
|
32
|
+
ctx.registerCommand('kvbuilder.ext.check', {
|
|
33
|
+
description: 'Type-checks a project and runs its kvman check.',
|
|
34
|
+
public: true,
|
|
35
|
+
...jobOptions['kvbuilder.ext.check'],
|
|
36
|
+
input: folderInput,
|
|
37
|
+
output: z.array(findingSchema),
|
|
38
|
+
handle: (input) => checkProject(projectAt(ctx.job.workspace.path, input.folder).folder, ctx.job.signal),
|
|
39
|
+
});
|
|
40
|
+
ctx.registerCommand('kvbuilder.ext.test', {
|
|
41
|
+
description: "Runs a project's tests.",
|
|
42
|
+
public: true,
|
|
43
|
+
...jobOptions['kvbuilder.ext.test'],
|
|
44
|
+
input: folderInput,
|
|
45
|
+
output: z.object({ passed: z.boolean(), exitCode: z.number(), output: z.string() }),
|
|
46
|
+
handle: (input) => testProject(projectAt(ctx.job.workspace.path, input.folder).folder, ctx.job.signal),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=register-ext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-ext.js","sourceRoot":"","sources":["../../src/ext/register-ext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ProjectManifest = {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
namespace: string;
|
|
5
|
+
scripts: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
/** The absolute path of `relative` inside the workspace folder. */
|
|
8
|
+
export declare function insideWorkspace(workspaceFolder: string, relative: string, what: string): string;
|
|
9
|
+
/** A path as kvbuilder reports it: relative to the workspace folder, with `/`, and `.` for the folder itself. */
|
|
10
|
+
export declare function workspaceRelative(workspaceFolder: string, absolute: string): string;
|
|
11
|
+
/** The project manifest in `folder`, or `undefined` when it has no package.json with a `kvman` field. */
|
|
12
|
+
export declare function readProjectManifest(folder: string): ProjectManifest | undefined;
|
|
13
|
+
/** The project in `folder`, which must be inside the workspace folder; `kvbuilder/NOT_A_PROJECT` otherwise. */
|
|
14
|
+
export declare function projectAt(workspaceFolder: string, folder: string): {
|
|
15
|
+
folder: string;
|
|
16
|
+
manifest: ProjectManifest;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=folders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders.d.ts","sourceRoot":"","sources":["../src/folders.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAWpH,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/F;AAED,iHAAiH;AACjH,wBAAgB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAa/E;AAED,+GAA+G;AAC/G,wBAAgB,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAKhH"}
|
package/dist/folders.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { z } from '@kvman/sdk';
|
|
4
|
+
import { invalid, kvbuilderProblem } from "./problems.js";
|
|
5
|
+
const manifestSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
name: z.string(),
|
|
8
|
+
version: z.string(),
|
|
9
|
+
scripts: z.record(z.string(), z.string()).optional(),
|
|
10
|
+
kvman: z.object({ namespace: z.string() }).loose(),
|
|
11
|
+
})
|
|
12
|
+
.loose();
|
|
13
|
+
/** The absolute path of `relative` inside the workspace folder. */
|
|
14
|
+
export function insideWorkspace(workspaceFolder, relative, what) {
|
|
15
|
+
const resolved = path.resolve(workspaceFolder, relative);
|
|
16
|
+
const fromWorkspace = path.relative(workspaceFolder, resolved);
|
|
17
|
+
if (fromWorkspace.startsWith('..') || path.isAbsolute(fromWorkspace)) {
|
|
18
|
+
throw invalid(`The ${what} ${relative} is outside the workspace folder ${workspaceFolder}.`, { [what]: relative });
|
|
19
|
+
}
|
|
20
|
+
return resolved;
|
|
21
|
+
}
|
|
22
|
+
/** A path as kvbuilder reports it: relative to the workspace folder, with `/`, and `.` for the folder itself. */
|
|
23
|
+
export function workspaceRelative(workspaceFolder, absolute) {
|
|
24
|
+
return path.relative(workspaceFolder, absolute).split(path.sep).join('/') || '.';
|
|
25
|
+
}
|
|
26
|
+
/** The project manifest in `folder`, or `undefined` when it has no package.json with a `kvman` field. */
|
|
27
|
+
export function readProjectManifest(folder) {
|
|
28
|
+
const file = path.join(folder, 'package.json');
|
|
29
|
+
if (!existsSync(file))
|
|
30
|
+
return undefined;
|
|
31
|
+
let raw;
|
|
32
|
+
try {
|
|
33
|
+
raw = JSON.parse(readFileSync(file, 'utf8'));
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error instanceof SyntaxError)
|
|
37
|
+
return undefined;
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
const parsed = manifestSchema.safeParse(raw);
|
|
41
|
+
if (!parsed.success)
|
|
42
|
+
return undefined;
|
|
43
|
+
return { name: parsed.data.name, version: parsed.data.version, namespace: parsed.data.kvman.namespace, scripts: parsed.data.scripts ?? {} };
|
|
44
|
+
}
|
|
45
|
+
/** The project in `folder`, which must be inside the workspace folder; `kvbuilder/NOT_A_PROJECT` otherwise. */
|
|
46
|
+
export function projectAt(workspaceFolder, folder) {
|
|
47
|
+
const absolute = insideWorkspace(workspaceFolder, folder, 'folder');
|
|
48
|
+
const manifest = readProjectManifest(absolute);
|
|
49
|
+
if (manifest === undefined)
|
|
50
|
+
throw kvbuilderProblem('NOT_A_PROJECT', `${folder} has no package.json with a kvman field.`, { folder });
|
|
51
|
+
return { folder: absolute, manifest };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=folders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders.js","sourceRoot":"","sources":["../src/folders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAO1D,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE;CACnD,CAAC;KACD,KAAK,EAAE,CAAC;AAEX,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,eAAuB,EAAE,QAAgB,EAAE,IAAY;IACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,MAAM,OAAO,CAAC,OAAO,IAAI,IAAI,QAAQ,oCAAoC,eAAe,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,iBAAiB,CAAC,eAAuB,EAAE,QAAgB;IACzE,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AACnF,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW;YAAE,OAAO,SAAS,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;AAC9I,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,SAAS,CAAC,eAAuB,EAAE,MAAc;IAC/D,MAAM,QAAQ,GAAG,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,gBAAgB,CAAC,eAAe,EAAE,GAAG,MAAM,0CAA0C,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACrI,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAWtC,YAAY,EAAE,MAAM,UAAU,CAAC;yBAKf,KAAK,GAAG,KAAG,IAAI;AAA/B,wBAUE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { registerApp } from "./app/register-app.js";
|
|
2
|
+
import { registerAppReads } from "./app/register-app-reads.js";
|
|
3
|
+
import { registerBuild } from "./build/register-build.js";
|
|
4
|
+
import { registerDocs } from "./docs/register-docs.js";
|
|
5
|
+
import { registerExt } from "./ext/register-ext.js";
|
|
6
|
+
import { registerPreset } from "./preset/register-preset.js";
|
|
7
|
+
import { registerPreview } from "./preview/register-preview.js";
|
|
8
|
+
import { registerAppQuery } from "./query/register-app-query.js";
|
|
9
|
+
import { registerWithKvcoder } from "./register-with-kvcoder.js";
|
|
10
|
+
// kvbuilder (plan 09): the harness for developing kvman extensions and presets, and for seeing and changing the app
|
|
11
|
+
// itself. It has no loop of its own; it extends kvcoder with the kvman, ext, preset, preview, and docs connectors and
|
|
12
|
+
// its guide, which a chat has once the person runs `/build-kvman` in it (ADR 0027).
|
|
13
|
+
export default (ctx) => {
|
|
14
|
+
registerApp(ctx);
|
|
15
|
+
registerBuild(ctx);
|
|
16
|
+
registerAppReads(ctx);
|
|
17
|
+
registerAppQuery(ctx);
|
|
18
|
+
registerExt(ctx);
|
|
19
|
+
registerPreset(ctx);
|
|
20
|
+
registerPreview(ctx);
|
|
21
|
+
registerDocs(ctx);
|
|
22
|
+
registerWithKvcoder(ctx);
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIjE,oHAAoH;AACpH,sHAAsH;AACtH,oFAAoF;AACpF,eAAe,CAAC,GAAQ,EAAQ,EAAE;IAChC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const jobOptions: {
|
|
2
|
+
readonly 'kvbuilder.ext.new': {
|
|
3
|
+
readonly retries: 0;
|
|
4
|
+
readonly timeoutMs: 600000;
|
|
5
|
+
};
|
|
6
|
+
readonly 'kvbuilder.ext.check': {
|
|
7
|
+
readonly retries: 0;
|
|
8
|
+
readonly timeoutMs: 300000;
|
|
9
|
+
};
|
|
10
|
+
readonly 'kvbuilder.ext.test': {
|
|
11
|
+
readonly retries: 0;
|
|
12
|
+
readonly timeoutMs: 600000;
|
|
13
|
+
};
|
|
14
|
+
readonly 'kvbuilder.preview.start': {
|
|
15
|
+
readonly retries: 0;
|
|
16
|
+
readonly timeoutMs: 300000;
|
|
17
|
+
};
|
|
18
|
+
readonly 'kvbuilder.preview.stop': {
|
|
19
|
+
readonly retries: 0;
|
|
20
|
+
};
|
|
21
|
+
readonly 'kvbuilder.preview.command.run': {
|
|
22
|
+
readonly retries: 0;
|
|
23
|
+
readonly timeoutMs: 120000;
|
|
24
|
+
};
|
|
25
|
+
readonly 'kvbuilder.preset.new': {
|
|
26
|
+
readonly retries: 0;
|
|
27
|
+
};
|
|
28
|
+
readonly 'kvbuilder.preset.check': {
|
|
29
|
+
readonly retries: 0;
|
|
30
|
+
readonly timeoutMs: 300000;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=job-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-options.d.ts","sourceRoot":"","sources":["../src/job-options.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASb,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Job options of kvbuilder's commands (ADR 0009, 126): every command has `retries: 0`, since each runs a program that a
|
|
2
|
+
// retry would only run again; the long ones have their own timeouts.
|
|
3
|
+
export const jobOptions = {
|
|
4
|
+
'kvbuilder.ext.new': { retries: 0, timeoutMs: 600_000 },
|
|
5
|
+
'kvbuilder.ext.check': { retries: 0, timeoutMs: 300_000 },
|
|
6
|
+
'kvbuilder.ext.test': { retries: 0, timeoutMs: 600_000 },
|
|
7
|
+
'kvbuilder.preview.start': { retries: 0, timeoutMs: 300_000 },
|
|
8
|
+
'kvbuilder.preview.stop': { retries: 0 },
|
|
9
|
+
'kvbuilder.preview.command.run': { retries: 0, timeoutMs: 120_000 },
|
|
10
|
+
'kvbuilder.preset.new': { retries: 0 },
|
|
11
|
+
'kvbuilder.preset.check': { retries: 0, timeoutMs: 300_000 },
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=job-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-options.js","sourceRoot":"","sources":["../src/job-options.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,qEAAqE;AAErE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;IACvD,qBAAqB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;IACzD,oBAAoB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;IACxD,yBAAyB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;IAC7D,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;IACxC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;IACnE,sBAAsB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;IACtC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;CACpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-preset.d.ts","sourceRoot":"","sources":["../../src/preset/register-preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAyCzC,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAiB7C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from '@kvman/sdk';
|
|
2
|
+
import { insideWorkspace, workspaceRelative } from "../folders.js";
|
|
3
|
+
import { jobOptions } from "../job-options.js";
|
|
4
|
+
import { binResult, lastOutputLine, runBin } from "../run-bin.js";
|
|
5
|
+
// The `preset` connector's commands (plan 09 §9.1): `kvman-preset new` writes a preset skeleton, and
|
|
6
|
+
// `kvman-preset check` validates a preset's references. Both take the file as given, relative to the workspace
|
|
7
|
+
// folder, since the bin runs with the workspace folder as its working folder.
|
|
8
|
+
const fileField = z.string().min(1).describe('The preset file, relative to the workspace folder.');
|
|
9
|
+
const newOutputSchema = z.object({ file: z.string() });
|
|
10
|
+
const checkOutputSchema = z.array(z.object({ file: z.string(), message: z.string(), hint: z.string() }));
|
|
11
|
+
async function newPreset(ctx, workspaceFolder, name, file) {
|
|
12
|
+
insideWorkspace(workspaceFolder, file, 'file');
|
|
13
|
+
const run = await runBin('kvman-preset', ['new', file, '--name', name], workspaceFolder, ctx.job.signal);
|
|
14
|
+
const created = binResult(ctx.log, 'kvman-preset', run, newOutputSchema);
|
|
15
|
+
return { file: workspaceRelative(workspaceFolder, created.file) };
|
|
16
|
+
}
|
|
17
|
+
async function checkPreset(ctx, workspaceFolder, file) {
|
|
18
|
+
insideWorkspace(workspaceFolder, file, 'file');
|
|
19
|
+
const run = await runBin('kvman-preset', ['check', file], workspaceFolder, ctx.job.signal);
|
|
20
|
+
const line = lastOutputLine(run.stdout);
|
|
21
|
+
if (line !== undefined) {
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(line);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
parsed = undefined;
|
|
28
|
+
}
|
|
29
|
+
if (parsed !== undefined) {
|
|
30
|
+
const findings = checkOutputSchema.safeParse(parsed);
|
|
31
|
+
if (findings.success)
|
|
32
|
+
return findings.data;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return binResult(ctx.log, 'kvman-preset', run, checkOutputSchema);
|
|
36
|
+
}
|
|
37
|
+
export function registerPreset(ctx) {
|
|
38
|
+
ctx.registerCommand('kvbuilder.preset.new', {
|
|
39
|
+
description: 'Writes a preset that runs as-is, for adding extensions and settings to.',
|
|
40
|
+
public: true,
|
|
41
|
+
...jobOptions['kvbuilder.preset.new'],
|
|
42
|
+
input: z.object({ name: z.string().min(1).describe('The preset name, as kernel.health.get reports it.'), file: fileField }),
|
|
43
|
+
output: z.object({ file: z.string() }),
|
|
44
|
+
handle: (input) => newPreset(ctx, ctx.job.workspace.path, input.name, input.file),
|
|
45
|
+
});
|
|
46
|
+
ctx.registerCommand('kvbuilder.preset.check', {
|
|
47
|
+
description: "Checks a preset's schema and its extensions, settings, and home page.",
|
|
48
|
+
public: true,
|
|
49
|
+
...jobOptions['kvbuilder.preset.check'],
|
|
50
|
+
input: z.object({ file: fileField }),
|
|
51
|
+
output: z.array(z.object({ file: z.string(), message: z.string(), hint: z.string() })),
|
|
52
|
+
handle: (input) => checkPreset(ctx, ctx.job.workspace.path, input.file),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=register-preset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-preset.js","sourceRoot":"","sources":["../../src/preset/register-preset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z, type Ctx } from '@kvman/sdk';
|
|
2
|
+
export type PreviewRoute = 'queries' | 'commands';
|
|
3
|
+
/** The preview's envelope without its job id: the output of a call, or its Problem. */
|
|
4
|
+
export declare const previewAnswerSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
5
|
+
ok: z.ZodLiteral<true>;
|
|
6
|
+
output: z.ZodJSONSchema;
|
|
7
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
8
|
+
ok: z.ZodLiteral<false>;
|
|
9
|
+
problem: z.ZodObject<{
|
|
10
|
+
code: z.ZodString;
|
|
11
|
+
message: z.ZodString;
|
|
12
|
+
params: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
}, z.core.$strip>]>;
|
|
15
|
+
export type PreviewAnswer = z.output<typeof previewAnswerSchema>;
|
|
16
|
+
/** What the preview answered, or `kvbuilder/PREVIEW_FAILED` when it isn't kvman's envelope. */
|
|
17
|
+
export declare function previewAnswer(body: unknown): PreviewAnswer;
|
|
18
|
+
/** Runs one public query or command of the running preview, in its Home. */
|
|
19
|
+
export declare function callPreview(ctx: Ctx, route: PreviewRoute, name: string, input: Record<string, unknown>): Promise<PreviewAnswer>;
|
|
20
|
+
//# sourceMappingURL=preview-call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-call.d.ts","sourceRoot":"","sources":["../../src/preview/preview-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,CAAC,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAQvD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAElD,uFAAuF;AACvF,eAAO,MAAM,mBAAmB;;;;;;;;;;mBAG9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEjE,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAI1D;AAmBD,4EAA4E;AAC5E,wBAAsB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAGrI"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ProblemError, z } from '@kvman/sdk';
|
|
2
|
+
import { kvbuilderProblem } from "../problems.js";
|
|
3
|
+
import { previewRecordSchema, recordKey } from "./preview-state.js";
|
|
4
|
+
/** The preview's envelope without its job id: the output of a call, or its Problem. */
|
|
5
|
+
export const previewAnswerSchema = z.union([
|
|
6
|
+
z.object({ ok: z.literal(true), output: z.json() }),
|
|
7
|
+
z.object({ ok: z.literal(false), problem: z.object({ code: z.string(), message: z.string(), params: z.record(z.string(), z.json()).exactOptional() }) }),
|
|
8
|
+
]);
|
|
9
|
+
/** What the preview answered, or `kvbuilder/PREVIEW_FAILED` when it isn't kvman's envelope. */
|
|
10
|
+
export function previewAnswer(body) {
|
|
11
|
+
const parsed = previewAnswerSchema.safeParse(body);
|
|
12
|
+
if (!parsed.success)
|
|
13
|
+
throw kvbuilderProblem('PREVIEW_FAILED', "The preview's answer isn't one kvman gives.");
|
|
14
|
+
return parsed.data.ok ? { ok: true, output: parsed.data.output } : { ok: false, problem: parsed.data.problem };
|
|
15
|
+
}
|
|
16
|
+
async function previewUrl(ctx) {
|
|
17
|
+
const running = (await ctx.processes.list()).some((process) => process.name === 'preview');
|
|
18
|
+
const record = previewRecordSchema.safeParse(await ctx.store.kv.get(recordKey));
|
|
19
|
+
if (!running || !record.success)
|
|
20
|
+
throw new ProblemError({ code: 'NOT_FOUND', message: 'No preview is running; start one with preview start.' });
|
|
21
|
+
return record.data.url;
|
|
22
|
+
}
|
|
23
|
+
async function post(address, input, signal) {
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(address, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ input }), signal });
|
|
26
|
+
return await response.json();
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof TypeError || error instanceof SyntaxError)
|
|
30
|
+
throw kvbuilderProblem('PREVIEW_FAILED', `The preview didn't answer the call: ${error.message}`);
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Runs one public query or command of the running preview, in its Home. */
|
|
35
|
+
export async function callPreview(ctx, route, name, input) {
|
|
36
|
+
const address = new URL(`api/${route}/${encodeURIComponent(name)}`, await previewUrl(ctx));
|
|
37
|
+
return previewAnswer(await post(address, input, ctx.job.signal));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=preview-call.js.map
|