@graview/core 0.1.28 → 0.1.30
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/README.md +17 -0
- package/dist/amount-input.d.ts +21 -0
- package/dist/amount-input.d.ts.map +1 -0
- package/dist/amount-input.js +96 -0
- package/dist/amount-input.js.map +1 -0
- package/dist/answer-seen.d.ts +38 -0
- package/dist/answer-seen.d.ts.map +1 -0
- package/dist/answer-seen.js +122 -0
- package/dist/answer-seen.js.map +1 -0
- package/dist/app-places.d.ts +56 -0
- package/dist/app-places.d.ts.map +1 -0
- package/dist/app-places.js +203 -0
- package/dist/app-places.js.map +1 -0
- package/dist/app.d.ts +16 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/arrange.d.ts +4 -2
- package/dist/arrange.d.ts.map +1 -1
- package/dist/arrange.js +4 -2
- package/dist/arrange.js.map +1 -1
- package/dist/arrangement-words.d.ts +3 -0
- package/dist/arrangement-words.d.ts.map +1 -0
- package/dist/arrangement-words.js +50 -0
- package/dist/arrangement-words.js.map +1 -0
- package/dist/arrangement.d.ts +43 -3
- package/dist/arrangement.d.ts.map +1 -1
- package/dist/arrangement.js +69 -31
- package/dist/arrangement.js.map +1 -1
- package/dist/arranging.d.ts.map +1 -1
- package/dist/arranging.js +36 -14
- package/dist/arranging.js.map +1 -1
- package/dist/bind.d.ts +3 -0
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js.map +1 -1
- package/dist/blocks.d.ts +1 -1
- package/dist/blocks.d.ts.map +1 -1
- package/dist/capabilities.js +1 -1
- package/dist/capabilities.js.map +1 -1
- package/dist/check.d.ts +3 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +3 -0
- package/dist/check.js.map +1 -1
- package/dist/city.d.ts +58 -50
- package/dist/city.d.ts.map +1 -1
- package/dist/city.js +160 -147
- package/dist/city.js.map +1 -1
- package/dist/cli/check/brand.d.ts.map +1 -1
- package/dist/cli/check/brand.js +30 -2
- package/dist/cli/check/brand.js.map +1 -1
- package/dist/cli/check/clock-rules.d.ts +4 -0
- package/dist/cli/check/clock-rules.d.ts.map +1 -0
- package/dist/cli/check/clock-rules.js +26 -0
- package/dist/cli/check/clock-rules.js.map +1 -0
- package/dist/cli/check/field-sight.d.ts +11 -0
- package/dist/cli/check/field-sight.d.ts.map +1 -0
- package/dist/cli/check/field-sight.js +113 -0
- package/dist/cli/check/field-sight.js.map +1 -0
- package/dist/cli/check/index.d.ts +2 -0
- package/dist/cli/check/index.d.ts.map +1 -1
- package/dist/cli/check/index.js +2 -0
- package/dist/cli/check/index.js.map +1 -1
- package/dist/cli/check/lenses.d.ts +1 -1
- package/dist/cli/check/lenses.d.ts.map +1 -1
- package/dist/cli/check/lenses.js +48 -2
- package/dist/cli/check/lenses.js.map +1 -1
- package/dist/cli/check/relations.d.ts +23 -0
- package/dist/cli/check/relations.d.ts.map +1 -1
- package/dist/cli/check/relations.js +55 -4
- package/dist/cli/check/relations.js.map +1 -1
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +7 -4
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +32 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/describe.d.ts.map +1 -1
- package/dist/cli/describe.js +71 -7
- package/dist/cli/describe.js.map +1 -1
- package/dist/cli/docs.d.ts.map +1 -1
- package/dist/cli/docs.js +4 -3
- package/dist/cli/docs.js.map +1 -1
- package/dist/cli/doctor.d.ts +18 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +58 -5
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/document-schema.d.ts +2 -0
- package/dist/cli/document-schema.d.ts.map +1 -1
- package/dist/cli/document-schema.js +154 -5
- package/dist/cli/document-schema.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js +16 -2
- package/dist/cli/types.js.map +1 -1
- package/dist/clock-readers.d.ts +18 -0
- package/dist/clock-readers.d.ts.map +1 -0
- package/dist/clock-readers.js +70 -0
- package/dist/clock-readers.js.map +1 -0
- package/dist/clock.d.ts +30 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +41 -0
- package/dist/clock.js.map +1 -0
- package/dist/columns.d.ts.map +1 -1
- package/dist/columns.js +2 -1
- package/dist/columns.js.map +1 -1
- package/dist/conformance/fixtures.d.ts.map +1 -1
- package/dist/conformance/fixtures.js +491 -43
- package/dist/conformance/fixtures.js.map +1 -1
- package/dist/coverage-words.d.ts +18 -0
- package/dist/coverage-words.d.ts.map +1 -0
- package/dist/coverage-words.js +18 -0
- package/dist/coverage-words.js.map +1 -0
- package/dist/days.d.ts +53 -4
- package/dist/days.d.ts.map +1 -1
- package/dist/days.js +136 -16
- package/dist/days.js.map +1 -1
- package/dist/describe.d.ts +1 -0
- package/dist/describe.d.ts.map +1 -1
- package/dist/describe.js +1 -0
- package/dist/describe.js.map +1 -1
- package/dist/document/act-findings.d.ts.map +1 -1
- package/dist/document/act-findings.js +32 -4
- package/dist/document/act-findings.js.map +1 -1
- package/dist/document/amount.d.ts +4 -0
- package/dist/document/amount.d.ts.map +1 -0
- package/dist/document/amount.js +22 -0
- package/dist/document/amount.js.map +1 -0
- package/dist/document/block-context.d.ts.map +1 -1
- package/dist/document/block-context.js +1 -0
- package/dist/document/block-context.js.map +1 -1
- package/dist/document/blocks.d.ts +33 -10
- package/dist/document/blocks.d.ts.map +1 -1
- package/dist/document/blocks.js +139 -25
- package/dist/document/blocks.js.map +1 -1
- package/dist/document/brand-check.d.ts +5 -0
- package/dist/document/brand-check.d.ts.map +1 -1
- package/dist/document/brand-check.js +16 -2
- package/dist/document/brand-check.js.map +1 -1
- package/dist/document/compile-checked.d.ts.map +1 -1
- package/dist/document/compile-checked.js +12 -4
- package/dist/document/compile-checked.js.map +1 -1
- package/dist/document/compile.d.ts +0 -2
- package/dist/document/compile.d.ts.map +1 -1
- package/dist/document/compile.js +49 -24
- package/dist/document/compile.js.map +1 -1
- package/dist/document/compiled.d.ts +6 -2
- package/dist/document/compiled.d.ts.map +1 -1
- package/dist/document/compiled.js +94 -26
- package/dist/document/compiled.js.map +1 -1
- package/dist/document/computed-values.d.ts +3 -0
- package/dist/document/computed-values.d.ts.map +1 -1
- package/dist/document/computed-values.js +12 -2
- package/dist/document/computed-values.js.map +1 -1
- package/dist/document/describe-coverage.d.ts +3 -0
- package/dist/document/describe-coverage.d.ts.map +1 -1
- package/dist/document/describe-coverage.js +14 -6
- package/dist/document/describe-coverage.js.map +1 -1
- package/dist/document/describe-place.d.ts +6 -2
- package/dist/document/describe-place.d.ts.map +1 -1
- package/dist/document/describe-place.js +17 -9
- package/dist/document/describe-place.js.map +1 -1
- package/dist/document/diff.d.ts +2 -0
- package/dist/document/diff.d.ts.map +1 -1
- package/dist/document/diff.js +70 -11
- package/dist/document/diff.js.map +1 -1
- package/dist/document/durations.d.ts +8 -0
- package/dist/document/durations.d.ts.map +1 -0
- package/dist/document/durations.js +82 -0
- package/dist/document/durations.js.map +1 -0
- package/dist/document/edit.d.ts +1 -1
- package/dist/document/edit.d.ts.map +1 -1
- package/dist/document/edit.js +436 -27
- package/dist/document/edit.js.map +1 -1
- package/dist/document/expr/evaluate.d.ts +26 -1
- package/dist/document/expr/evaluate.d.ts.map +1 -1
- package/dist/document/expr/evaluate.js +55 -4
- package/dist/document/expr/evaluate.js.map +1 -1
- package/dist/document/field-spec.d.ts.map +1 -1
- package/dist/document/field-spec.js +15 -1
- package/dist/document/field-spec.js.map +1 -1
- package/dist/document/format-findings.d.ts +4 -0
- package/dist/document/format-findings.d.ts.map +1 -0
- package/dist/document/format-findings.js +39 -0
- package/dist/document/format-findings.js.map +1 -0
- package/dist/document/format-rules.d.ts +8 -0
- package/dist/document/format-rules.d.ts.map +1 -0
- package/dist/document/format-rules.js +19 -0
- package/dist/document/format-rules.js.map +1 -0
- package/dist/document/format-words.d.ts +9 -0
- package/dist/document/format-words.d.ts.map +1 -0
- package/dist/document/format-words.js +31 -0
- package/dist/document/format-words.js.map +1 -0
- package/dist/document/framework-path.d.ts +11 -0
- package/dist/document/framework-path.d.ts.map +1 -0
- package/dist/document/framework-path.js +122 -0
- package/dist/document/framework-path.js.map +1 -0
- package/dist/document/graview-template.d.ts +2 -2
- package/dist/document/index.d.ts +2 -2
- package/dist/document/index.d.ts.map +1 -1
- package/dist/document/index.js +1 -1
- package/dist/document/index.js.map +1 -1
- package/dist/document/linked-findings.d.ts +5 -0
- package/dist/document/linked-findings.d.ts.map +1 -0
- package/dist/document/linked-findings.js +100 -0
- package/dist/document/linked-findings.js.map +1 -0
- package/dist/document/migrate.d.ts +1 -0
- package/dist/document/migrate.d.ts.map +1 -1
- package/dist/document/migrate.js +48 -1
- package/dist/document/migrate.js.map +1 -1
- package/dist/document/money.d.ts +14 -0
- package/dist/document/money.d.ts.map +1 -0
- package/dist/document/money.js +14 -0
- package/dist/document/money.js.map +1 -0
- package/dist/document/policy-words.d.ts +4 -0
- package/dist/document/policy-words.d.ts.map +1 -1
- package/dist/document/policy-words.js +34 -4
- package/dist/document/policy-words.js.map +1 -1
- package/dist/document/right-names.d.ts +10 -0
- package/dist/document/right-names.d.ts.map +1 -0
- package/dist/document/right-names.js +57 -0
- package/dist/document/right-names.js.map +1 -0
- package/dist/document/rule-line.d.ts.map +1 -1
- package/dist/document/rule-line.js +16 -12
- package/dist/document/rule-line.js.map +1 -1
- package/dist/document/rules.d.ts.map +1 -1
- package/dist/document/rules.js +15 -6
- package/dist/document/rules.js.map +1 -1
- package/dist/document/schema.d.ts +142 -22
- package/dist/document/schema.d.ts.map +1 -1
- package/dist/document/schema.js +86 -10
- package/dist/document/schema.js.map +1 -1
- package/dist/document/template-parse.d.ts.map +1 -1
- package/dist/document/template-parse.js +45 -5
- package/dist/document/template-parse.js.map +1 -1
- package/dist/document/template.d.ts +16 -14
- package/dist/document/template.d.ts.map +1 -1
- package/dist/document/template.js +52 -30
- package/dist/document/template.js.map +1 -1
- package/dist/document/thumbnail.d.ts.map +1 -1
- package/dist/document/thumbnail.js +4 -3
- package/dist/document/thumbnail.js.map +1 -1
- package/dist/document/to-document.d.ts +0 -1
- package/dist/document/to-document.d.ts.map +1 -1
- package/dist/document/to-document.js +30 -2
- package/dist/document/to-document.js.map +1 -1
- package/dist/document/view-specs.d.ts.map +1 -1
- package/dist/document/view-specs.js +3 -0
- package/dist/document/view-specs.js.map +1 -1
- package/dist/document/views.d.ts +38 -4
- package/dist/document/views.d.ts.map +1 -1
- package/dist/document/views.js +81 -26
- package/dist/document/views.js.map +1 -1
- package/dist/document.schema.json +1184 -141
- package/dist/excerpt-of.d.ts +14 -0
- package/dist/excerpt-of.d.ts.map +1 -0
- package/dist/excerpt-of.js +120 -0
- package/dist/excerpt-of.js.map +1 -0
- package/dist/excerpt.d.ts +9 -0
- package/dist/excerpt.d.ts.map +1 -0
- package/dist/excerpt.js +43 -0
- package/dist/excerpt.js.map +1 -0
- package/dist/field-sight.d.ts +33 -0
- package/dist/field-sight.d.ts.map +1 -0
- package/dist/field-sight.js +313 -0
- package/dist/field-sight.js.map +1 -0
- package/dist/forms.d.ts +2 -0
- package/dist/forms.d.ts.map +1 -1
- package/dist/forms.js +3 -0
- package/dist/forms.js.map +1 -1
- package/dist/graph/archived.d.ts +34 -0
- package/dist/graph/archived.d.ts.map +1 -0
- package/dist/graph/archived.js +25 -0
- package/dist/graph/archived.js.map +1 -0
- package/dist/graph/diff.d.ts +16 -0
- package/dist/graph/diff.d.ts.map +1 -1
- package/dist/graph/diff.js +20 -1
- package/dist/graph/diff.js.map +1 -1
- package/dist/graph/graph.d.ts +37 -13
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +84 -41
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/tracked.d.ts +8 -8
- package/dist/graph/tracked.d.ts.map +1 -1
- package/dist/graph/tracked.js +15 -20
- package/dist/graph/tracked.js.map +1 -1
- package/dist/graph/types.d.ts +16 -8
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/types.js.map +1 -1
- package/dist/grid-sort.d.ts +20 -0
- package/dist/grid-sort.d.ts.map +1 -0
- package/dist/grid-sort.js +58 -0
- package/dist/grid-sort.js.map +1 -0
- package/dist/history.d.ts +88 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +146 -0
- package/dist/history.js.map +1 -0
- package/dist/import/coerce.d.ts +45 -0
- package/dist/import/coerce.d.ts.map +1 -0
- package/dist/import/coerce.js +252 -0
- package/dist/import/coerce.js.map +1 -0
- package/dist/import/csv.d.ts +16 -0
- package/dist/import/csv.d.ts.map +1 -0
- package/dist/import/csv.js +77 -0
- package/dist/import/csv.js.map +1 -0
- package/dist/import/index.d.ts +17 -0
- package/dist/import/index.d.ts.map +1 -0
- package/dist/import/index.js +13 -0
- package/dist/import/index.js.map +1 -0
- package/dist/import/mapping.d.ts +99 -0
- package/dist/import/mapping.d.ts.map +1 -0
- package/dist/import/mapping.js +182 -0
- package/dist/import/mapping.js.map +1 -0
- package/dist/import/rows.d.ts +116 -0
- package/dist/import/rows.d.ts.map +1 -0
- package/dist/import/rows.js +584 -0
- package/dist/import/rows.js.map +1 -0
- package/dist/index.d.ts +53 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -18
- package/dist/index.js.map +1 -1
- package/dist/invariants/engine.d.ts +5 -1
- package/dist/invariants/engine.d.ts.map +1 -1
- package/dist/invariants/engine.js +4 -3
- package/dist/invariants/engine.js.map +1 -1
- package/dist/invariants/types.d.ts +18 -3
- package/dist/invariants/types.d.ts.map +1 -1
- package/dist/json-schema.d.ts +1 -0
- package/dist/json-schema.d.ts.map +1 -1
- package/dist/json-schema.js +2 -0
- package/dist/json-schema.js.map +1 -1
- package/dist/kind-list.d.ts +78 -0
- package/dist/kind-list.d.ts.map +1 -0
- package/dist/kind-list.js +176 -0
- package/dist/kind-list.js.map +1 -0
- package/dist/labels.d.ts.map +1 -1
- package/dist/labels.js +2 -1
- package/dist/labels.js.map +1 -1
- package/dist/lines.d.ts +1 -0
- package/dist/lines.d.ts.map +1 -1
- package/dist/lines.js +5 -3
- package/dist/lines.js.map +1 -1
- package/dist/linked.d.ts +95 -0
- package/dist/linked.d.ts.map +1 -0
- package/dist/linked.js +181 -0
- package/dist/linked.js.map +1 -0
- package/dist/markdown.d.ts +102 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +460 -0
- package/dist/markdown.js.map +1 -0
- package/dist/mutations/arg-shape.d.ts +95 -0
- package/dist/mutations/arg-shape.d.ts.map +1 -0
- package/dist/mutations/arg-shape.js +101 -0
- package/dist/mutations/arg-shape.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts +48 -2
- package/dist/mutations/define-mutation.d.ts.map +1 -1
- package/dist/mutations/define-mutation.js +103 -36
- package/dist/mutations/define-mutation.js.map +1 -1
- package/dist/mutations/derive-edits.d.ts +16 -1
- package/dist/mutations/derive-edits.d.ts.map +1 -1
- package/dist/mutations/derive-edits.js +146 -56
- package/dist/mutations/derive-edits.js.map +1 -1
- package/dist/mutations/derive-repeats.d.ts +8 -0
- package/dist/mutations/derive-repeats.d.ts.map +1 -0
- package/dist/mutations/derive-repeats.js +118 -0
- package/dist/mutations/derive-repeats.js.map +1 -0
- package/dist/mutations/derived-names.d.ts +22 -0
- package/dist/mutations/derived-names.d.ts.map +1 -0
- package/dist/mutations/derived-names.js +21 -0
- package/dist/mutations/derived-names.js.map +1 -0
- package/dist/mutations/edit-start.d.ts +28 -0
- package/dist/mutations/edit-start.d.ts.map +1 -0
- package/dist/mutations/edit-start.js +24 -0
- package/dist/mutations/edit-start.js.map +1 -0
- package/dist/mutations/form.d.ts +33 -1
- package/dist/mutations/form.d.ts.map +1 -1
- package/dist/mutations/form.js +23 -2
- package/dist/mutations/form.js.map +1 -1
- package/dist/mutations/invalid-arguments.d.ts +14 -0
- package/dist/mutations/invalid-arguments.d.ts.map +1 -0
- package/dist/mutations/invalid-arguments.js +18 -0
- package/dist/mutations/invalid-arguments.js.map +1 -0
- package/dist/mutations/keep-link.d.ts +27 -0
- package/dist/mutations/keep-link.d.ts.map +1 -0
- package/dist/mutations/keep-link.js +56 -0
- package/dist/mutations/keep-link.js.map +1 -0
- package/dist/mutations/kept-arguments.d.ts +26 -0
- package/dist/mutations/kept-arguments.d.ts.map +1 -0
- package/dist/mutations/kept-arguments.js +77 -0
- package/dist/mutations/kept-arguments.js.map +1 -0
- package/dist/mutations/node-ref.d.ts +0 -80
- package/dist/mutations/node-ref.d.ts.map +1 -1
- package/dist/mutations/node-ref.js +0 -93
- package/dist/mutations/node-ref.js.map +1 -1
- package/dist/mutations/types.d.ts +17 -1
- package/dist/mutations/types.d.ts.map +1 -1
- package/dist/mutations/words.d.ts +0 -13
- package/dist/mutations/words.d.ts.map +1 -1
- package/dist/mutations/words.js +1 -12
- package/dist/mutations/words.js.map +1 -1
- package/dist/navigate.d.ts +13 -0
- package/dist/navigate.d.ts.map +1 -0
- package/dist/navigate.js +13 -0
- package/dist/navigate.js.map +1 -0
- package/dist/ops/digest.d.ts +33 -0
- package/dist/ops/digest.d.ts.map +1 -0
- package/dist/ops/digest.js +47 -0
- package/dist/ops/digest.js.map +1 -0
- package/dist/ops/kept-fields.d.ts +7 -0
- package/dist/ops/kept-fields.d.ts.map +1 -0
- package/dist/ops/kept-fields.js +24 -0
- package/dist/ops/kept-fields.js.map +1 -0
- package/dist/ops/lineage.d.ts +43 -0
- package/dist/ops/lineage.d.ts.map +1 -0
- package/dist/ops/lineage.js +27 -0
- package/dist/ops/lineage.js.map +1 -0
- package/dist/ops/log.d.ts +6 -0
- package/dist/ops/log.d.ts.map +1 -1
- package/dist/ops/log.js +20 -12
- package/dist/ops/log.js.map +1 -1
- package/dist/ops/provenance.d.ts +68 -0
- package/dist/ops/provenance.d.ts.map +1 -0
- package/dist/ops/provenance.js +83 -0
- package/dist/ops/provenance.js.map +1 -0
- package/dist/ops/suggestions.d.ts +26 -0
- package/dist/ops/suggestions.d.ts.map +1 -0
- package/dist/ops/suggestions.js +21 -0
- package/dist/ops/suggestions.js.map +1 -0
- package/dist/ops/tidying.d.ts +48 -0
- package/dist/ops/tidying.d.ts.map +1 -0
- package/dist/ops/tidying.js +84 -0
- package/dist/ops/tidying.js.map +1 -0
- package/dist/ops/types.d.ts +42 -0
- package/dist/ops/types.d.ts.map +1 -1
- package/dist/ops/undo.d.ts.map +1 -1
- package/dist/ops/undo.js +10 -0
- package/dist/ops/undo.js.map +1 -1
- package/dist/ops/withheld.d.ts +25 -2
- package/dist/ops/withheld.d.ts.map +1 -1
- package/dist/ops/withheld.js +6 -15
- package/dist/ops/withheld.js.map +1 -1
- package/dist/past.d.ts +35 -0
- package/dist/past.d.ts.map +1 -0
- package/dist/past.js +173 -0
- package/dist/past.js.map +1 -0
- package/dist/permissions/policy.d.ts +13 -1
- package/dist/permissions/policy.d.ts.map +1 -1
- package/dist/permissions/policy.js +44 -9
- package/dist/permissions/policy.js.map +1 -1
- package/dist/permissions/sight.d.ts +40 -2
- package/dist/permissions/sight.d.ts.map +1 -1
- package/dist/permissions/sight.js +25 -2
- package/dist/permissions/sight.js.map +1 -1
- package/dist/permissions/types.d.ts +21 -0
- package/dist/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js.map +1 -1
- package/dist/places.d.ts +6 -51
- package/dist/places.d.ts.map +1 -1
- package/dist/places.js +50 -144
- package/dist/places.js.map +1 -1
- package/dist/provenance.d.ts +14 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +13 -0
- package/dist/provenance.js.map +1 -0
- package/dist/repeat-words.d.ts +13 -0
- package/dist/repeat-words.d.ts.map +1 -0
- package/dist/repeat-words.js +56 -0
- package/dist/repeat-words.js.map +1 -0
- package/dist/repeat.d.ts +59 -0
- package/dist/repeat.d.ts.map +1 -0
- package/dist/repeat.js +155 -0
- package/dist/repeat.js.map +1 -0
- package/dist/scaffold/agents.d.ts.map +1 -1
- package/dist/scaffold/agents.js +13 -0
- package/dist/scaffold/agents.js.map +1 -1
- package/dist/scaffold/project.d.ts.map +1 -1
- package/dist/scaffold/project.js +18 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/ui.d.ts.map +1 -1
- package/dist/scaffold/ui.js +17 -7
- package/dist/scaffold/ui.js.map +1 -1
- package/dist/scene-districts.d.ts +2 -1
- package/dist/scene-districts.d.ts.map +1 -1
- package/dist/scene-districts.js +2 -1
- package/dist/scene-districts.js.map +1 -1
- package/dist/scene.d.ts +4 -2
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +2 -1
- package/dist/scene.js.map +1 -1
- package/dist/schema/amount-mark.d.ts +13 -0
- package/dist/schema/amount-mark.d.ts.map +1 -0
- package/dist/schema/amount-mark.js +20 -0
- package/dist/schema/amount-mark.js.map +1 -0
- package/dist/schema/amount-words.d.ts +12 -0
- package/dist/schema/amount-words.d.ts.map +1 -0
- package/dist/schema/amount-words.js +31 -0
- package/dist/schema/amount-words.js.map +1 -0
- package/dist/schema/app-address.d.ts +5 -0
- package/dist/schema/app-address.d.ts.map +1 -0
- package/dist/schema/app-address.js +10 -0
- package/dist/schema/app-address.js.map +1 -0
- package/dist/schema/app-link-field.d.ts +4 -0
- package/dist/schema/app-link-field.d.ts.map +1 -0
- package/dist/schema/app-link-field.js +19 -0
- package/dist/schema/app-link-field.js.map +1 -0
- package/dist/schema/app-link.d.ts +38 -0
- package/dist/schema/app-link.d.ts.map +1 -0
- package/dist/schema/app-link.js +38 -0
- package/dist/schema/app-link.js.map +1 -0
- package/dist/schema/define-node.d.ts +39 -92
- package/dist/schema/define-node.d.ts.map +1 -1
- package/dist/schema/define-node.js +8 -246
- package/dist/schema/define-node.js.map +1 -1
- package/dist/schema/field-words.d.ts +45 -0
- package/dist/schema/field-words.d.ts.map +1 -0
- package/dist/schema/field-words.js +124 -0
- package/dist/schema/field-words.js.map +1 -0
- package/dist/schema/files.d.ts +8 -0
- package/dist/schema/files.d.ts.map +1 -1
- package/dist/schema/files.js.map +1 -1
- package/dist/schema/json-schema.d.ts +6 -1
- package/dist/schema/json-schema.d.ts.map +1 -1
- package/dist/schema/json-schema.js +101 -2
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/linked-field.d.ts +6 -0
- package/dist/schema/linked-field.d.ts.map +1 -0
- package/dist/schema/linked-field.js +34 -0
- package/dist/schema/linked-field.js.map +1 -0
- package/dist/schema/linked-reads.d.ts +20 -0
- package/dist/schema/linked-reads.d.ts.map +1 -0
- package/dist/schema/linked-reads.js +69 -0
- package/dist/schema/linked-reads.js.map +1 -0
- package/dist/schema/linked-schema.d.ts +5 -0
- package/dist/schema/linked-schema.d.ts.map +1 -0
- package/dist/schema/linked-schema.js +9 -0
- package/dist/schema/linked-schema.js.map +1 -0
- package/dist/schema/linked.d.ts +147 -0
- package/dist/schema/linked.d.ts.map +1 -0
- package/dist/schema/linked.js +151 -0
- package/dist/schema/linked.js.map +1 -0
- package/dist/schema/markdown-field.d.ts +4 -0
- package/dist/schema/markdown-field.d.ts.map +1 -0
- package/dist/schema/markdown-field.js +20 -0
- package/dist/schema/markdown-field.js.map +1 -0
- package/dist/schema/markdown.d.ts +6 -0
- package/dist/schema/markdown.d.ts.map +1 -0
- package/dist/schema/markdown.js +27 -0
- package/dist/schema/markdown.js.map +1 -0
- package/dist/schema/reading.d.ts +86 -0
- package/dist/schema/reading.d.ts.map +1 -0
- package/dist/schema/reading.js +325 -0
- package/dist/schema/reading.js.map +1 -0
- package/dist/schema/repeat-field.d.ts +5 -0
- package/dist/schema/repeat-field.d.ts.map +1 -0
- package/dist/schema/repeat-field.js +20 -0
- package/dist/schema/repeat-field.js.map +1 -0
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +12 -1
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/to-json-schema.d.ts +14 -0
- package/dist/schema/to-json-schema.d.ts.map +1 -0
- package/dist/schema/to-json-schema.js +616 -0
- package/dist/schema/to-json-schema.js.map +1 -0
- package/dist/schema/typed-field-builders.d.ts +8 -0
- package/dist/schema/typed-field-builders.d.ts.map +1 -0
- package/dist/schema/typed-field-builders.js +30 -0
- package/dist/schema/typed-field-builders.js.map +1 -0
- package/dist/schema/typed-field-of.d.ts +4 -0
- package/dist/schema/typed-field-of.d.ts.map +1 -0
- package/dist/schema/typed-field-of.js +14 -0
- package/dist/schema/typed-field-of.js.map +1 -0
- package/dist/schema/typed-fields.d.ts +11 -0
- package/dist/schema/typed-fields.d.ts.map +1 -0
- package/dist/schema/typed-fields.js +16 -0
- package/dist/schema/typed-fields.js.map +1 -0
- package/dist/schema/types.d.ts +31 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/value-words.d.ts +21 -0
- package/dist/schema/value-words.d.ts.map +1 -0
- package/dist/schema/value-words.js +32 -0
- package/dist/schema/value-words.js.map +1 -0
- package/dist/search.d.ts +91 -4
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +317 -54
- package/dist/search.js.map +1 -1
- package/dist/seat-of.d.ts +9 -0
- package/dist/seat-of.d.ts.map +1 -0
- package/dist/seat-of.js +14 -0
- package/dist/seat-of.js.map +1 -0
- package/dist/seat.d.ts +19 -0
- package/dist/seat.d.ts.map +1 -0
- package/dist/seat.js +19 -0
- package/dist/seat.js.map +1 -0
- package/dist/seen.d.ts +15 -45
- package/dist/seen.d.ts.map +1 -1
- package/dist/seen.js +49 -135
- package/dist/seen.js.map +1 -1
- package/dist/store.d.ts +104 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +214 -30
- package/dist/store.js.map +1 -1
- package/dist/theme/derive.d.ts +16 -0
- package/dist/theme/derive.d.ts.map +1 -1
- package/dist/theme/derive.js +14 -0
- package/dist/theme/derive.js.map +1 -1
- package/dist/theme/marks.d.ts +19 -2
- package/dist/theme/marks.d.ts.map +1 -1
- package/dist/theme/marks.js +67 -2
- package/dist/theme/marks.js.map +1 -1
- package/dist/theme/types.d.ts +14 -3
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js.map +1 -1
- package/dist/tidying.d.ts +62 -0
- package/dist/tidying.d.ts.map +1 -0
- package/dist/tidying.js +131 -0
- package/dist/tidying.js.map +1 -0
- package/dist/typed.d.ts +12 -3
- package/dist/typed.d.ts.map +1 -1
- package/dist/typed.js.map +1 -1
- package/dist/validate-graph.d.ts.map +1 -1
- package/dist/validate-graph.js +3 -10
- package/dist/validate-graph.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/via.d.ts.map +1 -1
- package/dist/via.js +2 -1
- package/dist/via.js.map +1 -1
- package/dist/views/address.d.ts +13 -0
- package/dist/views/address.d.ts.map +1 -0
- package/dist/views/address.js +29 -0
- package/dist/views/address.js.map +1 -0
- package/dist/views/types.d.ts +106 -8
- package/dist/views/types.d.ts.map +1 -1
- package/dist/views/types.js +24 -4
- package/dist/views/types.js.map +1 -1
- package/dist/village.d.ts +63 -0
- package/dist/village.d.ts.map +1 -0
- package/dist/village.js +143 -0
- package/dist/village.js.map +1 -0
- package/dist/watched.d.ts +12 -45
- package/dist/watched.d.ts.map +1 -1
- package/dist/watched.js +7 -119
- package/dist/watched.js.map +1 -1
- package/dist/words.d.ts +33 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +36 -0
- package/dist/words.js.map +1 -0
- package/package.json +57 -2
package/dist/document/edit.js
CHANGED
|
@@ -1,26 +1,37 @@
|
|
|
1
|
+
import { DERIVED_ACTS, derivedActOf, derivedActsOf, givenWhenNeverArchived, givenWhenNeverTidied } from "../mutations/derived-names.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { ExprSyntaxError, parseExpr } from "./expr/parse.js";
|
|
3
4
|
import { printExpr } from "./expr/print.js";
|
|
4
5
|
import { error } from "./findings.js";
|
|
5
6
|
import { coerce } from "./migrate.js";
|
|
6
7
|
import { outsideRange, rangeWords } from "./range.js";
|
|
8
|
+
import { formatWords } from "./format-words.js";
|
|
9
|
+
import { formatFits, formatMisplaced } from "./format-rules.js";
|
|
10
|
+
/** Why a format is refused where it does not fit, in the checker's words (`field-format`). */
|
|
11
|
+
const refusedFormat = (format, type) => {
|
|
12
|
+
const { sentence, fix } = formatMisplaced(format, type);
|
|
13
|
+
return `${sentence}; ${fix}`;
|
|
14
|
+
};
|
|
7
15
|
import { farEnd } from "./far-end.js";
|
|
8
16
|
import { ActSpec, EDGE_NAME, EdgeSpec, FIELD_NAME, FIELD_TYPES, FieldSpec, GrantSpec, KindSpec, NAME, RuleSpec, SightSpec, } from "./schema.js";
|
|
9
17
|
import { SHIPPED_LENSES, isShippedLens, SHIPPED_LENS_NAMES } from "../places.js";
|
|
10
18
|
import { placeSlug } from "../views/types.js";
|
|
19
|
+
import { documentListFields, kindListFindings, kindListWords, listGroup, listSort, sortTypeOfDocumentField } from "../kind-list.js";
|
|
11
20
|
import { computedOf, validateComputed } from "./computed.js";
|
|
12
21
|
import { parseTemplate, templateBraces, TemplateError } from "./template-parse.js";
|
|
13
22
|
import { validateViews, VIEW_SLOTS } from "./views.js";
|
|
14
|
-
import { brandFindings } from "./brand-check.js";
|
|
23
|
+
import { brandFindings, emojiIconSentence } from "./brand-check.js";
|
|
24
|
+
import { emojiOf } from "../theme/marks.js";
|
|
15
25
|
import { canonicalize } from "./canonical.js";
|
|
16
26
|
import { quotedAtTheEnd } from "./quote.js";
|
|
17
27
|
import { isRecord as isObject, respellDocument } from "./respell.js";
|
|
18
28
|
import { refName } from "./compiled.js";
|
|
29
|
+
import { localeSentence } from "./diff.js";
|
|
19
30
|
import { accentProblem } from "../theme/accent.js";
|
|
20
31
|
import { pageFieldFindings, pageNames, renamedOnPage, withoutOnPage } from "./page-fields.js";
|
|
21
32
|
import { capitalize, listed as listOf } from "../capital.js";
|
|
22
33
|
import { quoted } from "./quote.js";
|
|
23
|
-
import { FIRST_GRANT, FIRST_SIGHT, grantBody, grantGone, grantSentence, NO_GRANT_LEFT, NO_SIGHT_LEFT, peopleKinds, peopleSentence, nounWords, pluralWords as pluralOf, sightGone, sightSentence, sightWords, whoWords } from "./policy-words.js";
|
|
34
|
+
import { FIRST_GRANT, FIRST_SIGHT, grantBody, grantGone, grantSentence, NO_GRANT_LEFT, NO_SIGHT_LEFT, peopleKinds, peopleSentence, archivesSentence, tidyingSentence, nounWords, pluralWords as pluralOf, sightGone, sightSentence, sightWords, whoWords } from "./policy-words.js";
|
|
24
35
|
/** The ops, for tool schemas and the guide. */
|
|
25
36
|
export const EDIT_OPS = [
|
|
26
37
|
"add-kind",
|
|
@@ -31,8 +42,10 @@ export const EDIT_OPS = [
|
|
|
31
42
|
"retype-field",
|
|
32
43
|
"set-options",
|
|
33
44
|
"set-range",
|
|
45
|
+
"set-format",
|
|
34
46
|
"set-required",
|
|
35
47
|
"set-default",
|
|
48
|
+
"set-repeats",
|
|
36
49
|
"remove-field",
|
|
37
50
|
"add-relation",
|
|
38
51
|
"rename-relation",
|
|
@@ -51,10 +64,13 @@ export const EDIT_OPS = [
|
|
|
51
64
|
"set-page-fields",
|
|
52
65
|
"add-lens",
|
|
53
66
|
"remove-lens",
|
|
67
|
+
"set-lens-hidden",
|
|
54
68
|
"set-home",
|
|
55
69
|
"arrange-pages",
|
|
56
70
|
"set-computed",
|
|
57
71
|
"set-people",
|
|
72
|
+
"set-archives",
|
|
73
|
+
"set-tidying",
|
|
58
74
|
"add-grant",
|
|
59
75
|
"remove-grant",
|
|
60
76
|
"add-sight",
|
|
@@ -65,6 +81,10 @@ const KEYWORDS = new Set(["and", "or", "not", "in", "where", "true", "false", "n
|
|
|
65
81
|
const MAX_EDITS = 50;
|
|
66
82
|
// ── shapes ─────────────────────────────────────────────────────────────────
|
|
67
83
|
const kindName = z.string().regex(NAME, 'kind names are lower-case words joined by hyphens, like "guest-list"');
|
|
84
|
+
const listKey = z.string().min(1).max(120);
|
|
85
|
+
const listDirection = z.enum(["asc", "desc"]).optional();
|
|
86
|
+
const listSortShape = z.union([listKey, z.object({ by: listKey, direction: listDirection, then: z.union([listKey, z.object({ by: listKey, direction: listDirection }).strict()]).optional() }).strict()]);
|
|
87
|
+
const listGroupShape = z.union([listKey, z.object({ by: listKey, order: z.array(z.string().min(1).max(80)).max(40).optional(), closed: z.array(z.string().min(1).max(80)).max(40).optional() }).strict()]);
|
|
68
88
|
const fieldName = z.string().regex(FIELD_NAME, 'field names are one word or camelCase, like "dueDate"');
|
|
69
89
|
const edgeName = z.string().regex(EDGE_NAME, 'relation names are one camelCase word, like "tendedBy"');
|
|
70
90
|
const actName = z.string().regex(NAME, 'act names are lower-case words joined by hyphens, like "mark-paid"');
|
|
@@ -75,11 +95,13 @@ const SHAPES = {
|
|
|
75
95
|
"remove-kind": z.object({ op: z.literal("remove-kind"), kind: kindName }).strict(),
|
|
76
96
|
"add-field": z.object({ op: z.literal("add-field"), kind: kindName, field: fieldName, fill: z.unknown().optional(), spec: z.record(z.string(), z.unknown()).optional() }).passthrough(),
|
|
77
97
|
"rename-field": z.object({ op: z.literal("rename-field"), kind: kindName, field: fieldName, to: fieldName }).strict(),
|
|
78
|
-
"retype-field": z.object({ op: z.literal("retype-field"), kind: kindName, field: fieldName, type: z.enum(FIELD_TYPES), options: z.array(z.string().min(1).max(80)).min(1).max(100).optional(), of: z.enum(["string", "number", "date", "image", "file"]).optional(), format: z.enum(["money", "percent", "duration"]).optional() }).strict(),
|
|
98
|
+
"retype-field": z.object({ op: z.literal("retype-field"), kind: kindName, field: fieldName, type: z.enum(FIELD_TYPES), options: z.array(z.string().min(1).max(80)).min(1).max(100).optional(), of: z.enum(["string", "number", "date", "image", "file"]).optional(), format: z.enum(["money", "percent", "duration", "markdown"]).optional() }).strict(),
|
|
79
99
|
"set-options": z.object({ op: z.literal("set-options"), kind: kindName, field: fieldName, add: z.array(z.string().min(1).max(80)).optional(), remove: z.array(z.string().min(1).max(80)).optional() }).strict(),
|
|
100
|
+
"set-format": z.object({ op: z.literal("set-format"), kind: kindName, field: fieldName, format: z.union([z.enum(["money", "percent", "duration", "markdown"]), z.null()]).optional(), unit: z.union([z.string().min(1).max(12), z.null()]).optional() }).strict(),
|
|
80
101
|
"set-range": z.object({ op: z.literal("set-range"), kind: kindName, field: fieldName, min: z.union([z.number(), z.null()]).optional(), max: z.union([z.number(), z.null()]).optional(), step: z.union([z.number().positive(), z.null()]).optional() }).strict(),
|
|
81
102
|
"set-required": z.object({ op: z.literal("set-required"), kind: kindName, field: fieldName, required: z.boolean() }).strict(),
|
|
82
103
|
"set-default": z.object({ op: z.literal("set-default"), kind: kindName, field: fieldName, default: z.unknown() }).strict(),
|
|
104
|
+
"set-repeats": z.object({ op: z.literal("set-repeats"), kind: kindName, field: fieldName, repeats: z.boolean() }).strict(),
|
|
83
105
|
"remove-field": z.object({ op: z.literal("remove-field"), kind: kindName, field: fieldName }).strict(),
|
|
84
106
|
"add-relation": z.object({ op: z.literal("add-relation"), kind: kindName, relation: edgeName }).passthrough(),
|
|
85
107
|
"rename-relation": z.object({ op: z.literal("rename-relation"), kind: kindName, relation: edgeName, to: edgeName }).strict(),
|
|
@@ -97,7 +119,7 @@ const SHAPES = {
|
|
|
97
119
|
locale: z.union([z.string(), z.null()]).optional(),
|
|
98
120
|
// The rest of the brand (FR-124, FR-125): each as the document holds it, null to clear it.
|
|
99
121
|
logo: z.union([z.string().min(1), z.object({ src: z.string().min(1), alt: z.string().min(1).max(120).optional() }).strict(), z.null()]).optional(),
|
|
100
|
-
favicon: z.union([z.string().min(1), z.null()]).optional(),
|
|
122
|
+
favicon: z.union([z.string().min(1), z.object({ emoji: z.string() }).strict(), z.null()]).optional(),
|
|
101
123
|
typography: z.union([z.object({ display: z.union([z.string().min(1).max(200), z.null()]).optional(), body: z.union([z.string().min(1).max(200), z.null()]).optional(), mono: z.union([z.string().min(1).max(200), z.null()]).optional() }).strict(), z.null()]).optional(),
|
|
102
124
|
shape: z.union([z.object({ radius: z.union([z.number().min(0).max(32), z.null()]).optional(), density: z.union([z.number().min(0.75).max(1.5), z.null()]).optional() }).strict(), z.null()]).optional(),
|
|
103
125
|
accents: z.union([z.record(z.string(), z.union([z.number().min(0).max(360), z.null()])), z.null()]).optional(),
|
|
@@ -128,11 +150,15 @@ const SHAPES = {
|
|
|
128
150
|
on: kindName.optional(),
|
|
129
151
|
bindings: z.record(z.string(), z.unknown()).optional(),
|
|
130
152
|
options: z.record(z.string(), z.unknown()).optional(),
|
|
153
|
+
// False: the place's page leaves off the forms that begin its kind.
|
|
154
|
+
create: z.boolean().optional(),
|
|
131
155
|
at: z.number().int().min(0).optional(),
|
|
132
156
|
replace: lensTitle.optional(),
|
|
133
157
|
})
|
|
134
158
|
.strict(),
|
|
135
159
|
"remove-lens": z.object({ op: z.literal("remove-lens"), title: lensTitle, on: kindName.optional() }).strict(),
|
|
160
|
+
// A lens kept off the bar's places, the page list and the home's gallery, still reached by its address, a link or navigate.
|
|
161
|
+
"set-lens-hidden": z.object({ op: z.literal("set-lens-hidden"), title: lensTitle, on: kindName.optional(), hidden: z.boolean() }).strict(),
|
|
136
162
|
"set-home": z.object({ op: z.literal("set-home"), blocks: z.union([z.array(z.unknown()).min(1), z.null()]) }).strict(),
|
|
137
163
|
"arrange-pages": z
|
|
138
164
|
.object({
|
|
@@ -143,6 +169,12 @@ const SHAPES = {
|
|
|
143
169
|
primary: z.union([z.array(z.string().min(1).max(80)).max(40), z.null()]).optional(),
|
|
144
170
|
scene: z.union([z.string().min(1).max(40), z.null()]).optional(),
|
|
145
171
|
pages: z.union([z.string().min(1).max(40), z.null()]).optional(),
|
|
172
|
+
// What a kind's list offers to filter by: `{ "request": ["status", "became.stage"] }`; null or [] gives a kind back its derived filters.
|
|
173
|
+
filters: z.record(kindName, z.union([z.array(z.string().min(1).max(120)).max(40), z.null()])).optional(),
|
|
174
|
+
// The order a kind's list opens in: `{ "feature": { "by": "score", "direction": "desc", "then": "label" } }` or a key; null gives it back its own.
|
|
175
|
+
sort: z.record(kindName, z.union([listSortShape, z.null()])).optional(),
|
|
176
|
+
// How a kind's list opens grouped: `{ "request": { "by": "status", "order": [...], "closed": ["done"] } }` or a field; null opens it ungrouped.
|
|
177
|
+
group: z.record(kindName, z.union([listGroupShape, z.null()])).optional(),
|
|
146
178
|
// The scene's word as a chat or a tool written before 0.1.17 sends it (FR-132's key, RESPELLED as `scene`).
|
|
147
179
|
overview: z.union([z.string().min(1).max(40), z.null()]).optional(),
|
|
148
180
|
})
|
|
@@ -159,6 +191,10 @@ const SHAPES = {
|
|
|
159
191
|
.strict(),
|
|
160
192
|
// Who the people are, and who may do and see what (FR-170): a grant and a sight as the document holds one.
|
|
161
193
|
"set-people": z.object({ op: z.literal("set-people"), kind: kindName, people: z.boolean() }).strict(),
|
|
194
|
+
// Whether a kind's records are archived and merged, or only kept and removed (FR-173).
|
|
195
|
+
"set-archives": z.object({ op: z.literal("set-archives"), kind: kindName, archives: z.boolean() }).strict(),
|
|
196
|
+
// What the app's own actor may do on its own to a kind, or to one relation of it (`@graview/core/tidying`).
|
|
197
|
+
"set-tidying": z.object({ op: z.literal("set-tidying"), kind: kindName, relation: z.optional(z.string()), tidying: z.enum(["never", "no-links", "allowed"]) }).strict(),
|
|
162
198
|
"add-grant": z.object({ op: z.literal("add-grant") }).passthrough(),
|
|
163
199
|
"remove-grant": z.object({ op: z.literal("remove-grant") }).passthrough(),
|
|
164
200
|
"add-sight": z.object({ op: z.literal("add-sight") }).passthrough(),
|
|
@@ -271,9 +307,10 @@ function mapNames(doc, e, ctx, rename) {
|
|
|
271
307
|
const first = x.args[0];
|
|
272
308
|
const literal = first?.t === "lit" && typeof first.value === "string" ? first.value : undefined;
|
|
273
309
|
let args;
|
|
274
|
-
if ((x.fn === "out" || x.fn === "in" || x.fn === "all") && literal !== undefined && x.args.length === 1) {
|
|
310
|
+
if ((x.fn === "out" || x.fn === "in" || x.fn === "all") && literal !== undefined && (x.args.length === 1 || (x.fn === "all" && x.args.length === 2))) {
|
|
275
311
|
const name = rename({ role: x.fn === "all" ? "kind" : "edge", kinds: NONE, name: literal });
|
|
276
|
-
|
|
312
|
+
// all('task', 'all') keeps what it asked of the archived (FR-173).
|
|
313
|
+
args = name === literal ? [...x.args] : [{ ...first, value: name }, ...x.args.slice(1)];
|
|
277
314
|
}
|
|
278
315
|
else if ((x.fn === "out" || x.fn === "in") && x.args.length === 2 && x.args[1].t === "lit" && typeof x.args[1].value === "string") {
|
|
279
316
|
// out(S, 'edge'): the set is read where the walk stands, and its relation renamed like any walk's (FR-101).
|
|
@@ -481,7 +518,7 @@ class Editor {
|
|
|
481
518
|
const emptyPart = ["typography", "shape", "accents"].find((key) => isObject(e[key]) && Object.keys(e[key]).length === 0);
|
|
482
519
|
if (emptyPart)
|
|
483
520
|
return this.fail(i, emptyPart, `${emptyPart} names no part to set; name one, or give null to clear all of it`);
|
|
484
|
-
const judged = brandFindings({ ...(typeof e.logo === "string" || isObject(e.logo) ? { logo: e.logo } : {}), ...(typeof e.favicon === "string" ? { favicon: e.favicon } : {}), ...(isObject(e.typography) ? { typography: Object.fromEntries(Object.entries(e.typography).filter(([, v]) => typeof v === "string")) } : {}) }, { at, ...(this.options.fonts ? { fonts: this.options.fonts } : {}) });
|
|
521
|
+
const judged = brandFindings({ ...(typeof e.logo === "string" || isObject(e.logo) ? { logo: e.logo } : {}), ...(typeof e.favicon === "string" || isObject(e.favicon) ? { favicon: e.favicon } : {}), ...(isObject(e.typography) ? { typography: Object.fromEntries(Object.entries(e.typography).filter(([, v]) => typeof v === "string")) } : {}) }, { at, ...(this.options.fonts ? { fonts: this.options.fonts } : {}) });
|
|
485
522
|
if (judged.length > 0)
|
|
486
523
|
return void this.findings.push(...judged);
|
|
487
524
|
if (e.accent === null) {
|
|
@@ -507,13 +544,17 @@ class Editor {
|
|
|
507
544
|
brand["currency"] = e.currency;
|
|
508
545
|
this.said.push(`Money is said in ${e.currency}.`);
|
|
509
546
|
}
|
|
510
|
-
if (e.locale === null)
|
|
547
|
+
if (e.locale === null) {
|
|
548
|
+
if (brand["locale"] !== undefined)
|
|
549
|
+
this.said.push(localeSentence(undefined));
|
|
511
550
|
delete brand["locale"];
|
|
551
|
+
}
|
|
512
552
|
else if (e.locale !== undefined) {
|
|
513
553
|
if (!/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/.test(e.locale))
|
|
514
554
|
return this.fail(i, "locale", 'a locale is a language tag, like "en-US" or "de-DE"');
|
|
515
555
|
brand["locale"] = e.locale;
|
|
516
|
-
|
|
556
|
+
// Its days, times and numbers as well as its money (FR-178).
|
|
557
|
+
this.said.push(localeSentence(e.locale));
|
|
517
558
|
}
|
|
518
559
|
if (e.name === null) {
|
|
519
560
|
delete brand["name"];
|
|
@@ -535,6 +576,8 @@ class Editor {
|
|
|
535
576
|
const alt = (mark) => (isObject(mark) && typeof mark["alt"] === "string" ? mark["alt"] : undefined);
|
|
536
577
|
if (e[key] === null)
|
|
537
578
|
this.said.push(`The app has no ${what}.`);
|
|
579
|
+
else if (key === "favicon" && emojiOf(e[key]) !== undefined)
|
|
580
|
+
this.said.push(emojiIconSentence(emojiOf(e[key]), brand["logo"] !== undefined));
|
|
538
581
|
else if (was === undefined)
|
|
539
582
|
this.said.push(`The app gets a ${what}.`);
|
|
540
583
|
else if (canonicalize(was) === canonicalize(e[key]))
|
|
@@ -651,6 +694,8 @@ class Editor {
|
|
|
651
694
|
return this.setOptions(i, e);
|
|
652
695
|
case "set-range":
|
|
653
696
|
return this.setRange(i, e);
|
|
697
|
+
case "set-format":
|
|
698
|
+
return this.setFormat(i, e);
|
|
654
699
|
case "set-required": {
|
|
655
700
|
const f = this.field(i, e.kind, e.field);
|
|
656
701
|
if (!f)
|
|
@@ -681,6 +726,20 @@ class Editor {
|
|
|
681
726
|
}
|
|
682
727
|
return;
|
|
683
728
|
}
|
|
729
|
+
case "set-repeats": {
|
|
730
|
+
// A date that repeats keeps how it does beside it, as `<field>Repeat` (`repeat.ts`).
|
|
731
|
+
const f = this.field(i, e.kind, e.field);
|
|
732
|
+
if (!f)
|
|
733
|
+
return;
|
|
734
|
+
if (e.repeats && f.type !== "date" && f.type !== "datetime")
|
|
735
|
+
return this.fail(i, "repeats", `${e.kind}'s ${e.field} is ${f.type === "enum" ? "a choice" : `a ${f.type}`}, and only a date or a date and time can repeat`);
|
|
736
|
+
if (e.repeats)
|
|
737
|
+
f.repeats = true;
|
|
738
|
+
else
|
|
739
|
+
delete f.repeats;
|
|
740
|
+
this.said.push(e.repeats ? `${e.kind}'s ${e.field} may repeat: weekly, monthly, on chosen days, until a day.` : `${e.kind}'s ${e.field} no longer repeats.`);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
684
743
|
case "remove-field":
|
|
685
744
|
return this.removeField(i, e.kind, e.field);
|
|
686
745
|
case "add-relation":
|
|
@@ -792,6 +851,8 @@ class Editor {
|
|
|
792
851
|
return this.addLens(i, e);
|
|
793
852
|
case "remove-lens":
|
|
794
853
|
return this.removeLens(i, e);
|
|
854
|
+
case "set-lens-hidden":
|
|
855
|
+
return this.setLensHidden(i, e);
|
|
795
856
|
case "set-home":
|
|
796
857
|
return this.setHome(i, e.blocks);
|
|
797
858
|
case "arrange-pages":
|
|
@@ -800,6 +861,10 @@ class Editor {
|
|
|
800
861
|
return this.setComputed(i, e);
|
|
801
862
|
case "set-people":
|
|
802
863
|
return this.setPeople(i, e);
|
|
864
|
+
case "set-archives":
|
|
865
|
+
return this.setArchives(i, e);
|
|
866
|
+
case "set-tidying":
|
|
867
|
+
return this.setTidying(i, e);
|
|
803
868
|
case "add-grant":
|
|
804
869
|
case "remove-grant":
|
|
805
870
|
case "add-sight":
|
|
@@ -930,7 +995,8 @@ class Editor {
|
|
|
930
995
|
return;
|
|
931
996
|
was = lenses[at];
|
|
932
997
|
}
|
|
933
|
-
|
|
998
|
+
// A lens drawn anew in another's place stays off the lists if that one was.
|
|
999
|
+
const lens = { name, title: e.title, ...(e.on !== undefined ? { on: e.on } : {}), ...(e.bindings !== undefined ? { bindings: e.bindings } : {}), ...(e.options !== undefined ? { options: e.options } : {}), ...(was?.["hidden"] === true ? { hidden: true } : {}), ...(e.create === false ? { create: false } : {}) };
|
|
934
1000
|
// A title is an address: one lens a title on a kind.
|
|
935
1001
|
const clash = lenses.findIndex((other, index) => index !== at && isObject(other) && typeof other["title"] === "string" && placeSlug(other["title"]) === placeSlug(e.title) && (e.on === undefined || other["on"] === undefined || other["on"] === e.on));
|
|
936
1002
|
if (clash >= 0)
|
|
@@ -952,8 +1018,9 @@ class Editor {
|
|
|
952
1018
|
return;
|
|
953
1019
|
const over = lens.on ?? kindsBound(lens)[0];
|
|
954
1020
|
const where = over ? `, over ${pluralWords(this.doc, over)}` : "";
|
|
1021
|
+
const formless = lens.create === false ? "; its page offers no form to add one" : "";
|
|
955
1022
|
if (!was) {
|
|
956
|
-
this.said.push(`A lens "${e.title}" is added${where}.`);
|
|
1023
|
+
this.said.push(`A lens "${e.title}" is added${where}${formless}.`);
|
|
957
1024
|
return;
|
|
958
1025
|
}
|
|
959
1026
|
const retitled = was["title"] !== e.title;
|
|
@@ -994,6 +1061,31 @@ class Editor {
|
|
|
994
1061
|
}
|
|
995
1062
|
return true;
|
|
996
1063
|
}
|
|
1064
|
+
/**
|
|
1065
|
+
* A LENS KEPT OFF THE LISTS, or put back on them: still a place at its
|
|
1066
|
+
* address, reached by a link or `navigate`, but not offered by the bar,
|
|
1067
|
+
* the page list or the home's gallery. A lens a custom home links to.
|
|
1068
|
+
*/
|
|
1069
|
+
setLensHidden(i, e) {
|
|
1070
|
+
const index = this.lensIndex(i, e.title, e.on);
|
|
1071
|
+
if (index < 0)
|
|
1072
|
+
return;
|
|
1073
|
+
const lens = this.doc.lenses[index];
|
|
1074
|
+
const title = String(lens["title"]);
|
|
1075
|
+
const primary = Array.isArray(this.doc.pages?.primary) ? this.doc.pages.primary : [];
|
|
1076
|
+
if (e.hidden && primary.some((word) => namesLens(word, title))) {
|
|
1077
|
+
return this.fail(i, "hidden", `pages.primary stands "${title}" on the bar, so it cannot be kept off the lists`, 'take it out of "primary" with arrange-pages first');
|
|
1078
|
+
}
|
|
1079
|
+
const was = lens["hidden"] === true;
|
|
1080
|
+
if (e.hidden)
|
|
1081
|
+
lens["hidden"] = true;
|
|
1082
|
+
else
|
|
1083
|
+
delete lens["hidden"];
|
|
1084
|
+
if (was === e.hidden)
|
|
1085
|
+
this.said.push(e.hidden ? `The lens "${title}" was already kept off the lists.` : `The lens "${title}" was already listed.`);
|
|
1086
|
+
else
|
|
1087
|
+
this.said.push(e.hidden ? `The lens "${title}" is kept off the bar and the page list; a link or navigate still reaches it.` : `The lens "${title}" is listed on the bar and the page list again.`);
|
|
1088
|
+
}
|
|
997
1089
|
removeLens(i, e) {
|
|
998
1090
|
const index = this.lensIndex(i, e.title, e.on);
|
|
999
1091
|
if (index < 0)
|
|
@@ -1005,8 +1097,29 @@ class Editor {
|
|
|
1005
1097
|
// `overview` is the scene's word as 0.1.15 and 0.1.16 took it (FR-134): read as `scene`, which wins when both are said.
|
|
1006
1098
|
const { overview, ...rest } = given;
|
|
1007
1099
|
const e = rest.scene === undefined && overview !== undefined ? { ...rest, scene: overview } : rest;
|
|
1008
|
-
if (e.order === undefined && e.hide === undefined && e.first === undefined && e.scene === undefined && e.pages === undefined && e.primary === undefined)
|
|
1009
|
-
return this.fail(i, "", 'arrange-pages says at least one of "order", "hide", "first", "primary", "scene" or "
|
|
1100
|
+
if (e.order === undefined && e.hide === undefined && e.first === undefined && e.scene === undefined && e.pages === undefined && e.primary === undefined && e.filters === undefined && e.sort === undefined && e.group === undefined)
|
|
1101
|
+
return this.fail(i, "", 'arrange-pages says at least one of "order", "hide", "first", "primary", "scene", "pages", "filters", "sort" or "group"');
|
|
1102
|
+
// A list's order and grouping are judged as the checker judges them, each refusal its sentence.
|
|
1103
|
+
for (const part of ["sort", "group"]) {
|
|
1104
|
+
for (const [kind, spec] of Object.entries((e[part] ?? {}))) {
|
|
1105
|
+
if (!this.doc.kinds[kind])
|
|
1106
|
+
return this.fail(i, `${part}.${kind}`, `"${kind}" is not a kind this app has; it has ${Object.keys(this.doc.kinds).join(", ")}`);
|
|
1107
|
+
if (spec === null)
|
|
1108
|
+
continue;
|
|
1109
|
+
const [finding] = kindListFindings(kind, { [part]: spec }, documentListFields(this.doc.kinds[kind]), `${part}.${kind}`);
|
|
1110
|
+
if (finding)
|
|
1111
|
+
return this.fail(i, finding.path.replace(new RegExp(`^${part}\\.${kind}\\.${part}`), `${part}.${kind}`), finding.message.replace(/\.$/, ""), finding.fix.replace(/\.$/, ""));
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
for (const [kind, keys] of Object.entries((e.filters ?? {}))) {
|
|
1115
|
+
if (!this.doc.kinds[kind])
|
|
1116
|
+
return this.fail(i, `filters.${kind}`, `"${kind}" is not a kind this app has; it has ${Object.keys(this.doc.kinds).join(", ")}`);
|
|
1117
|
+
for (const [n, key] of (keys ?? []).entries()) {
|
|
1118
|
+
const offered = this.filterKeys(kind);
|
|
1119
|
+
if (!offered.includes(key))
|
|
1120
|
+
return this.fail(i, `filters.${kind}.${n}`, `${kind} cannot be filtered by "${key}"`, `name one of ${offered.join(", ")}`);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1010
1123
|
for (const [n, word] of (e.primary ?? []).entries()) {
|
|
1011
1124
|
if (typeof word !== "string" || !this.opens(word) || word.trim().toLowerCase() === "home") {
|
|
1012
1125
|
const titles = (this.doc.lenses ?? []).flatMap((lens) => (isObject(lens) && typeof lens["title"] === "string" ? [`"${lens["title"]}"`] : []));
|
|
@@ -1085,10 +1198,156 @@ class Editor {
|
|
|
1085
1198
|
said.push(`the switch calls the ${face} "${pages[face]}"`);
|
|
1086
1199
|
}
|
|
1087
1200
|
}
|
|
1201
|
+
// Each kind's list keeps what this edit does not say: its filters, its order, its grouping.
|
|
1202
|
+
const listOfKind = (kind, part, value) => {
|
|
1203
|
+
const lists = (pages.lists ??= {});
|
|
1204
|
+
const list = (lists[kind] ??= {});
|
|
1205
|
+
if (value === null)
|
|
1206
|
+
delete list[part];
|
|
1207
|
+
else
|
|
1208
|
+
list[part] = value;
|
|
1209
|
+
if (Object.keys(list).length === 0)
|
|
1210
|
+
delete lists[kind];
|
|
1211
|
+
if (Object.keys(lists).length === 0)
|
|
1212
|
+
delete pages.lists;
|
|
1213
|
+
};
|
|
1214
|
+
for (const [kind, keys] of Object.entries((e.filters ?? {}))) {
|
|
1215
|
+
if (keys === null || keys.length === 0) {
|
|
1216
|
+
listOfKind(kind, "filters", null);
|
|
1217
|
+
said.push(`the list of ${pluralWords(this.doc, kind)} offers its own filters again`);
|
|
1218
|
+
}
|
|
1219
|
+
else {
|
|
1220
|
+
listOfKind(kind, "filters", [...keys]);
|
|
1221
|
+
said.push(`the list of ${pluralWords(this.doc, kind)} filters by ${listOf(keys.map((key) => `"${key}"`))}`);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
for (const part of ["sort", "group"]) {
|
|
1225
|
+
for (const [kind, spec] of Object.entries((e[part] ?? {}))) {
|
|
1226
|
+
listOfKind(kind, part, spec === null ? null : clone(spec));
|
|
1227
|
+
const plural = pluralWords(this.doc, kind);
|
|
1228
|
+
if (spec === null)
|
|
1229
|
+
said.push(part === "sort" ? `the list of ${plural} opens in its own order again` : `the list of ${plural} opens ungrouped again`);
|
|
1230
|
+
else
|
|
1231
|
+
said.push(`the list of ${plural} opens ${kindListWords({ [part]: spec }, this.listKeyType(kind))[part]}`);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1088
1234
|
if (Object.keys(pages).length === 0)
|
|
1089
1235
|
delete this.doc.pages;
|
|
1090
1236
|
this.said.push(`${capitalize(listOf(said))}.`);
|
|
1091
1237
|
}
|
|
1238
|
+
/**
|
|
1239
|
+
* A KIND'S LIST FOLLOWS ITS FIELDS. Its order and grouping name a field
|
|
1240
|
+
* renamed by its new name; one gone (or a computed field no longer worked
|
|
1241
|
+
* out) lets go of the part that named it — a tiebreak, the order, the
|
|
1242
|
+
* grouping — and says so. A list left saying nothing is unsaid.
|
|
1243
|
+
*/
|
|
1244
|
+
listsFollow(kind, from, to) {
|
|
1245
|
+
const list = this.doc.pages?.lists?.[kind];
|
|
1246
|
+
if (!list)
|
|
1247
|
+
return [];
|
|
1248
|
+
const out = [];
|
|
1249
|
+
const sort = listSort(list.sort);
|
|
1250
|
+
if (sort && (sort.by === from || sort.then?.by === from)) {
|
|
1251
|
+
if (to !== undefined) {
|
|
1252
|
+
if (typeof list.sort === "string")
|
|
1253
|
+
list.sort = to;
|
|
1254
|
+
else {
|
|
1255
|
+
if (list.sort.by === from)
|
|
1256
|
+
list.sort.by = to;
|
|
1257
|
+
if (list.sort.then === from)
|
|
1258
|
+
list.sort.then = to;
|
|
1259
|
+
else if (isObject(list.sort.then) && list.sort.then["by"] === from)
|
|
1260
|
+
list.sort.then.by = to;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
else if (sort.by === from)
|
|
1264
|
+
delete list.sort;
|
|
1265
|
+
else
|
|
1266
|
+
delete list.sort.then;
|
|
1267
|
+
out.push(`the ${kind} list's order`);
|
|
1268
|
+
}
|
|
1269
|
+
if (listGroup(list.group)?.by === from) {
|
|
1270
|
+
if (to === undefined)
|
|
1271
|
+
delete list.group;
|
|
1272
|
+
else if (typeof list.group === "string")
|
|
1273
|
+
list.group = to;
|
|
1274
|
+
else
|
|
1275
|
+
list.group.by = to;
|
|
1276
|
+
out.push(`the ${kind} list's grouping`);
|
|
1277
|
+
}
|
|
1278
|
+
this.listsTidied(kind);
|
|
1279
|
+
return out;
|
|
1280
|
+
}
|
|
1281
|
+
/** A field retyped or a choice dropped: the list's order and grouping keep what still holds, and let go of what does not. */
|
|
1282
|
+
listsHold(kind, removedOptions = []) {
|
|
1283
|
+
const list = this.doc.pages?.lists?.[kind];
|
|
1284
|
+
if (!list)
|
|
1285
|
+
return [];
|
|
1286
|
+
const out = [];
|
|
1287
|
+
if (isObject(list.group) && removedOptions.length > 0) {
|
|
1288
|
+
for (const part of ["order", "closed"]) {
|
|
1289
|
+
if (!Array.isArray(list.group[part]))
|
|
1290
|
+
continue;
|
|
1291
|
+
const kept = list.group[part].filter((value) => !removedOptions.includes(value));
|
|
1292
|
+
if (kept.length === list.group[part].length)
|
|
1293
|
+
continue;
|
|
1294
|
+
if (kept.length > 0)
|
|
1295
|
+
list.group[part] = kept;
|
|
1296
|
+
else
|
|
1297
|
+
delete list.group[part];
|
|
1298
|
+
if (!out.includes(`the ${kind} list's grouping`))
|
|
1299
|
+
out.push(`the ${kind} list's grouping`);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
for (const finding of kindListFindings(kind, list, documentListFields(this.doc.kinds[kind]))) {
|
|
1303
|
+
const part = finding.path.slice(`pages.lists.${kind}.`.length).startsWith("sort") ? "sort" : "group";
|
|
1304
|
+
if (list[part] === undefined)
|
|
1305
|
+
continue;
|
|
1306
|
+
delete list[part];
|
|
1307
|
+
out.push(`the ${kind} list's ${part === "sort" ? "order" : "grouping"}`);
|
|
1308
|
+
}
|
|
1309
|
+
this.listsTidied(kind);
|
|
1310
|
+
return out;
|
|
1311
|
+
}
|
|
1312
|
+
listsTidied(kind) {
|
|
1313
|
+
const lists = this.doc.pages?.lists;
|
|
1314
|
+
if (!lists)
|
|
1315
|
+
return;
|
|
1316
|
+
if (lists[kind] && Object.keys(lists[kind]).length === 0)
|
|
1317
|
+
delete lists[kind];
|
|
1318
|
+
if (Object.keys(lists).length === 0)
|
|
1319
|
+
delete this.doc.pages.lists;
|
|
1320
|
+
if (Object.keys(this.doc.pages).length === 0)
|
|
1321
|
+
delete this.doc.pages;
|
|
1322
|
+
}
|
|
1323
|
+
/** What a key of a kind's list reads as, for the words its order is said in: a computed field is a number. */
|
|
1324
|
+
listKeyType(kind) {
|
|
1325
|
+
const spec = this.doc.kinds[kind];
|
|
1326
|
+
return (key) => (spec?.computed?.[key] !== undefined ? "number" : sortTypeOfDocumentField(spec?.fields?.[key]?.type));
|
|
1327
|
+
}
|
|
1328
|
+
/** What a kind's list may be filtered by: its fields, its relations either way, `is`, and a choice at a relation's single far kind. */
|
|
1329
|
+
filterKeys(kind) {
|
|
1330
|
+
const kinds = this.doc.kinds;
|
|
1331
|
+
const keys = new Set(["is", ...Object.keys(kinds[kind]?.fields ?? {})]);
|
|
1332
|
+
const edges = new Map();
|
|
1333
|
+
for (const [edge, spec] of Object.entries((kinds[kind]?.edges ?? {})))
|
|
1334
|
+
edges.set(edge, spec.to === "*" ? [] : [spec.to].flat());
|
|
1335
|
+
for (const [other, spec] of Object.entries(kinds)) {
|
|
1336
|
+
for (const [edge, declared] of Object.entries((spec.edges ?? {}))) {
|
|
1337
|
+
if (other !== kind && !edges.has(edge) && (declared.to === "*" || [declared.to].flat().includes(kind)))
|
|
1338
|
+
edges.set(edge, [other]);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
for (const [edge, far] of edges) {
|
|
1342
|
+
keys.add(edge);
|
|
1343
|
+
if (far.length !== 1 || far[0] === kind)
|
|
1344
|
+
continue;
|
|
1345
|
+
for (const [field, spec] of Object.entries((kinds[far[0]]?.fields ?? {})))
|
|
1346
|
+
if (spec.type === "enum")
|
|
1347
|
+
keys.add(`${edge}.${field}`);
|
|
1348
|
+
}
|
|
1349
|
+
return [...keys];
|
|
1350
|
+
}
|
|
1092
1351
|
/** Whether `first` names something the app can open on: home, a kind or its plural, a titled lens. */
|
|
1093
1352
|
opens(first) {
|
|
1094
1353
|
const word = first.trim();
|
|
@@ -1179,6 +1438,73 @@ class Editor {
|
|
|
1179
1438
|
delete spec.people;
|
|
1180
1439
|
this.said.push(peopleSentence(this.doc.kinds, e.kind, e.people, already));
|
|
1181
1440
|
}
|
|
1441
|
+
/** A kind's records kept or removed, never archived (FR-173) — or archived and merged again. */
|
|
1442
|
+
setArchives(i, e) {
|
|
1443
|
+
const spec = this.kind(i, e.kind);
|
|
1444
|
+
if (!spec)
|
|
1445
|
+
return;
|
|
1446
|
+
const already = (spec.archives !== false) === e.archives;
|
|
1447
|
+
if (!e.archives && !already) {
|
|
1448
|
+
// A grant that names one of the three acts would name an act the app no longer has.
|
|
1449
|
+
const gone = new Set(["archive", "unarchive", "merge"].map((verb) => `${verb}-${e.kind}`).filter((act) => !this.doc.acts?.[act]));
|
|
1450
|
+
const grant = (this.doc.policy?.grants ?? []).find((g) => Array.isArray(g.mutations) && g.mutations.some((m) => gone.has(m)));
|
|
1451
|
+
if (grant) {
|
|
1452
|
+
const named = grant.mutations.filter((m) => gone.has(m));
|
|
1453
|
+
return this.failAs("grant-unknown-mutation", i, "archives", `a grant names ${listOf(named.map((m) => `"${m}"`))}, which ${pluralOf(this.doc.kinds, e.kind)} would no longer have`, `{"op": "remove-grant", "roles": ${JSON.stringify(grant.roles)}, "mutations": ${JSON.stringify(grant.mutations)}} first, in the same change`);
|
|
1454
|
+
}
|
|
1455
|
+
spec.archives = false;
|
|
1456
|
+
}
|
|
1457
|
+
else if (e.archives)
|
|
1458
|
+
delete spec.archives;
|
|
1459
|
+
if (!already)
|
|
1460
|
+
this.toolsMoved.add(`archive-${e.kind}, unarchive-${e.kind} and merge-${e.kind} ${e.archives ? "are offered" : "are gone"}`);
|
|
1461
|
+
this.said.push(archivesSentence(this.doc.kinds, e.kind, e.archives, already));
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* WHAT THE APP'S OWN ACTOR MAY DO ON ITS OWN (`@graview/core/tidying`):
|
|
1465
|
+
* a kind never tidied, or never linked automatically, or tidied again; a
|
|
1466
|
+
* relation never made or broken automatically, or tidied again. A kind
|
|
1467
|
+
* never tidied is given no leave-alone-<kind> or allow-tidying-<kind>,
|
|
1468
|
+
* which a grant may not then name.
|
|
1469
|
+
*/
|
|
1470
|
+
setTidying(i, e) {
|
|
1471
|
+
const spec = this.kind(i, e.kind);
|
|
1472
|
+
if (!spec)
|
|
1473
|
+
return;
|
|
1474
|
+
const tidying = e.tidying;
|
|
1475
|
+
if (e.relation !== undefined) {
|
|
1476
|
+
const relation = spec.edges?.[e.relation];
|
|
1477
|
+
if (!relation)
|
|
1478
|
+
return this.failAs("edit", i, "relation", `${e.kind} has no relation "${e.relation}"; it has ${Object.keys(spec.edges ?? {}).join(", ") || "none"}`);
|
|
1479
|
+
if (tidying === "no-links")
|
|
1480
|
+
return this.failAs("edit", i, "tidying", `a relation is tidied or never ("never"); "no-links" is said of a kind`, `{"op": "set-tidying", "kind": "${e.kind}", "relation": "${e.relation}", "tidying": "never"}`);
|
|
1481
|
+
const already = (relation.tidying === "never") === (tidying === "never");
|
|
1482
|
+
if (tidying === "never")
|
|
1483
|
+
relation.tidying = "never";
|
|
1484
|
+
else
|
|
1485
|
+
delete relation.tidying;
|
|
1486
|
+
this.said.push(tidyingSentence(this.doc.kinds, e.kind, e.relation, tidying, already));
|
|
1487
|
+
return;
|
|
1488
|
+
}
|
|
1489
|
+
const was = spec.tidying ?? "allowed";
|
|
1490
|
+
const already = was === tidying;
|
|
1491
|
+
if (tidying === "never" && !already) {
|
|
1492
|
+
// A grant that names leave-alone-<kind> or allow-tidying-<kind> would name an act the app no longer has.
|
|
1493
|
+
const gone = new Set(["leave-alone", "allow-tidying"].map((verb) => `${verb}-${e.kind}`).filter((act) => !this.doc.acts?.[act]));
|
|
1494
|
+
const grant = (this.doc.policy?.grants ?? []).find((g) => Array.isArray(g.mutations) && g.mutations.some((m) => gone.has(m)));
|
|
1495
|
+
if (grant) {
|
|
1496
|
+
const named = grant.mutations.filter((m) => gone.has(m));
|
|
1497
|
+
return this.failAs("grant-unknown-mutation", i, "tidying", `a grant names ${listOf(named.map((m) => `"${m}"`))}, which ${pluralOf(this.doc.kinds, e.kind)} would no longer have`, `{"op": "remove-grant", "roles": ${JSON.stringify(grant.roles)}, "mutations": ${JSON.stringify(grant.mutations)}} first, in the same change`);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
if (tidying === "allowed")
|
|
1501
|
+
delete spec.tidying;
|
|
1502
|
+
else
|
|
1503
|
+
spec.tidying = tidying;
|
|
1504
|
+
if (!already && (was === "never" || tidying === "never"))
|
|
1505
|
+
this.toolsMoved.add(`leave-alone-${e.kind} and allow-tidying-${e.kind} ${tidying === "never" ? "are gone" : "are offered"}`);
|
|
1506
|
+
this.said.push(tidyingSentence(this.doc.kinds, e.kind, undefined, tidying, already));
|
|
1507
|
+
}
|
|
1182
1508
|
/** A grant or a sight as the document holds one, or undefined having said why not. */
|
|
1183
1509
|
policyPart(i, e, sight) {
|
|
1184
1510
|
const { op: _op, ...rest } = e;
|
|
@@ -1202,12 +1528,21 @@ class Editor {
|
|
|
1202
1528
|
if (!this.doc.kinds[kind])
|
|
1203
1529
|
return this.failAs(sight ? "sight-kind" : "edit", i, `kinds.${n}`, `"${kind}" is not a kind this app has; it has ${Object.keys(this.doc.kinds).join(", ")}`);
|
|
1204
1530
|
}
|
|
1531
|
+
// A field a sight shows or hides is one of the kinds it shows (Roadmap f-field-sight).
|
|
1532
|
+
for (const key of sight ? ["fields", "hide"] : []) {
|
|
1533
|
+
for (const [n, field] of (part[key] ?? []).entries()) {
|
|
1534
|
+
const kinds = part.kinds;
|
|
1535
|
+
if (kinds.some((kind) => this.doc.kinds[kind]?.fields[field]))
|
|
1536
|
+
continue;
|
|
1537
|
+
return this.failAs("sight-field", i, `${key}.${n}`, `"${field}" is not a field of ${kinds.join(" or ")}`, `one of ${[...new Set(kinds.flatMap((kind) => Object.keys(this.doc.kinds[kind]?.fields ?? {})))].join(", ")}`);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1205
1540
|
if (!sight && part.mutations !== "*") {
|
|
1206
1541
|
for (const [n, act] of part.mutations.entries()) {
|
|
1207
|
-
const derived =
|
|
1208
|
-
if (this.doc.acts?.[act] || (derived && this.doc.kinds[derived[
|
|
1542
|
+
const derived = derivedActOf(act);
|
|
1543
|
+
if (this.doc.acts?.[act] || (derived && this.doc.kinds[derived.kind] && (this.doc.kinds[derived.kind].archives !== false || givenWhenNeverArchived(derived.act)) && (this.doc.kinds[derived.kind].tidying !== "never" || givenWhenNeverTidied(derived.act))))
|
|
1209
1544
|
continue;
|
|
1210
|
-
return this.failAs("grant-act", i, `mutations.${n}`, `"${act}" is not an act this app has`, `one of ${[...Object.keys(this.doc.acts ?? {}), ...Object.keys(this.doc.kinds).flatMap(
|
|
1545
|
+
return this.failAs("grant-act", i, `mutations.${n}`, `"${act}" is not an act this app has`, `one of ${[...Object.keys(this.doc.acts ?? {}), ...Object.keys(this.doc.kinds).flatMap(derivedActsOf)].join(", ")}`);
|
|
1211
1546
|
}
|
|
1212
1547
|
}
|
|
1213
1548
|
const said = [];
|
|
@@ -1306,8 +1641,8 @@ class Editor {
|
|
|
1306
1641
|
const to = e.to;
|
|
1307
1642
|
const touched = this.rewriteAll({ t: "kind", from, to });
|
|
1308
1643
|
// The acts the framework derives for every kind are named for it, so they move with it.
|
|
1309
|
-
|
|
1310
|
-
|
|
1644
|
+
for (const act of DERIVED_ACTS)
|
|
1645
|
+
this.toolsMoved.add(`${act}-${from} is now ${act}-${to}`);
|
|
1311
1646
|
// The kind itself, in order, continuing its records.
|
|
1312
1647
|
const kinds = {};
|
|
1313
1648
|
for (const [k, v] of Object.entries(this.doc.kinds))
|
|
@@ -1338,6 +1673,13 @@ class Editor {
|
|
|
1338
1673
|
spec.plural = e.plural;
|
|
1339
1674
|
else if (spec.plural && (spec.plural === `${words(from)}s` || spec.plural === `${from}s`))
|
|
1340
1675
|
spec.plural = `${words(to)}s`;
|
|
1676
|
+
// Its list's filters, order and grouping follow it.
|
|
1677
|
+
const lists = this.doc.pages?.lists;
|
|
1678
|
+
if (lists?.[from] !== undefined && lists[to] === undefined) {
|
|
1679
|
+
lists[to] = lists[from];
|
|
1680
|
+
delete lists[from];
|
|
1681
|
+
touched.push(`its list`);
|
|
1682
|
+
}
|
|
1341
1683
|
// Where the app opens, when it named the kind by its plural, follows the plural (FR-80).
|
|
1342
1684
|
const pluralNow = spec.plural ?? `${words(to)}s`;
|
|
1343
1685
|
if (typeof this.doc.pages?.first === "string" && placeSlug(this.doc.pages.first) === placeSlug(pluralWas) && placeSlug(pluralWas) !== placeSlug(pluralNow)) {
|
|
@@ -1424,7 +1766,7 @@ class Editor {
|
|
|
1424
1766
|
* whose last act is removed — kept, it read as a grant on every kind.
|
|
1425
1767
|
*/
|
|
1426
1768
|
if (this.doc.policy) {
|
|
1427
|
-
const derived =
|
|
1769
|
+
const derived = derivedActsOf(kind);
|
|
1428
1770
|
this.doc.policy.grants = this.doc.policy.grants.flatMap((g) => {
|
|
1429
1771
|
const kinds = Array.isArray(g.kinds) ? g.kinds.filter((k) => k !== kind) : g.kinds;
|
|
1430
1772
|
const mutations = Array.isArray(g.mutations) ? g.mutations.filter((m) => !derived.includes(m) || this.doc.acts?.[m]) : g.mutations;
|
|
@@ -1491,6 +1833,8 @@ class Editor {
|
|
|
1491
1833
|
delete f.renamedFrom;
|
|
1492
1834
|
if (f.type === "enum" && f.default !== undefined && !f.options.includes(f.default))
|
|
1493
1835
|
return this.fail(i, "default", `"${String(f.default)}" is not one of the options`);
|
|
1836
|
+
if (f.format && !formatFits(f.format, f.type))
|
|
1837
|
+
return this.fail(i, "format", refusedFormat(f.format, f.type));
|
|
1494
1838
|
spec.fields[field] = f;
|
|
1495
1839
|
this.fieldOrigin.set(`${kind}.${field}`, undefined);
|
|
1496
1840
|
let filled = "";
|
|
@@ -1510,7 +1854,9 @@ class Editor {
|
|
|
1510
1854
|
filled = `, set to ${JSON.stringify(fill)} on the records already there`;
|
|
1511
1855
|
}
|
|
1512
1856
|
}
|
|
1513
|
-
|
|
1857
|
+
// What it is said as, in words: "(number, money in USD — 10000 reads $10,000)".
|
|
1858
|
+
const said = formatWords(f, this.doc.brand);
|
|
1859
|
+
this.said.push(`${kind} gains a field, ${field} (${f.type}${said ? `, ${said}` : ""}${f.required ? ", required" : ""})${filled}.`);
|
|
1514
1860
|
}
|
|
1515
1861
|
renameField(i, kind, field, to) {
|
|
1516
1862
|
const f = this.field(i, kind, field);
|
|
@@ -1554,6 +1900,7 @@ class Editor {
|
|
|
1554
1900
|
spec.page = renamedOnPage(spec.page, field, to);
|
|
1555
1901
|
touched.push(`${kind}'s page`);
|
|
1556
1902
|
}
|
|
1903
|
+
touched.push(...this.listsFollow(kind, field, to));
|
|
1557
1904
|
for (const x of this.fills) {
|
|
1558
1905
|
if (x.kind === kind && x.field === field)
|
|
1559
1906
|
x.field = to;
|
|
@@ -1572,6 +1919,9 @@ class Editor {
|
|
|
1572
1919
|
return;
|
|
1573
1920
|
if (e.type === "enum" && !e.options && !f.options)
|
|
1574
1921
|
return this.fail(i, "options", `to make ${e.field} a choice, list its "options"`);
|
|
1922
|
+
// A format goes where it says something (FR-180): money, a percent and a duration on a number, Markdown on a text field.
|
|
1923
|
+
if (e.format && !formatFits(e.format, e.type))
|
|
1924
|
+
return this.fail(i, "format", refusedFormat(e.format, e.type));
|
|
1575
1925
|
const was = f.type;
|
|
1576
1926
|
f.type = e.type;
|
|
1577
1927
|
if (e.type === "enum")
|
|
@@ -1584,25 +1934,73 @@ class Editor {
|
|
|
1584
1934
|
delete f.of;
|
|
1585
1935
|
if (e.format)
|
|
1586
1936
|
f.format = e.format;
|
|
1587
|
-
else if (e.type
|
|
1937
|
+
else if (e.type === "text" || !formatFits(f.format ?? "", e.type))
|
|
1588
1938
|
delete f.format;
|
|
1589
1939
|
// A range is a number's (FR-114): a field that is no longer one lets it go.
|
|
1590
|
-
if (e.type !== "number" && e.type !== "integer")
|
|
1940
|
+
if (e.type !== "number" && e.type !== "integer" && e.type !== "duration")
|
|
1591
1941
|
for (const key of ["min", "max", "step"])
|
|
1592
1942
|
delete f[key];
|
|
1943
|
+
// Only a date repeats: a field that is no longer one lets its repeat go.
|
|
1944
|
+
if (e.type !== "date" && e.type !== "datetime")
|
|
1945
|
+
delete f.repeats;
|
|
1593
1946
|
if (f.default !== undefined && coerce(f.default, was, f) === undefined)
|
|
1594
1947
|
delete f.default;
|
|
1595
1948
|
else if (f.default !== undefined)
|
|
1596
1949
|
f.default = coerce(f.default, was, f);
|
|
1597
|
-
|
|
1950
|
+
const said = f.format && f.format !== "markdown" ? formatWords(f, this.doc.brand) : undefined;
|
|
1951
|
+
// A list grouped by a choice that is no longer one opens ungrouped, and says so.
|
|
1952
|
+
const held = this.listsHold(e.kind);
|
|
1953
|
+
if (held.length > 0)
|
|
1954
|
+
this.said.push(`${capitalize(listOf(held))} ${held.length === 1 ? "goes" : "go"} back to the list's own, since ${e.field} is no longer ${was === "enum" ? "a choice" : `a ${was}`}.`);
|
|
1955
|
+
if (was === e.type && e.type === "text")
|
|
1956
|
+
this.said.push(`${e.kind}'s ${e.field} ${e.format === "markdown" ? "is now written in Markdown, drawn as prose on the record's page" : "is drawn as written, not as Markdown"}; its values are kept.`);
|
|
1957
|
+
else
|
|
1958
|
+
this.said.push(`${e.kind}'s ${e.field} changes from ${was} to ${e.type}${said ? `, said as ${said}` : ""}; values that convert are kept.`);
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* HOW A FIELD IS SAID, and nothing else about it: a number's `format`
|
|
1962
|
+
* (money, a percent, a duration) and `unit` (a currency like "EUR" for
|
|
1963
|
+
* money, a measure like "kg"), or a text field's `format`, `markdown`
|
|
1964
|
+
* (FR-180) — each set by a value, cleared by `null`, kept when left out.
|
|
1965
|
+
* The values stay as they are; every face says them anew.
|
|
1966
|
+
*/
|
|
1967
|
+
setFormat(i, e) {
|
|
1968
|
+
const f = this.field(i, e.kind, e.field);
|
|
1969
|
+
if (!f)
|
|
1970
|
+
return;
|
|
1971
|
+
if (e.format === undefined && e.unit === undefined)
|
|
1972
|
+
return this.fail(i, "format", 'say a "format" ("money", "percent" or "duration" for a number, "markdown" for a text field, or null for neither), a "unit" ("EUR", "kg", or null), or both');
|
|
1973
|
+
if (f.type === "text") {
|
|
1974
|
+
if (e.unit !== undefined && e.unit !== null)
|
|
1975
|
+
return this.fail(i, "unit", refusedFormat("a unit", f.type));
|
|
1976
|
+
if (e.format && e.format !== "markdown")
|
|
1977
|
+
return this.fail(i, "format", refusedFormat(e.format, f.type));
|
|
1978
|
+
if (e.format === "markdown")
|
|
1979
|
+
f.format = "markdown";
|
|
1980
|
+
else if (e.format === null)
|
|
1981
|
+
delete f.format;
|
|
1982
|
+
this.said.push(`${e.kind}'s ${e.field} ${f.format === "markdown" ? "is now written in Markdown, drawn as prose on the record's page" : "is drawn as written, not as Markdown"}; its values are kept.`);
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
if (!formatFits(typeof e.format === "string" ? e.format : "money", f.type))
|
|
1986
|
+
return this.fail(i, "field", refusedFormat(typeof e.format === "string" ? e.format : "a unit", f.type));
|
|
1987
|
+
const before = formatWords(f, this.doc.brand);
|
|
1988
|
+
for (const key of ["format", "unit"]) {
|
|
1989
|
+
if (e[key] === null)
|
|
1990
|
+
delete f[key];
|
|
1991
|
+
else if (e[key] !== undefined)
|
|
1992
|
+
f[key] = e[key];
|
|
1993
|
+
}
|
|
1994
|
+
const now = formatWords(f, this.doc.brand);
|
|
1995
|
+
this.said.push(`${e.kind}'s ${e.field} is said as ${now ?? "a plain number"}${before ? `, where it was ${before.replace(/ — .*/, "")}` : ""}; its values are kept.`);
|
|
1598
1996
|
}
|
|
1599
1997
|
/** A number's range (FR-114): a key given sets it, `null` clears it, one left out stays. */
|
|
1600
1998
|
setRange(i, e) {
|
|
1601
1999
|
const f = this.field(i, e.kind, e.field);
|
|
1602
2000
|
if (!f)
|
|
1603
2001
|
return;
|
|
1604
|
-
if (f.type !== "number" && f.type !== "integer")
|
|
1605
|
-
return this.fail(i, "field", `${e.field} is ${f.type === "integer" ? "an" : "a"} ${f.type}, not a number; a range belongs on a number or
|
|
2002
|
+
if (f.type !== "number" && f.type !== "integer" && f.type !== "duration")
|
|
2003
|
+
return this.fail(i, "field", `${e.field} is ${f.type === "integer" ? "an" : "a"} ${f.type}, not a number; a range belongs on a number, integer or duration field`);
|
|
1606
2004
|
const next = { ...f };
|
|
1607
2005
|
for (const key of ["min", "max", "step"]) {
|
|
1608
2006
|
if (e[key] === null)
|
|
@@ -1647,6 +2045,9 @@ class Editor {
|
|
|
1647
2045
|
delete f.default;
|
|
1648
2046
|
out.push("has no default now");
|
|
1649
2047
|
}
|
|
2048
|
+
const held = this.listsHold(e.kind, remove);
|
|
2049
|
+
if (held.length > 0)
|
|
2050
|
+
out.push(`${listOf(held)} ${held.length === 1 ? "lets" : "let"} go of ${remove.length === 1 ? "it" : "them"}`);
|
|
1650
2051
|
// An act that sets a dropped option cannot stand.
|
|
1651
2052
|
for (const [name, act] of Object.entries(this.doc.acts ?? {})) {
|
|
1652
2053
|
for (const t of setTargets(act, this.doc))
|
|
@@ -2025,7 +2426,7 @@ class Editor {
|
|
|
2025
2426
|
rule.over = r.to;
|
|
2026
2427
|
for (const rep of rule.repairs ?? []) {
|
|
2027
2428
|
if (r.t === "kind")
|
|
2028
|
-
rep.act = rep.act
|
|
2429
|
+
rep.act = renamedAct(rep.act, r.from, r.to);
|
|
2029
2430
|
const args = renamedArgs.get(rep.act);
|
|
2030
2431
|
if (args && rep.args)
|
|
2031
2432
|
for (const [a, b] of args)
|
|
@@ -2052,7 +2453,7 @@ class Editor {
|
|
|
2052
2453
|
if (Array.isArray(g.kinds))
|
|
2053
2454
|
g.kinds = g.kinds.map(swap);
|
|
2054
2455
|
if (Array.isArray(g.mutations))
|
|
2055
|
-
g.mutations = g.mutations.map((m) => (m
|
|
2456
|
+
g.mutations = g.mutations.map((m) => renamedAct(m, r.from, r.to));
|
|
2056
2457
|
}
|
|
2057
2458
|
for (const s of doc.policy.sees ?? [])
|
|
2058
2459
|
s.kinds = s.kinds.map(swap);
|
|
@@ -2115,6 +2516,9 @@ class Editor {
|
|
|
2115
2516
|
dropMentions(r, worked = false) {
|
|
2116
2517
|
const doc = this.doc;
|
|
2117
2518
|
const gone = [];
|
|
2519
|
+
// A kind's list ordered or grouped by it lets that go (a stored field removed, a computed one no longer worked out).
|
|
2520
|
+
if (r.t === "field")
|
|
2521
|
+
gone.push(...this.listsFollow(r.kind, r.from, undefined));
|
|
2118
2522
|
for (const [kind, spec] of Object.entries(doc.kinds)) {
|
|
2119
2523
|
for (const key of ["label", "describe"]) {
|
|
2120
2524
|
if (templateMentions(doc, spec[key], new Set([kind]), r)) {
|
|
@@ -2808,4 +3212,9 @@ export function renameIn(kinds, over, text, change) {
|
|
|
2808
3212
|
return rewriteTemplate(doc, text.template, ctx, r);
|
|
2809
3213
|
return undefined;
|
|
2810
3214
|
}
|
|
3215
|
+
/** A derived act of a renamed kind, renamed with it: `archive-task` becomes `archive-chore`. Any other act as it was. */
|
|
3216
|
+
function renamedAct(act, from, to) {
|
|
3217
|
+
const derived = derivedActOf(act);
|
|
3218
|
+
return derived && derived.kind === from ? `${derived.act}-${to}` : act;
|
|
3219
|
+
}
|
|
2811
3220
|
//# sourceMappingURL=edit.js.map
|