Merge branch 'master' of github.com:Budibase/budibase into component-nav-update
This commit is contained in:
commit
aa3d724d0e
|
@ -57,23 +57,23 @@
|
|||
|
||||
.budibase__nav-item {
|
||||
cursor: pointer;
|
||||
padding: 0 7px 0 3px;
|
||||
padding: 0 4px 0 2px;
|
||||
height: 35px;
|
||||
margin: 5px 20px 5px 0px;
|
||||
margin: 5px 0px 4px 0px;
|
||||
border-radius: 0 5px 5px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.budibase__nav-item.selected {
|
||||
color: var(--button-text);
|
||||
background: #f1f4fc;
|
||||
color: var(--ink);
|
||||
background: var(--blue-light);
|
||||
}
|
||||
|
||||
.budibase__nav-item:hover {
|
||||
background: #fafafa;
|
||||
background: var(--grey-light);
|
||||
}
|
||||
|
||||
.budibase__input {
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
margin-left: 20px;
|
||||
}
|
||||
|
||||
:global(.refresh-page-button):hover{
|
||||
:global(.refresh-page-button):hover {
|
||||
background: var(--grey-light);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
let selectedIndex = 0
|
||||
|
||||
const isSelected = tab => selected === tab
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
@ -19,9 +16,7 @@
|
|||
<div class="switcher">
|
||||
|
||||
{#each tabs as tab}
|
||||
<button
|
||||
class:selected={selected === tab}
|
||||
on:click={() => selectTab(tab)}>
|
||||
<button class:selected={selected === tab} on:click={() => selectTab(tab)}>
|
||||
{tab}
|
||||
</button>
|
||||
{/each}
|
||||
|
@ -30,13 +25,13 @@
|
|||
|
||||
<div class="panel">
|
||||
{#if selectedIndex === 0}
|
||||
<slot name="0"></slot>
|
||||
<slot name="0" />
|
||||
{:else if selectedIndex === 1}
|
||||
<slot name="1"></slot>
|
||||
<slot name="1" />
|
||||
{:else if selectedIndex === 2}
|
||||
<slot name="2"></slot>
|
||||
<slot name="2" />
|
||||
{:else if selectedIndex === 3}
|
||||
<slot name="3"></slot>
|
||||
<slot name="3" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -13,17 +13,33 @@
|
|||
|
||||
const FIELD_TYPES = ["string", "number", "boolean"]
|
||||
|
||||
export let field = { type: "string" }
|
||||
export let field = { type: "string", constraints: { type: "string", presence: false } }
|
||||
export let schema
|
||||
export let goBack
|
||||
|
||||
let errors = []
|
||||
let draftField = cloneDeep(field)
|
||||
|
||||
let type = field.type
|
||||
let constraints = field.constraints
|
||||
let required = field.constraints.presence && !field.constraints.presence.allowEmpty
|
||||
|
||||
const save = () => {
|
||||
constraints.presence = required ? { allowEmpty: false } : false
|
||||
draftField.constraints = constraints
|
||||
draftField.type = type
|
||||
schema[field.name] = draftField
|
||||
goBack()
|
||||
}
|
||||
|
||||
$: constraints =
|
||||
type === "string" ? { type: "string", length: {}, presence: false }
|
||||
: type === "number" ? { type: "number", presence: false, numericality: {} }
|
||||
: type === "boolean" ? { type: "boolean", presence: false }
|
||||
: type === "datetime" ? { type: "date", datetime: {}, presence: false }
|
||||
: type.startsWith('array') ? { type: "array", presence: false }
|
||||
: { type: "string", presence: false }
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
@ -34,30 +50,22 @@
|
|||
<Textbox label="Name" bind:text={field.name} />
|
||||
<Dropdown
|
||||
label="Type"
|
||||
bind:selected={draftField.type}
|
||||
bind:selected={type}
|
||||
options={FIELD_TYPES} />
|
||||
|
||||
{#if field.type === 'string'}
|
||||
<NumberBox label="Max Length" bind:value={draftField.maxLength} />
|
||||
<ValuesList label="Categories" bind:values={draftField.values} />
|
||||
{:else if field.type === 'boolean'}
|
||||
<Checkbox label="Required" bind:checked={required} />
|
||||
|
||||
|
||||
{#if type === 'string'}
|
||||
<NumberBox label="Max Length" bind:value={constraints.length.maximum} />
|
||||
<ValuesList label="Categories" bind:values={constraints.inclusion} />
|
||||
{:else if type === 'datetime'}
|
||||
<!-- TODO: revisit and fix with JSON schema -->
|
||||
<Checkbox label="Allow Null" bind:checked={draftField.allowNulls} />
|
||||
{:else if field.format === 'datetime'}
|
||||
<!-- TODO: revisit and fix with JSON schema -->
|
||||
<DatePicker label="Min Value" bind:value={draftField.minValue} />
|
||||
<DatePicker label="Max Value" bind:value={draftField.maxValue} />
|
||||
{:else if field.type === 'number'}
|
||||
<NumberBox label="Min Value" bind:value={draftField.minimum} />
|
||||
<NumberBox label="Max Value" bind:value={draftField.maximum} />
|
||||
{:else if draftField.type.startsWith('array')}
|
||||
<!-- TODO: revisit and fix with JSON schema -->
|
||||
<NumberBox
|
||||
label="Min Length"
|
||||
bind:value={draftField.typeOptions.minLength} />
|
||||
<NumberBox
|
||||
label="Max Length"
|
||||
bind:value={draftField.typeOptions.maxLength} />
|
||||
<DatePicker label="Min Value" bind:value={constraints.datetime.earliest} />
|
||||
<DatePicker label="Max Value" bind:value={constraints.datetime.latest} />
|
||||
{:else if type === 'number'}
|
||||
<NumberBox label="Min Value" bind:value={constraints.numericality.greaterThanOrEqualTo} />
|
||||
<NumberBox label="Max Value" bind:value={constraints.numericality.lessThanOrEqualTo} />
|
||||
{/if}
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
import * as api from "../api"
|
||||
import ErrorsBox from "components/common/ErrorsBox.svelte"
|
||||
|
||||
const CLASS_NAME_MAP = {
|
||||
boolean: "uk-checkbox",
|
||||
}
|
||||
|
||||
export let record = {}
|
||||
export let onClosed
|
||||
|
||||
|
@ -28,14 +24,25 @@
|
|||
onClosed()
|
||||
}
|
||||
|
||||
const isSelect = meta =>
|
||||
meta.type === "string"
|
||||
&& meta.constraints
|
||||
&& meta.constraints.inclusion
|
||||
&& meta.constraints.inclusion.length > 0
|
||||
|
||||
function determineInputType(meta) {
|
||||
if (meta.type === "datetime") return "date"
|
||||
if (meta.type === "number") return "number"
|
||||
if (meta.type === "boolean") return "checkbox"
|
||||
if (isSelect(meta)) return "select"
|
||||
|
||||
return "text"
|
||||
}
|
||||
|
||||
function determineOptions(meta) {
|
||||
return isSelect(meta) ? meta.constraints.inclusion : []
|
||||
}
|
||||
|
||||
async function saveRecord() {
|
||||
const recordResponse = await api.saveRecord(
|
||||
{
|
||||
|
@ -46,7 +53,9 @@
|
|||
$backendUiStore.selectedModel._id
|
||||
)
|
||||
if (recordResponse.errors) {
|
||||
errors = recordResponse.errors
|
||||
errors = Object.keys(recordResponse.errors)
|
||||
.map(k => ({dataPath: k, message: recordResponse.errors[k]}))
|
||||
.flat()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -65,8 +74,8 @@
|
|||
{#each modelSchema as [key, meta]}
|
||||
<div class="uk-margin">
|
||||
<RecordFieldControl
|
||||
className={CLASS_NAME_MAP[meta.type]}
|
||||
type={determineInputType(meta)}
|
||||
options={determineOptions(meta)}
|
||||
label={key}
|
||||
bind:value={record[key]} />
|
||||
</div>
|
||||
|
|
|
@ -3,10 +3,16 @@
|
|||
export let value = ""
|
||||
export let label
|
||||
export let errors = []
|
||||
export let className = "uk-input"
|
||||
export let options = []
|
||||
|
||||
let checked = type === "checkbox" ? value : false
|
||||
|
||||
const determineClassName = type => {
|
||||
if (type === "checkbox") return "uk-checkbox"
|
||||
if (type === "select") return "uk-select"
|
||||
return "uk-input"
|
||||
}
|
||||
|
||||
const handleInput = event => {
|
||||
if (event.target.type === "checkbox") {
|
||||
value = event.target.checked
|
||||
|
@ -23,11 +29,23 @@
|
|||
</script>
|
||||
|
||||
<label>{label}</label>
|
||||
|
||||
{#if type === "select"}
|
||||
<select
|
||||
class={determineClassName(type)}
|
||||
bind:value={value}
|
||||
class:uk-form-danger={errors.length > 0} >
|
||||
{#each options as opt}
|
||||
<option value={opt}>{ opt }</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else}
|
||||
<input
|
||||
class={className}
|
||||
class={determineClassName(type)}
|
||||
class:uk-form-danger={errors.length > 0}
|
||||
{checked}
|
||||
{type}
|
||||
{value}
|
||||
on:input={handleInput}
|
||||
on:change={handleInput} />
|
||||
{/if}
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.title > div:nth-child(1) {
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
// Go to correct URL
|
||||
$goto(`./:page/:screen/${path}`)
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import { params, goto } from "@sveltech/routify"
|
||||
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte"
|
||||
|
||||
import { last, sortBy, map, trimCharsStart, trimChars, join } from "lodash/fp"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import { pipe } from "components/common/core"
|
||||
|
@ -62,9 +61,7 @@
|
|||
{/if}
|
||||
</span>
|
||||
|
||||
<span class="icon">
|
||||
<ShapeIcon />
|
||||
</span>
|
||||
<i class="ri-artboard-2-fill icon" />
|
||||
|
||||
<span class="title">{screen.title}</span>
|
||||
</div>
|
||||
|
@ -88,21 +85,23 @@
|
|||
<style>
|
||||
.root {
|
||||
font-weight: 400;
|
||||
color: #000333;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
margin-top: 2px;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
transition: 0.2s;
|
||||
font-size: 24px;
|
||||
width: 20px;
|
||||
margin-top: 2px;
|
||||
color: #333;
|
||||
color: var(--ink-light);
|
||||
}
|
||||
|
||||
.icon:nth-of-type(2) {
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<script>
|
||||
import { store } from "builderStore/"
|
||||
import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
|
||||
import ComponentSelectionList from "./ComponentSelectionList.svelte"
|
||||
|
||||
const PROPERTIES_TAB = "properties"
|
||||
const COMPONENT_SELECTION_TAB = "components"
|
||||
|
||||
let selected = PROPERTIES_TAB
|
||||
|
||||
const isSelected = tab => selected === tab
|
||||
|
||||
const selectTab = tab => (selected = tab)
|
||||
|
||||
const toggleTab = () =>
|
||||
(selected =
|
||||
selected === PROPERTIES_TAB ? COMPONENT_SELECTION_TAB : PROPERTIES_TAB)
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
{#if $store.currentFrontEndType === 'page' || $store.screens.length}
|
||||
<div class="switcher">
|
||||
|
||||
<button
|
||||
class:selected={selected === COMPONENT_SELECTION_TAB}
|
||||
on:click={() => selectTab(COMPONENT_SELECTION_TAB)}>
|
||||
Add
|
||||
</button>
|
||||
|
||||
<button
|
||||
class:selected={selected === PROPERTIES_TAB}
|
||||
on:click={() => selectTab(PROPERTIES_TAB)}>
|
||||
Edit
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
{#if selected === PROPERTIES_TAB}
|
||||
<ComponentPropertiesPanel {toggleTab} />
|
||||
{/if}
|
||||
|
||||
{#if selected === COMPONENT_SELECTION_TAB}
|
||||
<ComponentSelectionList {toggleTab} />
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px 20px;
|
||||
border-left: solid 1px var(--grey);
|
||||
}
|
||||
|
||||
.switcher {
|
||||
display: flex;
|
||||
margin: 0px 20px 20px 0px;
|
||||
}
|
||||
|
||||
.switcher > button {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--ink-lighter);
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.switcher > .selected {
|
||||
color: var(--ink);
|
||||
}
|
||||
</style>
|
|
@ -3,7 +3,6 @@
|
|||
import ComponentsHierarchy from "components/userInterface/ComponentsHierarchy.svelte"
|
||||
import PageLayout from "components/userInterface/PageLayout.svelte"
|
||||
import PagesList from "components/userInterface/PagesList.svelte"
|
||||
import { AddIcon } from "components/common/Icons"
|
||||
import NewScreen from "components/userInterface/NewScreen.svelte"
|
||||
|
||||
const newScreen = () => {
|
||||
|
@ -13,114 +12,38 @@
|
|||
let newScreenPicker
|
||||
</script>
|
||||
|
||||
<div class="pages-list-container">
|
||||
<div class="nav-header">
|
||||
<span class="navigator-title">Navigate</span>
|
||||
<span class="components-nav-page">Pages</span>
|
||||
</div>
|
||||
<PagesList />
|
||||
|
||||
<div class="nav-items-container">
|
||||
<PagesList />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-line" />
|
||||
<button class="newscreen" on:click={newScreen}>Create New Screen</button>
|
||||
|
||||
<PageLayout layout={$store.pages[$store.currentPageName]} />
|
||||
|
||||
<div class="border-line" />
|
||||
|
||||
<div class="components-list-container">
|
||||
<div class="nav-group-header">
|
||||
<span class="components-nav-header" style="margin-top: 0;">
|
||||
Screens
|
||||
</span>
|
||||
<div>
|
||||
<button on:click={newScreen}>
|
||||
<AddIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-items-container">
|
||||
<div class="nav-items-container">
|
||||
<ComponentsHierarchy screens={$store.screens} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NewScreen bind:this={newScreenPicker} />
|
||||
|
||||
<style>
|
||||
|
||||
button {
|
||||
.newscreen {
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
width: 20px;
|
||||
padding-bottom: 10px;
|
||||
border: 1px solid var(--grey-dark);
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
padding: 8px 16px;
|
||||
margin: 12px 0px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.components-nav-page {
|
||||
font-size: 13px;
|
||||
background: white;
|
||||
color: var(--ink);
|
||||
padding-left: 20px;
|
||||
margin-top: 20px;
|
||||
font-weight: 600;
|
||||
opacity: 0.4;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 2ms;
|
||||
}
|
||||
|
||||
.components-nav-header {
|
||||
font-size: 13px;
|
||||
color: var(--ink);
|
||||
margin-top: 20px;
|
||||
font-weight: 600;
|
||||
opacity: 0.4;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.nav-items-container {
|
||||
padding: 1rem 0rem 0rem 0rem;
|
||||
}
|
||||
|
||||
.nav-group-header {
|
||||
display: flex;
|
||||
padding: 0px 20px 0px 20px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: bold;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-group-header > span:nth-child(3) {
|
||||
margin-left: 5px;
|
||||
vertical-align: bottom;
|
||||
grid-column-start: title;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.navigator-title {
|
||||
font-size: 18px;
|
||||
color: var(--ink);
|
||||
font-weight: bold;
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
.border-line {
|
||||
border-bottom: 1px solid #d8d8d8;
|
||||
}
|
||||
|
||||
.components-list-container {
|
||||
padding: 20px 0px 0 0;
|
||||
}
|
||||
.newscreen:hover {
|
||||
background: var(--grey-light);
|
||||
}
|
||||
|
||||
</style>
|
|
@ -3,7 +3,7 @@
|
|||
export let item
|
||||
</script>
|
||||
|
||||
<div class="item-item" transition:fly={{ y: 100, duration: 1000 }} on:click>
|
||||
<div class="item-item" in:fly={{ y: 100, duration: 1000 }} on:click>
|
||||
<div class="item-icon">
|
||||
<i class={item.icon} />
|
||||
</div>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
</script>
|
||||
|
||||
<div class="pagelayoutSection">
|
||||
<div class="components-nav-page">Page Layout</div>
|
||||
<div
|
||||
class="budibase__nav-item root"
|
||||
class:selected={$store.currentComponentInfo._id === _layout.component.props._id}
|
||||
|
@ -56,12 +55,8 @@
|
|||
class:rotate={$store.currentPreviewItem.name !== _layout.title}>
|
||||
<ArrowDownIcon />
|
||||
</span>
|
||||
|
||||
<span class="icon">
|
||||
<GridIcon />
|
||||
</span>
|
||||
|
||||
<span class="title">Page Layout</span>
|
||||
<i class="ri-layout-3-fill icon-big" />
|
||||
<span class="title">Master Screen</span>
|
||||
</div>
|
||||
|
||||
{#if $store.currentPreviewItem.name === _layout.title && _layout.component.props._children}
|
||||
|
@ -80,36 +75,28 @@
|
|||
onOk={() => store.deleteComponent(componentToDelete)} />
|
||||
|
||||
<style>
|
||||
.components-nav-page {
|
||||
font-size: 13px;
|
||||
color: #000333;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 20px;
|
||||
font-weight: 600;
|
||||
opacity: 0.4;
|
||||
letter-spacing: 1px;
|
||||
.pagelayoutSection {
|
||||
margin: 20px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.pagelayoutSection {
|
||||
margin: 20px 0px 20px 0px;
|
||||
}
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
display: inline-block;
|
||||
transition: 0.2s;
|
||||
width: 20px;
|
||||
margin-top: 2px;
|
||||
color: #000333;
|
||||
color: var(--ink-light);
|
||||
}
|
||||
|
||||
.icon:nth-of-type(2) {
|
||||
width: 14px;
|
||||
margin: 0 0 0 5px;
|
||||
.icon-big {
|
||||
font-size: 24px;
|
||||
color: var(--ink-light);
|
||||
}
|
||||
|
||||
:global(svg) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<script>
|
||||
import { params, goto } from "@sveltech/routify"
|
||||
import { store } from "builderStore"
|
||||
import getIcon from "components/common/icon"
|
||||
import { CheckIcon } from "components/common/Icons"
|
||||
|
||||
const getPage = (s, name) => {
|
||||
const props = s.pages[name]
|
||||
|
@ -30,63 +28,37 @@
|
|||
</script>
|
||||
|
||||
<div class="root">
|
||||
<ul>
|
||||
{#each pages as { title, id }}
|
||||
<li>
|
||||
<span class="icon">
|
||||
{#if id === $params.page}
|
||||
<CheckIcon />
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
<button
|
||||
class:active={id === $params.page}
|
||||
on:click={() => changePage(id)}>
|
||||
<button class:active={id === $params.page} on:click={() => changePage(id)}>
|
||||
{title}
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
padding-bottom: 10px;
|
||||
font-size: 0.9rem;
|
||||
color: #000333;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
padding-left: 1.8rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0.5rem 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0 0 0 6px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
font-family: Roboto;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
padding: 8px 16px;
|
||||
text-align: center;
|
||||
background: #ffffff;
|
||||
color: var(--ink-light);
|
||||
border-radius: 5px;
|
||||
font-family: Roboto;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
transition: all 0.3s;
|
||||
text-rendering: optimizeLegibility;
|
||||
border: none !important;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.active {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
color: #000333;
|
||||
background: var(--ink-light);
|
||||
color: var(--white);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -120,7 +120,6 @@
|
|||
background-color: var(--white);
|
||||
height: calc(100vh - 49px);
|
||||
padding: 0;
|
||||
overflow: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
@ -215,10 +214,6 @@
|
|||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.border-line {
|
||||
border-bottom: 1px solid #d8d8d8;
|
||||
}
|
||||
|
||||
.components-list-container {
|
||||
padding: 20px 0px 0 0;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,9 @@
|
|||
}
|
||||
})
|
||||
|
||||
|
||||
let confirmDeleteDialog
|
||||
let componentToDelete = ""
|
||||
|
||||
|
||||
let settingsView
|
||||
const settings = () => {
|
||||
settingsView.show()
|
||||
|
@ -50,7 +48,7 @@
|
|||
|
||||
<div class="ui-nav">
|
||||
|
||||
<Switcher bind:this={leftNavSwitcher} tabs={["Navigate", "Add"]}>
|
||||
<Switcher bind:this={leftNavSwitcher} tabs={['Navigate', 'Add']}>
|
||||
<div slot="0">
|
||||
<FrontendNavigatePane />
|
||||
</div>
|
||||
|
@ -59,7 +57,6 @@
|
|||
</div>
|
||||
</Switcher>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="preview-pane">
|
||||
|
@ -76,8 +73,6 @@
|
|||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
title="Confirm Delete"
|
||||
|
@ -100,7 +95,6 @@
|
|||
background-color: var(--white);
|
||||
height: calc(100vh - 49px);
|
||||
padding: 0;
|
||||
overflow: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 5;
|
||||
|
@ -118,8 +112,6 @@
|
|||
background-color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nav-group-header > div:nth-child(1) {
|
||||
padding: 0rem 0.5rem 0rem 0rem;
|
||||
vertical-align: bottom;
|
||||
|
@ -127,8 +119,6 @@
|
|||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nav-group-header > div:nth-child(3) {
|
||||
vertical-align: bottom;
|
||||
grid-column-start: button;
|
||||
|
@ -139,5 +129,4 @@
|
|||
.nav-group-header > div:nth-child(3):hover {
|
||||
color: var(--primary75);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -117,15 +117,6 @@
|
|||
</Modal>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
display: grid;
|
||||
grid-template-columns: 275px 1fr;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: var(--grey-light);
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1800px) {
|
||||
.root {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
|
@ -133,7 +124,6 @@
|
|||
width: 100%;
|
||||
background: var(--grey-light);
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
grid-column: 2;
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"@budibase/client": "^0.0.32",
|
||||
"@budibase/core": "^0.0.32",
|
||||
"@koa/router": "^8.0.0",
|
||||
"ajv": "^6.12.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"electron-is-dev": "^1.2.0",
|
||||
|
@ -66,6 +65,7 @@
|
|||
"squirrelly": "^7.5.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"uuid": "^3.3.2",
|
||||
"validate.js": "^0.13.1",
|
||||
"yargs": "^13.2.4",
|
||||
"zlib": "^1.0.5"
|
||||
},
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
const CouchDB = require("../../db")
|
||||
const Ajv = require("ajv")
|
||||
const validateJs = require("validate.js")
|
||||
const newid = require("../../db/newid")
|
||||
|
||||
const ajv = new Ajv()
|
||||
|
||||
exports.save = async function(ctx) {
|
||||
const db = new CouchDB(ctx.params.instanceId)
|
||||
const record = ctx.request.body
|
||||
|
@ -13,18 +11,18 @@ exports.save = async function(ctx) {
|
|||
record._id = newid()
|
||||
}
|
||||
|
||||
// validation with ajv
|
||||
const model = await db.get(record.modelId)
|
||||
const validate = ajv.compile({
|
||||
properties: model.schema,
|
||||
})
|
||||
const valid = validate(record)
|
||||
|
||||
if (!valid) {
|
||||
const validateResult = await validate({
|
||||
record,
|
||||
model,
|
||||
})
|
||||
|
||||
if (!validateResult.valid) {
|
||||
ctx.status = 400
|
||||
ctx.body = {
|
||||
status: 400,
|
||||
errors: validate.errors,
|
||||
errors: validateResult.errors,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -84,3 +82,29 @@ exports.destroy = async function(ctx) {
|
|||
}
|
||||
ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
|
||||
}
|
||||
|
||||
exports.validate = async function(ctx) {
|
||||
const errors = await validate({
|
||||
instanceId: ctx.params.instanceId,
|
||||
modelId: ctx.params.modelId,
|
||||
record: ctx.request.body,
|
||||
})
|
||||
ctx.status = 200
|
||||
ctx.body = errors
|
||||
}
|
||||
|
||||
async function validate({ instanceId, modelId, record, model }) {
|
||||
if (!model) {
|
||||
const db = new CouchDB(instanceId)
|
||||
model = await db.get(modelId)
|
||||
}
|
||||
const errors = {}
|
||||
for (let fieldName in model.schema) {
|
||||
const res = validateJs.single(
|
||||
record[fieldName],
|
||||
model.schema[fieldName].constraints
|
||||
)
|
||||
if (res) errors[fieldName] = res
|
||||
}
|
||||
return { valid: Object.keys(errors).length === 0, errors }
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ router
|
|||
authorized(WRITE_MODEL, ctx => ctx.params.modelId),
|
||||
recordController.save
|
||||
)
|
||||
.post(
|
||||
"/api/:instanceId/:modelId/records/validate",
|
||||
authorized(WRITE_MODEL, ctx => ctx.params.modelId),
|
||||
recordController.validate
|
||||
)
|
||||
.delete(
|
||||
"/api/:instanceId/:modelId/records/:recordId/:revId",
|
||||
authorized(WRITE_MODEL, ctx => ctx.params.modelId),
|
||||
|
|
|
@ -27,7 +27,12 @@ exports.createModel = async (request, instanceId, model) => {
|
|||
type: "model",
|
||||
key: "name",
|
||||
schema: {
|
||||
name: { type: "string" },
|
||||
name: {
|
||||
type: "text",
|
||||
constraints: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ describe("/records", () => {
|
|||
server.close();
|
||||
})
|
||||
|
||||
describe("save, load, update, delete", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
instance = await createInstance(request, app._id)
|
||||
model = await createModel(request, instance._id)
|
||||
|
@ -37,6 +35,8 @@ describe("/records", () => {
|
|||
}
|
||||
})
|
||||
|
||||
describe("save, load, update, delete", () => {
|
||||
|
||||
const createRecord = async r =>
|
||||
await request
|
||||
.post(`/api/${instance._id}/${model._id}/records`)
|
||||
|
@ -119,4 +119,31 @@ describe("/records", () => {
|
|||
.expect(404)
|
||||
})
|
||||
})
|
||||
|
||||
describe("validate", () => {
|
||||
it("should return no errors on valid record", async () => {
|
||||
const result = await request
|
||||
.post(`/api/${instance._id}/${model._id}/records/validate`)
|
||||
.send({ name: "ivan" })
|
||||
.set(defaultHeaders)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
||||
expect(result.body.valid).toBe(true)
|
||||
expect(Object.keys(result.body.errors)).toEqual([])
|
||||
})
|
||||
|
||||
it("should errors on invalid record", async () => {
|
||||
const result = await request
|
||||
.post(`/api/${instance._id}/${model._id}/records/validate`)
|
||||
.send({ name: 1 })
|
||||
.set(defaultHeaders)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
||||
expect(result.body.valid).toBe(false)
|
||||
expect(Object.keys(result.body.errors)).toEqual(["name"])
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -194,6 +194,20 @@
|
|||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@budibase/client@^0.0.32":
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.32.tgz#76d9f147563a0bf939eae7f32ce75b2a527ba496"
|
||||
integrity sha512-jmCCLn0CUoQbL6h623S5IqK6+GYLqX3WzUTZInSb1SCBOM3pI0eLP5HwTR6s7r42SfD0v9jTWRdyTnHiElNj8A==
|
||||
dependencies:
|
||||
"@nx-js/compiler-util" "^2.0.0"
|
||||
bcryptjs "^2.4.3"
|
||||
deep-equal "^2.0.1"
|
||||
lodash "^4.17.15"
|
||||
lunr "^2.3.5"
|
||||
regexparam "^1.3.0"
|
||||
shortid "^2.2.8"
|
||||
svelte "^3.9.2"
|
||||
|
||||
"@budibase/core@^0.0.32":
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.32.tgz#c5d9ab869c5e9596a1ac337aaf041e795b1cc7fa"
|
||||
|
@ -655,7 +669,7 @@ ajv-keywords@^3.4.1:
|
|||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
|
||||
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
|
||||
|
||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2:
|
||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0:
|
||||
version "6.12.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
|
||||
integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==
|
||||
|
@ -825,6 +839,11 @@ array-equal@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
||||
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
|
||||
|
||||
array-filter@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
|
||||
integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
|
||||
|
||||
array-unique@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
|
||||
|
@ -897,6 +916,13 @@ atomic-sleep@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
|
||||
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
|
||||
|
||||
available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5"
|
||||
integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==
|
||||
dependencies:
|
||||
array-filter "^1.0.0"
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
|
@ -1612,6 +1638,26 @@ decompress-response@^3.3.0:
|
|||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
deep-equal@^2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.3.tgz#cad1c15277ad78a5c01c49c2dee0f54de8a6a7b0"
|
||||
integrity sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA==
|
||||
dependencies:
|
||||
es-abstract "^1.17.5"
|
||||
es-get-iterator "^1.1.0"
|
||||
is-arguments "^1.0.4"
|
||||
is-date-object "^1.0.2"
|
||||
is-regex "^1.0.5"
|
||||
isarray "^2.0.5"
|
||||
object-is "^1.1.2"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.0"
|
||||
regexp.prototype.flags "^1.3.0"
|
||||
side-channel "^1.0.2"
|
||||
which-boxed-primitive "^1.0.1"
|
||||
which-collection "^1.0.1"
|
||||
which-typed-array "^1.1.2"
|
||||
|
||||
deep-equal@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
|
||||
|
@ -1965,7 +2011,7 @@ error-inject@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
|
||||
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
|
||||
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5:
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5:
|
||||
version "1.17.5"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9"
|
||||
integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==
|
||||
|
@ -1982,6 +2028,19 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5:
|
|||
string.prototype.trimleft "^2.1.1"
|
||||
string.prototype.trimright "^2.1.1"
|
||||
|
||||
es-get-iterator@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
|
||||
integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
|
||||
dependencies:
|
||||
es-abstract "^1.17.4"
|
||||
has-symbols "^1.0.1"
|
||||
is-arguments "^1.0.4"
|
||||
is-map "^2.0.1"
|
||||
is-set "^2.0.1"
|
||||
is-string "^1.0.5"
|
||||
isarray "^2.0.5"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
|
@ -2967,11 +3026,21 @@ is-accessor-descriptor@^1.0.0:
|
|||
dependencies:
|
||||
kind-of "^6.0.0"
|
||||
|
||||
is-arguments@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
|
||||
integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
|
||||
|
||||
is-bigint@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"
|
||||
integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
|
@ -2979,6 +3048,11 @@ is-binary-path@~2.1.0:
|
|||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-boolean-object@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
|
||||
integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
|
||||
|
||||
is-buffer@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
@ -3015,7 +3089,7 @@ is-data-descriptor@^1.0.0:
|
|||
dependencies:
|
||||
kind-of "^6.0.0"
|
||||
|
||||
is-date-object@^1.0.1:
|
||||
is-date-object@^1.0.1, is-date-object@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
|
||||
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
|
||||
|
@ -3090,11 +3164,21 @@ is-installed-globally@^0.3.1:
|
|||
global-dirs "^2.0.1"
|
||||
is-path-inside "^3.0.1"
|
||||
|
||||
is-map@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
|
||||
integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
|
||||
|
||||
is-npm@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
|
||||
integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
|
||||
|
||||
is-number-object@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
|
||||
integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
|
||||
|
||||
is-number@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
|
||||
|
@ -3131,11 +3215,21 @@ is-regex@^1.0.5:
|
|||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-set@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
|
||||
integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
is-string@^1.0.4, is-string@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
|
||||
integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
|
||||
|
||||
is-symbol@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
|
||||
|
@ -3152,11 +3246,31 @@ is-type-of@^1.0.0:
|
|||
is-class-hotfix "~0.0.6"
|
||||
isstream "~0.1.2"
|
||||
|
||||
is-typed-array@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d"
|
||||
integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==
|
||||
dependencies:
|
||||
available-typed-arrays "^1.0.0"
|
||||
es-abstract "^1.17.4"
|
||||
foreach "^2.0.5"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
is-weakmap@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
|
||||
integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
|
||||
|
||||
is-weakset@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"
|
||||
integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==
|
||||
|
||||
is-windows@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||
|
@ -3182,6 +3296,11 @@ isarray@1.0.0, isarray@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isarray@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
|
||||
|
||||
isbinaryfile@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b"
|
||||
|
@ -4589,6 +4708,14 @@ object-inspect@^1.7.0:
|
|||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
|
||||
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
|
||||
|
||||
object-is@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6"
|
||||
integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.5"
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
|
@ -5310,6 +5437,19 @@ regex-not@^1.0.0, regex-not@^1.0.2:
|
|||
extend-shallow "^3.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
regexp.prototype.flags@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
|
||||
integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.0-next.1"
|
||||
|
||||
regexparam@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
|
||||
integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
|
||||
|
||||
regexpp@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
|
||||
|
@ -5638,6 +5778,14 @@ shortid@^2.2.8:
|
|||
dependencies:
|
||||
nanoid "^2.1.0"
|
||||
|
||||
side-channel@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
|
||||
integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
|
||||
dependencies:
|
||||
es-abstract "^1.17.0-next.1"
|
||||
object-inspect "^1.7.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
|
@ -6046,6 +6194,11 @@ supports-color@^7.1.0:
|
|||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
svelte@^3.9.2:
|
||||
version "3.23.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.23.0.tgz#bbcd6887cf588c24a975b14467455abfff9acd3f"
|
||||
integrity sha512-cnyd96bK/Nw5DnYuB1hzm5cl6+I1fpmdKOteA7KLzU9KGLsLmvWsSkSKbcntzODCLmSySN3HjcgTHRo6/rJNTw==
|
||||
|
||||
symbol-tree@^3.2.2:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
|
@ -6458,6 +6611,11 @@ validate-npm-package-license@^3.0.1:
|
|||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
validate.js@^0.13.1:
|
||||
version "0.13.1"
|
||||
resolved "https://registry.yarnpkg.com/validate.js/-/validate.js-0.13.1.tgz#b58bfac04a0f600a340f62e5227e70d95971e92a"
|
||||
integrity sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==
|
||||
|
||||
vary@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
|
@ -6526,11 +6684,44 @@ whatwg-url@^7.0.0:
|
|||
tr46 "^1.0.1"
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
which-boxed-primitive@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"
|
||||
integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==
|
||||
dependencies:
|
||||
is-bigint "^1.0.0"
|
||||
is-boolean-object "^1.0.0"
|
||||
is-number-object "^1.0.3"
|
||||
is-string "^1.0.4"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
which-collection@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
|
||||
integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
|
||||
dependencies:
|
||||
is-map "^2.0.1"
|
||||
is-set "^2.0.1"
|
||||
is-weakmap "^2.0.1"
|
||||
is-weakset "^2.0.1"
|
||||
|
||||
which-module@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||
|
||||
which-typed-array@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2"
|
||||
integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==
|
||||
dependencies:
|
||||
available-typed-arrays "^1.0.2"
|
||||
es-abstract "^1.17.5"
|
||||
foreach "^2.0.5"
|
||||
function-bind "^1.1.1"
|
||||
has-symbols "^1.0.1"
|
||||
is-typed-array "^1.1.3"
|
||||
|
||||
which@^1.2.9, which@^1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
|
|
Loading…
Reference in New Issue