@graview/core 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/LICENSE +96 -0
- package/README.md +35 -0
- package/dist/app.d.ts +294 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +49 -0
- package/dist/app.js.map +1 -0
- package/dist/arrange.d.ts +185 -0
- package/dist/arrange.d.ts.map +1 -0
- package/dist/arrange.js +456 -0
- package/dist/arrange.js.map +1 -0
- package/dist/beginning.d.ts +65 -0
- package/dist/beginning.d.ts.map +1 -0
- package/dist/beginning.js +94 -0
- package/dist/beginning.js.map +1 -0
- package/dist/bind.d.ts +42 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +26 -0
- package/dist/bind.js.map +1 -0
- package/dist/city.d.ts +93 -0
- package/dist/city.d.ts.map +1 -0
- package/dist/city.js +160 -0
- package/dist/city.js.map +1 -0
- package/dist/cli/check/arrangement.d.ts +13 -0
- package/dist/cli/check/arrangement.d.ts.map +1 -0
- package/dist/cli/check/arrangement.js +63 -0
- package/dist/cli/check/arrangement.js.map +1 -0
- package/dist/cli/check/beginnings.d.ts +16 -0
- package/dist/cli/check/beginnings.d.ts.map +1 -0
- package/dist/cli/check/beginnings.js +53 -0
- package/dist/cli/check/beginnings.js.map +1 -0
- package/dist/cli/check/brand.d.ts +17 -0
- package/dist/cli/check/brand.d.ts.map +1 -0
- package/dist/cli/check/brand.js +153 -0
- package/dist/cli/check/brand.js.map +1 -0
- package/dist/cli/check/city.d.ts +17 -0
- package/dist/cli/check/city.d.ts.map +1 -0
- package/dist/cli/check/city.js +58 -0
- package/dist/cli/check/city.js.map +1 -0
- package/dist/cli/check/context.d.ts +50 -0
- package/dist/cli/check/context.d.ts.map +1 -0
- package/dist/cli/check/context.js +37 -0
- package/dist/cli/check/context.js.map +1 -0
- package/dist/cli/check/fields.d.ts +16 -0
- package/dist/cli/check/fields.d.ts.map +1 -0
- package/dist/cli/check/fields.js +237 -0
- package/dist/cli/check/fields.js.map +1 -0
- package/dist/cli/check/index.d.ts +14 -0
- package/dist/cli/check/index.d.ts.map +1 -0
- package/dist/cli/check/index.js +14 -0
- package/dist/cli/check/index.js.map +1 -0
- package/dist/cli/check/intelligence.d.ts +17 -0
- package/dist/cli/check/intelligence.d.ts.map +1 -0
- package/dist/cli/check/intelligence.js +136 -0
- package/dist/cli/check/intelligence.js.map +1 -0
- package/dist/cli/check/lenses.d.ts +17 -0
- package/dist/cli/check/lenses.d.ts.map +1 -0
- package/dist/cli/check/lenses.js +239 -0
- package/dist/cli/check/lenses.js.map +1 -0
- package/dist/cli/check/migrations.d.ts +16 -0
- package/dist/cli/check/migrations.d.ts.map +1 -0
- package/dist/cli/check/migrations.js +43 -0
- package/dist/cli/check/migrations.js.map +1 -0
- package/dist/cli/check/modules.d.ts +16 -0
- package/dist/cli/check/modules.d.ts.map +1 -0
- package/dist/cli/check/modules.js +123 -0
- package/dist/cli/check/modules.js.map +1 -0
- package/dist/cli/check/policy.d.ts +16 -0
- package/dist/cli/check/policy.d.ts.map +1 -0
- package/dist/cli/check/policy.js +90 -0
- package/dist/cli/check/policy.js.map +1 -0
- package/dist/cli/check/relations.d.ts +29 -0
- package/dist/cli/check/relations.d.ts.map +1 -0
- package/dist/cli/check/relations.js +279 -0
- package/dist/cli/check/relations.js.map +1 -0
- package/dist/cli/check/routes.d.ts +16 -0
- package/dist/cli/check/routes.d.ts.map +1 -0
- package/dist/cli/check/routes.js +31 -0
- package/dist/cli/check/routes.js.map +1 -0
- package/dist/cli/check/settings.d.ts +16 -0
- package/dist/cli/check/settings.d.ts.map +1 -0
- package/dist/cli/check/settings.js +81 -0
- package/dist/cli/check/settings.js.map +1 -0
- package/dist/cli/check.d.ts +36 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +76 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/create.d.ts +20 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +251 -0
- package/dist/cli/create.js.map +1 -0
- package/dist/cli/describe.d.ts +35 -0
- package/dist/cli/describe.d.ts.map +1 -0
- package/dist/cli/describe.js +230 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/docs.d.ts +11 -0
- package/dist/cli/docs.d.ts.map +1 -0
- package/dist/cli/docs.js +152 -0
- package/dist/cli/docs.js.map +1 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +281 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/extend.d.ts +23 -0
- package/dist/extend.d.ts.map +1 -0
- package/dist/extend.js +53 -0
- package/dist/extend.js.map +1 -0
- package/dist/graph/diff.d.ts +31 -0
- package/dist/graph/diff.d.ts.map +1 -0
- package/dist/graph/diff.js +71 -0
- package/dist/graph/diff.js.map +1 -0
- package/dist/graph/graph.d.ts +69 -0
- package/dist/graph/graph.d.ts.map +1 -0
- package/dist/graph/graph.js +284 -0
- package/dist/graph/graph.js.map +1 -0
- package/dist/graph/primitives.d.ts +52 -0
- package/dist/graph/primitives.d.ts.map +1 -0
- package/dist/graph/primitives.js +62 -0
- package/dist/graph/primitives.js.map +1 -0
- package/dist/graph/tracked.d.ts +31 -0
- package/dist/graph/tracked.d.ts.map +1 -0
- package/dist/graph/tracked.js +69 -0
- package/dist/graph/tracked.js.map +1 -0
- package/dist/graph/types.d.ts +34 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +0 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/installation.d.ts +112 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +193 -0
- package/dist/installation.js.map +1 -0
- package/dist/intelligence-bridge.d.ts +73 -0
- package/dist/intelligence-bridge.d.ts.map +1 -0
- package/dist/intelligence-bridge.js +31 -0
- package/dist/intelligence-bridge.js.map +1 -0
- package/dist/invariants/engine.d.ts +36 -0
- package/dist/invariants/engine.d.ts.map +1 -0
- package/dist/invariants/engine.js +88 -0
- package/dist/invariants/engine.js.map +1 -0
- package/dist/invariants/types.d.ts +75 -0
- package/dist/invariants/types.d.ts.map +1 -0
- package/dist/invariants/types.js +2 -0
- package/dist/invariants/types.js.map +1 -0
- package/dist/modules.d.ts +75 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +87 -0
- package/dist/modules.js.map +1 -0
- package/dist/mutations/decidable.d.ts +26 -0
- package/dist/mutations/decidable.d.ts.map +1 -0
- package/dist/mutations/decidable.js +39 -0
- package/dist/mutations/decidable.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts +32 -0
- package/dist/mutations/define-mutation.d.ts.map +1 -0
- package/dist/mutations/define-mutation.js +181 -0
- package/dist/mutations/define-mutation.js.map +1 -0
- package/dist/mutations/derive-edits.d.ts +75 -0
- package/dist/mutations/derive-edits.d.ts.map +1 -0
- package/dist/mutations/derive-edits.js +240 -0
- package/dist/mutations/derive-edits.js.map +1 -0
- package/dist/mutations/form.d.ts +63 -0
- package/dist/mutations/form.d.ts.map +1 -0
- package/dist/mutations/form.js +113 -0
- package/dist/mutations/form.js.map +1 -0
- package/dist/mutations/node-ref.d.ts +83 -0
- package/dist/mutations/node-ref.d.ts.map +1 -0
- package/dist/mutations/node-ref.js +113 -0
- package/dist/mutations/node-ref.js.map +1 -0
- package/dist/mutations/types.d.ts +136 -0
- package/dist/mutations/types.d.ts.map +1 -0
- package/dist/mutations/types.js +2 -0
- package/dist/mutations/types.js.map +1 -0
- package/dist/ops/log.d.ts +35 -0
- package/dist/ops/log.d.ts.map +1 -0
- package/dist/ops/log.js +103 -0
- package/dist/ops/log.js.map +1 -0
- package/dist/ops/types.d.ts +52 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +2 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/ops/undo.d.ts +33 -0
- package/dist/ops/undo.d.ts.map +1 -0
- package/dist/ops/undo.js +65 -0
- package/dist/ops/undo.js.map +1 -0
- package/dist/permissions/policy.d.ts +68 -0
- package/dist/permissions/policy.d.ts.map +1 -0
- package/dist/permissions/policy.js +191 -0
- package/dist/permissions/policy.js.map +1 -0
- package/dist/permissions/types.d.ts +78 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +17 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/persistence/memory.d.ts +6 -0
- package/dist/persistence/memory.d.ts.map +1 -0
- package/dist/persistence/memory.js +31 -0
- package/dist/persistence/memory.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +59 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +131 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/persistence/types.d.ts +22 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +2 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/presence.d.ts +38 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +50 -0
- package/dist/presence.js.map +1 -0
- package/dist/scaffold/domain.d.ts +8 -0
- package/dist/scaffold/domain.d.ts.map +1 -0
- package/dist/scaffold/domain.js +331 -0
- package/dist/scaffold/domain.js.map +1 -0
- package/dist/scaffold/index.d.ts +66 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +142 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/lens.d.ts +31 -0
- package/dist/scaffold/lens.d.ts.map +1 -0
- package/dist/scaffold/lens.js +176 -0
- package/dist/scaffold/lens.js.map +1 -0
- package/dist/scaffold/names.d.ts +44 -0
- package/dist/scaffold/names.d.ts.map +1 -0
- package/dist/scaffold/names.js +69 -0
- package/dist/scaffold/names.js.map +1 -0
- package/dist/scaffold/project.d.ts +41 -0
- package/dist/scaffold/project.d.ts.map +1 -0
- package/dist/scaffold/project.js +604 -0
- package/dist/scaffold/project.js.map +1 -0
- package/dist/scaffold/ui.d.ts +15 -0
- package/dist/scaffold/ui.d.ts.map +1 -0
- package/dist/scaffold/ui.js +536 -0
- package/dist/scaffold/ui.js.map +1 -0
- package/dist/schema/define-node.d.ts +132 -0
- package/dist/schema/define-node.d.ts.map +1 -0
- package/dist/schema/define-node.js +254 -0
- package/dist/schema/define-node.js.map +1 -0
- package/dist/schema/figures.d.ts +42 -0
- package/dist/schema/figures.d.ts.map +1 -0
- package/dist/schema/figures.js +220 -0
- package/dist/schema/figures.js.map +1 -0
- package/dist/schema/json-schema.d.ts +39 -0
- package/dist/schema/json-schema.d.ts.map +1 -0
- package/dist/schema/json-schema.js +74 -0
- package/dist/schema/json-schema.js.map +1 -0
- package/dist/schema/schema.d.ts +43 -0
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/schema.js +102 -0
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/types.d.ts +201 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +2 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/search.d.ts +215 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +449 -0
- package/dist/search.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +74 -0
- package/dist/settings.js.map +1 -0
- package/dist/store.d.ts +284 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +660 -0
- package/dist/store.js.map +1 -0
- package/dist/studio-door.d.ts +187 -0
- package/dist/studio-door.d.ts.map +1 -0
- package/dist/studio-door.js +20 -0
- package/dist/studio-door.js.map +1 -0
- package/dist/sync/conflict.d.ts +37 -0
- package/dist/sync/conflict.d.ts.map +1 -0
- package/dist/sync/conflict.js +56 -0
- package/dist/sync/conflict.js.map +1 -0
- package/dist/sync/engine.d.ts +118 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +341 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/google-calendar.d.ts +54 -0
- package/dist/sync/google-calendar.d.ts.map +1 -0
- package/dist/sync/google-calendar.js +167 -0
- package/dist/sync/google-calendar.js.map +1 -0
- package/dist/sync/types.d.ts +125 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +6 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/temporal/effectivity.d.ts +75 -0
- package/dist/temporal/effectivity.d.ts.map +1 -0
- package/dist/temporal/effectivity.js +89 -0
- package/dist/temporal/effectivity.js.map +1 -0
- package/dist/testing.d.ts +63 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +194 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme/contrast.d.ts +47 -0
- package/dist/theme/contrast.d.ts.map +1 -0
- package/dist/theme/contrast.js +172 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/derive.d.ts +81 -0
- package/dist/theme/derive.d.ts.map +1 -0
- package/dist/theme/derive.js +171 -0
- package/dist/theme/derive.js.map +1 -0
- package/dist/theme/kit.d.ts +106 -0
- package/dist/theme/kit.d.ts.map +1 -0
- package/dist/theme/kit.js +84 -0
- package/dist/theme/kit.js.map +1 -0
- package/dist/theme/palettes.d.ts +32 -0
- package/dist/theme/palettes.d.ts.map +1 -0
- package/dist/theme/palettes.js +96 -0
- package/dist/theme/palettes.js.map +1 -0
- package/dist/theme/types.d.ts +131 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +23 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/views/types.d.ts +89 -0
- package/dist/views/types.d.ts.map +1 -0
- package/dist/views/types.js +88 -0
- package/dist/views/types.js.map +1 -0
- package/dist/watched.d.ts +33 -0
- package/dist/watched.d.ts.map +1 -0
- package/dist/watched.js +50 -0
- package/dist/watched.js.map +1 -0
- package/dist/who.d.ts +26 -0
- package/dist/who.d.ts.map +1 -0
- package/dist/who.js +20 -0
- package/dist/who.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnySchema } from "../../schema/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* `note` is a QUESTION ASKED OUT LOUD, not a problem.
|
|
4
|
+
*
|
|
5
|
+
* Some things a checker can see are legitimate designs that the author
|
|
6
|
+
* should nonetheless have looked at once: a lens written for this app and
|
|
7
|
+
* never proved against another domain, a role name two vocabularies both
|
|
8
|
+
* use, a kind unreachable on an empty graph. Filed as warnings they would
|
|
9
|
+
* be warnings that can only ever be acknowledged, and those are the ones
|
|
10
|
+
* people learn to scroll past — which costs the checker its authority on
|
|
11
|
+
* the warnings that matter. So they have their own voice: counted, printed,
|
|
12
|
+
* and never a failure.
|
|
13
|
+
*/
|
|
14
|
+
import type { CheckContext } from "./context.js";
|
|
15
|
+
export declare function checkSettings<S extends AnySchema>(ctx: CheckContext<S>): void;
|
|
16
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/cli/check/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CA8E7E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export function checkSettings(ctx) {
|
|
2
|
+
const { app, add } = ctx;
|
|
3
|
+
/*
|
|
4
|
+
* A SETTING NOBODY CAN HONOUR IS A CONTROL THAT DOES NOTHING.
|
|
5
|
+
*
|
|
6
|
+
* The profile pane draws what the app declares, and the shell knows
|
|
7
|
+
* exactly two ways to carry an answer to every surface. A setting with
|
|
8
|
+
* one option is not a setting; one whose starting value is not among its
|
|
9
|
+
* options opens on an answer nobody chose and cannot choose again; two
|
|
10
|
+
* settings with one name write over each other's storage.
|
|
11
|
+
*/
|
|
12
|
+
const settingNames = new Set();
|
|
13
|
+
const HONOURED = ["root-font-size", "root-attribute"];
|
|
14
|
+
for (const setting of app.settings ?? []) {
|
|
15
|
+
const where = `settings["${setting.name}"]`;
|
|
16
|
+
if (!/^[a-z][a-z0-9-]*$/.test(setting.name)) {
|
|
17
|
+
add({
|
|
18
|
+
severity: "error",
|
|
19
|
+
code: "setting-name-unusable",
|
|
20
|
+
where,
|
|
21
|
+
message: `"${setting.name}" becomes a storage key and a data-graview- attribute, so it must be kebab-case.`,
|
|
22
|
+
fix: `Rename it to lower-case letters, digits and hyphens — "text-size", not "${setting.name}".`,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (settingNames.has(setting.name)) {
|
|
26
|
+
add({
|
|
27
|
+
severity: "error",
|
|
28
|
+
code: "setting-name-taken",
|
|
29
|
+
where,
|
|
30
|
+
message: `Two settings are called "${setting.name}"; they would write over each other.`,
|
|
31
|
+
fix: `Give one of them another name.`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
settingNames.add(setting.name);
|
|
35
|
+
if (!HONOURED.includes(setting.honoured)) {
|
|
36
|
+
add({
|
|
37
|
+
severity: "error",
|
|
38
|
+
code: "setting-not-honourable",
|
|
39
|
+
where: `${where}.honoured`,
|
|
40
|
+
message: `Nothing knows how to apply "${setting.honoured}", so this control would do nothing.`,
|
|
41
|
+
fix: `Use ${HONOURED.map((one) => `"${one}"`).join(" or ")}.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (setting.options.length < 2) {
|
|
45
|
+
add({
|
|
46
|
+
severity: "error",
|
|
47
|
+
code: "setting-without-a-choice",
|
|
48
|
+
where: `${where}.options`,
|
|
49
|
+
message: `A setting with ${setting.options.length === 0 ? "no" : "one"} option is not something a person can set.`,
|
|
50
|
+
fix: `Declare at least two options, or drop the setting.`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (!setting.options.some((option) => option.value === setting.initial)) {
|
|
54
|
+
add({
|
|
55
|
+
severity: "error",
|
|
56
|
+
code: "setting-starts-nowhere",
|
|
57
|
+
where: `${where}.initial`,
|
|
58
|
+
message: `It opens on "${setting.initial}", which is not one of its options — nobody could choose it back.`,
|
|
59
|
+
fix: `Set initial to one of: ${setting.options.map((option) => `"${option.value}"`).join(", ")}.`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (setting.honoured === "root-font-size") {
|
|
63
|
+
for (const option of setting.options) {
|
|
64
|
+
// The starting option means "leave it as the reader has it" and
|
|
65
|
+
// stamps nothing, so it is a word rather than a length.
|
|
66
|
+
if (option.value === setting.initial)
|
|
67
|
+
continue;
|
|
68
|
+
if (!/^[0-9.]+(px|rem|em|%|pt)$/.test(option.value)) {
|
|
69
|
+
add({
|
|
70
|
+
severity: "error",
|
|
71
|
+
code: "setting-not-a-length",
|
|
72
|
+
where: `${where}.options["${option.value}"]`,
|
|
73
|
+
message: `A root font size has to be a CSS length; "${option.value}" is not one.`,
|
|
74
|
+
fix: `Use a length with a unit, such as "18px".`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/cli/check/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { GraviewApp } from "../app.js";
|
|
2
|
+
import type { AnySchema } from "../schema/schema.js";
|
|
3
|
+
export type Severity = "error" | "warning" | "note";
|
|
4
|
+
export interface Finding {
|
|
5
|
+
readonly severity: Severity;
|
|
6
|
+
readonly code: string;
|
|
7
|
+
/** Where the problem is, in terms an agent can act on. */
|
|
8
|
+
readonly where: string;
|
|
9
|
+
readonly message: string;
|
|
10
|
+
/** The concrete edit that would fix it. */
|
|
11
|
+
readonly fix: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CheckResult {
|
|
14
|
+
readonly app: string;
|
|
15
|
+
readonly findings: readonly Finding[];
|
|
16
|
+
readonly errors: number;
|
|
17
|
+
readonly warnings: number;
|
|
18
|
+
/** Questions asked out loud: never a failure, always worth one read. */
|
|
19
|
+
readonly notes: number;
|
|
20
|
+
readonly ok: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The build-time safety net. Most of these mistakes are already typecheck
|
|
24
|
+
* failures — an edge to an undeclared kind, a view for a kind nobody
|
|
25
|
+
* declared — but a schema assembled dynamically, or an app mid-rename, can
|
|
26
|
+
* slip past `tsc`. Every message names the file-level thing to change,
|
|
27
|
+
* because the primary reader is an agent editing the declaration.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* EVERY QUESTION A DECLARATION IS ASKED, in the order it is asked. Each
|
|
31
|
+
* family of checks lives in `check/` and is handed the same context; the
|
|
32
|
+
* order is the report's order, which is the order a person reads it in.
|
|
33
|
+
*/
|
|
34
|
+
export declare function checkApp<S extends AnySchema>(app: GraviewApp<S>): CheckResult;
|
|
35
|
+
export declare function formatFindings(result: CheckResult): string;
|
|
36
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAsCrD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AAEH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,CAsC7E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAiB1D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { deriveEditMutations, deriveRemoveMutations } from "../mutations/derive-edits.js";
|
|
2
|
+
/**
|
|
3
|
+
* `note` is a QUESTION ASKED OUT LOUD, not a problem.
|
|
4
|
+
*
|
|
5
|
+
* Some things a checker can see are legitimate designs that the author
|
|
6
|
+
* should nonetheless have looked at once: a lens written for this app and
|
|
7
|
+
* never proved against another domain, a role name two vocabularies both
|
|
8
|
+
* use, a kind unreachable on an empty graph. Filed as warnings they would
|
|
9
|
+
* be warnings that can only ever be acknowledged, and those are the ones
|
|
10
|
+
* people learn to scroll past — which costs the checker its authority on
|
|
11
|
+
* the warnings that matter. So they have their own voice: counted, printed,
|
|
12
|
+
* and never a failure.
|
|
13
|
+
*/
|
|
14
|
+
import { checkAccents, checkActsFromEnds, checkBlankInstallation, checkEditableFields, checkFigures, checkLensBindings, checkMigrations, checkModelWritten, checkModules, checkPalette, checkPlots, checkPolicy, checkProviders, checkReadings, checkEdgeNamesAgree, checkRoutes, checkSettings, checkShippedLenses, checkUnmakeable, checkArrangement, } from "./check/index.js";
|
|
15
|
+
/**
|
|
16
|
+
* The build-time safety net. Most of these mistakes are already typecheck
|
|
17
|
+
* failures — an edge to an undeclared kind, a view for a kind nobody
|
|
18
|
+
* declared — but a schema assembled dynamically, or an app mid-rename, can
|
|
19
|
+
* slip past `tsc`. Every message names the file-level thing to change,
|
|
20
|
+
* because the primary reader is an agent editing the declaration.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* EVERY QUESTION A DECLARATION IS ASKED, in the order it is asked. Each
|
|
24
|
+
* family of checks lives in `check/` and is handed the same context; the
|
|
25
|
+
* order is the report's order, which is the order a person reads it in.
|
|
26
|
+
*/
|
|
27
|
+
export function checkApp(app) {
|
|
28
|
+
const findings = [];
|
|
29
|
+
const kinds = new Set(app.schema.kinds);
|
|
30
|
+
const declaredMutations = app.mutations ?? [];
|
|
31
|
+
const derivedEdits = deriveEditMutations(app.schema, declaredMutations);
|
|
32
|
+
const derivedRemoves = deriveRemoveMutations(app.schema, declaredMutations);
|
|
33
|
+
// Declared and derived: a grant may name `edit-<kind>` or `remove-<kind>`, and a repair may too.
|
|
34
|
+
const mutations = new Map([...declaredMutations, ...derivedEdits, ...derivedRemoves].map((m) => [m.name, m]));
|
|
35
|
+
const invariants = new Map((app.invariants ?? []).map((i) => [i.name, i]));
|
|
36
|
+
const add = (f) => findings.push(f);
|
|
37
|
+
const ctx = { app, kinds, declaredMutations, derivedEdits, derivedRemoves, mutations, invariants, add };
|
|
38
|
+
checkRoutes(ctx);
|
|
39
|
+
checkShippedLenses(ctx);
|
|
40
|
+
checkBlankInstallation(ctx);
|
|
41
|
+
checkProviders(ctx);
|
|
42
|
+
checkPlots(ctx);
|
|
43
|
+
checkFigures(ctx);
|
|
44
|
+
const writtenByAModel = checkModelWritten(ctx);
|
|
45
|
+
checkSettings(ctx);
|
|
46
|
+
checkMigrations(ctx);
|
|
47
|
+
checkAccents(ctx);
|
|
48
|
+
checkModules(ctx);
|
|
49
|
+
checkReadings(ctx);
|
|
50
|
+
checkEdgeNamesAgree(ctx);
|
|
51
|
+
checkActsFromEnds(ctx, writtenByAModel);
|
|
52
|
+
checkUnmakeable(ctx);
|
|
53
|
+
checkEditableFields(ctx);
|
|
54
|
+
checkPolicy(ctx);
|
|
55
|
+
checkPalette(ctx);
|
|
56
|
+
checkLensBindings(ctx);
|
|
57
|
+
checkArrangement(ctx);
|
|
58
|
+
const errors = findings.filter((f) => f.severity === "error").length;
|
|
59
|
+
const notes = findings.filter((f) => f.severity === "note").length;
|
|
60
|
+
const warnings = findings.length - errors - notes;
|
|
61
|
+
return { app: app.name, findings, errors, warnings, notes, ok: errors === 0 };
|
|
62
|
+
}
|
|
63
|
+
export function formatFindings(result) {
|
|
64
|
+
if (result.findings.length === 0) {
|
|
65
|
+
return `graview check: ${result.app} — no problems found.`;
|
|
66
|
+
}
|
|
67
|
+
const said = { error: "ERROR", warning: "warn ", note: "note " };
|
|
68
|
+
const lines = result.findings.map((f) => `${said[f.severity]} [${f.code}] ${f.where}\n` +
|
|
69
|
+
` ${f.message}\n fix: ${f.fix}`);
|
|
70
|
+
return [
|
|
71
|
+
`graview check: ${result.app}`,
|
|
72
|
+
...lines,
|
|
73
|
+
`${result.errors} error(s), ${result.warnings} warning(s)${result.notes > 0 ? `, ${result.notes} note(s)` : ""}`,
|
|
74
|
+
].join("\n");
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAG1F;;;;;;;;;;;GAWG;AACH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAyB1B;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAsB,GAAkB;IAC9D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,GAAG,CAAC,MAAM,CAAC,KAA0B,CAAC,CAAC;IACrE,MAAM,iBAAiB,GAAG,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;IAC9C,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5E,iGAAiG;IACjG,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,iBAAiB,EAAE,GAAG,YAAY,EAAE,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9G,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3E,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAoB,EAAE,GAAG,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IAEzH,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACxB,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5B,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,UAAU,CAAC,GAAG,CAAC,CAAC;IAChB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,eAAe,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC/C,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACzB,iBAAiB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACxC,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACzB,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACvB,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEtB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACnE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAClD,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,kBAAkB,MAAM,CAAC,GAAG,uBAAuB,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAW,CAAC;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI;QAC9C,WAAW,CAAC,CAAC,OAAO,kBAAkB,CAAC,CAAC,GAAG,EAAE,CAChD,CAAC;IACF,OAAO;QACL,kBAAkB,MAAM,CAAC,GAAG,EAAE;QAC9B,GAAG,KAAK;QACR,GAAG,MAAM,CAAC,MAAM,cAAc,MAAM,CAAC,QAAQ,cAC3C,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,EACnD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `graview create <dir>`: a product on Graview, started.
|
|
3
|
+
*
|
|
4
|
+
* The generator (`../scaffold`) decides what a project is; this decides
|
|
5
|
+
* what touching a real filesystem should look like — refusing to write into
|
|
6
|
+
* a directory that already has things in it, installing with the package
|
|
7
|
+
* manager the person is evidently using, and saying what to do next rather
|
|
8
|
+
* than printing a file list.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CREATE_USAGE = " graview create <dir> [--name \"Field Notes\"] [--kind note] [--plural notes]\n Starts a product on Graview in <dir>: the declaration split into domain\n and UI, an eighty-line shell, a headless test, a CI workflow.\n --name <text> the product's name (default: from <dir>)\n --kind <slug> the first node kind (default: item)\n --plural <slug> its plural (default: <kind>s)\n --link <path> consume the framework from a sibling checkout by\n path rather than from a registry\n --pm pnpm|npm the package manager (default: whichever ran this)\n --port <n> the dev server port (default: 5170)\n --accent <#hex> the brand accent (default: a worked green)\n --no-install write the files and stop\n --no-skills do not install the authoring skills\n --no-git do not initialise a git repository\n --workspace the layout every real product ends up with: a\n workspace root with the app under app/ and the\n harness scripts at the root\n --merge write only the files that do not exist yet, and\n name every collision without touching it\n --force write into a directory that is not empty\n";
|
|
11
|
+
export interface CreateIo {
|
|
12
|
+
readonly stdout: (text: string) => void;
|
|
13
|
+
readonly stderr: (text: string) => void;
|
|
14
|
+
/** Runs a command in a directory and reports whether it succeeded. */
|
|
15
|
+
readonly run: (command: string, args: readonly string[], cwd: string) => boolean;
|
|
16
|
+
}
|
|
17
|
+
/** pnpm when it ran this (`pnpm create graview`, `pnpm dlx`), else npm. */
|
|
18
|
+
export declare function packageManagerFromEnv(env?: NodeJS.ProcessEnv): "pnpm" | "npm";
|
|
19
|
+
export declare function create(argv: readonly string[], io?: CreateIo): Promise<number>;
|
|
20
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AAEH,eAAO,MAAM,YAAY,81CAoBxB,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sEAAsE;IACtE,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAClF;AAgBD,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,KAAK,CAG1F;AAkBD,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,GAAE,QAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6K/F"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { LINKED_PACKAGES, scaffoldProject, validateScaffoldOptions } from "../scaffold/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* `graview create <dir>`: a product on Graview, started.
|
|
8
|
+
*
|
|
9
|
+
* The generator (`../scaffold`) decides what a project is; this decides
|
|
10
|
+
* what touching a real filesystem should look like — refusing to write into
|
|
11
|
+
* a directory that already has things in it, installing with the package
|
|
12
|
+
* manager the person is evidently using, and saying what to do next rather
|
|
13
|
+
* than printing a file list.
|
|
14
|
+
*/
|
|
15
|
+
export const CREATE_USAGE = ` graview create <dir> [--name "Field Notes"] [--kind note] [--plural notes]
|
|
16
|
+
Starts a product on Graview in <dir>: the declaration split into domain
|
|
17
|
+
and UI, an eighty-line shell, a headless test, a CI workflow.
|
|
18
|
+
--name <text> the product's name (default: from <dir>)
|
|
19
|
+
--kind <slug> the first node kind (default: item)
|
|
20
|
+
--plural <slug> its plural (default: <kind>s)
|
|
21
|
+
--link <path> consume the framework from a sibling checkout by
|
|
22
|
+
path rather than from a registry
|
|
23
|
+
--pm pnpm|npm the package manager (default: whichever ran this)
|
|
24
|
+
--port <n> the dev server port (default: 5170)
|
|
25
|
+
--accent <#hex> the brand accent (default: a worked green)
|
|
26
|
+
--no-install write the files and stop
|
|
27
|
+
--no-skills do not install the authoring skills
|
|
28
|
+
--no-git do not initialise a git repository
|
|
29
|
+
--workspace the layout every real product ends up with: a
|
|
30
|
+
workspace root with the app under app/ and the
|
|
31
|
+
harness scripts at the root
|
|
32
|
+
--merge write only the files that do not exist yet, and
|
|
33
|
+
name every collision without touching it
|
|
34
|
+
--force write into a directory that is not empty
|
|
35
|
+
`;
|
|
36
|
+
const defaultIo = {
|
|
37
|
+
stdout: (text) => process.stdout.write(text),
|
|
38
|
+
stderr: (text) => process.stderr.write(text),
|
|
39
|
+
run: (command, args, cwd) => spawnSync(command, [...args], { cwd, stdio: "inherit", shell: process.platform === "win32" }).status === 0,
|
|
40
|
+
};
|
|
41
|
+
function flag(argv, name) {
|
|
42
|
+
const index = argv.indexOf(name);
|
|
43
|
+
if (index === -1)
|
|
44
|
+
return undefined;
|
|
45
|
+
const value = argv[index + 1];
|
|
46
|
+
return value === undefined || value.startsWith("--") ? "" : value;
|
|
47
|
+
}
|
|
48
|
+
/** pnpm when it ran this (`pnpm create graview`, `pnpm dlx`), else npm. */
|
|
49
|
+
export function packageManagerFromEnv(env = process.env) {
|
|
50
|
+
const agent = env["npm_config_user_agent"] ?? "";
|
|
51
|
+
return agent.startsWith("pnpm") ? "pnpm" : "npm";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The core that is running: its version, so a project pins what made it.
|
|
55
|
+
* Every @graview/* package and the `graview` tool share one version (a
|
|
56
|
+
* changesets fixed group), so `^<this>` names a version of each that exists.
|
|
57
|
+
*/
|
|
58
|
+
function ownManifest() {
|
|
59
|
+
try {
|
|
60
|
+
const manifest = JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), "../../package.json"), "utf8"));
|
|
61
|
+
return { version: manifest.version ?? "0.0.0" };
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return { version: "0.0.0" };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function create(argv, io = defaultIo) {
|
|
68
|
+
const dir = argv.find((arg, index) => !arg.startsWith("--") && (index === 0 || !argv[index - 1].startsWith("--")));
|
|
69
|
+
if (!dir) {
|
|
70
|
+
io.stderr(`graview create: a directory is required\n\n${CREATE_USAGE}`);
|
|
71
|
+
return 2;
|
|
72
|
+
}
|
|
73
|
+
const asked = resolve(process.cwd(), dir);
|
|
74
|
+
const force = argv.includes("--force");
|
|
75
|
+
/*
|
|
76
|
+
* A DIRECTORY THAT ALREADY EXISTS IS THE NORMAL CASE.
|
|
77
|
+
*
|
|
78
|
+
* The realistic start is a repository somebody has already made: a README
|
|
79
|
+
* they wrote, a licence, CI, assistant instruction files from some other
|
|
80
|
+
* tool. `--force` is too blunt for that — it writes over the README — so
|
|
81
|
+
* two products independently worked around it by scaffolding into `app/`
|
|
82
|
+
* and hand-writing a workspace root, which is a scaffolder gap rather
|
|
83
|
+
* than a taste they shared.
|
|
84
|
+
*
|
|
85
|
+
* `--merge` writes only what is not there, names every collision without
|
|
86
|
+
* touching it, and exits non-zero so a script cannot mistake a partial
|
|
87
|
+
* write for a clean one. `--force` keeps its meaning exactly.
|
|
88
|
+
*/
|
|
89
|
+
const merge = argv.includes("--merge");
|
|
90
|
+
if (existsSync(asked) && readdirSync(asked).length > 0 && !force && !merge) {
|
|
91
|
+
io.stderr(`graview create: ${dir} is not empty. Pass --merge to write only what is missing, or --force to write into it anyway.\n`);
|
|
92
|
+
return 2;
|
|
93
|
+
}
|
|
94
|
+
const { version } = ownManifest();
|
|
95
|
+
const pmFlag = flag(argv, "--pm");
|
|
96
|
+
const packageManager = pmFlag === "pnpm" || pmFlag === "npm" ? pmFlag : packageManagerFromEnv();
|
|
97
|
+
const portFlag = flag(argv, "--port");
|
|
98
|
+
const linkFlag = flag(argv, "--link");
|
|
99
|
+
// Everything that can be refused is refused before a directory exists.
|
|
100
|
+
const base = {
|
|
101
|
+
name: flag(argv, "--name") || fromDirectoryName(dir),
|
|
102
|
+
...(flag(argv, "--kind") ? { kind: flag(argv, "--kind") } : {}),
|
|
103
|
+
// "Shifts" is what a person types; the slug is what the generator wants.
|
|
104
|
+
...(flag(argv, "--plural") ? { plural: flag(argv, "--plural").trim().toLowerCase() } : {}),
|
|
105
|
+
...(flag(argv, "--accent") ? { accent: flag(argv, "--accent") } : {}),
|
|
106
|
+
...(portFlag ? { port: Number(portFlag) } : {}),
|
|
107
|
+
packageManager,
|
|
108
|
+
...(argv.includes("--workspace") ? { workspace: true } : {}),
|
|
109
|
+
range: `^${version}`,
|
|
110
|
+
};
|
|
111
|
+
const problems = [...validateScaffoldOptions(base)];
|
|
112
|
+
if (linkFlag !== undefined && linkFlag !== "") {
|
|
113
|
+
const checkout = resolve(process.cwd(), linkFlag);
|
|
114
|
+
if (!existsSync(resolve(checkout, "packages/core"))) {
|
|
115
|
+
problems.push(`--link ${linkFlag} is not a framework checkout: no packages/core in it`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// A linked project resolves every type from the framework's dist, so
|
|
119
|
+
// an unbuilt framework fails later, in tsc, one package at a time.
|
|
120
|
+
const unbuilt = LINKED_PACKAGES.filter((pkg) => !existsSync(resolve(checkout, "packages", pkg, "dist/index.js")));
|
|
121
|
+
if (unbuilt.length > 0) {
|
|
122
|
+
problems.push(`the framework at ${linkFlag} is not built (no dist in ${unbuilt.join(", ")}). Run: pnpm -C ${linkFlag} install && pnpm -C ${linkFlag} build`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (problems.length > 0) {
|
|
127
|
+
io.stderr(`graview create: ${problems.join("\ngraview create: ")}\n`);
|
|
128
|
+
return 2;
|
|
129
|
+
}
|
|
130
|
+
/*
|
|
131
|
+
* Relative paths are computed from where the project REALLY is. A temp
|
|
132
|
+
* directory on macOS is reached through a symlink, and a `link:` written
|
|
133
|
+
* from the unresolved path is one level short of the framework once pnpm
|
|
134
|
+
* resolves the project — a dangling symlink, and no error until tsc.
|
|
135
|
+
*/
|
|
136
|
+
mkdirSync(asked, { recursive: true });
|
|
137
|
+
const target = realpathSync(asked);
|
|
138
|
+
const framework = linkFlag !== undefined && linkFlag !== "" ? realpathSync(resolve(process.cwd(), linkFlag)) : undefined;
|
|
139
|
+
const link = framework !== undefined ? toPosix(relative(target, framework)) : undefined;
|
|
140
|
+
if (framework !== undefined && !relative(framework, target).startsWith("..")) {
|
|
141
|
+
io.stderr(`graview create: ${dir} is inside the framework checkout, so it will land in the framework's git history. A product lives in its own repository beside it — e.g. ${toPosix(relative(process.cwd(), resolve(framework, "..", dir.split(/[\\/]/).pop() ?? dir)))}.\n`);
|
|
142
|
+
}
|
|
143
|
+
const frameworkRepo = framework !== undefined ? originSlug(framework) : undefined;
|
|
144
|
+
const options = {
|
|
145
|
+
...base,
|
|
146
|
+
...(link !== undefined ? { link } : {}),
|
|
147
|
+
...(frameworkRepo ? { frameworkRepo } : {}),
|
|
148
|
+
};
|
|
149
|
+
const scaffold = scaffoldProject(options);
|
|
150
|
+
const collisions = [];
|
|
151
|
+
let written = 0;
|
|
152
|
+
for (const file of scaffold.files) {
|
|
153
|
+
const path = resolve(target, file.path);
|
|
154
|
+
if (merge && existsSync(path)) {
|
|
155
|
+
collisions.push(file.path);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
159
|
+
writeFileSync(path, file.contents, "utf8");
|
|
160
|
+
written += 1;
|
|
161
|
+
}
|
|
162
|
+
io.stdout(`graview create: ${written} files → ${dir}\n`);
|
|
163
|
+
const install = !argv.includes("--no-install");
|
|
164
|
+
const skills = !argv.includes("--no-skills");
|
|
165
|
+
const pm = scaffold.packageManager;
|
|
166
|
+
const run = pm === "pnpm" ? "pnpm" : "npm run";
|
|
167
|
+
// A repository, because the CI workflow just written assumes one — unless
|
|
168
|
+
// this directory is already inside one, which is the person's own choice.
|
|
169
|
+
let initialised = false;
|
|
170
|
+
if (!argv.includes("--no-git") && !insideGitRepo(target)) {
|
|
171
|
+
initialised = io.run("git", ["init", "--quiet"], target);
|
|
172
|
+
}
|
|
173
|
+
if (install) {
|
|
174
|
+
io.stdout(`graview create: ${pm} install\n`);
|
|
175
|
+
if (!io.run(pm, ["install"], target)) {
|
|
176
|
+
io.stderr(`graview create: ${pm} install failed. The files are in place; install by hand and run \`${run} verify\`.\n`);
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
if (skills) {
|
|
180
|
+
const bin = resolve(target, "node_modules/.bin/graview");
|
|
181
|
+
if (existsSync(bin)) {
|
|
182
|
+
io.run(bin, ["skills", "install", "."], target);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
io.stderr("graview create: graview did not install, so the authoring skills were not written.\n");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (skills) {
|
|
190
|
+
/*
|
|
191
|
+
* THE SKILLS COME THROUGH THE PACKAGE MANAGER, so `--no-install` skips
|
|
192
|
+
* them too — and it used to skip them SILENTLY, which is the expensive
|
|
193
|
+
* half: an agent starts on a fresh product without the skills that teach
|
|
194
|
+
* it how, which is the single highest-leverage thing the framework
|
|
195
|
+
* ships, and nothing on the screen said they were missing.
|
|
196
|
+
*/
|
|
197
|
+
io.stdout(`graview create: skills: skipped (needs install — then \`${run} skills\`)\n`);
|
|
198
|
+
}
|
|
199
|
+
io.stdout(`\n${scaffold.name} is a product on Graview. Its first kind is "${scaffold.kind}".\n\n` +
|
|
200
|
+
` cd ${dir}\n` +
|
|
201
|
+
(install ? "" : ` ${pm} install\n`) +
|
|
202
|
+
` ${run} dev # http://localhost:${scaffold.port} (/pages is the routed face)\n` +
|
|
203
|
+
` ${run} verify # typecheck, tests, build, graview check\n` +
|
|
204
|
+
(initialised ? ` git add -A && git commit -m "${scaffold.name}, on Graview"\n` : "") +
|
|
205
|
+
"\n" +
|
|
206
|
+
(scaffold.linked
|
|
207
|
+
? `The framework is consumed by path from ${link}: rebuild it (pnpm -C ${link} build) when its sources change.\n` +
|
|
208
|
+
`Its CI checks the framework out beside the app${frameworkRepo ? ` from ${frameworkRepo}` : " — fill in the repository in .github/workflows/ci.yml"}; a private framework needs a FRAMEWORK_TOKEN secret.\n\n`
|
|
209
|
+
: "") +
|
|
210
|
+
`Then declare more: src/domain/ is the whole surface, and \`${run} check\` says what is wrong with it.\n`);
|
|
211
|
+
if (collisions.length > 0) {
|
|
212
|
+
io.stderr(`\ngraview create: ${collisions.length} file${collisions.length === 1 ? "" : "s"} already existed and ${collisions.length === 1 ? "was" : "were"} left exactly as ${collisions.length === 1 ? "it was" : "they were"}:\n` +
|
|
213
|
+
collisions.map((path) => ` ${path}\n`).join("") +
|
|
214
|
+
`Merge what you want from a scaffold written elsewhere, or pass --force to overwrite.\n`);
|
|
215
|
+
return 1;
|
|
216
|
+
}
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
/** Whether a directory already sits inside a git work tree. */
|
|
220
|
+
function insideGitRepo(dir) {
|
|
221
|
+
let current = dir;
|
|
222
|
+
for (;;) {
|
|
223
|
+
if (existsSync(resolve(current, ".git")))
|
|
224
|
+
return true;
|
|
225
|
+
const parent = dirname(current);
|
|
226
|
+
if (parent === current)
|
|
227
|
+
return false;
|
|
228
|
+
current = parent;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** The framework's GitHub "owner/name", from its origin remote, if it has one. */
|
|
232
|
+
function originSlug(framework) {
|
|
233
|
+
const result = spawnSync("git", ["-C", framework, "remote", "get-url", "origin"], { encoding: "utf8" });
|
|
234
|
+
if (result.status !== 0)
|
|
235
|
+
return undefined;
|
|
236
|
+
const match = /github\.com[:/]([^/\s]+\/[^/\s]+?)(?:\.git)?\s*$/.exec(result.stdout);
|
|
237
|
+
return match?.[1];
|
|
238
|
+
}
|
|
239
|
+
function fromDirectoryName(dir) {
|
|
240
|
+
const base = dir.replace(/[\\/]+$/, "").split(/[\\/]/).pop() ?? dir;
|
|
241
|
+
return base
|
|
242
|
+
.split(/[-_\s]+/)
|
|
243
|
+
.filter(Boolean)
|
|
244
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
245
|
+
.join(" ");
|
|
246
|
+
}
|
|
247
|
+
function toPosix(path) {
|
|
248
|
+
const posix = path.split("\\").join("/");
|
|
249
|
+
return isAbsolute(path) || posix.startsWith(".") ? posix : `./${posix}`;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type GraviewApp } from "../app.js";
|
|
2
|
+
import type { AnySchema } from "../schema/schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* WHAT THIS APP IS, READ OUT — the rung between `check` and a browser.
|
|
5
|
+
*
|
|
6
|
+
* "Run it and look" is the sentence every skill ends on, and it is the one
|
|
7
|
+
* instruction an agent cannot follow: it can declare, and it cannot see. The
|
|
8
|
+
* product that found thirty-one things in this framework said so plainly —
|
|
9
|
+
* *"what no check caught, running it did"* — and listed four faults that
|
|
10
|
+
* passed every static check and were obvious the moment somebody opened the
|
|
11
|
+
* thing: a hue in the wrong unit, so every surface drew red; a lens built
|
|
12
|
+
* from the wrong node set, so every piece of ground drew empty; a policy
|
|
13
|
+
* declared with no principal supplied, so every act in the product was
|
|
14
|
+
* refused; a colour that was not a token, so the contrast guarantee did not
|
|
15
|
+
* apply.
|
|
16
|
+
*
|
|
17
|
+
* Every one of those is visible in a DESCRIPTION. The interface here is
|
|
18
|
+
* derived, which is exactly what makes it describable: the same derivations
|
|
19
|
+
* that draw a district, offer an act and refuse one can say what they would
|
|
20
|
+
* do, in words, with no browser and no eyes.
|
|
21
|
+
*
|
|
22
|
+
* This is deliberately not a screenshot in prose. It states the things that
|
|
23
|
+
* are wrong ON A SCREEN and invisible IN A FILE, and says nothing that
|
|
24
|
+
* `check` already says.
|
|
25
|
+
*/
|
|
26
|
+
export interface DescribeOptions {
|
|
27
|
+
/** A seat to answer "what can this person do" as. */
|
|
28
|
+
readonly as?: {
|
|
29
|
+
readonly kind: "human" | "agent";
|
|
30
|
+
readonly id?: string;
|
|
31
|
+
readonly roles?: readonly string[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export declare function describeApp<S extends AnySchema>(app: GraviewApp<S>, options?: DescribeOptions): string;
|
|
35
|
+
//# sourceMappingURL=describe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/cli/describe.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,UAAU,EAAwC,MAAM,WAAW,CAAC;AAItH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;CAC9G;AAoBD,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAC7C,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EAClB,OAAO,GAAE,eAAoB,GAC5B,MAAM,CA+PR"}
|