@stubber/form-fields 1.6.4 → 1.7.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/README.md CHANGED
@@ -34,58 +34,48 @@ See default ruleset [here](https://github.com/semantic-release/commit-analyzer/b
34
34
 
35
35
  Conversion Progress:
36
36
 
37
- | Component | TS DONE | TESTS DONE |
38
- | -------------------- | ---------- | ---------- |
39
- | AgGrid | x | |
40
- | Arraybuilder | x | |
41
- | Checkbox | x | |
42
- | CheckboxAutocomplete | x | |
43
- | Code | x | |
44
- | Contactselector | x | |
45
- | Currency | x | |
46
- | Dataindication | x | |
47
- | Date | x | |
48
- | Datetime | x | |
49
- | Email | x | |
50
- | Fieldbuilder | x | |
51
- | Fieldsbuilder | deprecated | |
52
- | File | x | |
53
- | Heading | x | |
54
- | Hidden | x | |
55
- | Hiddenlocation | x | |
56
- | Html | x | |
57
- | Jsoneditor | x | |
58
- | Map | x | |
59
- | Multicheckbox | x | |
60
- | Multistep | x | |
61
- | Note | x | |
62
- | Number | x | |
63
- | Objectbuilder | x | |
64
- | Qrcodescanner | x | |
65
- | Radio | x | |
66
- | Renderfield | deprecated | |
67
- | Screenrecorder | x | |
68
- | Screenshot | x | |
69
- | Scrollandreaddisplay | x | |
70
- | Section | x | |
71
- | Select | x | |
72
- | Selectresource | x | |
73
- | Signature | x | |
74
- | Slider | x | |
75
- | SmartText | x | |
76
- | Telephone | x | |
77
- | Text | x | |
78
- | Voicenote | x | |
79
-
80
- Generate Features
81
-
82
- | Feature | TS DONE | TESTS DONE |
83
- | --------------------- | ------- | ---------- |
84
- | hide_label | x | |
85
- | init_value | x | |
86
- | without_value_details | x | |
87
- | attachments | x | |
88
- | fieldbuilder support | x | |
37
+ | Component | TS DONE | IS STRING |
38
+ | -------------------- | ---------- | --------- |
39
+ | AgGrid | x | |
40
+ | Arraybuilder | x | |
41
+ | Checkbox | x | |
42
+ | CheckboxAutocomplete | x | |
43
+ | Code | x | |
44
+ | Contactselector | x | |
45
+ | Currency | x | |
46
+ | Dataindication | x | |
47
+ | Date | x | |
48
+ | Datetime | x | |
49
+ | Email | x | |
50
+ | Fieldbuilder | x | |
51
+ | Fieldsbuilder | deprecated | |
52
+ | File | x | |
53
+ | Heading | x | |
54
+ | Hidden | x | |
55
+ | Hiddenlocation | x | |
56
+ | Html | x | |
57
+ | Jsoneditor | x | |
58
+ | Map | x | |
59
+ | Multicheckbox | x | |
60
+ | Multistep | x | |
61
+ | Note | x | |
62
+ | Number | x | |
63
+ | Objectbuilder | x | |
64
+ | Qrcodescanner | x | |
65
+ | Radio | x | |
66
+ | Renderfield | deprecated | |
67
+ | Screenrecorder | x | |
68
+ | Screenshot | x | |
69
+ | Scrollandreaddisplay | x | |
70
+ | Section | x | |
71
+ | Select | x | |
72
+ | Selectresource | x | |
73
+ | Signature | x | |
74
+ | Slider | x | |
75
+ | SmartText | x | |
76
+ | Telephone | x | |
77
+ | Text | x | |
78
+ | Voicenote | x | |
89
79
 
90
80
  ## TS Refactor
91
81
 
@@ -0,0 +1,29 @@
1
+ <script>import { getContext } from "svelte";
2
+ export let fieldStore;
3
+ const field_component_store = getContext("field_component");
4
+ const show_toggle = getContext("show_field_expr_toggle") ?? false;
5
+ $: selected_fieldtype = $field_component_store.fieldtype;
6
+ $: is_true_field = $fieldStore.fieldtype === selected_fieldtype;
7
+ const handle_fieldtype_click = (ft) => {
8
+ $field_component_store.fieldtype = ft;
9
+ };
10
+ </script>
11
+
12
+ {#if show_toggle}
13
+ <div
14
+ class="ml-auto flex h-fit w-fit flex-row items-center gap-0.5 rounded bg-gray-300 p-0.5 text-xs"
15
+ >
16
+ <button
17
+ on:click={() => handle_fieldtype_click($fieldStore.fieldtype)}
18
+ class={is_true_field ? "rounded bg-white px-0.5" : ""}
19
+ >
20
+ field
21
+ </button>
22
+ <button
23
+ on:click={() => handle_fieldtype_click("smart_text")}
24
+ class={!is_true_field ? "rounded bg-white px-0.5" : ""}
25
+ >
26
+ expr
27
+ </button>
28
+ </div>
29
+ {/if}
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ import type { IBuiltField } from "./interfaces";
4
+ declare const __propDef: {
5
+ props: {
6
+ fieldStore: Writable<IBuiltField>;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ exports?: {} | undefined;
13
+ bindings?: string | undefined;
14
+ };
15
+ export type FieldExprToggleProps = typeof __propDef.props;
16
+ export type FieldExprToggleEvents = typeof __propDef.events;
17
+ export type FieldExprToggleSlots = typeof __propDef.slots;
18
+ export default class FieldExprToggle extends SvelteComponent<FieldExprToggleProps, FieldExprToggleEvents, FieldExprToggleSlots> {
19
+ }
20
+ export {};
@@ -1,8 +1,12 @@
1
1
  <script>import { Label } from "@stubber/ui/label";
2
+ import FieldExprToggle from "./FieldExprToggle.svelte";
2
3
  export let fieldStore;
3
4
  $: hide_label = $fieldStore.hide_label;
4
5
  </script>
5
6
 
6
- {#if !hide_label}
7
- <Label for={$fieldStore.id}>{$fieldStore.label}</Label>
8
- {/if}
7
+ <div class="mb-1 flex flex-row items-center justify-between">
8
+ {#if !hide_label}
9
+ <Label for={$fieldStore.id}>{$fieldStore.label}</Label>
10
+ {/if}
11
+ <FieldExprToggle {fieldStore} />
12
+ </div>
@@ -1,6 +1,4 @@
1
1
  <script>import { Label } from "@stubber/ui/label";
2
- import { get, startCase } from "lodash-es";
3
- import { get_field_help_message } from "./utils";
4
2
  export let fieldStore;
5
3
  $: validation_result = $fieldStore.validation_result;
6
4
  $: type = validation_result?.type;
@@ -8,7 +6,8 @@ $: type = validation_result?.type;
8
6
 
9
7
  <Label
10
8
  id="message-{$fieldStore.id}"
11
- class="ml-2 truncate text-xs {!$fieldStore.validation_result ? 'invisible' : ''} {type == 'error'
9
+ for={$fieldStore.id}
10
+ class="block truncate text-xs {!$fieldStore.validation_result ? 'invisible' : ''} {type == 'error'
12
11
  ? 'text-red-500'
13
12
  : 'text-muted-foreground'}"
14
13
  >
@@ -1,6 +1,6 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { IBuiltField } from "./interfaces";
3
2
  import type { Writable } from "svelte/store";
3
+ import type { IBuiltField } from "./interfaces";
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  fieldStore: Writable<IBuiltField>;
@@ -2,11 +2,14 @@
2
2
  import FormField from "./form-field.svelte";
3
3
  import { build_fields } from "./utils";
4
4
  import { validate_field } from "./validations/validate_field";
5
+ import { setContext } from "svelte";
5
6
  export let initial_form;
6
7
  export let form;
7
8
  export let attachments = writable([]);
8
9
  export let dependencies = void 0;
9
10
  export let form_valid = false;
11
+ export let show_field_expr_toggle = false;
12
+ setContext("show_field_expr_toggle", show_field_expr_toggle);
10
13
  if (initial_form.data) {
11
14
  form.update((data) => {
12
15
  return { ...data, ...initial_form.data };
@@ -28,7 +31,7 @@ const validate_form = async (_) => {
28
31
  };
29
32
  </script>
30
33
 
31
- <div class="flex flex-col gap-y-1">
34
+ <div class="flex flex-col gap-y-2">
32
35
  {#each fields as fieldStore (getStoreValue(fieldStore).id)}
33
36
  <FormField {fieldStore} />
34
37
  {/each}
@@ -9,6 +9,7 @@ declare const __propDef: {
9
9
  attachments?: Writable<UploadedFile[]>;
10
10
  dependencies?: IFormDependencies | undefined;
11
11
  form_valid?: boolean;
12
+ show_field_expr_toggle?: boolean;
12
13
  };
13
14
  events: {
14
15
  [evt: string]: CustomEvent<any>;
@@ -1,6 +1,26 @@
1
- <script>import { component_for } from "./interfaces";
1
+ <script>import { set } from "lodash-es";
2
+ import { getContext, setContext } from "svelte";
3
+ import { writable } from "svelte/store";
4
+ import { component_for, final_field_type } from "./interfaces";
2
5
  export let fieldStore;
3
- const component = component_for($fieldStore);
6
+ const show_toggle = getContext("show_field_expr_toggle") ?? false;
7
+ let fieldtype = final_field_type($fieldStore, show_toggle);
8
+ let component = component_for(fieldtype);
9
+ const field_component_store = writable({ fieldtype });
10
+ setContext("field_component", field_component_store);
11
+ $: handle_field_type_change($field_component_store.fieldtype);
12
+ const handle_field_type_change = (new_fieldtype) => {
13
+ if (new_fieldtype === fieldtype) {
14
+ return;
15
+ }
16
+ fieldtype = new_fieldtype;
17
+ const new_value = new_fieldtype == "smart_text" ? typeof $fieldStore.value === "string" ? $fieldStore.value : "" : new_fieldtype == "checkbox" ? false : new_fieldtype == "number" ? 0 : new_fieldtype == "arraybuilder" ? [] : new_fieldtype == "section" || new_fieldtype == "objectbuilder" ? {} : null;
18
+ $fieldStore.formStore.update((form) => {
19
+ set(form, $fieldStore.data_path, new_value);
20
+ return form;
21
+ });
22
+ component = component_for(new_fieldtype);
23
+ };
4
24
  </script>
5
25
 
6
26
  {#if !$fieldStore.hidden}
@@ -1,9 +1,9 @@
1
1
  import { SvelteComponent } from "svelte";
2
+ import { type Writable } from "svelte/store";
2
3
  import { type IBuiltField } from "./interfaces";
3
- import type { Writable } from "svelte/store";
4
4
  declare const __propDef: {
5
5
  props: {
6
- fieldStore: Writable<IBuiltField>;
6
+ fieldStore: Writable<IBuiltField<any>>;
7
7
  };
8
8
  events: {
9
9
  [evt: string]: CustomEvent<any>;
@@ -177,7 +177,8 @@ export interface IBuiltField<T = {}> {
177
177
  set value(val: any);
178
178
  params?: T;
179
179
  }
180
- export declare const component_for: (f: IBuiltField) => typeof TextField | typeof NumberField | typeof SectionField | typeof CheckboxField | typeof CheckboxAutocomplete | typeof ArrayBuilderField | typeof GridField | typeof SelectField | typeof SelectresourceField | typeof SliderField | typeof ContactSelectorField | typeof CurrencyField | typeof DataIndicationField | typeof DateField | typeof DateTimeField | typeof EmailField | typeof FieldBuilderField | typeof JSONEditorField | typeof FileField | typeof HeadingField | typeof HiddenField | typeof HiddenLocationField | typeof HtmlField | typeof MapField | typeof TelephoneField | typeof NoteField | typeof MultistepField | typeof ObjectBuilderField | typeof RadioField | typeof MultiCheckboxField | typeof QrCodeScannerField | typeof ScrollAndReadDisplayField | typeof VoicenoteField | typeof SignatureField | typeof SmartTextField | typeof ScreenshotField | typeof ScreenrecorderField | typeof CodeField;
180
+ export declare const final_field_type: (f: IBuiltField, allow_dynamic_switching: boolean) => FieldType;
181
+ export declare const component_for: (fieldtype: FieldType) => typeof GridField | typeof TextField | typeof NumberField | typeof SectionField | typeof CheckboxField | typeof CheckboxAutocomplete | typeof ArrayBuilderField | typeof SelectField | typeof SelectresourceField | typeof SliderField | typeof ContactSelectorField | typeof CurrencyField | typeof DataIndicationField | typeof DateField | typeof DateTimeField | typeof EmailField | typeof FieldBuilderField | typeof JSONEditorField | typeof FileField | typeof HeadingField | typeof HiddenField | typeof HiddenLocationField | typeof HtmlField | typeof MapField | typeof TelephoneField | typeof NoteField | typeof MultistepField | typeof ObjectBuilderField | typeof RadioField | typeof MultiCheckboxField | typeof QrCodeScannerField | typeof ScrollAndReadDisplayField | typeof VoicenoteField | typeof SignatureField | typeof SmartTextField | typeof ScreenshotField | typeof ScreenrecorderField | typeof CodeField;
181
182
  export interface IBaseValidation {
182
183
  invalid_message?: string;
183
184
  }
@@ -76,7 +76,21 @@ export const fields = {
76
76
  screenrecorder: ScreenrecorderField,
77
77
  code: CodeField,
78
78
  };
79
- export const component_for = (f) => {
80
- return fields[f.fieldtype];
79
+ const string_fields = ["text", "email", "telephone", "smart_text", "note", "code"];
80
+ export const final_field_type = (f, allow_dynamic_switching) => {
81
+ if (!allow_dynamic_switching) {
82
+ return f.fieldtype;
83
+ }
84
+ const is_string = typeof f.value === "string";
85
+ // if the initial value is a string
86
+ // but this field isn't typically a string field,
87
+ // rather render it as a smart_text field
88
+ if (is_string && !string_fields.includes(f.fieldtype)) {
89
+ return "smart_text";
90
+ }
91
+ return f.fieldtype;
92
+ };
93
+ export const component_for = (fieldtype) => {
94
+ return fields[fieldtype];
81
95
  };
82
96
  export const validation_types = ["required", "regex", "jsonata"];
@@ -17,11 +17,16 @@ import FieldLabel from "../FieldLabel.svelte";
17
17
  import FieldMessage from "../FieldMessage.svelte";
18
18
  import FormField from "../form-field.svelte";
19
19
  import { build_field } from "../utils";
20
+ import FieldExprToggle from "../FieldExprToggle.svelte";
21
+ import { Label } from "@stubber/ui/label";
20
22
  export let fieldStore;
21
23
  const new_entry_field = $fieldStore?.params?.new_entry_field || {
22
24
  fieldtype: "text"
23
25
  };
24
26
  const update_sub_fields = (new_value) => {
27
+ if (!Array.isArray(new_value)) {
28
+ return;
29
+ }
25
30
  const field = $fieldStore;
26
31
  field.sub_fields = new_value.map((_value, index) => {
27
32
  return build_field(
@@ -79,7 +84,7 @@ const move_value_down = (index) => {
79
84
  <Collapsible.Root open={true} class="w-full">
80
85
  <Collapsible.Trigger asChild let:builder>
81
86
  <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
82
- <FieldLabel {fieldStore} />
87
+ <Label>{$fieldStore.label}</Label>
83
88
  <FieldMessage {fieldStore} />
84
89
 
85
90
  <i class="fa fa-sort" />
@@ -87,7 +92,7 @@ const move_value_down = (index) => {
87
92
  </Collapsible.Trigger>
88
93
  <Collapsible.Content class="flex flex-col gap-y-1 pl-2">
89
94
  {#each $fieldStore.sub_fields || [] as sub_field, index (get_store_value(sub_field).id)}
90
- <div class="flex items-center space-x-2 w-full">
95
+ <div class="flex w-full items-center space-x-2">
91
96
  <!-- up and down sort buttons -->
92
97
  <div class="flex flex-col items-center space-y-1">
93
98
  <Button variant="ghost" class="h-6 w-6 p-2" on:click={() => move_value_up(index)}>
@@ -103,8 +108,11 @@ const move_value_down = (index) => {
103
108
  </Button>
104
109
  </div>
105
110
  {/each}
106
- <Button size="icon" variant="outline" on:click={add_value}>
107
- <i class="fa fa-plus" />
108
- </Button>
111
+ <div class="flex items-center justify-between">
112
+ <Button size="icon" variant="outline" on:click={add_value}>
113
+ <i class="fa fa-plus" />
114
+ </Button>
115
+ <FieldExprToggle {fieldStore} />
116
+ </div>
109
117
  </Collapsible.Content>
110
118
  </Collapsible.Root>
@@ -19,6 +19,7 @@ import { Label } from "@stubber/ui/label";
19
19
  import { isEqual } from "lodash-es";
20
20
  import FieldMessage from "../FieldMessage.svelte";
21
21
  import { set_value_details } from "../utils";
22
+ import FieldExprToggle from "../FieldExprToggle.svelte";
22
23
  export let fieldStore;
23
24
  let field = $fieldStore;
24
25
  set_value_details(field, "label", field.label);
@@ -34,8 +35,9 @@ const on_change = (new_value) => {
34
35
  };
35
36
  </script>
36
37
 
37
- <div class="w-full flex items-center space-x-2">
38
+ <div class="flex w-full items-center gap-x-2">
38
39
  <Checkbox {checked} onCheckedChange={on_change} />
39
40
  <Label>{field.label}</Label>
41
+ <FieldExprToggle {fieldStore} />
40
42
  </div>
41
43
  <FieldMessage {fieldStore} />
@@ -16,9 +16,9 @@ export const object_builder_field_param_spec = {
16
16
  <script>import * as Collapsible from "@stubber/ui/collapsible";
17
17
  import { Button } from "@stubber/ui/button";
18
18
  import { Input } from "@stubber/ui/input";
19
- import { Separator } from "@stubber/ui/separator";
19
+ import { Label } from "@stubber/ui/label";
20
20
  import { cloneDeep } from "lodash-es";
21
- import FieldLabel from "../FieldLabel.svelte";
21
+ import FieldExprToggle from "../FieldExprToggle.svelte";
22
22
  import FieldMessage from "../FieldMessage.svelte";
23
23
  import FormField from "../form-field.svelte";
24
24
  import { build_field } from "../utils";
@@ -73,7 +73,7 @@ const make_key_unique = (key) => {
73
73
  <Collapsible.Root open={true} class="w-full">
74
74
  <Collapsible.Trigger asChild let:builder>
75
75
  <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
76
- <FieldLabel {fieldStore} />
76
+ <Label>{$fieldStore.label}</Label>
77
77
  <FieldMessage {fieldStore} />
78
78
 
79
79
  <i class="fa fa-sort" />
@@ -102,7 +102,7 @@ const make_key_unique = (key) => {
102
102
  </Button>
103
103
  </div>
104
104
  </div>
105
- <Collapsible.Content class="pl-6 mt-2">
105
+ <Collapsible.Content class="mt-2 pl-6">
106
106
  {@const built_value_field = build_field(
107
107
  $fieldStore.formStore,
108
108
  $fieldStore.attachmentsStore,
@@ -116,8 +116,12 @@ const make_key_unique = (key) => {
116
116
  </Collapsible.Root>
117
117
  <!-- <Separator class="my-2" /> -->
118
118
  {/each}
119
- <Button size="icon" variant="outline" on:click={add_value}>
120
- <i class="fa fa-plus" />
121
- </Button>
119
+
120
+ <div class="flex items-center justify-between">
121
+ <Button size="icon" variant="outline" on:click={add_value}>
122
+ <i class="fa fa-plus" />
123
+ </Button>
124
+ <FieldExprToggle {fieldStore} />
125
+ </div>
122
126
  </Collapsible.Content>
123
127
  </Collapsible.Root>
@@ -23,6 +23,7 @@ import { isEqual } from "lodash-es";
23
23
  import FieldMessage from "../FieldMessage.svelte";
24
24
  import { set_value_details } from "../utils";
25
25
  import { onMount } from "svelte";
26
+ import FieldExprToggle from "../FieldExprToggle.svelte";
26
27
  export let fieldStore;
27
28
  let params = $fieldStore.params;
28
29
  let yes_value = params?.checkedvalue ?? true;
@@ -59,11 +60,11 @@ const update_value_details = (new_value) => {
59
60
  };
60
61
  </script>
61
62
 
62
- <div class="flex flex-col w-full text-surface-900 my-2">
63
+ <div class="my-2 flex w-full flex-col text-surface-900">
63
64
  <!-- div with inner shadow -->
64
65
  <div
65
66
  bind:this={outer}
66
- class="border max-h-[300px] overflow-y-scroll shadow-inner rounded-md"
67
+ class="max-h-[300px] overflow-y-scroll rounded-md border shadow-inner"
67
68
  on:scroll={handle_scroll}
68
69
  >
69
70
  <div class="p-6 px-2">
@@ -73,9 +74,7 @@ const update_value_details = (new_value) => {
73
74
  <div
74
75
  class="{!scrolled_to_bottom
75
76
  ? 'opacity-20'
76
- : ''} flex space-x-3 relative mt-2 items-center {is_error
77
- ? 'border-b border-warning-500'
78
- : ''}"
77
+ : ''} relative mt-2 flex items-center gap-x-2 {is_error ? 'border-b border-warning-500' : ''}"
79
78
  >
80
79
  <Checkbox
81
80
  disabled={!scrolled_to_bottom}
@@ -87,6 +86,7 @@ const update_value_details = (new_value) => {
87
86
  <Label for="input_{$fieldStore.id}" class="block">
88
87
  {$fieldStore.label}
89
88
  </Label>
89
+ <FieldExprToggle {fieldStore} />
90
90
  </div>
91
91
  <FieldMessage {fieldStore} />
92
92
  </div>
@@ -6,22 +6,25 @@ import * as Collapsible from "@stubber/ui/collapsible";
6
6
  import FieldLabel from "../FieldLabel.svelte";
7
7
  import FieldMessage from "../FieldMessage.svelte";
8
8
  import FormField from "../form-field.svelte";
9
+ import { Label } from "@stubber/ui/label";
10
+ import FieldExprToggle from "../FieldExprToggle.svelte";
9
11
  export let fieldStore;
10
12
  </script>
11
13
 
12
14
  <Collapsible.Root open={true} class="w-full">
13
15
  <Collapsible.Trigger asChild let:builder>
14
16
  <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
15
- <FieldLabel {fieldStore} />
17
+ <Label>{$fieldStore.label}</Label>
16
18
  <FieldMessage {fieldStore} />
17
19
 
18
20
  <i class="fa fa-sort" />
19
21
  </Button>
20
22
  </Collapsible.Trigger>
21
23
 
22
- <Collapsible.Content class="flex flex-col gap-y-1 pl-2">
24
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
23
25
  {#each $fieldStore.sub_fields || [] as sub_field (get_store_value(sub_field).id)}
24
26
  <FormField fieldStore={sub_field} />
25
27
  {/each}
28
+ <FieldExprToggle {fieldStore} />
26
29
  </Collapsible.Content>
27
30
  </Collapsible.Root>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stubber/form-fields",
3
- "version": "1.6.4",
3
+ "version": "1.7.0",
4
4
  "description": "An automatic form builder based on field specifications",
5
5
  "keywords": [
6
6
  "components",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "scripts": {
29
29
  "dev": "vite dev --host",
30
- "build": "vite build && npm run package",
30
+ "build": "vite build",
31
31
  "package": "svelte-kit sync && svelte-package && publint",
32
32
  "preview": "vite preview",
33
33
  "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
@@ -94,7 +94,7 @@
94
94
  },
95
95
  "release": {
96
96
  "branches": [
97
- "master"
97
+ "staging"
98
98
  ],
99
99
  "plugins": [
100
100
  "@semantic-release/commit-analyzer",