yarramate 1.30.0 → 1.31.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/dist/adapters/likec4-cli.js +28 -317
- package/dist/adapters/likec4-project-export.d.ts +74 -0
- package/dist/adapters/likec4-project-export.js +242 -0
- package/dist/adapters/mcp-cli.d.ts +12 -7
- package/dist/adapters/mcp-cli.js +175 -265
- package/dist/adapters/visual/wire.d.ts +12 -1
- package/dist/apply-command.d.ts +1 -1
- package/dist/ask-command.js +131 -522
- package/dist/check-command.js +79 -338
- package/dist/design-command.js +45 -180
- package/dist/digest.d.ts +13 -0
- package/dist/digest.js +81 -0
- package/dist/export-command.js +110 -173
- package/dist/host/editor-host.d.ts +70 -0
- package/dist/host/editor-host.js +1 -0
- package/dist/host/local-host.d.ts +123 -0
- package/dist/host/local-host.js +477 -0
- package/dist/host-entry.d.ts +15 -0
- package/dist/host-entry.js +12 -0
- package/dist/likec4-specification.generated.d.ts +1 -0
- package/dist/likec4-specification.generated.js +3 -0
- package/dist/shipped-catalogue.generated.d.ts +1 -0
- package/dist/shipped-catalogue.generated.js +3 -0
- package/dist/tools/apply.d.ts +31 -0
- package/dist/tools/apply.js +45 -0
- package/dist/tools/ask.d.ts +239 -0
- package/dist/tools/ask.js +466 -0
- package/dist/tools/check.d.ts +83 -0
- package/dist/tools/check.js +350 -0
- package/dist/tools/design.d.ts +57 -0
- package/dist/tools/design.js +138 -0
- package/dist/tools/export.d.ts +58 -0
- package/dist/tools/export.js +194 -0
- package/dist/tools/table.d.ts +85 -0
- package/dist/tools/table.js +323 -0
- package/dist/tools/workspace.d.ts +108 -0
- package/dist/tools/workspace.js +84 -0
- package/dist/tools-entry.d.ts +21 -0
- package/dist/tools-entry.js +18 -0
- package/dist/visual-app/assets/{elk.bundled-COwlLbLc.js → elk.bundled-JlCCXIin.js} +1 -1
- package/dist/visual-app/assets/{index-CK1GVgBn.js → index-BSwETsaq.js} +2 -2
- package/dist/visual-app/assets/index-CZSChZa6.css +1 -0
- package/dist/visual-app/index.html +2 -2
- package/dist/visual-app-lib/editor.js +23356 -23277
- package/dist/visual-app-lib/styles.css +1 -1
- package/dist/visual-app-lib/types/adapters/visual/wire.d.ts +12 -1
- package/dist/visual-app-lib/types/apply-command.d.ts +1 -1
- package/dist/visual-app-lib/types/host/editor-host.d.ts +70 -0
- package/dist/visual-app-lib/types/host/local-host.d.ts +123 -0
- package/dist/visual-app-lib/types/shipped-catalogue.generated.d.ts +1 -0
- package/dist/visual-app-lib/types/tools/workspace.d.ts +108 -0
- package/dist/visual-app-lib/types/visual-app/editor-host.d.ts +1 -70
- package/dist/visual-app-lib/types/visual-app/local-host.d.ts +1 -123
- package/dist/visual-app-lib/types/visual-app/mount.d.ts +16 -1
- package/dist/visual-app-lib/types/visual-app/socket-host.d.ts +26 -0
- package/dist/visual-app-lib/types/visual-app/state.d.ts +9 -0
- package/dist/visual-app-lib/types/workspace-resolution.d.ts +106 -0
- package/dist/visual-app-lib/types/workspace.d.ts +3 -54
- package/dist/workspace-resolution.d.ts +106 -0
- package/dist/workspace-resolution.js +189 -0
- package/dist/workspace.d.ts +3 -54
- package/dist/workspace.js +11 -129
- package/docs/CONSUMING-YARRAMATE.md +106 -4
- package/package.json +10 -1
- package/schema/yarramate-ask-result.schema.json +4 -0
- package/dist/visual-app/assets/index-CfFZAmkF.css +0 -1
- package/dist/visual-app-lib/types/visual-app/shipped-catalogue.d.ts +0 -10
|
@@ -9,9 +9,8 @@ import { isMainModule, resolveCliWorkspaceSources, versionResult, } from '../cli
|
|
|
9
9
|
import { deriveChangedSubjects } from '../changed.js';
|
|
10
10
|
import { compileWorkspace } from '../compiler.js';
|
|
11
11
|
import { adapterMappingLocation, loadAdapterMapping, validateAdapterMapping, } from '../adapter-mapping.js';
|
|
12
|
-
import { locateSourcePath } from '../source-document.js';
|
|
13
12
|
import { prepareLikeC4Export, } from './likec4-prepare.js';
|
|
14
|
-
import {
|
|
13
|
+
import { exportLikeC4ProjectFromSources, inputDigestsOf, ownershipOf, projectNameOf, } from './likec4-project-export.js';
|
|
15
14
|
import generatedProjectSchema from '../../schema/yarramate-likec4-generated-project.schema.json' with { type: 'json'
|
|
16
15
|
};
|
|
17
16
|
import generatedProjectV2Schema from '../../schema/yarramate-likec4-generated-project-v2.schema.json' with { type: 'json'
|
|
@@ -515,9 +514,6 @@ const checkGeneratedProject = (cwd, outputDirectory, input) => {
|
|
|
515
514
|
stderr: '',
|
|
516
515
|
};
|
|
517
516
|
};
|
|
518
|
-
const inputDigestsOf = (inputs) => Object.fromEntries(inputs
|
|
519
|
-
.map(({ path, source }) => [path, sha256(source)])
|
|
520
|
-
.sort(([left], [right]) => left.localeCompare(right)));
|
|
521
517
|
export function runLikeC4Cli(args, cwd = process.cwd()) {
|
|
522
518
|
if (args[0] === '--version') {
|
|
523
519
|
return versionResult('yarramate-likec4');
|
|
@@ -653,286 +649,10 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
|
|
|
653
649
|
path: projectionPath,
|
|
654
650
|
source: readFileSync(resolve(cwd, projectionPath), 'utf8'),
|
|
655
651
|
};
|
|
656
|
-
const loadedProject = loadLikeC4ProjectDefinition(projectSource);
|
|
657
|
-
if (!loadedProject.ok) {
|
|
658
|
-
return {
|
|
659
|
-
exitCode: 1,
|
|
660
|
-
stdout: diagnosticOutput(loadedProject.diagnostics),
|
|
661
|
-
stderr: '',
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
652
|
const projectDirectory = dirname(resolve(cwd, projectionPath));
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
const existing = referencedSources.get(path);
|
|
669
|
-
if (existing !== undefined)
|
|
670
|
-
return existing;
|
|
671
|
-
try {
|
|
672
|
-
const source = {
|
|
673
|
-
path,
|
|
674
|
-
source: readFileSync(resolve(projectDirectory, path), 'utf8'),
|
|
675
|
-
};
|
|
676
|
-
referencedSources.set(path, source);
|
|
677
|
-
return source;
|
|
678
|
-
}
|
|
679
|
-
catch (error) {
|
|
680
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, yamlPath, pointer);
|
|
681
|
-
const absent = error instanceof Error &&
|
|
682
|
-
'code' in error &&
|
|
683
|
-
error.code === 'ENOENT';
|
|
684
|
-
referenceDiagnostics.push({
|
|
685
|
-
severity: 'error',
|
|
686
|
-
code: 'YMLC110',
|
|
687
|
-
message: absent
|
|
688
|
-
? `LikeC4 project ${label} "${path}" does not exist`
|
|
689
|
-
: `LikeC4 project ${label} "${path}" cannot be read`,
|
|
690
|
-
...location,
|
|
691
|
-
});
|
|
692
|
-
return undefined;
|
|
693
|
-
}
|
|
694
|
-
};
|
|
695
|
-
const subjectMapping = readProjectReference(loadedProject.document.value.mapping, 'mapping', ['mapping'], '/mapping');
|
|
696
|
-
const kindMapping = loadedProject.document.value.kindMapping === undefined
|
|
697
|
-
? undefined
|
|
698
|
-
: readProjectReference(loadedProject.document.value.kindMapping, 'kind mapping', ['kindMapping'], '/kindMapping');
|
|
699
|
-
const projections = loadedProject.document.value.views.map((view, index) => readProjectReference(view.projection, 'projection', ['views', index, 'projection'], `/views/${index}/projection`));
|
|
700
|
-
if (referenceDiagnostics.length > 0 ||
|
|
701
|
-
subjectMapping === undefined) {
|
|
702
|
-
return {
|
|
703
|
-
exitCode: 1,
|
|
704
|
-
stdout: diagnosticOutput(referenceDiagnostics.sort((left, right) => left.path.localeCompare(right.path) ||
|
|
705
|
-
left.line - right.line ||
|
|
706
|
-
left.column - right.column ||
|
|
707
|
-
left.code.localeCompare(right.code) ||
|
|
708
|
-
left.message.localeCompare(right.message))),
|
|
709
|
-
stderr: '',
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
const preparedViews = loadedProject.document.value.views.map((view, index) => ({
|
|
713
|
-
view,
|
|
714
|
-
prepared: prepareLikeC4Export({
|
|
715
|
-
sources,
|
|
716
|
-
projection: projections[index],
|
|
717
|
-
subjectMapping,
|
|
718
|
-
...(loadedProject.document.value.kindMapping === undefined
|
|
719
|
-
? {}
|
|
720
|
-
: {
|
|
721
|
-
kindMapping: kindMapping,
|
|
722
|
-
}),
|
|
723
|
-
...(view.compare === undefined
|
|
724
|
-
? {}
|
|
725
|
-
: { comparison: view.compare }),
|
|
726
|
-
vocabulary: 'bundled',
|
|
727
|
-
requireMappedRelationships: command === 'check',
|
|
728
|
-
}),
|
|
729
|
-
}));
|
|
730
|
-
const failed = preparedViews.find(({ prepared }) => !prepared.ok);
|
|
731
|
-
if (failed !== undefined && !failed.prepared.ok) {
|
|
732
|
-
return {
|
|
733
|
-
exitCode: 1,
|
|
734
|
-
stdout: diagnosticOutput(failed.prepared.diagnostics),
|
|
735
|
-
stderr: '',
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
const successfulViews = preparedViews.flatMap(({ view, prepared }) => prepared.ok
|
|
739
|
-
? [
|
|
740
|
-
{
|
|
741
|
-
...(view.id === undefined ? {} : { id: view.id }),
|
|
742
|
-
...(view.folder === undefined
|
|
743
|
-
? {}
|
|
744
|
-
: { folder: view.folder }),
|
|
745
|
-
prepared,
|
|
746
|
-
...(view.compare === undefined
|
|
747
|
-
? {}
|
|
748
|
-
: { comparison: view.compare }),
|
|
749
|
-
...(view.dynamic === undefined
|
|
750
|
-
? {}
|
|
751
|
-
: { dynamic: view.dynamic }),
|
|
752
|
-
...(view.deployment === undefined
|
|
753
|
-
? {}
|
|
754
|
-
: { deployment: view.deployment }),
|
|
755
|
-
},
|
|
756
|
-
]
|
|
757
|
-
: []);
|
|
758
|
-
const renderedViewIds = new Set();
|
|
759
|
-
const deploymentIdentities = new Set();
|
|
760
|
-
for (const [index, view] of successfulViews.entries()) {
|
|
761
|
-
const deployment = view.deployment;
|
|
762
|
-
if (deployment !== undefined) {
|
|
763
|
-
const nodeIds = new Set();
|
|
764
|
-
for (const [nodeIndex, node] of deployment.nodes.entries()) {
|
|
765
|
-
const problem = nodeIds.has(node.id)
|
|
766
|
-
? `Deployment node "${node.id}" is duplicated`
|
|
767
|
-
: deploymentIdentities.has(node.id)
|
|
768
|
-
? `Deployment identity "${node.id}" is duplicated`
|
|
769
|
-
: node.parent === node.id
|
|
770
|
-
? `Deployment node "${node.id}" cannot parent itself`
|
|
771
|
-
: undefined;
|
|
772
|
-
if (problem !== undefined) {
|
|
773
|
-
const field = nodeIds.has(node.id) || deploymentIdentities.has(node.id)
|
|
774
|
-
? 'id'
|
|
775
|
-
: 'parent';
|
|
776
|
-
const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/${field}`;
|
|
777
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, ['views', index, 'deployment', 'nodes', nodeIndex, field], pointer);
|
|
778
|
-
return {
|
|
779
|
-
exitCode: 1,
|
|
780
|
-
stdout: diagnosticOutput([{
|
|
781
|
-
severity: 'error',
|
|
782
|
-
code: 'YMLC109',
|
|
783
|
-
message: problem,
|
|
784
|
-
...location,
|
|
785
|
-
}]),
|
|
786
|
-
stderr: '',
|
|
787
|
-
};
|
|
788
|
-
}
|
|
789
|
-
nodeIds.add(node.id);
|
|
790
|
-
deploymentIdentities.add(node.id);
|
|
791
|
-
}
|
|
792
|
-
for (const [nodeIndex, node] of deployment.nodes.entries()) {
|
|
793
|
-
if (node.parent !== undefined &&
|
|
794
|
-
!nodeIds.has(node.parent)) {
|
|
795
|
-
const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/parent`;
|
|
796
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
|
|
797
|
-
'views',
|
|
798
|
-
index,
|
|
799
|
-
'deployment',
|
|
800
|
-
'nodes',
|
|
801
|
-
nodeIndex,
|
|
802
|
-
'parent',
|
|
803
|
-
], pointer);
|
|
804
|
-
return {
|
|
805
|
-
exitCode: 1,
|
|
806
|
-
stdout: diagnosticOutput([{
|
|
807
|
-
severity: 'error',
|
|
808
|
-
code: 'YMLC109',
|
|
809
|
-
message: `Deployment parent "${node.parent}" does not exist`,
|
|
810
|
-
...location,
|
|
811
|
-
}]),
|
|
812
|
-
stderr: '',
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
const nodeById = new Map(deployment.nodes.map((candidate) => [
|
|
816
|
-
candidate.id,
|
|
817
|
-
candidate,
|
|
818
|
-
]));
|
|
819
|
-
const ancestors = new Set([node.id]);
|
|
820
|
-
let parent = node.parent;
|
|
821
|
-
while (parent !== undefined) {
|
|
822
|
-
if (ancestors.has(parent)) {
|
|
823
|
-
const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/parent`;
|
|
824
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
|
|
825
|
-
'views',
|
|
826
|
-
index,
|
|
827
|
-
'deployment',
|
|
828
|
-
'nodes',
|
|
829
|
-
nodeIndex,
|
|
830
|
-
'parent',
|
|
831
|
-
], pointer);
|
|
832
|
-
return {
|
|
833
|
-
exitCode: 1,
|
|
834
|
-
stdout: diagnosticOutput([{
|
|
835
|
-
severity: 'error',
|
|
836
|
-
code: 'YMLC109',
|
|
837
|
-
message: `Deployment node "${node.id}" participates in a parent cycle`,
|
|
838
|
-
...location,
|
|
839
|
-
}]),
|
|
840
|
-
stderr: '',
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
ancestors.add(parent);
|
|
844
|
-
parent = nodeById.get(parent)?.parent;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
const instanceIds = new Set();
|
|
848
|
-
for (const [instanceIndex, instance] of (deployment.instances).entries()) {
|
|
849
|
-
const projected = view.prepared.projection.subjects.find(({ id }) => id === instance.subject);
|
|
850
|
-
const problem = instanceIds.has(instance.id)
|
|
851
|
-
? `Deployment instance "${instance.id}" is duplicated`
|
|
852
|
-
: deploymentIdentities.has(instance.id)
|
|
853
|
-
? `Deployment identity "${instance.id}" is duplicated`
|
|
854
|
-
: !nodeIds.has(instance.node)
|
|
855
|
-
? `Deployment instance node "${instance.node}" does not exist`
|
|
856
|
-
: projected?.type !== 'concept'
|
|
857
|
-
? `Deployment instance subject "${instance.subject}" is not selected as a concept by its projection`
|
|
858
|
-
: undefined;
|
|
859
|
-
if (problem !== undefined) {
|
|
860
|
-
const field = instanceIds.has(instance.id) ||
|
|
861
|
-
deploymentIdentities.has(instance.id)
|
|
862
|
-
? 'id'
|
|
863
|
-
: !nodeIds.has(instance.node)
|
|
864
|
-
? 'node'
|
|
865
|
-
: 'subject';
|
|
866
|
-
const pointer = `/views/${index}/deployment/instances/${instanceIndex}/${field}`;
|
|
867
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
|
|
868
|
-
'views',
|
|
869
|
-
index,
|
|
870
|
-
'deployment',
|
|
871
|
-
'instances',
|
|
872
|
-
instanceIndex,
|
|
873
|
-
field,
|
|
874
|
-
], pointer);
|
|
875
|
-
return {
|
|
876
|
-
exitCode: 1,
|
|
877
|
-
stdout: diagnosticOutput([{
|
|
878
|
-
severity: 'error',
|
|
879
|
-
code: 'YMLC109',
|
|
880
|
-
message: problem,
|
|
881
|
-
...location,
|
|
882
|
-
}]),
|
|
883
|
-
stderr: '',
|
|
884
|
-
};
|
|
885
|
-
}
|
|
886
|
-
instanceIds.add(instance.id);
|
|
887
|
-
deploymentIdentities.add(instance.id);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
for (const [stepIndex, step] of (view.dynamic?.steps ?? []).entries()) {
|
|
891
|
-
const projected = view.prepared.projection.subjects.find(({ id }) => id === step.relationship);
|
|
892
|
-
if (projected?.type !== 'relationship') {
|
|
893
|
-
const pointer = `/views/${index}/dynamic/steps/${stepIndex}/relationship`;
|
|
894
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
|
|
895
|
-
'views',
|
|
896
|
-
index,
|
|
897
|
-
'dynamic',
|
|
898
|
-
'steps',
|
|
899
|
-
stepIndex,
|
|
900
|
-
'relationship',
|
|
901
|
-
], pointer);
|
|
902
|
-
return {
|
|
903
|
-
exitCode: 1,
|
|
904
|
-
stdout: diagnosticOutput([
|
|
905
|
-
{
|
|
906
|
-
severity: 'error',
|
|
907
|
-
code: 'YMLC108',
|
|
908
|
-
message: `Dynamic step relationship "${step.relationship}" is not selected as a relationship by its projection`,
|
|
909
|
-
...location,
|
|
910
|
-
},
|
|
911
|
-
]),
|
|
912
|
-
stderr: '',
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
const renderedId = view.id ?? view.prepared.projection.projection.split('@')[0];
|
|
917
|
-
if (renderedViewIds.has(renderedId)) {
|
|
918
|
-
const field = view.id === undefined ? 'projection' : 'id';
|
|
919
|
-
const pointer = `/views/${index}/${field}`;
|
|
920
|
-
const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, ['views', index, field], pointer);
|
|
921
|
-
return {
|
|
922
|
-
exitCode: 1,
|
|
923
|
-
stdout: diagnosticOutput([
|
|
924
|
-
{
|
|
925
|
-
severity: 'error',
|
|
926
|
-
code: 'YMLC107',
|
|
927
|
-
message: `LikeC4 view identity "${renderedId}" is duplicated`,
|
|
928
|
-
...location,
|
|
929
|
-
},
|
|
930
|
-
]),
|
|
931
|
-
stderr: '',
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
renderedViewIds.add(renderedId);
|
|
935
|
-
}
|
|
653
|
+
// The git-derived review overlay is the CLI's own: it needs a
|
|
654
|
+
// repository. Everything after it runs the same pure pipeline the
|
|
655
|
+
// path-free entry runs (ADR 0156).
|
|
936
656
|
let gitChange;
|
|
937
657
|
if (changedRange !== undefined) {
|
|
938
658
|
const modelDocuments = sources.flatMap((candidate) => {
|
|
@@ -958,7 +678,23 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
|
|
|
958
678
|
modified: all.filter((id) => !derived.changed.added.includes(id)),
|
|
959
679
|
};
|
|
960
680
|
}
|
|
961
|
-
const exported =
|
|
681
|
+
const exported = exportLikeC4ProjectFromSources({
|
|
682
|
+
project: projectSource,
|
|
683
|
+
sources,
|
|
684
|
+
readReference: (path) => {
|
|
685
|
+
try {
|
|
686
|
+
return {
|
|
687
|
+
path,
|
|
688
|
+
source: readFileSync(resolve(projectDirectory, path), 'utf8'),
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
catch {
|
|
692
|
+
return undefined;
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
requireMappedRelationships: command === 'check',
|
|
696
|
+
...(gitChange === undefined ? {} : { gitChange }),
|
|
697
|
+
});
|
|
962
698
|
if (!exported.ok) {
|
|
963
699
|
return {
|
|
964
700
|
exitCode: 1,
|
|
@@ -967,51 +703,26 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
|
|
|
967
703
|
};
|
|
968
704
|
}
|
|
969
705
|
if (command === 'check') {
|
|
970
|
-
const identity = `${loadedProject.document.value.id}@${loadedProject.document.value.version}`;
|
|
971
706
|
return {
|
|
972
707
|
exitCode: 0,
|
|
973
708
|
stdout: json
|
|
974
709
|
? checkJson(true, [])
|
|
975
|
-
: `Checked LikeC4 project ${
|
|
710
|
+
: `Checked LikeC4 project ${exported.projectIdentity}: no errors\n`,
|
|
976
711
|
stderr: '',
|
|
977
712
|
};
|
|
978
713
|
}
|
|
979
|
-
const
|
|
980
|
-
const mappingIdentity = `${first.prepared.subjectMapping.id}@${first.prepared.subjectMapping.version}`;
|
|
981
|
-
const kindMappingIdentity = first.prepared.kindMapping === undefined
|
|
982
|
-
? undefined
|
|
983
|
-
: `${first.prepared.kindMapping.id}@${first.prepared.kindMapping.version}`;
|
|
984
|
-
const projectIdentity = `${loadedProject.document.value.id}@${loadedProject.document.value.version}`;
|
|
985
|
-
const inputDigests = inputDigestsOf([
|
|
986
|
-
projectSource,
|
|
987
|
-
...sources,
|
|
988
|
-
...referencedSources.values(),
|
|
989
|
-
]);
|
|
714
|
+
const inputDigests = inputDigestsOf(exported.inputs);
|
|
990
715
|
if (checkFreshness) {
|
|
991
716
|
return checkGeneratedProject(cwd, outputDirectory, {
|
|
992
|
-
modelSource: exported.
|
|
717
|
+
modelSource: exported.modelSource,
|
|
993
718
|
inputDigests,
|
|
994
719
|
});
|
|
995
720
|
}
|
|
996
721
|
return publishGeneratedProject(cwd, outputDirectory, {
|
|
997
|
-
projectName:
|
|
998
|
-
title:
|
|
999
|
-
modelSource: exported.
|
|
1000
|
-
ownership: {
|
|
1001
|
-
format: 'yarramate/likec4-generated-project/v2',
|
|
1002
|
-
project: projectIdentity,
|
|
1003
|
-
mapping: mappingIdentity,
|
|
1004
|
-
...(kindMappingIdentity === undefined
|
|
1005
|
-
? {}
|
|
1006
|
-
: { kindMapping: kindMappingIdentity }),
|
|
1007
|
-
views: successfulViews.map(({ id, prepared, comparison }) => ({
|
|
1008
|
-
...(id === undefined ? {} : { id }),
|
|
1009
|
-
projection: prepared.projection.projection,
|
|
1010
|
-
...(comparison === undefined
|
|
1011
|
-
? {}
|
|
1012
|
-
: { comparison }),
|
|
1013
|
-
})),
|
|
1014
|
-
},
|
|
722
|
+
projectName: projectNameOf(exported.projectIdentity),
|
|
723
|
+
title: exported.project.title,
|
|
724
|
+
modelSource: exported.modelSource,
|
|
725
|
+
ownership: { ...ownershipOf(exported) },
|
|
1015
726
|
inputDigests,
|
|
1016
727
|
});
|
|
1017
728
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { WorkspaceSource } from '../compiler.js';
|
|
2
|
+
import { type LikeC4PreparationDiagnostic } from './likec4-prepare.js';
|
|
3
|
+
import type { GitChangeOverlay } from './likec4-export.js';
|
|
4
|
+
import { type LikeC4ProjectDefinition, type PreparedLikeC4ProjectView } from './likec4-project.js';
|
|
5
|
+
/**
|
|
6
|
+
* A LikeC4 project definition to a generated project, with no filesystem
|
|
7
|
+
* (ADR 0156). `yarramate-likec4 export-project` reads the definition and
|
|
8
|
+
* the files it names from disk, runs this, and writes what comes back;
|
|
9
|
+
* `yarramate/tools` reads them from a store and hands the files to whoever
|
|
10
|
+
* asked. The checks between preparation and export (deployment nodes,
|
|
11
|
+
* dynamic steps, duplicate view identities) live here so both callers
|
|
12
|
+
* refuse the same definitions with the same diagnostics.
|
|
13
|
+
*/
|
|
14
|
+
export interface LikeC4ProjectExportInput {
|
|
15
|
+
/** The `yarramate/likec4-project/v1` document. */
|
|
16
|
+
readonly project: WorkspaceSource;
|
|
17
|
+
/** The workspace's compiler sources: profiles, patterns, documents. */
|
|
18
|
+
readonly sources: readonly WorkspaceSource[];
|
|
19
|
+
/**
|
|
20
|
+
* The mapping, kind mapping and projections the definition names, by the
|
|
21
|
+
* path written in the definition (relative to its directory). `undefined`
|
|
22
|
+
* for one the caller cannot find is reported as YMLC110.
|
|
23
|
+
*/
|
|
24
|
+
readonly readReference: (path: string) => WorkspaceSource | undefined;
|
|
25
|
+
/** `check` refuses relationships the mapping does not cover; `export` does not. */
|
|
26
|
+
readonly requireMappedRelationships: boolean;
|
|
27
|
+
/** The git-derived review overlay, when the CLI derived one. */
|
|
28
|
+
readonly gitChange?: GitChangeOverlay;
|
|
29
|
+
}
|
|
30
|
+
export interface LikeC4ProjectExported {
|
|
31
|
+
readonly ok: true;
|
|
32
|
+
readonly project: LikeC4ProjectDefinition;
|
|
33
|
+
readonly views: readonly PreparedLikeC4ProjectView[];
|
|
34
|
+
/** The `model.likec4` text. */
|
|
35
|
+
readonly modelSource: string;
|
|
36
|
+
readonly projectIdentity: string;
|
|
37
|
+
readonly mappingIdentity: string;
|
|
38
|
+
readonly kindMappingIdentity?: string;
|
|
39
|
+
/** Every source that fed the export, for the marker's input digests. */
|
|
40
|
+
readonly inputs: readonly WorkspaceSource[];
|
|
41
|
+
}
|
|
42
|
+
export type LikeC4ProjectExportResult = LikeC4ProjectExported | {
|
|
43
|
+
readonly ok: false;
|
|
44
|
+
readonly diagnostics: readonly LikeC4PreparationDiagnostic[];
|
|
45
|
+
};
|
|
46
|
+
export declare const exportLikeC4ProjectFromSources: (input: LikeC4ProjectExportInput) => LikeC4ProjectExportResult;
|
|
47
|
+
export declare const GENERATED_FILE_NAMES: readonly ['likec4.config.json', 'model.likec4', 'specification.likec4'];
|
|
48
|
+
/** The ownership marker's fields, minus the digests this module computes. */
|
|
49
|
+
export interface GeneratedProjectOwnership {
|
|
50
|
+
readonly format: 'yarramate/likec4-generated-project/v2';
|
|
51
|
+
readonly project: string;
|
|
52
|
+
readonly mapping: string;
|
|
53
|
+
readonly kindMapping?: string;
|
|
54
|
+
readonly views: readonly {
|
|
55
|
+
readonly id?: string;
|
|
56
|
+
readonly projection: string;
|
|
57
|
+
readonly comparison?: {
|
|
58
|
+
readonly from: string;
|
|
59
|
+
readonly to: string;
|
|
60
|
+
};
|
|
61
|
+
}[];
|
|
62
|
+
}
|
|
63
|
+
export declare const ownershipOf: (exported: LikeC4ProjectExported) => GeneratedProjectOwnership;
|
|
64
|
+
export declare const inputDigestsOf: (inputs: readonly WorkspaceSource[]) => Readonly<Record<string, string>>;
|
|
65
|
+
export declare const projectNameOf: (projectIdentity: string) => string;
|
|
66
|
+
/**
|
|
67
|
+
* The four files a generated project holds, exactly as the CLI writes them
|
|
68
|
+
* under its output directory: the config, the model, the specification the
|
|
69
|
+
* package ships, and the `yarramate.generated.json` marker with every
|
|
70
|
+
* digest the freshness check reads back.
|
|
71
|
+
*/
|
|
72
|
+
export declare const generatedProjectFiles: (exported: LikeC4ProjectExported) => readonly WorkspaceSource[];
|
|
73
|
+
/** Whether a source is a project definition rather than a projection. */
|
|
74
|
+
export declare const isLikeC4ProjectDefinition: (source: string) => boolean;
|