@likec4/core 1.34.1 → 1.35.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.
Files changed (56) hide show
  1. package/dist/builder/index.d.mts +2 -2
  2. package/dist/builder/index.mjs +11 -10
  3. package/dist/compute-view/index.d.mts +2 -2
  4. package/dist/compute-view/index.mjs +12 -11
  5. package/dist/compute-view/relationships-view/index.d.mts +2 -2
  6. package/dist/compute-view/relationships-view/index.mjs +2 -2
  7. package/dist/index.d.mts +2 -2
  8. package/dist/index.mjs +9 -8
  9. package/dist/model/connection/deployment/index.d.mts +4 -4
  10. package/dist/model/connection/deployment/index.mjs +3 -3
  11. package/dist/model/connection/index.d.mts +5 -5
  12. package/dist/model/connection/index.mjs +4 -4
  13. package/dist/model/connection/model/index.d.mts +4 -4
  14. package/dist/model/connection/model/index.mjs +3 -3
  15. package/dist/model/index.d.mts +31 -7
  16. package/dist/model/index.mjs +9 -9
  17. package/dist/shared/{core.D3xEWj5B.d.mts → core.72IoI17N.d.mts} +1 -1
  18. package/dist/shared/{core.DXRAwwDB.mjs → core.B1ZN723l.mjs} +1 -1
  19. package/dist/shared/core.BpJu1RrF.mjs +5 -0
  20. package/dist/shared/{core.C80Z37Eu.mjs → core.C1GV0WWV.mjs} +1 -1
  21. package/dist/shared/{core.D5qVzkws.mjs → core.CQS11dNK.mjs} +2 -2
  22. package/dist/shared/{core.C_C-3c1S.mjs → core.DQj9iv_y.mjs} +3 -5
  23. package/dist/shared/{core.IWLie-Ma.d.mts → core.Ddua-wiI.d.mts} +3 -0
  24. package/dist/shared/{core.CJSFKrYf.d.mts → core.DhTO8rgm.d.mts} +2 -2
  25. package/dist/shared/{core.CtKXPqN_.mjs → core.HUONfQfd.mjs} +1 -1
  26. package/dist/shared/{core.Di7__sMg.d.mts → core.NBNeVyag.d.mts} +2 -2
  27. package/dist/shared/{core.PqNe5WxQ.mjs → core.RnUJywKk.mjs} +94 -92
  28. package/dist/shared/{core.DrS4Bf4y.d.mts → core.SciGxb--.d.mts} +183 -8
  29. package/dist/shared/{core.BTnf14gD.mjs → core.Y3j3s-oq.mjs} +2 -2
  30. package/dist/shared/{core.XptQjhMA.mjs → core.b2BzqGz0.mjs} +2 -2
  31. package/dist/shared/{core.4SpVCM9m.mjs → core.rpF8esVq.mjs} +354 -28
  32. package/dist/shared/{core.BMCb0wJI.mjs → core.yaRvRnMW.mjs} +1 -1
  33. package/dist/theme/index.mjs +33 -3
  34. package/dist/types/index.d.mts +2 -2
  35. package/dist/types/index.mjs +2 -2
  36. package/dist/utils/index.d.mts +6 -8
  37. package/dist/utils/index.mjs +5 -5
  38. package/dist/utils/iterable/index.d.mts +18 -1
  39. package/dist/utils/iterable/index.mjs +22 -2
  40. package/package.json +6 -5
  41. package/src/compute-view/element-view/predicates/relation-direct.ts +8 -2
  42. package/src/model/DeploymentModel.ts +1 -1
  43. package/src/model/LikeC4Model.ts +146 -7
  44. package/src/model/index.ts +8 -0
  45. package/src/model/types.ts +1 -8
  46. package/src/model/utils.ts +66 -0
  47. package/src/model/view/LikeC4ViewModel.ts +62 -7
  48. package/src/model/view/LikeC4ViewsFolder.ts +151 -0
  49. package/src/theme/__test__/theme-index.ts +29 -0
  50. package/src/theme/index.ts +49 -3
  51. package/src/types/model-spec.ts +4 -0
  52. package/src/utils/compare-natural.ts +14 -12
  53. package/src/utils/index.ts +1 -0
  54. package/src/utils/iterable/first.ts +48 -0
  55. package/src/utils/iterable/index.ts +1 -0
  56. package/dist/shared/{core.Br7Fab9l.mjs → core.BajmN8zR.mjs} +6 -6
