@nexdom/uimed-vue 1.3.0-beta.2 → 1.3.0-beta.3

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/AGENTS.md CHANGED
@@ -105,6 +105,7 @@ CI (`.github/workflows/ci.yml`) runs, in order: commitlint on PR commits, `vp pa
105
105
  ## Code conventions
106
106
 
107
107
  - All `src` code is written in English. `docs` content is written in Portuguese (aimed at Brazilian users), even though file/dir names stay in English.
108
+ - `docs` must not mention Vuetify
108
109
  - Never write CSS, classes or any kind of styling. Always use component props.
109
110
  - Path aliases: `@/*` → `src/*`, `@e2e/*` → `e2e/*`.
110
111
  - Every public component follows this pattern to block access to internals and give it an editor-hover description:
@@ -169,8 +169,8 @@ type RootProps = {
169
169
  *
170
170
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/root | Root Guide}
171
171
  */
172
- declare const _default$4: typeof __VLS_export$6;
173
- declare const __VLS_export$6: __VLS_WithSlots$5<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RootProps & {
172
+ declare const _default$6: typeof __VLS_export$8;
173
+ declare const __VLS_export$8: __VLS_WithSlots$7<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RootProps & {
174
174
  notificationsOpen?: boolean;
175
175
  }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
176
176
  "update:notificationsOpen": (value: boolean) => any;
@@ -181,7 +181,7 @@ declare const __VLS_export$6: __VLS_WithSlots$5<import("vue", { with: { "resolut
181
181
  }>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
182
182
  default?: (props: {}) => any;
183
183
  }>;
184
- type __VLS_WithSlots$5<T, S> = T & {
184
+ type __VLS_WithSlots$7<T, S> = T & {
185
185
  new (): {
186
186
  $slots: S;
187
187
  };
@@ -244,15 +244,15 @@ type BtnProps = {
244
244
  *
245
245
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/btn | Btn Guide}
246
246
  */
247
- declare const _default: typeof __VLS_export$5;
248
- declare const __VLS_export$5: __VLS_WithSlots$4<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<BtnProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
247
+ declare const _default: typeof __VLS_export$7;
248
+ declare const __VLS_export$7: __VLS_WithSlots$6<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<BtnProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
249
249
  click: (event: MouseEvent) => any;
250
250
  }, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<BtnProps> & Readonly<{
251
251
  onClick?: ((event: MouseEvent) => any) | undefined;
252
252
  }>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
253
253
  default?: (props: {}) => any;
254
254
  }>;
255
- type __VLS_WithSlots$4<T, S> = T & {
255
+ type __VLS_WithSlots$6<T, S> = T & {
256
256
  new (): {
257
257
  $slots: S;
258
258
  };
@@ -333,8 +333,8 @@ type TextFieldProps = {
333
333
  *
334
334
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/text-field | TextField Guide}
335
335
  */
336
- declare const _default$6: typeof __VLS_export$4;
337
- declare const __VLS_export$4: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<TextFieldProps & {
336
+ declare const _default$8: typeof __VLS_export$6;
337
+ declare const __VLS_export$6: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<TextFieldProps & {
338
338
  modelValue?: string;
339
339
  }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
340
340
  "update:modelValue": (value: string) => any;
@@ -372,11 +372,11 @@ type ContainerProps = {
372
372
  *
373
373
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/layout | Container Guide}
374
374
  */
375
- declare const _default$2: typeof __VLS_export$3;
376
- declare const __VLS_export$3: __VLS_WithSlots$3<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ContainerProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ContainerProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
375
+ declare const _default$2: typeof __VLS_export$5;
376
+ declare const __VLS_export$5: __VLS_WithSlots$5<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ContainerProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ContainerProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
377
377
  default?: (props: {}) => any;
378
378
  }>;
379
- type __VLS_WithSlots$3<T, S> = T & {
379
+ type __VLS_WithSlots$5<T, S> = T & {
380
380
  new (): {
381
381
  $slots: S;
382
382
  };
@@ -408,11 +408,11 @@ type RowProps = {
408
408
  *
409
409
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/layout | Row Guide}
410
410
  */
411
- declare const _default$5: typeof __VLS_export$2;
412
- declare const __VLS_export$2: __VLS_WithSlots$2<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RowProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<RowProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
411
+ declare const _default$7: typeof __VLS_export$4;
412
+ declare const __VLS_export$4: __VLS_WithSlots$4<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RowProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<RowProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
413
413
  default?: (props: {}) => any;
414
414
  }>;
415
- type __VLS_WithSlots$2<T, S> = T & {
415
+ type __VLS_WithSlots$4<T, S> = T & {
416
416
  new (): {
417
417
  $slots: S;
418
418
  };
@@ -455,13 +455,13 @@ type Cols = "auto" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10"
455
455
  *
456
456
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/layout | Column Guide}
457
457
  */
458
- declare const _default$1: typeof __VLS_export$1;
459
- declare const __VLS_export$1: __VLS_WithSlots$1<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ColumnProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ColumnProps> & Readonly<{}>, {
458
+ declare const _default$1: typeof __VLS_export$3;
459
+ declare const __VLS_export$3: __VLS_WithSlots$3<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ColumnProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ColumnProps> & Readonly<{}>, {
460
460
  cols: "12" | "auto" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11";
461
461
  }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
462
462
  default?: (props: {}) => any;
463
463
  }>;
464
- type __VLS_WithSlots$1<T, S> = T & {
464
+ type __VLS_WithSlots$3<T, S> = T & {
465
465
  new (): {
466
466
  $slots: S;
467
467
  };
@@ -496,18 +496,126 @@ type FrmProps = {
496
496
  *
497
497
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/frm | Form Guide}
498
498
  */
499
- declare const _default$3: typeof __VLS_export;
500
- declare const __VLS_export: __VLS_WithSlots<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<FrmProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
499
+ declare const _default$5: typeof __VLS_export$2;
500
+ declare const __VLS_export$2: __VLS_WithSlots$2<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<FrmProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
501
501
  submit: (event: SubmitEvent) => any;
502
502
  }, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<FrmProps> & Readonly<{
503
503
  onSubmit?: ((event: SubmitEvent) => any) | undefined;
504
504
  }>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
505
505
  default?: (props: {}) => any;
506
506
  }>;
507
+ type __VLS_WithSlots$2<T, S> = T & {
508
+ new (): {
509
+ $slots: S;
510
+ };
511
+ };
512
+ //#endregion
513
+ //#region src/components/content/content.vue.d.ts
514
+ /**
515
+ * Proxy component for Vuetify's `v-card-text`, used to structure content
516
+ * displayed inside a {@link ContentSet}.
517
+ *
518
+ * @example
519
+ * ```vue
520
+ * <content-set title="Title">
521
+ * <content>Content</content>
522
+ * </content-set>
523
+ * ```
524
+ *
525
+ * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/content-set | ContentSet Guide}
526
+ */
527
+ declare const _default$3: typeof __VLS_export$1;
528
+ declare const __VLS_export$1: __VLS_WithSlots$1<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<{}, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, true, {}, any>, {
529
+ default?: (props: {}) => any;
530
+ }>;
531
+ type __VLS_WithSlots$1<T, S> = T & {
532
+ new (): {
533
+ $slots: S;
534
+ };
535
+ };
536
+ //#endregion
537
+ //#region src/components/content/types.d.ts
538
+ type ContentSetVariant = "primary" | "secondary";
539
+ /**
540
+ * Props exposed by the {@link ContentSet} component.
541
+ */
542
+ type ContentSetProps = {
543
+ /**
544
+ * Applies a distinct style variation to the content set.
545
+ * One of `primary` or `secondary`.
546
+ * @default "primary"
547
+ */
548
+ variant?: ContentSetVariant;
549
+ /**
550
+ * Title displayed at the top of the content set.
551
+ */
552
+ title?: string;
553
+ /**
554
+ * Subtitle displayed below the title.
555
+ */
556
+ subtitle?: string;
557
+ /**
558
+ * List of actions displayed at the bottom of the content set, inside
559
+ * `v-card-actions`. When undefined or empty, no actions area is rendered.
560
+ */
561
+ actions?: ContentSetAction[];
562
+ /**
563
+ * Makes the content set occupy 100% of its parent's width.
564
+ * @default false
565
+ */
566
+ fullWidth?: boolean;
567
+ /**
568
+ * Makes the content set occupy 100% of its parent's height.
569
+ * @default false
570
+ */
571
+ fullHeight?: boolean;
572
+ /**
573
+ * Shows a skeleton loader in place of the content while data is being
574
+ * loaded.
575
+ * @default false
576
+ */
577
+ loading?: boolean;
578
+ /**
579
+ * Component id to use on automated tests.
580
+ */
581
+ dataTestid?: string;
582
+ };
583
+ /**
584
+ * A single action rendered inside {@link ContentSet}'s actions area.
585
+ */
586
+ interface ContentSetAction extends BtnProps {
587
+ /**
588
+ * Text displayed on the action button.
589
+ */
590
+ label: string;
591
+ /**
592
+ * Called when the action button is clicked.
593
+ */
594
+ onClick?: (event: MouseEvent) => void;
595
+ }
596
+ //#endregion
597
+ //#region src/components/content/content-set.vue.d.ts
598
+ /**
599
+ * Content set component to group related content and actions, to be used
600
+ * throughout the application.
601
+ *
602
+ * @example
603
+ * ```vue
604
+ * <content-set title="Title" subtitle="Subtitle">
605
+ * Content
606
+ * </content-set>
607
+ * ```
608
+ *
609
+ * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/content-set | ContentSet Guide}
610
+ */
611
+ declare const _default$4: typeof __VLS_export;
612
+ declare const __VLS_export: __VLS_WithSlots<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ContentSetProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ContentSetProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
613
+ default?: (props: {}) => any;
614
+ }>;
507
615
  type __VLS_WithSlots<T, S> = T & {
508
616
  new (): {
509
617
  $slots: S;
510
618
  };
511
619
  };
512
620
  //#endregion
513
- export { type AppBarProps as AppBarConfig, type AppBarUserProps as AppBarUserConfig, _default as Btn, _default$1 as Column, _default$2 as Container, _default$3 as Frm, type NavigationMenuProps as NavigationMenuConfig, _default$4 as Root, _default$5 as Row, _default$6 as TextField };
621
+ export { type AppBarProps as AppBarConfig, type AppBarUserProps as AppBarUserConfig, _default as Btn, _default$1 as Column, _default$2 as Container, _default$3 as Content, _default$4 as ContentSet, type ContentSetAction, _default$5 as Frm, type NavigationMenuProps as NavigationMenuConfig, _default$6 as Root, _default$7 as Row, _default$8 as TextField };
@@ -1,6 +1,6 @@
1
1
  import { r as useVuetifyColor, t as messages } from "./use-toast-CACuYhK_.js";
2
2
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, isRef, mergeModels, mergeProps, openBlock, ref, renderList, renderSlot, toDisplayString, toValue, unref, useModel, withCtx, withModifiers } from "vue";
3
- import { VApp, VAppBar, VAppBarNavIcon, VAppBarTitle, VAvatar, VBadge, VBtn, VCard, VCardText, VCol, VContainer, VDivider, VForm, VIcon, VIconBtn, VImg, VList, VListGroup, VListItem, VListItemAction, VListSubheader, VMain, VMenu, VNavigationDrawer, VRow, VSnackbarQueue, VTextField } from "vuetify/components";
3
+ import { VApp, VAppBar, VAppBarNavIcon, VAppBarTitle, VAvatar, VBadge, VBtn, VCard, VCardActions, VCardText, VCol, VContainer, VDivider, VForm, VIcon, VIconBtn, VImg, VList, VListGroup, VListItem, VListItemAction, VListSubheader, VMain, VMenu, VNavigationDrawer, VRow, VSkeletonLoader, VSnackbarQueue, VTextField } from "vuetify/components";
4
4
  import { formatDateTime, isEmail, isEmpty, isPhone, isUrl, toPeriodInterval } from "@nexdom/shared/utils";
5
5
  //#region src/composables/navigation/use-route-props.ts
6
6
  function useRouteProps(route) {
@@ -784,4 +784,125 @@ var frm_default = /* @__PURE__ */ defineComponent({
784
784
  }
785
785
  });
786
786
  //#endregion
787
- export { btn_default as Btn, column_default as Column, container_default as Container, frm_default as Frm, root_default as Root, row_default as Row, text_field_default as TextField };
787
+ //#region src/components/content/content.vue
788
+ var content_default = /* @__PURE__ */ defineComponent({
789
+ inheritAttrs: false,
790
+ __name: "content",
791
+ setup(__props) {
792
+ return (_ctx, _cache) => {
793
+ return openBlock(), createBlock(unref(VCardText), null, {
794
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
795
+ _: 3
796
+ });
797
+ };
798
+ }
799
+ });
800
+ //#endregion
801
+ //#region src/composables/content-set.ts
802
+ const contentSetVariantToVuetifyVariant = {
803
+ primary: "elevated",
804
+ secondary: "outlined"
805
+ };
806
+ function useContentSetVariant(variant) {
807
+ return computed(() => {
808
+ const variantValue = toValue(variant);
809
+ return variantValue ? contentSetVariantToVuetifyVariant[variantValue] : contentSetVariantToVuetifyVariant.primary;
810
+ });
811
+ }
812
+ //#endregion
813
+ //#region src/components/content/content-set.vue
814
+ var content_set_default = /* @__PURE__ */ defineComponent({
815
+ inheritAttrs: false,
816
+ __name: "content-set",
817
+ props: {
818
+ variant: {
819
+ type: String,
820
+ required: false
821
+ },
822
+ title: {
823
+ type: String,
824
+ required: false
825
+ },
826
+ subtitle: {
827
+ type: String,
828
+ required: false
829
+ },
830
+ actions: {
831
+ type: Array,
832
+ required: false
833
+ },
834
+ fullWidth: {
835
+ type: Boolean,
836
+ required: false
837
+ },
838
+ fullHeight: {
839
+ type: Boolean,
840
+ required: false
841
+ },
842
+ loading: {
843
+ type: Boolean,
844
+ required: false
845
+ },
846
+ dataTestid: {
847
+ type: String,
848
+ required: false
849
+ }
850
+ },
851
+ setup(__props) {
852
+ const props = __props;
853
+ const variant = useContentSetVariant(() => props.variant);
854
+ const title = computed(() => props.title || void 0);
855
+ const subtitle = computed(() => props.subtitle || void 0);
856
+ const width = computed(() => props.fullWidth ? "100%" : void 0);
857
+ const height = computed(() => props.fullHeight ? "100%" : void 0);
858
+ const showActions = computed(() => !!props.actions?.length);
859
+ const skeletonType = computed(() => showActions.value ? "image, actions" : "image");
860
+ return (_ctx, _cache) => {
861
+ return openBlock(), createBlock(unref(VSkeletonLoader), {
862
+ loading: props.loading,
863
+ type: skeletonType.value,
864
+ width: width.value,
865
+ height: height.value
866
+ }, {
867
+ default: withCtx(() => [createVNode(unref(VCard), {
868
+ title: title.value,
869
+ subtitle: subtitle.value,
870
+ variant: unref(variant),
871
+ width: width.value,
872
+ height: height.value,
873
+ "data-testid": props.dataTestid,
874
+ class: "d-flex flex-column"
875
+ }, {
876
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default"), showActions.value ? (openBlock(), createBlock(unref(VCardActions), {
877
+ key: 0,
878
+ class: "mt-auto"
879
+ }, {
880
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(props.actions, ({ label, onClick, ...action }, index) => {
881
+ return openBlock(), createBlock(btn_default, mergeProps({ key: index }, { ref_for: true }, action, { onClick }), {
882
+ default: withCtx(() => [createTextVNode(toDisplayString(label), 1)]),
883
+ _: 2
884
+ }, 1040, ["onClick"]);
885
+ }), 128))]),
886
+ _: 1
887
+ })) : createCommentVNode("v-if", true)]),
888
+ _: 3
889
+ }, 8, [
890
+ "title",
891
+ "subtitle",
892
+ "variant",
893
+ "width",
894
+ "height",
895
+ "data-testid"
896
+ ])]),
897
+ _: 3
898
+ }, 8, [
899
+ "loading",
900
+ "type",
901
+ "width",
902
+ "height"
903
+ ]);
904
+ };
905
+ }
906
+ });
907
+ //#endregion
908
+ export { btn_default as Btn, column_default as Column, container_default as Container, content_default as Content, content_set_default as ContentSet, frm_default as Frm, root_default as Root, row_default as Row, text_field_default as TextField };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexdom/uimed-vue",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.3.0-beta.3",
4
4
  "description": "A ui framework for NEXDOM applications.",
5
5
  "keywords": [
6
6
  "lib",
@@ -43,7 +43,6 @@
43
43
  "test": "vp test",
44
44
  "test:mutations": "stryker run",
45
45
  "test:e2e": "vpx playwright test",
46
- "check": "vp check && vpx vue-tsc",
47
46
  "prepublishOnly": "vpr build",
48
47
  "prepare": "vp config",
49
48
  "depcruise": "depcruise src --output-type err-long",