Merge branch 'master' of github.com:Budibase/budibase into linked-records
This commit is contained in:
commit
3dc30262d7
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
"test:e2e:ci": "lerna run cy:ci"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome": "^1.1.8",
|
||||
"pouchdb-replication-stream": "^1.2.9"
|
||||
"@fortawesome/fontawesome": "^1.1.8"
|
||||
}
|
||||
}
|
|
@ -50,13 +50,11 @@ context("Create a View", () => {
|
|||
|
||||
it("creates a stats calculation view based on age", () => {
|
||||
cy.contains("Calculate").click()
|
||||
// we may reinstate this - have commented this dropdown for now as there is only one option
|
||||
//cy.get(".menu-container").find("select").first().select("Statistics")
|
||||
cy.get(".menu-container")
|
||||
.find("select")
|
||||
.first()
|
||||
.select("Statistics")
|
||||
cy.get(".menu-container")
|
||||
.find("select")
|
||||
.eq(1)
|
||||
.eq(0)
|
||||
.select("age")
|
||||
cy.contains("Save").click()
|
||||
cy.get("thead th div").should($headers => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"license": "AGPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -64,7 +64,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.40.1",
|
||||
"@budibase/client": "^0.1.23",
|
||||
"@budibase/client": "^0.1.25",
|
||||
"@budibase/colorpicker": "^1.0.1",
|
||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||
"@sentry/browser": "5.19.1",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import Table from "./Table.svelte"
|
||||
|
||||
let data = []
|
||||
let loading = false
|
||||
|
||||
$: title = $backendUiStore.selectedModel.name
|
||||
$: schema = $backendUiStore.selectedModel.schema
|
||||
|
@ -19,14 +20,16 @@
|
|||
// Fetch records for specified model
|
||||
$: {
|
||||
if ($backendUiStore.selectedView?.name?.startsWith("all_")) {
|
||||
loading = true
|
||||
api.fetchDataForView($backendUiStore.selectedView).then(records => {
|
||||
data = records || []
|
||||
loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Table {title} {schema} {data} allowEditing={true}>
|
||||
<Table {title} {schema} {data} allowEditing={true} {loading}>
|
||||
<CreateColumnButton />
|
||||
{#if Object.keys(schema).length > 0}
|
||||
<CreateRowButton />
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { goto, params } from "@sveltech/routify"
|
||||
import { onMount } from "svelte"
|
||||
import { fade } from "svelte/transition"
|
||||
import fsort from "fast-sort"
|
||||
import getOr from "lodash/fp/getOr"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
|
@ -16,6 +17,7 @@
|
|||
import ColumnHeaderPopover from "./popovers/ColumnPopover.svelte"
|
||||
import EditRowPopover from "./popovers/RowPopover.svelte"
|
||||
import CalculationPopover from "./buttons/CalculateButton.svelte"
|
||||
import Spinner from "components/common/Spinner.svelte"
|
||||
|
||||
const ITEMS_PER_PAGE = 10
|
||||
|
||||
|
@ -23,6 +25,7 @@
|
|||
export let data = []
|
||||
export let title
|
||||
export let allowEditing = false
|
||||
export let loading = false
|
||||
|
||||
let currentPage = 0
|
||||
|
||||
|
@ -50,7 +53,14 @@
|
|||
|
||||
<section>
|
||||
<div class="table-controls">
|
||||
<h2 class="title">{title}</h2>
|
||||
<h2 class="title">
|
||||
<span>{title}</span>
|
||||
{#if loading}
|
||||
<div transition:fade>
|
||||
<Spinner size="10" />
|
||||
</div>
|
||||
{/if}
|
||||
</h2>
|
||||
<div class="popovers">
|
||||
<slot />
|
||||
</div>
|
||||
|
@ -123,6 +133,13 @@
|
|||
text-rendering: optimizeLegibility;
|
||||
text-transform: capitalize;
|
||||
margin-top: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.title > span {
|
||||
margin-right: var(--spacing-xs);
|
||||
}
|
||||
|
||||
table {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
)
|
||||
|
||||
function saveView() {
|
||||
if (!view.calculation) view.calculation = "stats"
|
||||
backendUiStore.actions.views.save(view)
|
||||
notifier.success(`View ${view.name} saved.`)
|
||||
onClosed()
|
||||
|
@ -34,14 +35,15 @@
|
|||
<div class="actions">
|
||||
<h5>Calculate</h5>
|
||||
<div class="input-group-row">
|
||||
<p>The</p>
|
||||
<!-- <p>The</p>
|
||||
<Select secondary thin bind:value={view.calculation}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each CALCULATIONS as calculation}
|
||||
<option value={calculation.key}>{calculation.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
<p>of</p>
|
||||
<p>of</p> -->
|
||||
<p>The statistics of</p>
|
||||
<Select secondary thin bind:value={view.field}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each fields as field}
|
||||
|
@ -74,7 +76,7 @@
|
|||
|
||||
.input-group-row {
|
||||
display: grid;
|
||||
grid-template-columns: 30px 1fr 20px 1fr;
|
||||
grid-template-columns: auto 1fr 20px 1fr;
|
||||
gap: var(--spacing-s);
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
$: modelOptions = $backendUiStore.models.filter(
|
||||
model => model._id !== $backendUiStore.draftModel._id
|
||||
)
|
||||
$: required = !!field?.constraints?.presence
|
||||
|
||||
async function saveColumn() {
|
||||
backendUiStore.update(state => {
|
||||
|
@ -53,6 +54,12 @@
|
|||
field.type = type
|
||||
field.constraints = constraints
|
||||
}
|
||||
|
||||
function onChangeRequired(e) {
|
||||
const req = e.target.checked
|
||||
field.constraints.presence = req ? { allowEmpty: false } : false
|
||||
required = req
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="actions">
|
||||
|
@ -71,8 +78,8 @@
|
|||
|
||||
{#if field.type !== 'link'}
|
||||
<Toggle
|
||||
checked={!field.constraints.presence.allowEmpty}
|
||||
on:change={e => (field.constraints.presence.allowEmpty = !e.target.checked)}
|
||||
checked={required}
|
||||
on:change={onChangeRequired}
|
||||
thin
|
||||
text="Required" />
|
||||
{/if}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { Button, Input, Select } from "@budibase/bbui"
|
||||
import { Button, Input, Select, DatePicker } from "@budibase/bbui"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import analytics from "analytics"
|
||||
|
@ -71,11 +71,38 @@
|
|||
|
||||
function isMultipleChoice(field) {
|
||||
return (
|
||||
viewModel.schema[field].constraints &&
|
||||
viewModel.schema[field].constraints.inclusion &&
|
||||
viewModel.schema[field].constraints.inclusion.length
|
||||
(viewModel.schema[field].constraints &&
|
||||
viewModel.schema[field].constraints.inclusion &&
|
||||
viewModel.schema[field].constraints.inclusion.length) ||
|
||||
viewModel.schema[field].type === "boolean"
|
||||
)
|
||||
}
|
||||
|
||||
function fieldOptions(field) {
|
||||
return viewModel.schema[field].type === "string"
|
||||
? viewModel.schema[field].constraints.inclusion
|
||||
: [true, false]
|
||||
}
|
||||
|
||||
function isDate(field) {
|
||||
return viewModel.schema[field].type === "datetime"
|
||||
}
|
||||
|
||||
function isNumber(field) {
|
||||
return viewModel.schema[field].type === "number"
|
||||
}
|
||||
|
||||
const fieldChanged = filter => ev => {
|
||||
// reset if type changed
|
||||
if (
|
||||
filter.key &&
|
||||
ev.target.value &&
|
||||
viewModel.schema[filter.key].type !==
|
||||
viewModel.schema[ev.target.value].type
|
||||
) {
|
||||
filter.value = ""
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="actions">
|
||||
|
@ -99,6 +126,16 @@
|
|||
<option value={field}>{field}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
<Select
|
||||
secondary
|
||||
thin
|
||||
bind:value={filter.key}
|
||||
on:change={fieldChanged(filter)}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each fields as field}
|
||||
<option value={field}>{field}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
<Select secondary thin bind:value={filter.condition}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each CONDITIONS as condition}
|
||||
|
@ -108,12 +145,25 @@
|
|||
{#if filter.key && isMultipleChoice(filter.key)}
|
||||
<Select secondary thin bind:value={filter.value}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each viewModel.schema[filter.key].constraints.inclusion as option}
|
||||
<option value={option}>{option}</option>
|
||||
{#each fieldOptions(filter.key) as option}
|
||||
<option value={option}>{option.toString()}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
{:else if filter.key && isDate(filter.key)}
|
||||
<DatePicker
|
||||
bind:value={filter.value}
|
||||
placeholder={filter.key || fields[0]} />
|
||||
{:else if filter.key && isNumber(filter.key)}
|
||||
<Input
|
||||
thin
|
||||
bind:value={filter.value}
|
||||
placeholder={filter.key || fields[0]}
|
||||
type="number" />
|
||||
{:else}
|
||||
<Input thin placeholder="Value" bind:value={filter.value} />
|
||||
<Input
|
||||
thin
|
||||
placeholder={filter.key || fields[0]}
|
||||
bind:value={filter.value} />
|
||||
{/if}
|
||||
<i class="ri-close-circle-fill" on:click={() => removeFilter(idx)} />
|
||||
{/each}
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
<script>
|
||||
import { Heading, Body, Button, Select } from "@budibase/bbui"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import { FIELDS } from "constants/backend"
|
||||
import api from "builderStore/api"
|
||||
|
||||
const BYTES_IN_KB = 1000
|
||||
const BYTES_IN_MB = 1000000
|
||||
const FILE_SIZE_LIMIT = BYTES_IN_MB * 1
|
||||
|
||||
export let files = []
|
||||
export let dataImport = {
|
||||
valid: true,
|
||||
schema: {},
|
||||
}
|
||||
|
||||
let parseResult
|
||||
|
||||
$: schema = parseResult && parseResult.schema
|
||||
$: valid =
|
||||
!schema || Object.keys(schema).every(column => schema[column].success)
|
||||
$: dataImport = {
|
||||
valid,
|
||||
schema: buildModelSchema(schema),
|
||||
path: files[0] && files[0].path,
|
||||
}
|
||||
|
||||
function buildModelSchema(schema) {
|
||||
const modelSchema = {}
|
||||
for (let key in schema) {
|
||||
const type = schema[key].type
|
||||
|
||||
if (type === "omit") continue
|
||||
|
||||
modelSchema[key] = {
|
||||
name: key,
|
||||
type,
|
||||
constraints: FIELDS[type.toUpperCase()].constraints,
|
||||
}
|
||||
}
|
||||
return modelSchema
|
||||
}
|
||||
|
||||
async function validateCSV() {
|
||||
const response = await api.post("/api/models/csv/validate", {
|
||||
file: files[0],
|
||||
schema: schema || {},
|
||||
})
|
||||
|
||||
parseResult = await response.json()
|
||||
|
||||
if (response.status !== 200) {
|
||||
notifier.danger("CSV Invalid, please try another CSV file")
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFile(evt) {
|
||||
const fileArray = Array.from(evt.target.files)
|
||||
const filesToProcess = fileArray.map(({ name, path, size }) => ({
|
||||
name,
|
||||
path,
|
||||
size,
|
||||
}))
|
||||
|
||||
if (filesToProcess.some(file => file.size >= FILE_SIZE_LIMIT)) {
|
||||
notifier.danger(
|
||||
`Files cannot exceed ${FILE_SIZE_LIMIT /
|
||||
BYTES_IN_MB}MB. Please try again with smaller files.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
files = filesToProcess
|
||||
|
||||
await validateCSV()
|
||||
}
|
||||
|
||||
async function omitColumn(columnName) {
|
||||
schema[columnName].type = "omit"
|
||||
await validateCSV()
|
||||
}
|
||||
|
||||
const handleTypeChange = column => evt => {
|
||||
schema[column].type = evt.target.value
|
||||
validateCSV()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="dropzone">
|
||||
<input id="file-upload" accept=".csv" type="file" on:change={handleFile} />
|
||||
<label for="file-upload" class:uploaded={files[0]}>
|
||||
{#if files[0]}{files[0].name}{:else}Upload{/if}
|
||||
</label>
|
||||
</div>
|
||||
<div class="schema-fields">
|
||||
{#if schema}
|
||||
{#each Object.keys(schema).filter(key => schema[key].type !== 'omit') as columnName}
|
||||
<div class="field">
|
||||
<span>{columnName}</span>
|
||||
<Select
|
||||
secondary
|
||||
thin
|
||||
bind:value={schema[columnName].type}
|
||||
on:change={handleTypeChange(columnName)}>
|
||||
<option value={'string'}>Text</option>
|
||||
<option value={'number'}>Number</option>
|
||||
<option value={'datetime'}>Date</option>
|
||||
</Select>
|
||||
<span class="field-status" class:error={!schema[columnName].success}>
|
||||
{schema[columnName].success ? 'Success' : 'Failure'}
|
||||
</span>
|
||||
<i
|
||||
class="omit-button ri-close-circle-fill"
|
||||
on:click={() => omitColumn(columnName)} />
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dropzone {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
border-radius: 10px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.field-status {
|
||||
color: var(--green);
|
||||
justify-self: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.uploaded {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label {
|
||||
font-family: var(--font-sans);
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius-s);
|
||||
color: var(--ink);
|
||||
padding: var(--spacing-s) var(--spacing-l);
|
||||
transition: all 0.2s ease 0s;
|
||||
display: inline-flex;
|
||||
text-rendering: optimizeLegibility;
|
||||
min-width: auto;
|
||||
outline: none;
|
||||
font-feature-settings: "case" 1, "rlig" 1, "calt" 0;
|
||||
-webkit-box-align: center;
|
||||
user-select: none;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
background-color: var(--grey-2);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
.omit-button {
|
||||
font-size: 1.2em;
|
||||
color: var(--grey-7);
|
||||
cursor: pointer;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
margin-top: var(--spacing-m);
|
||||
align-items: center;
|
||||
grid-gap: var(--spacing-m);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
</style>
|
|
@ -2,23 +2,30 @@
|
|||
import { goto } from "@sveltech/routify"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import { Popover, Button, Icon, Input, Select } from "@budibase/bbui"
|
||||
import { Popover, Button, Icon, Input, Select, Label } from "@budibase/bbui"
|
||||
import Spinner from "components/common/Spinner.svelte"
|
||||
import TableDataImport from "../TableDataImport.svelte"
|
||||
import analytics from "analytics"
|
||||
|
||||
let anchor
|
||||
let dropdown
|
||||
let name
|
||||
let dataImport
|
||||
let loading
|
||||
|
||||
async function saveTable() {
|
||||
loading = true
|
||||
const model = await backendUiStore.actions.models.save({
|
||||
name,
|
||||
schema: {},
|
||||
schema: dataImport.schema || {},
|
||||
dataImport,
|
||||
})
|
||||
notifier.success(`Table ${name} created successfully.`)
|
||||
$goto(`./model/${model._id}`)
|
||||
analytics.captureEvent("Table Created", { name })
|
||||
name = ""
|
||||
dropdown.hide()
|
||||
analytics.captureEvent("Table Created", { name })
|
||||
loading = false
|
||||
}
|
||||
|
||||
const onClosed = () => {
|
||||
|
@ -38,9 +45,21 @@
|
|||
thin
|
||||
label="Table Name"
|
||||
bind:value={name} />
|
||||
<div>
|
||||
<Label grey extraSmall>Create Table from CSV (Optional)</Label>
|
||||
<TableDataImport bind:dataImport />
|
||||
</div>
|
||||
<footer>
|
||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||
<Button primary on:click={saveTable}>Save</Button>
|
||||
<Button
|
||||
disabled={!name || (dataImport && !dataImport.valid)}
|
||||
primary
|
||||
on:click={saveTable}>
|
||||
<span style={`margin-right: ${loading ? '10px' : 0};`}>Save</span>
|
||||
{#if loading}
|
||||
<Spinner size="10" />
|
||||
{/if}
|
||||
</Button>
|
||||
</footer>
|
||||
</div>
|
||||
</Popover>
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
})
|
||||
const appJson = await appResp.json()
|
||||
analytics.captureEvent("App Created", {
|
||||
name,
|
||||
name: $createAppStore.values.applicationName,
|
||||
appId: appJson._id,
|
||||
template,
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
on:input={() => (blurred.api = true)}
|
||||
label="API Key"
|
||||
name="apiKey"
|
||||
placeholder="Enter your API Key"
|
||||
placeholder="Use command-V to paste your API Key"
|
||||
type="password"
|
||||
error={blurred.api && validationErrors.apiKey} />
|
||||
<a target="_blank" href="https://portal.budi.live/">Get API Key</a>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
label="Password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
type="pasword"
|
||||
type="password"
|
||||
error={blurred.password && validationErrors.password} />
|
||||
<Select label="Access Level" secondary name="accessLevelId">
|
||||
<option value="ADMIN">Admin</option>
|
||||
|
|
|
@ -6,7 +6,7 @@ export const FIELDS = {
|
|||
constraints: {
|
||||
type: "string",
|
||||
length: {},
|
||||
presence: { allowEmpty: true },
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
OPTIONS: {
|
||||
|
@ -25,7 +25,7 @@ export const FIELDS = {
|
|||
type: "number",
|
||||
constraints: {
|
||||
type: "number",
|
||||
presence: { allowEmpty: true },
|
||||
presence: false,
|
||||
numericality: { greaterThanOrEqualTo: "", lessThanOrEqualTo: "" },
|
||||
},
|
||||
},
|
||||
|
@ -35,7 +35,7 @@ export const FIELDS = {
|
|||
type: "boolean",
|
||||
constraints: {
|
||||
type: "boolean",
|
||||
presence: { allowEmpty: true },
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
DATETIME: {
|
||||
|
@ -45,7 +45,7 @@ export const FIELDS = {
|
|||
constraints: {
|
||||
type: "string",
|
||||
length: {},
|
||||
presence: { allowEmpty: true },
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
|
@ -58,7 +58,7 @@ export const FIELDS = {
|
|||
type: "attachment",
|
||||
constraints: {
|
||||
type: "array",
|
||||
presence: { allowEmpty: true },
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
LINK: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "budibase",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"description": "Budibase CLI",
|
||||
"repository": "https://github.com/Budibase/Budibase",
|
||||
"homepage": "https://www.budibase.com",
|
||||
|
@ -17,7 +17,7 @@
|
|||
"author": "Budibase",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@budibase/server": "^0.1.23",
|
||||
"@budibase/server": "^0.1.25",
|
||||
"@inquirer/password": "^0.0.6-alpha.0",
|
||||
"chalk": "^2.4.2",
|
||||
"dotenv": "^8.2.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"license": "MPL-2.0",
|
||||
"main": "dist/budibase-client.js",
|
||||
"module": "dist/budibase-client.esm.mjs",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/server",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"description": "Budibase Web Server",
|
||||
"main": "src/electron.js",
|
||||
"repository": {
|
||||
|
@ -42,13 +42,14 @@
|
|||
"author": "Michael Shanks",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@budibase/client": "^0.1.23",
|
||||
"@budibase/client": "^0.1.25",
|
||||
"@koa/router": "^8.0.0",
|
||||
"@sendgrid/mail": "^7.1.1",
|
||||
"@sentry/node": "^5.19.2",
|
||||
"aws-sdk": "^2.706.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"chmodr": "^1.2.0",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dotenv": "^8.2.0",
|
||||
"download": "^8.0.0",
|
||||
"electron-is-dev": "^1.2.0",
|
||||
|
@ -71,6 +72,7 @@
|
|||
"pino-pretty": "^4.0.0",
|
||||
"pouchdb": "^7.2.1",
|
||||
"pouchdb-all-dbs": "^1.0.2",
|
||||
"pouchdb-replication-stream": "^1.2.9",
|
||||
"sharp": "^0.26.0",
|
||||
"squirrelly": "^7.5.0",
|
||||
"tar-fs": "^2.1.0",
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
const CouchDB = require("../../db")
|
||||
const linkRecords = require("../../db/linkedRecords")
|
||||
const csvParser = require("../../utilities/csvParser")
|
||||
const {
|
||||
getRecordParams,
|
||||
getModelParams,
|
||||
generateModelID,
|
||||
generateRecordID,
|
||||
} = require("../../db/utils")
|
||||
|
||||
exports.fetch = async function(ctx) {
|
||||
|
@ -24,11 +26,12 @@ exports.find = async function(ctx) {
|
|||
exports.save = async function(ctx) {
|
||||
const instanceId = ctx.user.instanceId
|
||||
const db = new CouchDB(instanceId)
|
||||
const { dataImport, ...rest } = ctx.request.body
|
||||
const modelToSave = {
|
||||
type: "model",
|
||||
_id: generateModelID(),
|
||||
views: {},
|
||||
...ctx.request.body,
|
||||
...rest,
|
||||
}
|
||||
// get the model in its previous state for differencing
|
||||
let oldModel
|
||||
|
@ -89,6 +92,19 @@ exports.save = async function(ctx) {
|
|||
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitModel(`model:save`, instanceId, modelToSave)
|
||||
|
||||
if (dataImport && dataImport.path) {
|
||||
// Populate the table with records imported from CSV in a bulk update
|
||||
const data = await csvParser.transform(dataImport)
|
||||
|
||||
for (let row of data) {
|
||||
row._id = generateRecordID(modelToSave._id)
|
||||
row.modelId = modelToSave._id
|
||||
}
|
||||
|
||||
await db.bulkDocs(data)
|
||||
}
|
||||
|
||||
ctx.status = 200
|
||||
ctx.message = `Model ${ctx.request.body.name} saved successfully.`
|
||||
ctx.body = modelToSave
|
||||
|
@ -124,3 +140,12 @@ exports.destroy = async function(ctx) {
|
|||
ctx.status = 200
|
||||
ctx.message = `Model ${ctx.params.modelId} deleted.`
|
||||
}
|
||||
|
||||
exports.validateCSVSchema = async function(ctx) {
|
||||
const { file, schema = {} } = ctx.request.body
|
||||
const result = await csvParser.parse(file.path, schema)
|
||||
ctx.body = {
|
||||
schema: result,
|
||||
path: file.path,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ const CouchDB = require("../../db")
|
|||
const validateJs = require("validate.js")
|
||||
const linkRecords = require("../../db/linkedRecords")
|
||||
const { getRecordParams, generateRecordID } = require("../../db/utils")
|
||||
const { cloneDeep } = require("lodash")
|
||||
|
||||
const MODEL_VIEW_BEGINS_WITH = "all_model:"
|
||||
|
||||
|
@ -21,6 +22,7 @@ exports.patch = async function(ctx) {
|
|||
let record = await db.get(ctx.params.id)
|
||||
const model = await db.get(record.modelId)
|
||||
const patchfields = ctx.request.body
|
||||
record = coerceRecordValues(record, model)
|
||||
|
||||
for (let key of Object.keys(patchfields)) {
|
||||
if (!model.schema[key]) continue
|
||||
|
@ -72,6 +74,8 @@ exports.save = async function(ctx) {
|
|||
|
||||
const model = await db.get(record.modelId)
|
||||
|
||||
record = coerceRecordValues(record, model)
|
||||
|
||||
const validateResult = await validate({
|
||||
record,
|
||||
model,
|
||||
|
@ -284,3 +288,50 @@ exports.fetchEnrichedRecord = async function(ctx) {
|
|||
ctx.body = record
|
||||
ctx.status = 200
|
||||
}
|
||||
|
||||
function coerceRecordValues(rec, model) {
|
||||
const record = cloneDeep(rec)
|
||||
for (let [key, value] of Object.entries(record)) {
|
||||
const field = model.schema[key]
|
||||
if (!field) continue
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (TYPE_TRANSFORM_MAP[field.type].hasOwnProperty(value)) {
|
||||
record[key] = TYPE_TRANSFORM_MAP[field.type][value]
|
||||
} else if (TYPE_TRANSFORM_MAP[field.type].parse) {
|
||||
record[key] = TYPE_TRANSFORM_MAP[field.type].parse(value)
|
||||
}
|
||||
}
|
||||
return record
|
||||
}
|
||||
|
||||
const TYPE_TRANSFORM_MAP = {
|
||||
string: {
|
||||
"": "",
|
||||
[null]: "",
|
||||
[undefined]: undefined,
|
||||
},
|
||||
number: {
|
||||
"": null,
|
||||
[null]: null,
|
||||
[undefined]: undefined,
|
||||
parse: n => parseFloat(n),
|
||||
},
|
||||
datetime: {
|
||||
"": null,
|
||||
[undefined]: undefined,
|
||||
[null]: null,
|
||||
},
|
||||
attachment: {
|
||||
"": [],
|
||||
[null]: [],
|
||||
[undefined]: undefined,
|
||||
},
|
||||
boolean: {
|
||||
"": null,
|
||||
[null]: null,
|
||||
[undefined]: undefined,
|
||||
true: true,
|
||||
false: false,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -61,8 +61,11 @@ function parseFilterExpression(filters) {
|
|||
`doc["${filter.key}"].${TOKEN_MAP[filter.condition]}("${filter.value}")`
|
||||
)
|
||||
} else {
|
||||
const value =
|
||||
typeof filter.value == "string" ? `"${filter.value}"` : filter.value
|
||||
|
||||
expression.push(
|
||||
`doc["${filter.key}"] ${TOKEN_MAP[filter.condition]} "${filter.value}"`
|
||||
`doc["${filter.key}"] ${TOKEN_MAP[filter.condition]} ${value}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ router
|
|||
modelController.find
|
||||
)
|
||||
.post("/api/models", authorized(BUILDER), modelController.save)
|
||||
.post(
|
||||
"/api/models/csv/validate",
|
||||
authorized(BUILDER),
|
||||
modelController.validateCSVSchema
|
||||
)
|
||||
.delete(
|
||||
"/api/models/:modelId/:revId",
|
||||
authorized(BUILDER),
|
||||
|
|
|
@ -46,13 +46,13 @@ exports.createModel = async (request, appId, instanceId, model) => {
|
|||
key: "name",
|
||||
schema: {
|
||||
name: {
|
||||
type: "text",
|
||||
type: "string",
|
||||
constraints: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
description: {
|
||||
type: "text",
|
||||
type: "string",
|
||||
constraints: {
|
||||
type: "string",
|
||||
},
|
||||
|
|
|
@ -180,7 +180,7 @@ describe("/models", () => {
|
|||
key: "name",
|
||||
schema: {
|
||||
name: {
|
||||
type: "text",
|
||||
type: "string",
|
||||
constraints: {
|
||||
type: "string",
|
||||
},
|
||||
|
|
|
@ -38,7 +38,7 @@ describe("/records", () => {
|
|||
|
||||
const createRecord = async r =>
|
||||
await request
|
||||
.post(`/api/${model._id}/records`)
|
||||
.post(`/api/${r ? r.modelId : record.modelId}/records`)
|
||||
.send(r || record)
|
||||
.set(defaultHeaders(app._id, instance._id))
|
||||
.expect('Content-Type', /json/)
|
||||
|
@ -152,6 +152,95 @@ describe("/records", () => {
|
|||
.expect('Content-Type', /json/)
|
||||
.expect(404)
|
||||
})
|
||||
|
||||
it("record values are coerced", async () => {
|
||||
const str = {type:"string", constraints: { type: "string", presence: false }}
|
||||
const attachment = {type:"attachment", constraints: { type: "array", presence: false }}
|
||||
const bool = {type:"boolean", constraints: { type: "boolean", presence: false }}
|
||||
const number = {type:"number", constraints: { type: "number", presence: false }}
|
||||
const datetime = {type:"datetime", constraints: { type: "string", presence: false, datetime: {earliest:"", latest: ""} }}
|
||||
|
||||
model = await createModel(request, app._id, instance._id, {
|
||||
name: "TestModel2",
|
||||
type: "model",
|
||||
key: "name",
|
||||
schema: {
|
||||
name: str,
|
||||
stringUndefined: str,
|
||||
stringNull: str,
|
||||
stringString: str,
|
||||
numberEmptyString: number,
|
||||
numberNull: number,
|
||||
numberUndefined: number,
|
||||
numberString: number,
|
||||
datetimeEmptyString: datetime,
|
||||
datetimeNull: datetime,
|
||||
datetimeUndefined: datetime,
|
||||
datetimeString: datetime,
|
||||
datetimeDate: datetime,
|
||||
boolNull: bool,
|
||||
boolEmpty: bool,
|
||||
boolUndefined: bool,
|
||||
boolString: bool,
|
||||
boolBool: bool,
|
||||
attachmentNull : attachment,
|
||||
attachmentUndefined : attachment,
|
||||
attachmentEmpty : attachment,
|
||||
},
|
||||
})
|
||||
|
||||
record = {
|
||||
name: "Test Record",
|
||||
stringUndefined: undefined,
|
||||
stringNull: null,
|
||||
stringString: "i am a string",
|
||||
numberEmptyString: "",
|
||||
numberNull: null,
|
||||
numberUndefined: undefined,
|
||||
numberString: "123",
|
||||
numberNumber: 123,
|
||||
datetimeEmptyString: "",
|
||||
datetimeNull: null,
|
||||
datetimeUndefined: undefined,
|
||||
datetimeString: "1984-04-20T00:00:00.000Z",
|
||||
datetimeDate: new Date("1984-04-20"),
|
||||
boolNull: null,
|
||||
boolEmpty: "",
|
||||
boolUndefined: undefined,
|
||||
boolString: "true",
|
||||
boolBool: true,
|
||||
modelId: model._id,
|
||||
attachmentNull : null,
|
||||
attachmentUndefined : undefined,
|
||||
attachmentEmpty : "",
|
||||
}
|
||||
|
||||
const id = (await createRecord(record)).body._id
|
||||
|
||||
const saved = (await loadRecord(id)).body
|
||||
|
||||
expect(saved.stringUndefined).toBe(undefined)
|
||||
expect(saved.stringNull).toBe("")
|
||||
expect(saved.stringString).toBe("i am a string")
|
||||
expect(saved.numberEmptyString).toBe(null)
|
||||
expect(saved.numberNull).toBe(null)
|
||||
expect(saved.numberUndefined).toBe(undefined)
|
||||
expect(saved.numberString).toBe(123)
|
||||
expect(saved.numberNumber).toBe(123)
|
||||
expect(saved.datetimeEmptyString).toBe(null)
|
||||
expect(saved.datetimeNull).toBe(null)
|
||||
expect(saved.datetimeUndefined).toBe(undefined)
|
||||
expect(saved.datetimeString).toBe(new Date(record.datetimeString).toISOString())
|
||||
expect(saved.datetimeDate).toBe(record.datetimeDate.toISOString())
|
||||
expect(saved.boolNull).toBe(null)
|
||||
expect(saved.boolEmpty).toBe(null)
|
||||
expect(saved.boolUndefined).toBe(undefined)
|
||||
expect(saved.boolString).toBe(true)
|
||||
expect(saved.boolBool).toBe(true)
|
||||
expect(saved.attachmentNull).toEqual([])
|
||||
expect(saved.attachmentUndefined).toBe(undefined)
|
||||
expect(saved.attachmentEmpty).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe("patch", () => {
|
||||
|
|
|
@ -69,13 +69,13 @@ describe("/views", () => {
|
|||
filters: [],
|
||||
schema: {
|
||||
name: {
|
||||
type: "text",
|
||||
type: "string",
|
||||
constraints: {
|
||||
type: "string"
|
||||
},
|
||||
},
|
||||
description: {
|
||||
type: "text",
|
||||
type: "string",
|
||||
constraints: {
|
||||
type: "string"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
const csv = require("csvtojson")
|
||||
|
||||
const VALIDATORS = {
|
||||
string: () => true,
|
||||
number: attribute => !isNaN(Number(attribute)),
|
||||
datetime: attribute => !isNaN(new Date(attribute).getTime()),
|
||||
}
|
||||
|
||||
const PARSERS = {
|
||||
datetime: attribute => new Date(attribute).toISOString(),
|
||||
}
|
||||
|
||||
function parse(path, parsers) {
|
||||
const result = csv().fromFile(path)
|
||||
|
||||
const schema = {}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
result.on("header", headers => {
|
||||
for (let header of headers) {
|
||||
schema[header] = {
|
||||
type: parsers[header] ? parsers[header].type : "string",
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
})
|
||||
result.fromFile(path).subscribe(row => {
|
||||
// For each CSV row parse all the columns that need parsed
|
||||
for (let key in parsers) {
|
||||
if (!schema[key] || schema[key].success) {
|
||||
// get the validator for the column type
|
||||
const validator = VALIDATORS[parsers[key].type]
|
||||
|
||||
try {
|
||||
// allow null/undefined values
|
||||
schema[key].success = !row[key] || validator(row[key])
|
||||
} catch (err) {
|
||||
schema[key].success = false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
result.on("done", error => {
|
||||
if (error) {
|
||||
console.error(error)
|
||||
reject(error)
|
||||
}
|
||||
|
||||
resolve(schema)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function transform({ schema, path }) {
|
||||
const colParser = {}
|
||||
|
||||
for (let key in schema) {
|
||||
colParser[key] = PARSERS[schema[key].type] || schema[key].type
|
||||
}
|
||||
|
||||
try {
|
||||
const json = await csv({ colParser }).fromFile(path)
|
||||
return json
|
||||
} catch (err) {
|
||||
console.error(`Error transforming CSV to JSON for data import`, err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parse,
|
||||
transform,
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CSV Parser transformation transforms a CSV file into JSON 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"Address": "5 Sesame Street",
|
||||
"Age": 4324,
|
||||
"Name": "Bert",
|
||||
},
|
||||
Object {
|
||||
"Address": "1 World Trade Center",
|
||||
"Age": 34,
|
||||
"Name": "Ernie",
|
||||
},
|
||||
Object {
|
||||
"Address": "44 Second Avenue",
|
||||
"Age": 23423,
|
||||
"Name": "Big Bird",
|
||||
},
|
||||
]
|
||||
`;
|
|
@ -0,0 +1,108 @@
|
|||
const csvParser = require("../csvParser");
|
||||
|
||||
const CSV_PATH = __dirname + "/test.csv";
|
||||
|
||||
const SCHEMAS = {
|
||||
VALID: {
|
||||
Age: {
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
INVALID: {
|
||||
Address: {
|
||||
type: "number",
|
||||
},
|
||||
Age: {
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
IGNORE: {
|
||||
Address: {
|
||||
type: "omit",
|
||||
},
|
||||
Age: {
|
||||
type: "omit",
|
||||
},
|
||||
},
|
||||
BROKEN: {
|
||||
Address: {
|
||||
type: "datetime",
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
describe("CSV Parser", () => {
|
||||
describe("parsing", () => {
|
||||
it("returns status and types for a valid CSV transformation", async () => {
|
||||
expect(
|
||||
await csvParser.parse(CSV_PATH, SCHEMAS.VALID)
|
||||
).toEqual({
|
||||
Address: {
|
||||
success: true,
|
||||
type: "string",
|
||||
},
|
||||
Age: {
|
||||
success: true,
|
||||
type: "number",
|
||||
},
|
||||
Name: {
|
||||
success: true,
|
||||
type: "string",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("returns status and types for an invalid CSV transformation", async () => {
|
||||
expect(
|
||||
await csvParser.parse(CSV_PATH, SCHEMAS.INVALID)
|
||||
).toEqual({
|
||||
Address: {
|
||||
success: false,
|
||||
type: "number",
|
||||
},
|
||||
Age: {
|
||||
success: true,
|
||||
type: "number",
|
||||
},
|
||||
Name: {
|
||||
success: true,
|
||||
type: "string",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("transformation", () => {
|
||||
it("transforms a CSV file into JSON", async () => {
|
||||
expect(
|
||||
await csvParser.transform({
|
||||
schema: SCHEMAS.VALID,
|
||||
path: CSV_PATH,
|
||||
})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("transforms a CSV file into JSON ignoring certain fields", async () => {
|
||||
expect(
|
||||
await csvParser.transform({
|
||||
schema: SCHEMAS.IGNORE,
|
||||
path: CSV_PATH,
|
||||
})
|
||||
).toEqual([
|
||||
{
|
||||
Name: "Bert"
|
||||
},
|
||||
{
|
||||
Name: "Ernie"
|
||||
},
|
||||
{
|
||||
Name: "Big Bird"
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("throws an error on invalid schema", async () => {
|
||||
await expect(csvParser.transform({ schema: SCHEMAS.BROKEN, path: CSV_PATH })).rejects.toThrow()
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
"Name","Age","Address"
|
||||
"Bert","4324","5 Sesame Street"
|
||||
"Ernie","34","1 World Trade Center"
|
||||
"Big Bird","23423","44 Second Avenue"
|
|
|
@ -172,6 +172,15 @@
|
|||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@budibase/client@^0.1.24":
|
||||
version "0.1.24"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.1.24.tgz#d2967c050af9f559791e0189137f80e621ea2d69"
|
||||
integrity sha512-2Plu9PpF3TOPTDkAAIkPFEjZFolGkty0Sc0vbLk8lee4yqeonBj5paXT44O6kpxLFW47YjN5VCA4+EnwGl358w==
|
||||
dependencies:
|
||||
deep-equal "^2.0.1"
|
||||
mustache "^4.0.1"
|
||||
regexparam "^1.3.0"
|
||||
|
||||
"@cnakazawa/watch@^1.0.3":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
|
||||
|
@ -867,6 +876,11 @@ array-equal@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
||||
|
||||
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"
|
||||
|
@ -925,6 +939,13 @@ atomic-sleep@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
|
||||
|
||||
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-sdk@^2.706.0:
|
||||
version "2.706.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953"
|
||||
|
@ -1057,7 +1078,7 @@ bluebird-lst@^1.0.9:
|
|||
dependencies:
|
||||
bluebird "^3.5.5"
|
||||
|
||||
bluebird@^3.5.5:
|
||||
bluebird@^3.5.1, bluebird@^3.5.5:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
|
||||
|
@ -1596,6 +1617,15 @@ cssstyle@^1.0.0:
|
|||
dependencies:
|
||||
cssom "0.3.x"
|
||||
|
||||
csvtojson@^2.0.10:
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/csvtojson/-/csvtojson-2.0.10.tgz#11e7242cc630da54efce7958a45f443210357574"
|
||||
integrity sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==
|
||||
dependencies:
|
||||
bluebird "^3.5.1"
|
||||
lodash "^4.17.3"
|
||||
strip-bom "^2.0.0"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
|
@ -1725,6 +1755,26 @@ decompress@^4.2.1:
|
|||
pify "^2.3.0"
|
||||
strip-dirs "^2.0.0"
|
||||
|
||||
deep-equal@^2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.4.tgz#6b0b407a074666033169df3acaf128e1c6f3eab6"
|
||||
integrity sha512-BUfaXrVoCfgkOQY/b09QdO9L3XNoF2XH0A3aY9IQwQL/ZjLOe8FQgCNVl1wiolhsFo8kFdO9zdPViCPbmaJA5w==
|
||||
dependencies:
|
||||
es-abstract "^1.18.0-next.1"
|
||||
es-get-iterator "^1.1.0"
|
||||
is-arguments "^1.0.4"
|
||||
is-date-object "^1.0.2"
|
||||
is-regex "^1.1.1"
|
||||
isarray "^2.0.5"
|
||||
object-is "^1.1.3"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.1"
|
||||
regexp.prototype.flags "^1.3.0"
|
||||
side-channel "^1.0.3"
|
||||
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"
|
||||
|
@ -2073,6 +2123,54 @@ 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-abstract@^1.17.4:
|
||||
version "1.17.7"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c"
|
||||
integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==
|
||||
dependencies:
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
is-callable "^1.2.2"
|
||||
is-regex "^1.1.1"
|
||||
object-inspect "^1.8.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.1"
|
||||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.1"
|
||||
|
||||
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
|
||||
version "1.18.0-next.1"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
|
||||
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
|
||||
dependencies:
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
is-callable "^1.2.2"
|
||||
is-negative-zero "^2.0.0"
|
||||
is-regex "^1.1.1"
|
||||
object-inspect "^1.8.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.1"
|
||||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.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"
|
||||
|
@ -3112,6 +3210,11 @@ 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"
|
||||
|
@ -3121,12 +3224,22 @@ is-arrayish@^0.3.1:
|
|||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||
|
||||
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"
|
||||
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"
|
||||
|
@ -3135,6 +3248,11 @@ is-callable@^1.1.4, is-callable@^1.1.5:
|
|||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
|
||||
|
||||
is-callable@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
|
||||
integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==
|
||||
|
||||
is-ci@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
|
||||
|
@ -3157,7 +3275,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"
|
||||
|
||||
|
@ -3227,15 +3345,30 @@ 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-natural-number@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
|
||||
integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
|
||||
|
||||
is-negative-zero@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461"
|
||||
integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=
|
||||
|
||||
is-npm@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
|
||||
|
||||
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"
|
||||
|
@ -3276,15 +3409,32 @@ is-regex@^1.0.5:
|
|||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-regex@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9"
|
||||
integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==
|
||||
dependencies:
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-retry-allowed@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
|
||||
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
@ -3299,10 +3449,35 @@ 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"
|
||||
|
||||
is-utf8@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
|
||||
|
||||
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"
|
||||
|
@ -3323,6 +3498,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
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"
|
||||
|
@ -4180,6 +4360,13 @@ lie@3.0.4:
|
|||
inline-process-browser "^1.0.0"
|
||||
unreachable-branch-transform "^0.3.0"
|
||||
|
||||
lie@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
|
||||
integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=
|
||||
dependencies:
|
||||
immediate "~3.0.5"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
|
@ -4242,6 +4429,11 @@ lodash.once@^4.0.0:
|
|||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
|
||||
lodash.pick@^4.0.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
|
@ -4250,6 +4442,11 @@ lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15:
|
|||
version "4.17.19"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
||||
|
||||
lodash@^4.17.3:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
|
@ -4504,6 +4701,16 @@ natural-compare@^1.4.0:
|
|||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
ndjson@^1.4.3:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ndjson/-/ndjson-1.5.0.tgz#ae603b36b134bcec347b452422b0bf98d5832ec8"
|
||||
integrity sha1-rmA7NrE0vOw0e0UkIrC/mNWDLsg=
|
||||
dependencies:
|
||||
json-stringify-safe "^5.0.1"
|
||||
minimist "^1.2.0"
|
||||
split2 "^2.1.0"
|
||||
through2 "^2.0.3"
|
||||
|
||||
negotiator@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||
|
@ -4668,6 +4875,19 @@ object-inspect@^1.7.0:
|
|||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
|
||||
|
||||
object-inspect@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
||||
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
|
||||
|
||||
object-is@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.3.tgz#2e3b9e65560137455ee3bd62aec4d90a2ea1cc81"
|
||||
integrity sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.1"
|
||||
|
||||
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"
|
||||
|
@ -4687,6 +4907,16 @@ object.assign@^4.1.0:
|
|||
has-symbols "^1.0.0"
|
||||
object-keys "^1.0.11"
|
||||
|
||||
object.assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd"
|
||||
integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.0"
|
||||
has-symbols "^1.0.1"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
object.getownpropertydescriptors@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649"
|
||||
|
@ -4974,6 +5204,14 @@ posix-character-classes@^0.1.0:
|
|||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
|
||||
pouch-stream@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/pouch-stream/-/pouch-stream-0.4.1.tgz#0c6d8475c9307677627991a2f079b301c3b89bdd"
|
||||
integrity sha1-DG2EdckwdndieZGi8HmzAcO4m90=
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^1.0.27-1"
|
||||
|
||||
pouchdb-adapter-leveldb-core@7.2.1:
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pouchdb-adapter-leveldb-core/-/pouchdb-adapter-leveldb-core-7.2.1.tgz#71bf2a05755689e2b05e78e796003a18ebf65a69"
|
||||
|
@ -5061,6 +5299,26 @@ pouchdb-promise@5.4.3:
|
|||
dependencies:
|
||||
lie "3.0.4"
|
||||
|
||||
pouchdb-promise@^6.0.4:
|
||||
version "6.4.3"
|
||||
resolved "https://registry.yarnpkg.com/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz#74516f4acf74957b54debd0fb2c0e5b5a68ca7b3"
|
||||
integrity sha512-ruJaSFXwzsxRHQfwNHjQfsj58LBOY1RzGzde4PM5CWINZwFjCQAhZwfMrch2o/0oZT6d+Xtt0HTWhq35p3b0qw==
|
||||
dependencies:
|
||||
lie "3.1.1"
|
||||
|
||||
pouchdb-replication-stream@^1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/pouchdb-replication-stream/-/pouchdb-replication-stream-1.2.9.tgz#aa4fa5d8f52df4825392f18e07c7e11acffc650a"
|
||||
integrity sha1-qk+l2PUt9IJTkvGOB8fhGs/8ZQo=
|
||||
dependencies:
|
||||
argsarray "0.0.1"
|
||||
inherits "^2.0.3"
|
||||
lodash.pick "^4.0.0"
|
||||
ndjson "^1.4.3"
|
||||
pouch-stream "^0.4.0"
|
||||
pouchdb-promise "^6.0.4"
|
||||
through2 "^2.0.0"
|
||||
|
||||
pouchdb-utils@7.2.1:
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pouchdb-utils/-/pouchdb-utils-7.2.1.tgz#5dec1c53c8ecba717e5762311e9a1def2d4ebf9c"
|
||||
|
@ -5321,7 +5579,17 @@ readable-stream@1.0.33:
|
|||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5:
|
||||
readable-stream@^1.0.27-1:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
|
||||
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
dependencies:
|
||||
|
@ -5374,6 +5642,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"
|
||||
|
@ -5692,6 +5973,14 @@ shellwords@^0.1.1:
|
|||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
|
||||
side-channel@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
|
||||
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==
|
||||
dependencies:
|
||||
es-abstract "^1.18.0-next.0"
|
||||
object-inspect "^1.8.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"
|
||||
|
@ -5877,6 +6166,13 @@ split-string@^3.0.1, split-string@^3.0.2:
|
|||
dependencies:
|
||||
extend-shallow "^3.0.0"
|
||||
|
||||
split2@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493"
|
||||
integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==
|
||||
dependencies:
|
||||
through2 "^2.0.2"
|
||||
|
||||
split2@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/split2/-/split2-3.1.1.tgz#c51f18f3e06a8c4469aaab487687d8d956160bb6"
|
||||
|
@ -5981,7 +6277,7 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
|
|||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string.prototype.trimend@^1.0.0:
|
||||
string.prototype.trimend@^1.0.0, string.prototype.trimend@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
|
||||
dependencies:
|
||||
|
@ -6004,7 +6300,7 @@ string.prototype.trimright@^2.1.1:
|
|||
es-abstract "^1.17.5"
|
||||
string.prototype.trimend "^1.0.0"
|
||||
|
||||
string.prototype.trimstart@^1.0.0:
|
||||
string.prototype.trimstart@^1.0.0, string.prototype.trimstart@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
|
||||
dependencies:
|
||||
|
@ -6051,6 +6347,13 @@ strip-ansi@^6.0.0:
|
|||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
strip-bom@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
|
||||
integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
|
||||
dependencies:
|
||||
is-utf8 "^0.2.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
|
@ -6234,6 +6537,14 @@ through2@^0.6.2, through2@^0.6.5:
|
|||
readable-stream ">=1.0.33-1 <1.1.0-0"
|
||||
xtend ">=4.0.0 <4.1.0-0"
|
||||
|
||||
through2@^2.0.0, through2@^2.0.2, through2@^2.0.3:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
|
||||
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
|
||||
dependencies:
|
||||
readable-stream "~2.3.6"
|
||||
xtend "~4.0.1"
|
||||
|
||||
through@^2.3.6, through@^2.3.8, through@~2.3.4:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
@ -6611,6 +6922,27 @@ 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"
|
||||
|
@ -6620,6 +6952,18 @@ which-pm-runs@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
|
||||
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
|
||||
|
||||
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"
|
||||
|
@ -6724,7 +7068,7 @@ xmlbuilder@~9.0.1:
|
|||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||
|
||||
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.0:
|
||||
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@budibase/client": "^0.1.23",
|
||||
"@budibase/client": "^0.1.25",
|
||||
"@rollup/plugin-commonjs": "^11.1.0",
|
||||
"lodash": "^4.17.15",
|
||||
"rollup": "^1.11.0",
|
||||
|
@ -31,7 +31,7 @@
|
|||
"keywords": [
|
||||
"svelte"
|
||||
],
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"license": "MIT",
|
||||
"gitHead": "284cceb9b703c38566c6e6363c022f79a08d5691",
|
||||
"dependencies": {
|
||||
|
|
Loading…
Reference in New Issue