@@ -1,9 +1,9 @@
1
- import { A as Any, R as RelationKind, T as Tags, h as Metadata, j as MetadataKey, L as LooseTag, F as Fqn, g as ElementId, k as ElementKind, D as DeploymentKind, E as ExtractOnStage, l as RelationId$1, f as _type, m as StrictViewId, n as LooseElementId, o as LooseDeploymentId, p as DeploymentFqn, t as toComputed, q as toLayouted, r as Stage, s as DeploymentId, U as Unknown, V as ViewId, u as Tag, v as toParsed, P as ProjectId$1, w as LooseViewId, a as Aux, S as SpecAux, d as UnknownParsed, b as UnknownComputed, c as UnknownLayouted } from './core.DAj3LuFH.mjs';
1
+ import { A as Any, R as RelationKind, T as Tags, h as Metadata, j as MetadataKey, L as LooseTag, F as Fqn, g as ElementId, k as ElementKind, D as DeploymentKind, E as ExtractOnStage, l as RelationId$1, m as StrictViewId, f as _type, n as LooseElementId, o as LooseDeploymentId, p as DeploymentFqn, t as toComputed, q as toLayouted, r as Stage, s as DeploymentId, U as Unknown, V as ViewId, u as Tag, v as toParsed, P as ProjectId$1, w as LooseViewId, a as Aux, S as SpecAux, d as UnknownParsed, b as UnknownComputed, c as UnknownLayouted } from './core.DAj3LuFH.mjs';
2
2
  import { D as DefaultMap } from './core.CywrQs86.mjs';
3
3
  import { SetRequired } from 'type-fest';
4
4
  import { d as RelationId, P as ProjectId, a as IconUrl, N as NodeId, G as GroupElementKind, j as EdgeId, k as StepEdgeId, V as ViewId$1 } from './core.668kXpZq.mjs';
5
- import { b as RichTextOrEmpty, Y as Relationship, Q as Element, O as ElementStyle, as as ViewWithType, ao as ComputedView, am as LayoutedView, n as ParsedLikeC4ModelData, C as ComputedLikeC4ModelData, L as LayoutedLikeC4ModelData, f as FqnRef, q as DeployedInstance, D as DeploymentElementStyle, v as DeploymentRelationship, r as DeploymentElement, p as DeploymentNode, y as LikeC4ModelDump, z as AuxFromDump, a2 as Specification, m as ModelGlobals, ah as WhereOperator } from './core.IWLie-Ma.mjs';
6
- import { I as IteratorLike, L as Link } from './core.DuSLYTG6.mjs';
5
+ import { b as RichTextOrEmpty, Y as Relationship, Q as Element, O as ElementStyle, as as ViewWithType, ao as ComputedView, am as LayoutedView, n as ParsedLikeC4ModelData, C as ComputedLikeC4ModelData, L as LayoutedLikeC4ModelData, f as FqnRef, q as DeployedInstance, D as DeploymentElementStyle, v as DeploymentRelationship, r as DeploymentElement, p as DeploymentNode, y as LikeC4ModelDump, z as AuxFromDump, a2 as Specification, m as ModelGlobals, ah as WhereOperator } from './core.Ddua-wiI.mjs';
6
+ import { I as IteratorLike, L as Link, N as NonEmptyArray } from './core.DuSLYTG6.mjs';
7
7
  import { i as Color, R as RelationshipLineType, c as ElementShape } from './core.CzdwsPmY.mjs';
8
8
 
9
9
  type RelationshipsIterator<A extends Any> = IteratorLike<RelationshipModel<A>>;
@@ -268,6 +268,80 @@ declare namespace EdgeModel {
268
268
  }
269
269
  }
270
270
 
271
+ declare class LikeC4ViewsFolder<A extends Any = Any> {
272
+ readonly $model: LikeC4Model<A>;
273
+ /**
274
+ * Path to this view folder, processed by {@link normalizeViewPath}
275
+ *
276
+ * @example
277
+ * "Folder 1/Folder 2/Folder 3"
278
+ */
279
+ readonly path: string;
280
+ /**
281
+ * Title of this view folder.
282
+ *
283
+ * @example
284
+ * // title is the last segment of the path
285
+ * path = "Folder 1/Folder 2/Folder 3"
286
+ * title = "Folder 3"
287
+ */
288
+ readonly title: string;
289
+ /**
290
+ * Whether this is the root view folder.
291
+ *
292
+ * !NOTE
293
+ * Root folder is special folder with an empty path and used only for internal purposes. \
294
+ * It is not visible to the user and should not be used in the code.
295
+ */
296
+ readonly isRoot: boolean;
297
+ protected readonly parentPath: string | undefined;
298
+ protected readonly defaultViewId: StrictViewId<A> | undefined;
299
+ constructor($model: LikeC4Model<A>, path: NonEmptyArray<string>, defaultViewId: StrictViewId<A> | undefined);
300
+ /**
301
+ * Default view of this view folder.\
302
+ * It is for the case when there is a view at the same path as this folder.\
303
+ * (if there are multiple views at the same path, the first one is chosen)
304
+ *
305
+ * @example
306
+ * ```
307
+ * // Assume the following views exist:
308
+ * const views = [
309
+ * "Folder 1/ Folder 2 / View",
310
+ * "Folder 1/ Folder 2 / View / Subview",
311
+ * ]
312
+ * ```
313
+ * Group with path `Folder 1/ Folder 2 / View`\
314
+ * will have default view `Folder 1/ Folder 2 / View`
315
+ */
316
+ get defaultView(): LikeC4ViewModel<A> | null;
317
+ /**
318
+ * Returns path to this view folder as an array of ancestors (excluding root) and this view folder as the last element
319
+ *
320
+ * @throws Error if this is the root folder.
321
+ */
322
+ get breadcrumbs(): [...LikeC4ViewsFolder<A>[], this];
323
+ /**
324
+ * Returns parent folder
325
+ *
326
+ * @throws Error if this is the root folder.
327
+ */
328
+ get parent(): LikeC4ViewsFolder<A> | null;
329
+ /**
330
+ * Returns sorted set of children
331
+ * - First folders
332
+ * - Then views
333
+ */
334
+ get children(): ReadonlySet<LikeC4ViewsFolder<A> | LikeC4ViewModel<A>>;
335
+ /**
336
+ * Returns sorted array of children folders
337
+ */
338
+ get folders(): ReadonlyArray<LikeC4ViewsFolder<A>>;
339
+ /**
340
+ * Returns all views in this view folder.
341
+ */
342
+ get views(): ReadonlyArray<LikeC4ViewModel<A>>;
343
+ }
344
+
271
345
  type ViewsIterator<A extends Any, V extends $View<A> = $View<A>> = IteratorLike<LikeC4ViewModel<A, V>>;
272
346
  declare class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>> implements WithTags<A> {
273
347
  #private;
@@ -277,10 +351,44 @@ declare class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>
277
351
  readonly Aux: A;
278
352
  readonly $view: V;
279
353
  readonly $model: LikeC4Model<A>;
280
- constructor(model: LikeC4Model<A>, view: V);
354
+ readonly title: string | null;
355
+ /**
356
+ * View folder this view belongs to.
357
+ * If view is top-level, this is the root folder.
358
+ */
359
+ readonly folder: LikeC4ViewsFolder<A>;
360
+ /**
361
+ * Path to this view, processed by {@link normalizeViewPath}
362
+ *
363
+ * @example
364
+ * "Group 1/Group 2/View"
365
+ */
366
+ readonly viewPath: string;
367
+ constructor(model: LikeC4Model<A>, view: V, folder: LikeC4ViewsFolder<A>);
281
368
  get _type(): V[_type];
282
369
  get id(): StrictViewId<A>;
283
- get title(): string | null;
370
+ /**
371
+ * Returns title if defined, otherwise returns its {@link id}
372
+ */
373
+ get titleOrId(): string;
374
+ /**
375
+ * Returns title if defined, otherwise returns `Untitled`.
376
+ */
377
+ get titleOrUntitled(): string;
378
+ /**
379
+ * Returns path to this view as an array of groups and this view as the last element
380
+ * If view is top-level, returns only this view.
381
+ *
382
+ * @example
383
+ * viewPath = "Group 1/Group 2/View"
384
+ *
385
+ * breadcrumbs = [
386
+ * "Group 1", // folder
387
+ * "Group 1/Group 2", // folder
388
+ * "Group 1/Group 2/View" // view
389
+ * ]
390
+ */
391
+ get breadcrumbs(): [...LikeC4ViewsFolder<A>[], this];
284
392
  get description(): RichTextOrEmpty;
285
393
  get tags(): Tags<A>;
286
394
  get links(): ReadonlyArray<Link>;
@@ -715,7 +823,10 @@ declare class LikeC4Model<A extends Any = Unknown> {
715
823
  protected readonly _outgoing: DefaultMap<Fqn<A>, Set<RelationshipModel<A>>>;
716
824
  protected readonly _internal: DefaultMap<Fqn<A>, Set<RelationshipModel<A>>>;
717
825
  protected readonly _views: Map<ViewId<A>, LikeC4ViewModel<A, $View<A>>>;
718
- protected readonly _allTags: DefaultMap<Tag<A>, Set<ElementModel<A> | LikeC4ViewModel<A, $View<A>> | RelationshipModel<A>>>;
826
+ protected readonly _rootViewFolder: LikeC4ViewsFolder<A>;
827
+ protected readonly _viewFolders: Map<string, LikeC4ViewsFolder<A>>;
828
+ protected readonly _viewFolderItems: DefaultMap<string, Set<LikeC4ViewModel<A, $View<A>> | LikeC4ViewsFolder<A>>>;
829
+ protected readonly _allTags: DefaultMap<Tag<A>, Set<LikeC4ViewModel<A, $View<A>> | ElementModel<A> | RelationshipModel<A>>>;
719
830
  static fromParsed<T extends Any>(model: ParsedLikeC4ModelData<T>): LikeC4Model.Parsed<T>;
720
831
  /**
721
832
  * Creates a new LikeC4Model instance from the provided model data.
@@ -777,7 +888,31 @@ declare class LikeC4Model<A extends Any = Unknown> {
777
888
  get projectId(): ProjectId$1<A>;
778
889
  get specification(): Specification<A>;
779
890
  get globals(): ModelGlobals;
891
+ /**
892
+ * Returns the element with the given FQN.
893
+ *
894
+ * @throws Error if element is not found\
895
+ * Use {@link findElement} if you don't want to throw an error
896
+ *
897
+ * @note Method is type-safe for typed model
898
+
899
+ * @example
900
+ * model.element('cloud.frontend')
901
+ * // or object with id property of scalar.Fqn
902
+ * model.element({
903
+ * id: 'dashboard',
904
+ * })
905
+ */
780
906
  element(el: ElementOrFqn<A>): ElementModel<A>;
907
+ /**
908
+ * Returns the element with the given FQN.
909
+ *
910
+ * @returns Element if found, null otherwise
911
+ * @note Method is not type-safe as {@link element}
912
+ *
913
+ * @example
914
+ * model.findElement('cloud.frontend')
915
+ */
781
916
  findElement(el: LooseElementId<A>): ElementModel<A> | null;
782
917
  /**
783
918
  * Returns the root elements of the model.
@@ -808,11 +943,50 @@ declare class LikeC4Model<A extends Any = Unknown> {
808
943
  views(): IteratorLike<LikeC4ViewModel<A, $View<A>>>;
809
944
  /**
810
945
  * Returns a specific view by its ID.
946
+ * @note Method is type-safe for typed model
947
+ * @throws Error if view is not found\
948
+ * Use {@link findView} if you don't want to throw an error
949
+ *
950
+ * @example
951
+ * model.view('index')
952
+ * // or object with id property of scalar.ViewId
953
+ * model.view({
954
+ * id: 'index',
955
+ * })
811
956
  */
812
957
  view(viewId: ViewId<A> | {
813
958
  id: ViewId$1<ViewId<A>>;
814
959
  }): LikeC4ViewModel<A, $View<A>>;
960
+ /**
961
+ * Returns a specific view by its ID.
962
+ * @note Method is not type-safe as {@link view}
963
+ *
964
+ * @example
965
+ * model.findView('index')
966
+ */
815
967
  findView(viewId: LooseViewId<A>): LikeC4ViewModel<A, $View<A>> | null;
968
+ /**
969
+ * Returns a view folder by its path.
970
+ * Path is extracted from the view title, e.g. "Group 1/Group 2/View" -> "Group 1/Group 2"
971
+ * @throws Error if view folder is not found.
972
+ */
973
+ viewFolder(path: string): LikeC4ViewsFolder<A>;
974
+ /**
975
+ * Root folder is a special one with an empty path and used only for internal purposes.
976
+ * It is not visible to the user and should be used only to get top-level folders and views.
977
+ */
978
+ get rootViewFolder(): LikeC4ViewsFolder<A>;
979
+ /**
980
+ * Whether the model has any view folders.
981
+ */
982
+ get hasViewFolders(): boolean;
983
+ /**
984
+ * Returns all children of a view folder.
985
+ * Path is extracted from the view title, e.g. "Group 1/Group 2/View" -> "Group 1/Group 2"
986
+ *
987
+ * @throws Error if view folder is not found.
988
+ */
989
+ viewFolderItems(path: string): ReadonlySet<LikeC4ViewsFolder<A> | LikeC4ViewModel<A>>;
816
990
  /**
817
991
  * Returns the parent element of given element.
818
992
  * @see ancestors
@@ -847,7 +1021,8 @@ declare class LikeC4Model<A extends Any = Unknown> {
847
1021
  */
848
1022
  outgoing(element: ElementOrFqn<A>, filter?: OutgoingFilter): RelationshipsIterator<A>;
849
1023
  /**
850
- * Returns all tags used in the model, sorted alphabetically.
1024
+ * Returns array of all tags used in the model, sorted naturally.\
1025
+ * Use {@link specification.tags} to get all defined tags
851
1026
  */
852
1027
  get tags(): Tags<A>;
853
1028
  /**
@@ -925,4 +1100,4 @@ declare namespace LikeC4Model {
925
1100
  type AnyRelation<M = Unknown> = M extends Any ? RelationshipModel<M> | DeploymentRelationModel<M> : never;
926
1101
  }
927
1102
 
928
- export { type AnyRelationshipModel as A, DeploymentNodeModel as D, ElementModel as E, type IncomingFilter as I, LikeC4ViewModel as L, NestedElementOfDeployedInstanceModel as N, type OutgoingFilter as O, RelationshipModel as R, type WithMetadata as W, DeployedInstanceModel as a, DeploymentRelationModel as b, NodeModel as c, EdgeModel as d, type DeploymentElementModel as e, type AnyLikeC4Model as f, LikeC4Model as g, type DeploymentRelationEndpoint as h, RelationshipsAccum as i, LikeC4DeploymentModel as j, type DeploymentOrFqn as k, type EdgeOrId as l, type ElementOrFqn as m, type NodeOrId as n, type WithTags as o };
1103
+ export { type AnyRelationshipModel as A, DeploymentNodeModel as D, ElementModel as E, type IncomingFilter as I, LikeC4ViewModel as L, NestedElementOfDeployedInstanceModel as N, type OutgoingFilter as O, RelationshipModel as R, type WithMetadata as W, DeployedInstanceModel as a, DeploymentRelationModel as b, NodeModel as c, EdgeModel as d, type DeploymentElementModel as e, type AnyLikeC4Model as f, LikeC4Model as g, type DeploymentRelationEndpoint as h, RelationshipsAccum as i, LikeC4DeploymentModel as j, LikeC4ViewsFolder as k, type DeploymentOrFqn as l, type EdgeOrId as m, type ElementOrFqn as n, type NodeOrId as o, type WithTags as p };
@@ -1,9 +1,9 @@
1
- import { c as customInspectSymbol } from './core.C80Z37Eu.mjs';
1
+ import { c as customInspectSymbol } from './core.C1GV0WWV.mjs';
2
2
  import { o } from './core.BgvIuGGU.mjs';
3
3
  import { a as intersection, b as stringHash, u as union, d as difference, e as equals } from './core.CpwrZi3D.mjs';
4
4
  import { u } from './core.DbRvwARP.mjs';
5
5
  import { m } from './core.ByrmCl9I.mjs';
6
- import { j as isDescendantOf, i as isAncestor, q as isString, C, l as sortNaturalByFqn, k as isSameHierarchy } from './core.C_C-3c1S.mjs';
6
+ import { j as isDescendantOf, i as isAncestor, q as isString, C, l as sortNaturalByFqn, k as isSameHierarchy } from './core.DQj9iv_y.mjs';
7
7
  import { i as isome } from './core.BoyJPEen.mjs';
8
8
  import { i as ifilter } from './core.BH9nN-_I.mjs';
9
9
  import { i as invariant } from './core.D4npX2q8.mjs';
@@ -1,5 +1,5 @@
1
- import { r as getDefaultExportFromCjs, d as commonAncestor, f as compareFqnHierarchically } from './core.C_C-3c1S.mjs';
2
- import { r as requireForeach, a as requireIterator } from './core.CtKXPqN_.mjs';
1
+ import { r as getDefaultExportFromCjs, d as commonAncestor, f as compareFqnHierarchically } from './core.DQj9iv_y.mjs';
2
+ import { r as requireForeach, a as requireIterator } from './core.HUONfQfd.mjs';
3
3
 
4
4
  function o(r,n){let e=Math.ceil(r),t=Math.floor(n);if(t<e)throw new RangeError(`randomInteger: The range [${r.toString()},${n.toString()}] contains no integer`);return Math.floor(Math.random()*(t-e+1)+e)}
5
5