Browse Source

Merge pull request #209 from Budibase/bugfix/change-record-and-index

Changes a most instances of Record to Model. Less work done on Index to View conversion.
pull/4023/head
Kevin Åberg Kultalahti 6 years ago
committed by GitHub
parent
commit
6658021503
  1. 2916
      packages/bootstrap-components/public/bundle.js
  2. 211
      packages/bootstrap-components/public/bundle.js.map
  3. 6
      packages/bootstrap-components/public/clientAppDefinition.js
  4. 16
      packages/builder/src/builderStore/store/backend.js
  5. 6
      packages/builder/src/builderStore/store/index.js
  6. 12
      packages/builder/src/components/common/core.js
  7. 151
      packages/builder/src/components/database/IndexView.svelte
  8. 232
      packages/builder/src/components/database/ModelDataTable/modals/CreateEditModel.svelte
  9. 152
      packages/builder/src/components/database/ModelDataTable/modals/CreateEditView.svelte
  10. 240
      packages/builder/src/components/database/ModelView.svelte
  11. 6
      packages/builder/src/components/nav/HierarchyRow.svelte
  12. 8
      packages/builder/src/components/nav/SchemaManagementDrawer.svelte
  13. 4
      packages/core/src/authApi/generateFullPermissions.js
  14. 4
      packages/core/src/authApi/validateAccessLevels.js
  15. 6
      packages/core/src/indexApi/buildIndex.js
  16. 8
      packages/core/src/indexing/relevant.js
  17. 8
      packages/core/src/recordApi/initialiseChildren.js
  18. 2
      packages/core/src/recordApi/save.js
  19. 6
      packages/core/src/templateApi/canDeleteIndex.js
  20. 14
      packages/core/src/templateApi/canDeleteModel.js
  21. 28
      packages/core/src/templateApi/createNodes.js
  22. 4
      packages/core/src/templateApi/deleteNodes.js
  23. 14
      packages/core/src/templateApi/diffHierarchy.js
  24. 20
      packages/core/src/templateApi/hierarchy.js
  25. 4
      packages/core/src/templateApi/index.js
  26. 6
      packages/core/src/templateApi/indexes.js
  27. 10
      packages/core/src/templateApi/validate.js
  28. 4
      packages/core/test/indexing.getRelevantIndexes.spec.js
  29. 10
      packages/core/test/indexing.schema.spec.js
  30. 6
      packages/core/test/recordApi.getRecordInfo.spec.js
  31. 44
      packages/core/test/specHelpers.js
  32. 12
      packages/core/test/templateApi.canDelete.spec.js
  33. 52
      packages/core/test/templateApi.constructHeirarchy.spec.js
  34. 24
      packages/core/test/templateApi.diffHierarchy.spec.js
  35. 2
      packages/core/test/templateApi.fields.spec.js
  36. 5
      packages/core/test/templateApi.heirarchyValidation.spec.js
  37. 2
      packages/core/test/templateApi.loadSaveHeirarchy.spec.js
  38. 30
      packages/core/test/templateApi.upgradeData.spec.js
  39. 6
      packages/core/test/upgradeDataSetup.js
  40. 6
      packages/datastores/tests/setup.js
  41. 22
      packages/server/appPackages/_master/appDefinition.json
  42. 8
      packages/server/appPackages/testApp2/appDefinition.json
  43. 272
      packages/server/yarn.lock
  44. 21270
      packages/standard-components/public/bundle.js
  45. 244
      packages/standard-components/public/bundle.js.map
  46. 6
      packages/standard-components/public/clientAppDefinition.js

2916
packages/bootstrap-components/public/bundle.js

File diff suppressed because it is too large

211
packages/bootstrap-components/public/bundle.js.map

File diff suppressed because one or more lines are too long

6
packages/bootstrap-components/public/clientAppDefinition.js

@ -59,7 +59,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [2],
allowedModelNodeIds: [2],
nodeId: 5,
},
],
@ -79,7 +79,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [1],
allowedModelNodeIds: [1],
nodeId: 4,
},
{
@ -91,7 +91,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [2],
allowedModelNodeIds: [2],
nodeId: 6,
},
],

16
packages/builder/src/builderStore/store/backend.js

@ -9,7 +9,7 @@ import {
templateApi,
isIndex,
canDeleteIndex,
canDeleteRecord,
canDeleteModel,
} from "components/common/core"
export const getBackendUiStore = () => {
@ -107,7 +107,7 @@ export const saveBackend = async state => {
}
}
export const newRecord = (store, useRoot) => () => {
export const newModel = (store, useRoot) => () => {
store.update(state => {
state.currentNodeIsNew = true
const shadowHierarchy = createShadowHierarchy(state.hierarchy)
@ -115,7 +115,7 @@ export const newRecord = (store, useRoot) => () => {
? shadowHierarchy
: getNode(shadowHierarchy, state.currentNode.nodeId)
state.errors = []
state.currentNode = templateApi(shadowHierarchy).getNewRecordTemplate(
state.currentNode = templateApi(shadowHierarchy).getNewModelTemplate(
parent,
"",
true
@ -196,7 +196,7 @@ export const saveCurrentNode = store => () => {
? `all_${cloned.name}s`
: `${cloned.parent().name}_${cloned.name}s`
defaultIndex.allowedRecordNodeIds = [cloned.nodeId]
defaultIndex.allowedModelNodeIds = [cloned.nodeId]
}
state.currentNodeIsNew = false
@ -214,10 +214,10 @@ export const deleteCurrentNode = store => () => {
? state.hierarchy.children.find(node => node !== state.currentNode)
: nodeToDelete.parent()
const isRecord = hierarchyFunctions.isRecord(nodeToDelete)
const isModel = hierarchyFunctions.isModel(nodeToDelete)
const check = isRecord
? canDeleteRecord(nodeToDelete)
const check = isModel
? canDeleteModel(nodeToDelete)
: canDeleteIndex(nodeToDelete)
if (!check.canDelete) {
@ -225,7 +225,7 @@ export const deleteCurrentNode = store => () => {
return state
}
const recordOrIndexKey = isRecord ? "children" : "indexes"
const recordOrIndexKey = isModel ? "children" : "indexes"
// remove the selected record or index
const newCollection = remove(

6
packages/builder/src/builderStore/store/index.js

@ -20,8 +20,6 @@ import { generate_screen_css } from "../generate_css"
import { insertCodeMetadata } from "../insertCodeMetadata"
import { uuid } from "../uuid"
let appname = ""
export const getStore = () => {
const initial = {
apps: [],
@ -52,8 +50,8 @@ export const getStore = () => {
store.setPackage = setPackage(store, initial)
store.newChildRecord = backendStoreActions.newRecord(store, false)
store.newRootRecord = backendStoreActions.newRecord(store, true)
store.newChildModel = backendStoreActions.newModel(store, false)
store.newRootModel = backendStoreActions.newModel(store, true)
store.selectExistingNode = backendStoreActions.selectExistingNode(store)
store.newChildIndex = backendStoreActions.newIndex(store, false)
store.newRootIndex = backendStoreActions.newIndex(store, true)

12
packages/builder/src/components/common/core.js

@ -10,7 +10,7 @@ import { generateSchema } from "../../../../core/src/indexing/indexSchemaCreator
import { generate } from "shortid"
export { canDeleteIndex } from "../../../../core/src/templateApi/canDeleteIndex"
export { canDeleteRecord } from "../../../../core/src/templateApi/canDeleteRecord"
export { canDeleteModel } from "../../../../core/src/templateApi/canDeleteModel"
export { userWithFullAccess } from "../../../../core/src/index"
export { joinKey } from "../../../../core/src/common"
export { getExactNodeForKey } from "../../../../core/src/templateApi/hierarchy"
@ -65,20 +65,20 @@ export const getPotentialReverseReferenceIndexes = (hierarchy, refIndex) => {
return res
}
export const getPotentialReferenceIndexes = (hierarchy, record) =>
export const getPotentialReferenceIndexes = (hierarchy, model) =>
pipe(hierarchy, [
hierarchyFunctions.getFlattenedHierarchy,
filter(hierarchyFunctions.isAncestorIndex),
filter(
i =>
hierarchyFunctions.isAncestor(record)(i.parent()) ||
i.parent().nodeId === record.parent().nodeId ||
hierarchyFunctions.isAncestor(model)(i.parent()) ||
i.parent().nodeId === model.parent().nodeId ||
hierarchyFunctions.isRoot(i.parent())
),
])
export const isIndex = hierarchyFunctions.isIndex
export const isRecord = hierarchyFunctions.isRecord
export const isModel = hierarchyFunctions.isModel
export const nodeNameFromNodeKey = hierarchyFunctions.nodeNameFromNodeKey
export const getDefaultTypeOptions = type =>
@ -109,7 +109,7 @@ export const getIndexNodes = hierarchy =>
export const getRecordNodes = hierarchy =>
pipe(hierarchy, [
hierarchyFunctions.getFlattenedHierarchy,
filter(hierarchyFunctions.isRecord),
filter(hierarchyFunctions.isModel),
])
export const getIndexSchema = hierarchy => index =>

151
packages/builder/src/components/database/IndexView.svelte

@ -1,151 +0,0 @@
<script>
import Textbox from "components/common/Textbox.svelte"
import CodeArea from "components/common/CodeArea.svelte"
import Button from "components/common/Button.svelte"
import Dropdown from "components/common/Dropdown.svelte"
import { store } from "builderStore"
import { filter, some, map, compose } from "lodash/fp"
import {
hierarchy as hierarchyFunctions,
common,
} from "../../../../core/src/"
import ErrorsBox from "components/common/ErrorsBox.svelte"
import ActionButton from "components/common/ActionButton.svelte"
const SNIPPET_EDITORS = {
MAP: "Map",
FILTER: "Filter",
SHARD: "Shard Name",
}
let index
let indexableRecords = []
let currentSnippetEditor = SNIPPET_EDITORS.MAP
const indexableRecordsFromIndex = compose(
map(node => ({
node,
isallowed:
index.allowedRecordNodeIds &&
index.allowedRecordNodeIds.some(id => node.nodeId === id),
})),
filter(hierarchyFunctions.isRecord),
filter(hierarchyFunctions.isDecendant($store.currentNode.parent())),
hierarchyFunctions.getFlattenedHierarchy
)
store.subscribe($store => {
index = $store.currentNode
indexableRecords = indexableRecordsFromIndex($store.hierarchy)
})
const toggleAllowedRecord = record => {
if (record.isallowed) {
index.allowedRecordNodeIds = index.allowedRecordNodeIds.filter(
id => id !== record.node.nodeId
)
} else {
index.allowedRecordNodeIds.push(record.node.nodeId)
}
}
</script>
<heading>
<i class="ri-eye-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit View</h3>
</heading>
<form on:submit|preventDefault class="uk-form-stacked root">
<h4 class="budibase__label--big">Settings</h4>
{#if $store.errors && $store.errors.length > 0}
<ErrorsBox errors={$store.errors} />
{/if}
<div class="uk-grid-small" uk-grid>
<div class="uk-width-1-2@s">
<Textbox bind:text={index.name} label="Name" />
</div>
<div class="uk-width-1-2@s">
<Dropdown
label="View Type"
bind:selected={index.indexType}
options={['ancestor', 'reference']} />
</div>
</div>
<div class="allowed-records">
<div class="budibase__label--big">
Which models would you like to add to this view?
</div>
{#each indexableRecords as rec}
<input
class="uk-checkbox"
type="checkbox"
checked={rec.isallowed}
on:change={() => toggleAllowedRecord(rec)} />
<span class="checkbox-model-label">{rec.node.name}</span>
{/each}
</div>
<h4 class="budibase__label--big">Snippets</h4>
{#each Object.values(SNIPPET_EDITORS) as snippetType}
<span
class="snippet-selector__heading hoverable"
class:highlighted={currentSnippetEditor === snippetType}
on:click={() => (currentSnippetEditor = snippetType)}>
{snippetType}
</span>
{/each}
{#if currentSnippetEditor === SNIPPET_EDITORS.MAP}
<CodeArea bind:text={index.map} label="Map" />
{:else if currentSnippetEditor === SNIPPET_EDITORS.FILTER}
<CodeArea bind:text={index.filter} label="Filter" />
{:else if currentSnippetEditor === SNIPPET_EDITORS.SHARD}
<CodeArea bind:text={index.getShardName} label="Shard Name" />
{/if}
<ActionButton color="secondary" on:click={store.saveCurrentNode}>
Save
</ActionButton>
{#if !$store.currentNodeIsNew}
<ActionButton alert on:click={store.deleteCurrentNode}>Delete</ActionButton>
{/if}
</form>
<style>
.root {
height: 100%;
padding: 15px;
}
.allowed-records {
margin: 20px 0px;
}
.allowed-records > span {
margin-right: 30px;
}
.snippet-selector__heading {
margin-right: 20px;
opacity: 0.7;
}
.highlighted {
opacity: 1;
}
.checkbox-model-label {
text-transform: capitalize;
}
h3 {
margin: 0 0 0 10px;
}
heading {
padding: 20px 20px 0 20px;
display: flex;
align-items: center;
}
</style>

232
packages/builder/src/components/database/ModelDataTable/modals/CreateEditModel.svelte

@ -1,7 +1,231 @@
<script>
import ModelView from "../../ModelView.svelte"
import { tick } from "svelte"
import Textbox from "components/common/Textbox.svelte"
import Button from "components/common/Button.svelte"
import Select from "components/common/Select.svelte"
import ActionButton from "components/common/ActionButton.svelte"
import getIcon from "components/common/icon"
import FieldView from "../../FieldView.svelte"
import {
get,
compose,
map,
join,
filter,
some,
find,
keys,
isDate,
} from "lodash/fp"
import { store, backendUiStore } from "builderStore"
import { common, hierarchy } from "../../../../../../core/src/"
import { getNode } from "components/common/core"
import { templateApi, pipe, validate } from "components/common/core"
import ErrorsBox from "components/common/ErrorsBox.svelte"
let model
let editingField = false
let fieldToEdit
let isNewField = false
let newField
let editField
let deleteField
let onFinishedFieldEdit
let editIndex
$: parent = model && model.parent()
$: isChildModel = parent && parent.name !== "root"
$: modelExistsInHierarchy =
$store.currentNode && getNode($store.hierarchy, $store.currentNode.nodeId)
store.subscribe($store => {
model = $store.currentNode
const flattened = hierarchy.getFlattenedHierarchy($store.hierarchy)
newField = () => {
isNewField = true
fieldToEdit = templateApi($store.hierarchy).getNewField("string")
editingField = true
}
onFinishedFieldEdit = field => {
if (field) {
store.saveField(field)
}
editingField = false
}
editField = field => {
isNewField = false
fieldToEdit = field
editingField = true
}
deleteField = field => {
store.deleteField(field)
}
editIndex = index => {
store.selectExistingNode(index.nodeId)
}
})
let getTypeOptionsValueText = value => {
if (
value === Number.MAX_SAFE_INTEGER ||
value === Number.MIN_SAFE_INTEGER ||
new Date(value).getTime() === new Date(8640000000000000).getTime() ||
new Date(value).getTime() === new Date(-8640000000000000).getTime()
)
return "(any)"
if (value === null) return "(not set)"
return value
}
const nameChanged = ev => {
const pluralName = n => `${n}s`
if (model.collectionName === "") {
model.collectionName = pluralName(ev.target.value)
}
}
</script>
<section>
<ModelView />
</section>
<heading>
{#if !editingField}
<i class="ri-list-settings-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit Model</h3>
{:else}
<i class="ri-file-list-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit Field</h3>
{/if}
</heading>
{#if !editingField}
<div class="padding">
<h4 class="budibase__label--big">Settings</h4>
{#if $store.errors && $store.errors.length > 0}
<ErrorsBox errors={$store.errors} />
{/if}
<form on:submit|preventDefault class="uk-form-stacked">
<Textbox label="Name" bind:text={model.name} on:change={nameChanged} />
{#if isChildModel}
<div>
<label class="uk-form-label">Parent</label>
<div class="uk-form-controls parent-name">{parent.name}</div>
</div>
{/if}
</form>
<div class="table-controls">
<span class="budibase__label--big">Fields</span>
<h4 class="hoverable new-field" on:click={newField}>Add new field</h4>
</div>
<table class="uk-table fields-table budibase__table">
<thead>
<tr>
<th>Edit</th>
<th>Name</th>
<th>Type</th>
<th>Values</th>
<th />
</tr>
</thead>
<tbody>
{#each model ? model.fields : [] as field}
<tr>
<td>
<i class="ri-more-line" on:click={() => editField(field)} />
</td>
<td>
<div>{field.name}</div>
</td>
<td>{field.type}</td>
<td>{field.typeOptions.values || ''}</td>
<td>
<i
class="ri-delete-bin-6-line hoverable"
on:click={() => deleteField(field)} />
</td>
</tr>
{/each}
</tbody>
</table>
<div class="uk-margin">
<ActionButton color="secondary" on:click={store.saveCurrentNode}>
Save
</ActionButton>
{#if modelExistsInHierarchy}
<ActionButton color="primary" on:click={store.newChildModel}>
Create Child Model on {model.name}
</ActionButton>
<ActionButton
color="primary"
on:click={async () => {
backendUiStore.actions.modals.show('VIEW')
await tick()
store.newChildIndex()
}}>
Create Child View on {model.name}
</ActionButton>
<ActionButton alert on:click={store.deleteCurrentNode}>
Delete
</ActionButton>
{/if}
</div>
</div>
{:else}
<FieldView
field={fieldToEdit}
onFinished={onFinishedFieldEdit}
allFields={model.fields}
store={$store} />
{/if}
<style>
.padding {
padding: 20px;
}
.new-field {
font-size: 16px;
font-weight: bold;
color: var(--button-text);
}
.fields-table {
margin: 1rem 1rem 0rem 0rem;
border-collapse: collapse;
}
tbody > tr:hover {
background-color: var(--primary10);
}
.table-controls {
display: flex;
justify-content: space-between;
align-items: center;
}
.ri-more-line:hover {
cursor: pointer;
}
heading {
padding: 20px 20px 0 20px;
display: flex;
align-items: center;
}
h3 {
margin: 0 0 0 10px;
}
.parent-name {
font-weight: bold;
}
</style>

152
packages/builder/src/components/database/ModelDataTable/modals/CreateEditView.svelte

@ -1,7 +1,151 @@
<script>
import IndexView from "../../IndexView.svelte"
import Textbox from "components/common/Textbox.svelte"
import CodeArea from "components/common/CodeArea.svelte"
import Button from "components/common/Button.svelte"
import Dropdown from "components/common/Dropdown.svelte"
import { store } from "builderStore"
import { filter, some, map, compose } from "lodash/fp"
import {
hierarchy as hierarchyFunctions,
common,
} from "../../../../../../core/src/"
import ErrorsBox from "components/common/ErrorsBox.svelte"
import ActionButton from "components/common/ActionButton.svelte"
const SNIPPET_EDITORS = {
MAP: "Map",
FILTER: "Filter",
SHARD: "Shard Name",
}
let view
let indexableModels = []
let currentSnippetEditor = SNIPPET_EDITORS.MAP
const indexableModelsFromIndex = compose(
map(node => ({
node,
isallowed:
view.allowedModelNodeIds &&
view.allowedModelNodeIds.some(id => node.nodeId === id),
})),
filter(hierarchyFunctions.isModel),
filter(hierarchyFunctions.isDecendant($store.currentNode.parent())),
hierarchyFunctions.getFlattenedHierarchy
)
store.subscribe($store => {
view = $store.currentNode
indexableModels = indexableModelsFromIndex($store.hierarchy)
})
const toggleAllowedModel = model => {
if (model.isallowed) {
view.allowedModelNodeIds = view.allowedModelNodeIds.filter(
id => id !== model.node.nodeId
)
} else {
view.allowedModelNodeIds.push(model.node.nodeId)
}
}
</script>
<section>
<IndexView />
</section>
<heading>
<i class="ri-eye-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit View</h3>
</heading>
<form on:submit|preventDefault class="uk-form-stacked root">
<h4 class="budibase__label--big">Settings</h4>
{#if $store.errors && $store.errors.length > 0}
<ErrorsBox errors={$store.errors} />
{/if}
<div class="uk-grid-small" uk-grid>
<div class="uk-width-1-2@s">
<Textbox bind:text={view.name} label="Name" />
</div>
<div class="uk-width-1-2@s">
<Dropdown
label="View Type"
bind:selected={view.indexType}
options={['ancestor', 'reference']} />
</div>
</div>
<div class="allowed-records">
<div class="budibase__label--big">
Which models would you like to add to this view?
</div>
{#each indexableModels as model}
<input
class="uk-checkbox"
type="checkbox"
checked={model.isallowed}
on:change={() => toggleAllowedModel(model)} />
<span class="checkbox-model-label">{model.node.name}</span>
{/each}
</div>
<h4 class="budibase__label--big">Snippets</h4>
{#each Object.values(SNIPPET_EDITORS) as snippetType}
<span
class="snippet-selector__heading hoverable"
class:highlighted={currentSnippetEditor === snippetType}
on:click={() => (currentSnippetEditor = snippetType)}>
{snippetType}
</span>
{/each}
{#if currentSnippetEditor === SNIPPET_EDITORS.MAP}
<CodeArea bind:text={view.map} label="Map" />
{:else if currentSnippetEditor === SNIPPET_EDITORS.FILTER}
<CodeArea bind:text={view.filter} label="Filter" />
{:else if currentSnippetEditor === SNIPPET_EDITORS.SHARD}
<CodeArea bind:text={view.getShardName} label="Shard Name" />
{/if}
<ActionButton color="secondary" on:click={store.saveCurrentNode}>
Save
</ActionButton>
{#if !$store.currentNodeIsNew}
<ActionButton alert on:click={store.deleteCurrentNode}>Delete</ActionButton>
{/if}
</form>
<style>
.root {
height: 100%;
padding: 15px;
}
.allowed-records {
margin: 20px 0px;
}
.allowed-records > span {
margin-right: 30px;
}
.snippet-selector__heading {
margin-right: 20px;
opacity: 0.7;
}
.highlighted {
opacity: 1;
}
.checkbox-model-label {
text-transform: capitalize;
}
h3 {
margin: 0 0 0 10px;
}
heading {
padding: 20px 20px 0 20px;
display: flex;
align-items: center;
}
</style>

240
packages/builder/src/components/database/ModelView.svelte

@ -1,240 +0,0 @@
<script>
import { tick } from "svelte"
import Textbox from "components/common/Textbox.svelte"
import Button from "components/common/Button.svelte"
import Select from "components/common/Select.svelte"
import ActionButton from "components/common/ActionButton.svelte"
import getIcon from "components/common/icon"
import FieldView from "./FieldView.svelte"
import {
get,
compose,
map,
join,
filter,
some,
find,
keys,
isDate,
} from "lodash/fp"
import { store, backendUiStore } from "builderStore"
import { common, hierarchy } from "../../../../core/src/"
import { getNode } from "components/common/core"
import { templateApi, pipe, validate } from "components/common/core"
import ErrorsBox from "components/common/ErrorsBox.svelte"
let record
let getIndexAllowedRecords
let editingField = false
let fieldToEdit
let isNewField = false
let newField
let editField
let deleteField
let onFinishedFieldEdit
let editIndex
$: models = $store.hierarchy.children
$: parent = record && record.parent()
$: isChildModel = parent && parent.name !== "root"
$: modelExistsInHierarchy =
$store.currentNode && getNode($store.hierarchy, $store.currentNode.nodeId)
store.subscribe($store => {
record = $store.currentNode
const flattened = hierarchy.getFlattenedHierarchy($store.hierarchy)
getIndexAllowedRecords = compose(
join(", "),
map(id => flattened.find(n => n.nodeId === id).name),
filter(id => flattened.some(n => n.nodeId === id)),
get("allowedRecordNodeIds")
)
newField = () => {
isNewField = true
fieldToEdit = templateApi($store.hierarchy).getNewField("string")
editingField = true
}
onFinishedFieldEdit = field => {
if (field) {
store.saveField(field)
}
editingField = false
}
editField = field => {
isNewField = false
fieldToEdit = field
editingField = true
}
deleteField = field => {
store.deleteField(field)
}
editIndex = index => {
store.selectExistingNode(index.nodeId)
}
})
let getTypeOptionsValueText = value => {
if (
value === Number.MAX_SAFE_INTEGER ||
value === Number.MIN_SAFE_INTEGER ||
new Date(value).getTime() === new Date(8640000000000000).getTime() ||
new Date(value).getTime() === new Date(-8640000000000000).getTime()
)
return "(any)"
if (value === null) return "(not set)"
return value
}
const nameChanged = ev => {
const pluralName = n => `${n}s`
if (record.collectionName === "") {
record.collectionName = pluralName(ev.target.value)
}
}
</script>
<heading>
{#if !editingField}
<i class="ri-list-settings-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit Model</h3>
{:else}
<i class="ri-file-list-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit Field</h3>
{/if}
</heading>
{#if !editingField}
<div class="padding">
<h4 class="budibase__label--big">Settings</h4>
{#if $store.errors && $store.errors.length > 0}
<ErrorsBox errors={$store.errors} />
{/if}
<form on:submit|preventDefault class="uk-form-stacked">
<Textbox label="Name" bind:text={record.name} on:change={nameChanged} />
{#if isChildModel}
<div>
<label class="uk-form-label">Parent</label>
<div class="uk-form-controls parent-name">{parent.name}</div>
</div>
{/if}
</form>
<div class="table-controls">
<span class="budibase__label--big">Fields</span>
<h4 class="hoverable new-field" on:click={newField}>Add new field</h4>
</div>
<table class="uk-table fields-table budibase__table">
<thead>
<tr>
<th>Edit</th>
<th>Name</th>
<th>Type</th>
<th>Values</th>
<th />
</tr>
</thead>
<tbody>
{#each record ? record.fields : [] as field}
<tr>
<td>
<i class="ri-more-line" on:click={() => editField(field)} />
</td>
<td>
<div>{field.name}</div>
</td>
<td>{field.type}</td>
<td>{field.typeOptions.values || ''}</td>
<td>
<i
class="ri-delete-bin-6-line hoverable"
on:click={() => deleteField(field)} />
</td>
</tr>
{/each}
</tbody>
</table>
<div class="uk-margin">
<ActionButton color="secondary" on:click={store.saveCurrentNode}>
Save
</ActionButton>
{#if modelExistsInHierarchy}
<ActionButton color="primary" on:click={store.newChildRecord}>
Create Child Model on {record.name}
</ActionButton>
<ActionButton
color="primary"
on:click={async () => {
backendUiStore.actions.modals.show('VIEW')
await tick()
store.newChildIndex()
}}>
Create Child View on {record.name}
</ActionButton>
<ActionButton alert on:click={store.deleteCurrentNode}>
Delete
</ActionButton>
{/if}
</div>
</div>
{:else}
<FieldView
field={fieldToEdit}
onFinished={onFinishedFieldEdit}
allFields={record.fields}
store={$store} />
{/if}
<style>
.padding {
padding: 20px;
}
.new-field {
font-size: 16px;
font-weight: bold;
color: var(--button-text);
}
.fields-table {
margin: 1rem 1rem 0rem 0rem;
border-collapse: collapse;
}
tbody > tr:hover {
background-color: var(--primary10);
}
.table-controls {
display: flex;
justify-content: space-between;
align-items: center;
}
.ri-more-line:hover {
cursor: pointer;
}
heading {
padding: 20px 20px 0 20px;
display: flex;
align-items: center;
}
h3 {
margin: 0 0 0 10px;
}
.parent-name {
font-weight: bold;
}
</style>

6
packages/builder/src/components/nav/HierarchyRow.svelte

@ -18,7 +18,7 @@
const ICON_MAP = {
index: "ri-eye-line",
record: "ri-list-settings-line",
model: "ri-list-settings-line",
}
store.subscribe(state => {
@ -45,7 +45,7 @@
<div
on:click={() => selectHierarchyItem(node)}
class="budibase__nav-item hierarchy-item"
class:capitalized={type === 'record'}
class:capitalized={type === 'model'}
style="padding-left: {20 + level * 20}px"
class:selected={navActive}>
<i class={ICON_MAP[type]} />
@ -53,7 +53,7 @@
</div>
{#if node.children}
{#each node.children as child}
<svelte:self node={child} level={level + 1} type="record" />
<svelte:self node={child} level={level + 1} type="model" />
{/each}
{/if}
{#if node.indexes}

8
packages/builder/src/components/nav/SchemaManagementDrawer.svelte

@ -14,9 +14,9 @@
function newModel() {
if ($store.currentNode) {
store.newChildRecord()
store.newChildModel()
} else {
store.newRootRecord()
store.newRootModel()
}
open(
CreateEditModelModal,
@ -57,8 +57,8 @@
</div>
<div class="hierarchy-items-container">
{#each $store.hierarchy.children as record}
<HierarchyRow node={record} type="record" />
{#each $store.hierarchy.children as model}
<HierarchyRow node={model} type="model" />
{/each}
{#each $store.hierarchy.indexes as index}

4
packages/core/src/authApi/generateFullPermissions.js

@ -3,7 +3,7 @@ import { permission } from "./permissions"
import {
getFlattenedHierarchy,
isIndex,
isRecord,
isModel,
} from "../templateApi/hierarchy"
import { $ } from "../common"
@ -11,7 +11,7 @@ export const generateFullPermissions = app => {
const allNodes = getFlattenedHierarchy(app.hierarchy)
const accessLevel = { permissions: [] }
const recordNodes = $(allNodes, [filter(isRecord)])
const recordNodes = $(allNodes, [filter(isModel)])
for (const n of recordNodes) {
permission.createRecord.add(n.nodeKey(), accessLevel)

4
packages/core/src/authApi/validateAccessLevels.js

@ -24,7 +24,7 @@ import { alwaysAuthorized } from "./permissions"
const isAllowedType = t => $(permissionTypes, [values, includes(t)])
const isRecordOrIndexType = t =>
const isModelOrIndexType = t =>
some(p => p === t)([
permissionTypes.CREATE_RECORD,
permissionTypes.UPDATE_RECORD,
@ -42,7 +42,7 @@ const permissionRules = app => [
"nodeKey",
"record and index permissions must include a valid nodeKey",
p =>
!isRecordOrIndexType(p.type) ||
!isModelOrIndexType(p.type) ||
isSomething(getNode(app.hierarchy, p.nodeKey))
),
]

6
packages/core/src/indexApi/buildIndex.js

@ -5,7 +5,7 @@ import {
getRecordNodeById,
getNode,
isIndex,
isRecord,
isModel,
getActualKeyOfParent,
getAllowedRecordNodesForIndex,
fieldReversesReferenceToIndex,
@ -62,7 +62,7 @@ const buildReverseReferenceIndex = async (app, indexNode) => {
getFlattenedHierarchy,
filter(
n =>
isRecord(n) && some(fieldReversesReferenceToIndex(indexNode))(n.fields)
isModel(n) && some(fieldReversesReferenceToIndex(indexNode))(n.fields)
),
])
@ -138,6 +138,6 @@ const buildHeirarchalIndex = async (app, indexNode) => {
}
const recordNodeApplies = indexNode => recordNode =>
includes(recordNode.nodeId)(indexNode.allowedRecordNodeIds)
includes(recordNode.nodeId)(indexNode.allowedModelNodeIds)
export default buildIndex

8
packages/core/src/indexing/relevant.js

@ -23,7 +23,7 @@ import {
getRecordNodeId,
getExactNodeForKey,
recordNodeIdIsAllowed,
isRecord,
isModel,
isGlobalIndex,
} from "../templateApi/hierarchy"
import { indexTypes } from "../templateApi/indexes"
@ -57,7 +57,7 @@ export const getRelevantAncestorIndexes = (hierarchy, record) => {
return acc
}
if (!isRecord(nodeMatch) || nodeMatch.indexes.length === 0) {
if (!isModel(nodeMatch) || nodeMatch.indexes.length === 0) {
return acc
}
@ -65,8 +65,8 @@ export const getRelevantAncestorIndexes = (hierarchy, record) => {
filter(
i =>
i.indexType === indexTypes.ancestor &&
(i.allowedRecordNodeIds.length === 0 ||
includes(nodeId)(i.allowedRecordNodeIds))
(i.allowedModelNodeIds.length === 0 ||
includes(nodeId)(i.allowedModelNodeIds))
),
])

8
packages/core/src/recordApi/initialiseChildren.js

@ -4,7 +4,7 @@ import { _loadFromInfo } from "./load"
import { $, joinKey } from "../common"
import {
getFlattenedHierarchy,
isRecord,
isModel,
getNode,
isTopLevelRecord,
fieldReversesReferenceToNode,
@ -53,7 +53,7 @@ const initialiseAncestorIndexes = async (app, recordInfo) => {
const initialiseReverseReferenceIndexes = async (app, recordInfo) => {
const indexNodes = $(
fieldsThatReferenceThisRecord(app, recordInfo.recordNode),
fieldsThatReferenceThisModel(app, recordInfo.recordNode),
[
map(f =>
$(f.typeOptions.reverseIndexNodeKeys, [
@ -69,10 +69,10 @@ const initialiseReverseReferenceIndexes = async (app, recordInfo) => {
}
}
const fieldsThatReferenceThisRecord = (app, recordNode) =>
const fieldsThatReferenceThisModel = (app, recordNode) =>
$(app.hierarchy, [
getFlattenedHierarchy,
filter(isRecord),
filter(isModel),
map(n => n.fields),
flatten,
filter(fieldReversesReferenceToNode(recordNode)),

2
packages/core/src/recordApi/save.js

@ -4,7 +4,7 @@ import { _loadFromInfo } from "./load"
import { apiWrapper, events, $, joinKey } from "../common"
import {
getFlattenedHierarchy,
isRecord,
isModel,
getNode,
fieldReversesReferenceToNode,
} from "../templateApi/hierarchy"

6
packages/core/src/templateApi/canDeleteIndex.js

@ -2,7 +2,7 @@ import {
findRoot,
getFlattenedHierarchy,
fieldReversesReferenceToIndex,
isRecord,
isModel,
} from "./hierarchy"
import { $ } from "../common"
import { map, filter, reduce } from "lodash/fp"
@ -11,7 +11,7 @@ export const canDeleteIndex = indexNode => {
const flatHierarchy = $(indexNode, [findRoot, getFlattenedHierarchy])
const reverseIndexes = $(flatHierarchy, [
filter(isRecord),
filter(isModel),
reduce((obj, r) => {
for (let field of r.fields) {
if (fieldReversesReferenceToIndex(indexNode)(field)) {
@ -27,7 +27,7 @@ export const canDeleteIndex = indexNode => {
])
const lookupIndexes = $(flatHierarchy, [
filter(isRecord),
filter(isModel),
reduce((obj, r) => {
for (let field of r.fields) {
if (

14
packages/core/src/templateApi/canDeleteRecord.js → packages/core/src/templateApi/canDeleteModel.js

@ -2,17 +2,17 @@ import {
findRoot,
getFlattenedHierarchy,
fieldReversesReferenceToIndex,
isRecord,
isModel,
isAncestorIndex,
isAncestor,
} from "./hierarchy"
import { $ } from "../common"
import { map, filter, includes } from "lodash/fp"
export const canDeleteRecord = recordNode => {
const flatHierarchy = $(recordNode, [findRoot, getFlattenedHierarchy])
export const canDeleteModel = modelNode => {
const flatHierarchy = $(modelNode, [findRoot, getFlattenedHierarchy])
const ancestors = $(flatHierarchy, [filter(isAncestor(recordNode))])
const ancestors = $(flatHierarchy, [filter(isAncestor(modelNode))])
const belongsToAncestor = i => ancestors.includes(i.parent())
@ -22,11 +22,11 @@ export const canDeleteRecord = recordNode => {
i =>
isAncestorIndex(i) &&
belongsToAncestor(i) &&
includes(node.nodeId)(i.allowedRecordNodeIds)
includes(node.nodeId)(i.allowedModelNodeIds)
),
map(
i =>
`index "${i.name}" indexes this record. Please remove the record from the index, or delete the index`
`index "${i.name}" indexes this model. Please remove the model from the index, or delete the index`
),
])
@ -39,7 +39,7 @@ export const canDeleteRecord = recordNode => {
return errorsThisNode
}
const errors = errorsForNode(recordNode)
const errors = errorsForNode(modelNode)
return { errors, canDelete: errors.length === 0 }
}

28
packages/core/src/templateApi/createNodes.js

@ -13,7 +13,7 @@ import {
isRoot,
isSingleRecord,
isCollectionRecord,
isRecord,
isModel,
isaggregateGroup,
getFlattenedHierarchy,
} from "./hierarchy"
@ -34,7 +34,7 @@ const pathRegxMaker = node => () =>
const nodeKeyMaker = node => () =>
switchCase(
[
n => isRecord(n) && !isSingleRecord(n),
n => isModel(n) && !isSingleRecord(n),
n =>
joinKey(
node.parent().nodeKey(),
@ -49,7 +49,7 @@ const nodeKeyMaker = node => () =>
)(node)
const nodeNameMaker = node => () =>
isRoot(node)
isRoot(node)
? "/"
: joinKey(node.parent().nodeName(), node.name)
@ -58,7 +58,7 @@ const validate = parent => node => {
isIndex(node) &&
isSomething(parent) &&
!isRoot(parent) &&
!isRecord(parent)
!isModel(parent)
) {
throw new BadRequestError(createNodeErrors.indexParentMustBeRecordOrRoot)
}
@ -103,13 +103,13 @@ const addToParent = obj => {
parent.children.push(obj)
}
if (isRecord(obj)) {
if (isModel(obj)) {
const defaultIndex = find(
parent.indexes,
i => i.name === `${parent.name}_index`
)
if (defaultIndex) {
defaultIndex.allowedRecordNodeIds.push(obj.nodeId)
defaultIndex.allowedModelNodeIds.push(obj.nodeId)
}
}
}
@ -165,7 +165,7 @@ export const getNewRootLevel = () =>
nodeId: 0,
})
const _getNewRecordTemplate = (parent, name, createDefaultIndex, isSingle) => {
const _getNewModelTemplate = (parent, name, createDefaultIndex, isSingle) => {
const nodeId = getNodeId(parent)
const node = constructNode(parent, {
name,
@ -175,7 +175,7 @@ const _getNewRecordTemplate = (parent, name, createDefaultIndex, isSingle) => {
validationRules: [],
nodeId: nodeId,
indexes: [],
estimatedRecordCount: isRecord(parent) ? 500 : 1000000,
estimatedRecordCount: isModel(parent) ? 500 : 1000000,
collectionName: (nodeId || "").toString(),
isSingle,
})
@ -183,20 +183,20 @@ const _getNewRecordTemplate = (parent, name, createDefaultIndex, isSingle) => {
if (createDefaultIndex) {
const defaultIndex = getNewIndexTemplate(parent)
defaultIndex.name = `${name}_index`
defaultIndex.allowedRecordNodeIds.push(node.nodeId)
defaultIndex.allowedModelNodeIds.push(node.nodeId)
}
return node
}
export const getNewRecordTemplate = (
export const getNewModelTemplate = (
parent,
name = "",
createDefaultIndex = true
) => _getNewRecordTemplate(parent, name, createDefaultIndex, false)
) => _getNewModelTemplate(parent, name, createDefaultIndex, false)
export const getNewSingleRecordTemplate = parent =>
_getNewRecordTemplate(parent, "", false, true)
_getNewModelTemplate(parent, "", false, true)
export const getNewIndexTemplate = (parent, type = "ancestor") =>
constructNode(parent, {
@ -208,7 +208,7 @@ export const getNewIndexTemplate = (parent, type = "ancestor") =>
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [],
allowedModelNodeIds: [],
nodeId: getNodeId(parent),
})
@ -233,7 +233,7 @@ export const getNewAggregateTemplate = set => {
export default {
getNewRootLevel,
getNewRecordTemplate,
getNewModelTemplate,
getNewIndexTemplate,
createNodeErrors,
constructHierarchy,

4
packages/core/src/templateApi/deleteNodes.js

@ -1,8 +1,8 @@
import {} from "../templateApi/heirarchy"
import { } from "../templateApi/heirarchy"
export const canDelete = () => {
/*
it must not exist on any index.allowedRecordNodeIds
it must not exist on any index.allowedModelNodeIds
it must not exist on and reference type fields
these rules should apply to any child nodes , which will also be deleted
*/

14
packages/core/src/templateApi/diffHierarchy.js

@ -1,6 +1,6 @@
import {
getFlattenedHierarchy,
isRecord,
isModel,
isIndex,
isAncestor,
} from "./hierarchy"
@ -48,7 +48,7 @@ const changeItem = (type, oldNode, newNode) => ({
const findCreatedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const allCreated = $(newHierarchyFlat, [
filter(isRecord),
filter(isModel),
filter(nodeDoesNotExistIn(oldHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.recordCreated, null, n)),
])
@ -60,7 +60,7 @@ const findCreatedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const findDeletedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const allDeleted = $(oldHierarchyFlat, [
filter(isRecord),
filter(isModel),
filter(nodeDoesNotExistIn(newHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.recordDeleted, n, null)),
])
@ -72,7 +72,7 @@ const findDeletedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const findRenamedRecords = (oldHierarchyFlat, newHierarchyFlat) =>
$(oldHierarchyFlat, [
filter(isRecord),
filter(isModel),
filter(nodeExistsIn(newHierarchyFlat)),
filter(
nodeChanged(
@ -91,7 +91,7 @@ const findRenamedRecords = (oldHierarchyFlat, newHierarchyFlat) =>
const findRecordsWithFieldsChanged = (oldHierarchyFlat, newHierarchyFlat) =>
$(oldHierarchyFlat, [
filter(isRecord),
filter(isModel),
filter(nodeExistsIn(newHierarchyFlat)),
filter(hasDifferentFields(newHierarchyFlat)),
map(n =>
@ -108,7 +108,7 @@ const findRecordsWithEstimatedRecordTypeChanged = (
newHierarchyFlat
) =>
$(oldHierarchyFlat, [
filter(isRecord),
filter(isModel),
filter(nodeExistsIn(newHierarchyFlat)),
filter(
nodeChanged(
@ -187,7 +187,7 @@ const indexHasChanged = (_new, old) =>
_new.map !== old.map ||
_new.filter !== old.filter ||
_new.getShardName !== old.getShardName ||
difference(_new.allowedRecordNodeIds)(old.allowedRecordNodeIds).length > 0
difference(_new.allowedModelNodeIds)(old.allowedModelNodeIds).length > 0
const isFieldSame = f1 => f2 => f1.name === f2.name && f1.type === f2.type

20
packages/core/src/templateApi/hierarchy.js

@ -160,18 +160,18 @@ export const getRecordNodeIdFromId = recordId =>
export const getRecordNodeById = (hierarchy, recordId) =>
$(hierarchy, [
getFlattenedHierarchy,
find(n => isRecord(n) && n.nodeId === getRecordNodeIdFromId(recordId)),
find(n => isModel(n) && n.nodeId === getRecordNodeIdFromId(recordId)),
])
export const recordNodeIdIsAllowed = indexNode => nodeId =>
indexNode.allowedRecordNodeIds.length === 0 ||
includes(nodeId)(indexNode.allowedRecordNodeIds)
indexNode.allowedModelNodeIds.length === 0 ||
includes(nodeId)(indexNode.allowedModelNodeIds)
export const recordNodeIsAllowed = indexNode => recordNode =>
recordNodeIdIsAllowed(indexNode)(recordNode.nodeId)
export const getAllowedRecordNodesForIndex = (appHierarchy, indexNode) => {
const recordNodes = $(appHierarchy, [getFlattenedHierarchy, filter(isRecord)])
const recordNodes = $(appHierarchy, [getFlattenedHierarchy, filter(isModel)])
if (isGlobalIndex(indexNode)) {
return $(recordNodes, [filter(recordNodeIsAllowed(indexNode))])
@ -213,9 +213,9 @@ export const getNodeFromNodeKeyHash = hierarchy => hash =>
find(n => getHashCode(n.nodeKey()) === hash),
])
export const isRecord = node => isSomething(node) && node.type === "record"
export const isSingleRecord = node => isRecord(node) && node.isSingle
export const isCollectionRecord = node => isRecord(node) && !node.isSingle
export const isModel = node => isSomething(node) && node.type === "record"
export const isSingleRecord = node => isModel(node) && node.isSingle
export const isCollectionRecord = node => isModel(node) && !node.isSingle
export const isIndex = node => isSomething(node) && node.type === "index"
export const isaggregateGroup = node =>
isSomething(node) && node.type === "aggregateGroup"
@ -223,13 +223,13 @@ export const isShardedIndex = node =>
isIndex(node) && isNonEmptyString(node.getShardName)
export const isRoot = node => isSomething(node) && node.isRoot()
export const findRoot = node => (isRoot(node) ? node : findRoot(node.parent()))
export const isDecendantOfARecord = hasMatchingAncestor(isRecord)
export const isDecendantOfARecord = hasMatchingAncestor(isModel)
export const isGlobalIndex = node => isIndex(node) && isRoot(node.parent())
export const isReferenceIndex = node =>
isIndex(node) && node.indexType === indexTypes.reference
export const isAncestorIndex = node =>
isIndex(node) && node.indexType === indexTypes.ancestor
export const isTopLevelRecord = node => isRoot(node.parent()) && isRecord(node)
export const isTopLevelRecord = node => isRoot(node.parent()) && isModel(node)
export const isTopLevelIndex = node => isRoot(node.parent()) && isIndex(node)
export const getCollectionKey = recordKey =>
$(recordKey, [splitKey, parts => joinKey(parts.slice(0, parts.length - 1))])
@ -271,7 +271,7 @@ export default {
recordNodeIsAllowed,
getAllowedRecordNodesForIndex,
getNodeFromNodeKeyHash,
isRecord,
isModel,
isCollectionRecord,
isIndex,
isaggregateGroup,

4
packages/core/src/templateApi/index.js

@ -1,6 +1,6 @@
import {
getNewRootLevel,
getNewRecordTemplate,
getNewModelTemplate,
getNewIndexTemplate,
createNodeErrors,
constructHierarchy,
@ -38,7 +38,7 @@ const api = app => ({
getNewRootLevel,
constructNode,
getNewIndexTemplate,
getNewRecordTemplate,
getNewModelTemplate,
getNewField,
validateField,
addField,

6
packages/core/src/templateApi/indexes.js

@ -1,9 +1,9 @@
import { map, isEmpty, countBy, flatten, includes, join, keys } from "lodash/fp"
import {} from "lodash"
import { } from "lodash"
import { applyRuleSet, makerule } from "../common/validationCommon"
import { compileFilter, compileMap } from "../indexing/evaluate"
import { isNonEmptyString, executesWithoutException, $ } from "../common"
import { isRecord } from "./hierarchy"
import { isModel } from "./hierarchy"
export const indexTypes = { reference: "reference", ancestor: "ancestor" }
@ -39,7 +39,7 @@ export const indexRuleSet = [
"indexType",
"reference index may only exist on a record node",
index =>
isRecord(index.parent()) || index.indexType !== indexTypes.reference
isModel(index.parent()) || index.indexType !== indexTypes.reference
),
makerule(
"indexType",

10
packages/core/src/templateApi/validate.js

@ -23,7 +23,7 @@ import {
defaultCase,
} from "../common"
import {
isRecord,
isModel,
isRoot,
isaggregateGroup,
isIndex,
@ -47,7 +47,7 @@ const commonRules = [
makerule(
"type",
"node type not recognised",
anyTrue(isRecord, isRoot, isIndex, isaggregateGroup)
anyTrue(isModel, isRoot, isIndex, isaggregateGroup)
),
]
@ -79,7 +79,7 @@ const aggregateGroupRules = [
const getRuleSet = node =>
switchCase(
[isRecord, ruleSet(commonRules, recordRules)],
[isModel, ruleSet(commonRules, recordRules)],
[isIndex, ruleSet(commonRules, indexRuleSet)],
@ -108,7 +108,7 @@ export const validateAll = appHierarchy => {
])
const fieldErrors = $(flattened, [
filter(isRecord),
filter(isModel),
map(validateAllFields),
flatten,
])
@ -140,7 +140,7 @@ const actionRules = [
),
]
const duplicateActionRule = makerule("", "action name must be unique", () => {})
const duplicateActionRule = makerule("", "action name must be unique", () => { })
const validateAction = action => applyRuleSet(actionRules)(action)

4
packages/core/test/indexing.getRelevantIndexes.spec.js

@ -54,7 +54,7 @@ describe("getRelevantIndexes", () => {
expect(indexExists("/customersBySurname")).toBeTruthy()
})
it("should ignore index when allowedRecordNodeIds does not contain record's node id", async () => {
it("should ignore index when allowedModelNodeIds does not contain record's node id", async () => {
const { recordApi, appHierarchy } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
@ -72,7 +72,7 @@ describe("getRelevantIndexes", () => {
expect(indexExists("/customersBySurname")).toBeFalsy()
})
it("should include index when allowedRecordNodeIds contains record's node id", async () => {
it("should include index when allowedModelNodeIds contains record's node id", async () => {
const { recordApi, appHierarchy } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)

10
packages/core/test/indexing.schema.spec.js

@ -76,7 +76,7 @@ const setup = includeFish => setupApphierarchy(createApp(includeFish))
const createApp = includeFish => templateApi => {
const root = templateApi.getNewRootLevel()
const dogRecord = templateApi.getNewRecordTemplate(root, "dog")
const dogRecord = templateApi.getNewModelTemplate(root, "dog")
const addField = recordNode => (name, type, typeOptions) => {
const field = templateApi.getNewField(type)
@ -88,7 +88,7 @@ const createApp = includeFish => templateApi => {
const petsIndex = templateApi.getNewIndexTemplate(root)
petsIndex.name = "allPets"
petsIndex.allowedRecordNodeIds = [dogRecord.nodeId]
petsIndex.allowedModelNodeIds = [dogRecord.nodeId]
const addDogField = addField(dogRecord)
addDogField("name", "string")
@ -97,7 +97,7 @@ const createApp = includeFish => templateApi => {
let fishStuff = {}
if (includeFish) {
const fishRecord = templateApi.getNewRecordTemplate(root, "fish")
const fishRecord = templateApi.getNewModelTemplate(root, "fish")
const addFishField = addField(fishRecord)
addFishField("name", "string")
addFishField("isAlive", "bool")
@ -105,7 +105,7 @@ const createApp = includeFish => templateApi => {
fishStuff.fishRecord = fishRecord
const fishOnlyIndex = templateApi.getNewIndexTemplate(root)
fishOnlyIndex.name = "fishOnly"
fishOnlyIndex.allowedRecordNodeIds = [fishRecord.nodeId]
fishOnlyIndex.allowedModelNodeIds = [fishRecord.nodeId]
fishStuff.fishOnlyIndex = fishOnlyIndex
const dogFriends = templateApi.getNewIndexTemplate(
@ -115,7 +115,7 @@ const createApp = includeFish => templateApi => {
dogFriends.name = "dogFriends"
fishStuff.dogFriends = dogFriends
petsIndex.allowedRecordNodeIds.push(fishRecord.nodeId)
petsIndex.allowedModelNodeIds.push(fishRecord.nodeId)
const favFishField = addDogField("favouriteFish", "reference", {
indexNodeKey: fishOnlyIndex.nodeKey(),

6
packages/core/test/recordApi.getRecordInfo.spec.js

@ -133,15 +133,15 @@ const setup = ({ parentCount, childCount, grandChildCount }) =>
return field
}
const parent = templateApi.getNewRecordTemplate(root, "parent")
const parent = templateApi.getNewModelTemplate(root, "parent")
parent.estimatedRecordCount = parentCount || 1000
parent.collectionName = "parents"
addField(parent)
const child = templateApi.getNewRecordTemplate(parent, "child")
const child = templateApi.getNewModelTemplate(parent, "child")
child.estimatedRecordCount = childCount || 1000
child.collectionName = "children"
addField(child)
const grandchild = templateApi.getNewRecordTemplate(child, "grandchild")
const grandchild = templateApi.getNewModelTemplate(child, "grandchild")
grandchild.estimatedRecordCount = grandChildCount || 1000
grandchild.collectionName = "grandchildren"
addField(grandchild)

44
packages/core/test/specHelpers.js

@ -42,7 +42,7 @@ export const getMemoryStore = () => setupDatastore(memory({}))
export const getMemoryTemplateApi = store => {
const app = {
datastore: store || getMemoryStore(),
publish: () => {},
publish: () => { },
getEpochTime: async () => new Date().getTime(),
user: { name: "", permissions: [permission.writeTemplates.get()] },
}
@ -78,7 +78,7 @@ export const appFromTempalteApi = async (
const fullPermissions = generateFullPermissions(app)
app.user.permissions = fullPermissions
if (disableCleanupTransactions) setCleanupFunc(app, async () => {})
if (disableCleanupTransactions) setCleanupFunc(app, async () => { })
else setCleanupFunc(app)
return app
@ -138,15 +138,15 @@ export const hierarchyFactory = (...additionalFeatures) => templateApi => {
const settingsRecord = templateApi.getNewSingleRecordTemplate(root)
settingsRecord.name = "settings"
const customerRecord = templateApi.getNewRecordTemplate(root, "customer")
const customerRecord = templateApi.getNewModelTemplate(root, "customer")
customerRecord.collectionName = "customers"
findCollectionDefaultIndex(customerRecord).map =
"return {surname:record.surname, isalive:record.isalive, partner:record.partner};"
const partnerRecord = templateApi.getNewRecordTemplate(root, "partner")
const partnerRecord = templateApi.getNewModelTemplate(root, "partner")
partnerRecord.collectionName = "partners"
const partnerInvoiceRecord = templateApi.getNewRecordTemplate(
const partnerInvoiceRecord = templateApi.getNewModelTemplate(
partnerRecord,
"invoice"
)
@ -154,7 +154,7 @@ export const hierarchyFactory = (...additionalFeatures) => templateApi => {
findCollectionDefaultIndex(partnerInvoiceRecord).name =
"partnerInvoices_index"
const invoiceRecord = templateApi.getNewRecordTemplate(
const invoiceRecord = templateApi.getNewModelTemplate(
customerRecord,
"invoice"
)
@ -162,7 +162,7 @@ export const hierarchyFactory = (...additionalFeatures) => templateApi => {
findCollectionDefaultIndex(invoiceRecord).map =
"return {createdDate: record.createdDate, totalIncVat: record.totalIncVat};"
const chargeRecord = templateApi.getNewRecordTemplate(invoiceRecord, "charge")
const chargeRecord = templateApi.getNewModelTemplate(invoiceRecord, "charge")
chargeRecord.collectionName = "charges"
const hierarchy = {
@ -203,7 +203,7 @@ export const withFields = (hierarchy, templateApi) => {
partnersReferenceIndex.name = "partnersReference"
partnersReferenceIndex.map =
"return {name:record.businessName, phone:record.phone};"
partnersReferenceIndex.allowedRecordNodeIds = [partnerRecord.nodeId]
partnersReferenceIndex.allowedModelNodeIds = [partnerRecord.nodeId]
const partnerCustomersReverseIndex = templateApi.getNewIndexTemplate(
partnerRecord,
@ -212,7 +212,7 @@ export const withFields = (hierarchy, templateApi) => {
partnerCustomersReverseIndex.name = "partnerCustomers"
partnerCustomersReverseIndex.map = "return {...record};"
partnerCustomersReverseIndex.filter = "record.isalive === true"
partnerCustomersReverseIndex.allowedRecordNodeIds = [customerRecord.nodeId]
partnerCustomersReverseIndex.allowedModelNodeIds = [customerRecord.nodeId]
hierarchy.partnerCustomersReverseIndex = partnerCustomersReverseIndex
newCustomerField("surname", "string")
@ -236,7 +236,7 @@ export const withFields = (hierarchy, templateApi) => {
referredToCustomersReverseIndex.map = "return {...record};"
referredToCustomersReverseIndex.getShardName =
"return !record.surname ? 'null' : record.surname.substring(0,1);"
referredToCustomersReverseIndex.allowedRecordNodeIds = [customerRecord.nodeId]
referredToCustomersReverseIndex.allowedModelNodeIds = [customerRecord.nodeId]
hierarchy.referredToCustomersReverseIndex = referredToCustomersReverseIndex
const customerReferredByField = newCustomerField(
@ -295,7 +295,7 @@ export const withFields = (hierarchy, templateApi) => {
)
partnerChargesReverseIndex.name = "partnerCharges"
partnerChargesReverseIndex.map = "return {...record};"
partnerChargesReverseIndex.allowedRecordNodeIds = [chargeRecord]
partnerChargesReverseIndex.allowedModelNodeIds = [chargeRecord]
hierarchy.partnerChargesReverseIndex = partnerChargesReverseIndex
const customersReferenceIndex = templateApi.getNewIndexTemplate(
@ -304,7 +304,7 @@ export const withFields = (hierarchy, templateApi) => {
customersReferenceIndex.name = "customersReference"
customersReferenceIndex.map = "return {name:record.surname}"
customersReferenceIndex.filter = "record.isalive === true"
customersReferenceIndex.allowedRecordNodeIds = [customerRecord.nodeId]
customersReferenceIndex.allowedModelNodeIds = [customerRecord.nodeId]
newInvoiceField("customer", "reference", undefined, {
indexNodeKey: "/customersReference",
@ -328,21 +328,21 @@ export const withIndexes = (hierarchy, templateApi) => {
"return {surname: record.surname, age:record.age};"
deceasedCustomersIndex.filter = "record.isalive === false"
findCollectionDefaultIndex(customerRecord).map = "return record;"
deceasedCustomersIndex.allowedRecordNodeIds = [customerRecord.nodeId]
deceasedCustomersIndex.allowedModelNodeIds = [customerRecord.nodeId]
findCollectionDefaultIndex(invoiceRecord).allowedRecordNodeIds = [
findCollectionDefaultIndex(invoiceRecord).allowedModelNodeIds = [
invoiceRecord.nodeId,
]
findCollectionDefaultIndex(customerRecord).allowedRecordNodeIds = [
findCollectionDefaultIndex(customerRecord).allowedModelNodeIds = [
customerRecord.nodeId,
]
findCollectionDefaultIndex(partnerRecord).allowedRecordNodeIds = [
findCollectionDefaultIndex(partnerRecord).allowedModelNodeIds = [
partnerRecord.nodeId,
]
findIndex(partnerRecord, "partnerInvoices_index").allowedRecordNodeIds = [
findIndex(partnerRecord, "partnerInvoices_index").allowedModelNodeIds = [
partnerInvoiceRecord.nodeId,
]
findCollectionDefaultIndex(chargeRecord).allowedRecordNodeIds = [
findCollectionDefaultIndex(chargeRecord).allowedModelNodeIds = [
chargeRecord.nodeId,
]
@ -350,14 +350,14 @@ export const withIndexes = (hierarchy, templateApi) => {
customerInvoicesIndex.name = "customer_invoices"
customerInvoicesIndex.map = "return record;"
customerInvoicesIndex.filter = "record.type === 'invoice'"
customerInvoicesIndex.allowedRecordNodeIds = [invoiceRecord.nodeId]
customerInvoicesIndex.allowedModelNodeIds = [invoiceRecord.nodeId]
const outstandingInvoicesIndex = getNewIndexTemplate(root)
outstandingInvoicesIndex.name = "Outstanding Invoices"
outstandingInvoicesIndex.filter =
"record.type === 'invoice' && record.paidAmount < record.totalIncVat"
outstandingInvoicesIndex.map = "return {...record};"
outstandingInvoicesIndex.allowedRecordNodeIds = [
outstandingInvoicesIndex.allowedModelNodeIds = [
invoiceRecord.nodeId,
partnerInvoiceRecord.nodeId,
]
@ -403,7 +403,7 @@ export const withIndexes = (hierarchy, templateApi) => {
customersBySurnameIndex.name = "customersBySurname"
customersBySurnameIndex.map = "return {...record};"
customersBySurnameIndex.filter = ""
customersBySurnameIndex.allowedRecordNodeIds = [customerRecord.nodeId]
customersBySurnameIndex.allowedModelNodeIds = [customerRecord.nodeId]
customersBySurnameIndex.getShardName =
"return !record.surname ? 'null' : record.surname.substring(0,1);"
@ -426,7 +426,7 @@ export const withIndexes = (hierarchy, templateApi) => {
invoicesByOutstandingIndex.filter = ""
invoicesByOutstandingIndex.getShardName =
"return (record.totalIncVat > record.paidAmount ? 'outstanding' : 'paid');"
invoicesByOutstandingIndex.allowedRecordNodeIds = [
invoicesByOutstandingIndex.allowedModelNodeIds = [
partnerInvoiceRecord.nodeId,
invoiceRecord.nodeId,
]

12
packages/core/test/templateApi.canDelete.spec.js

@ -5,7 +5,7 @@ import {
basicAppHierarchyCreator_WithFields_AndIndexes,
} from "./specHelpers"
import { canDeleteIndex } from "../src/templateApi/canDeleteIndex"
import { canDeleteRecord } from "../src/templateApi/canDeleteRecord"
import { canDeleteModel } from "../src/templateApi/canDeleteModel"
describe("canDeleteIndex", () => {
it("should return no errors if deltion is valid", async () => {
@ -49,14 +49,14 @@ describe("canDeleteIndex", () => {
})
describe("canDeleteRecord", () => {
describe("canDeleteModel", () => {
it("should return no errors when deletion is valid", async () => {
const { appHierarchy } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
appHierarchy.root.indexes = appHierarchy.root.indexes.filter(i => !i.allowedRecordNodeIds.includes(appHierarchy.customerRecord.nodeId))
const result = canDeleteRecord(appHierarchy.customerRecord)
appHierarchy.root.indexes = appHierarchy.root.indexes.filter(i => !i.allowedModelNodeIds.includes(appHierarchy.customerRecord.nodeId))
const result = canDeleteModel(appHierarchy.customerRecord)
expect(result.canDelete).toBe(true)
expect(result.errors).toEqual([])
@ -67,7 +67,7 @@ describe("canDeleteRecord", () => {
basicAppHierarchyCreator_WithFields
)
const result = canDeleteRecord(appHierarchy.customerRecord)
const result = canDeleteModel(appHierarchy.customerRecord)
expect(result.canDelete).toBe(false)
expect(result.errors.some(e => e.includes("customer_index"))).toBe(true)
@ -78,7 +78,7 @@ describe("canDeleteRecord", () => {
basicAppHierarchyCreator_WithFields_AndIndexes
)
const result = canDeleteRecord(appHierarchy.customerRecord)
const result = canDeleteModel(appHierarchy.customerRecord)
expect(result.canDelete).toBe(false)
expect(result.errors.some(e => e.includes("Outstanding Invoices"))).toBe(true)

52
packages/core/test/templateApi.constructHeirarchy.spec.js

@ -16,10 +16,10 @@ describe("hierarchy node creation", () => {
expect(root.nodeName()).toBe("/")
})
it("> getNewRecordTemplate > should be initialise with correct members", async () => {
it("> getNewModelTemplate > should be initialise with correct members", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewModelTemplate(root)
record.name = "child"
expect(record.type).toBe("record")
expect(record.children).toEqual([])
@ -45,7 +45,7 @@ describe("hierarchy node creation", () => {
expect(record.isSingle).toBe(true)
})
it("> getNewrecordTemplate > should have static pathRegx if is singlerecord", async () => {
it("> getNewModelTemplate > should have static pathRegx if is singlerecord", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewSingleRecordTemplate(root)
@ -53,59 +53,59 @@ describe("hierarchy node creation", () => {
expect(record.pathRegx()).toBe("/child")
})
it("> getNewrecordTemplate > should add itself to parent records's children", async () => {
it("> getNewModelTemplate > should add itself to parent records's children", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const parentRecord = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewRecordTemplate(parentRecord)
const parentRecord = templateApi.getNewModelTemplate(root)
const record = templateApi.getNewModelTemplate(parentRecord)
expect(parentRecord.children.length).toBe(1)
expect(parentRecord.children[0]).toBe(record)
})
it("> getNewrecordTemplate > child should get correct nodeName ", async () => {
it("> getNewModelTemplate > child should get correct nodeName ", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const parentRecord = templateApi.getNewRecordTemplate(root)
const parentRecord = templateApi.getNewModelTemplate(root)
parentRecord.name = "parent"
const record = templateApi.getNewRecordTemplate(parentRecord)
const record = templateApi.getNewModelTemplate(parentRecord)
record.name = "child"
expect(record.nodeName()).toBe(`/${parentRecord.name}/${record.name}`)
})
it("> getNewrecordTemplate > should add itself to parents's default index allowedNodeIds", async () => {
it("> getNewModelTemplate > should add itself to parents's default index allowedNodeIds", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const parentRecord = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewRecordTemplate(parentRecord)
expect(root.indexes[0].allowedRecordNodeIds).toEqual([parentRecord.nodeId])
expect(parentRecord.indexes[0].allowedRecordNodeIds).toEqual([
const parentRecord = templateApi.getNewModelTemplate(root)
const record = templateApi.getNewModelTemplate(parentRecord)
expect(root.indexes[0].allowedModelNodeIds).toEqual([parentRecord.nodeId])
expect(parentRecord.indexes[0].allowedModelNodeIds).toEqual([
record.nodeId,
])
})
it("> getNewrecordTemplate > should add itself to root's children", async () => {
it("> getNewModelTemplate > should add itself to root's children", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewModelTemplate(root)
expect(root.children.length).toBe(1)
expect(root.children[0]).toBe(record)
})
it("> getNewrecordTemplate > should have dynamic pathRegx if parent is record", async () => {
it("> getNewModelTemplate > should have dynamic pathRegx if parent is record", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const parent = templateApi.getNewRecordTemplate(root)
const parent = templateApi.getNewModelTemplate(root)
parent.collectionName = "customers"
const record = templateApi.getNewRecordTemplate(parent)
const record = templateApi.getNewModelTemplate(parent)
record.name = "child"
expect(record.pathRegx().startsWith("/customers")).toBe(true)
expect(record.pathRegx().includes("[")).toBe(true)
})
it("> getNewrecordTemplate > should add default index", async () => {
it("> getNewModelTemplate > should add default index", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root, "rec")
const record = templateApi.getNewModelTemplate(root, "rec")
expect(root.indexes.length).toBe(1)
expect(root.indexes[0].name).toBe("rec_index")
})
@ -138,7 +138,7 @@ describe("hierarchy node creation", () => {
it("> getNewIndexTemplate > should add itself to record indexes", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewModelTemplate(root)
const index = templateApi.getNewIndexTemplate(record)
expect(record.indexes.length).toBe(1)
expect(record.indexes[0]).toBe(index)
@ -150,7 +150,7 @@ describe("hierarchy node creation", () => {
expect(() => templateApi.getNewIndexTemplate()).toThrow(
errors.allNonRootNodesMustHaveParent
)
expect(() => templateApi.getNewRecordTemplate()).toThrow(
expect(() => templateApi.getNewModelTemplate()).toThrow(
errors.allNonRootNodesMustHaveParent
)
})
@ -158,8 +158,8 @@ describe("hierarchy node creation", () => {
it("> adding node > should just add one (bugfix)", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const parent = templateApi.getNewRecordTemplate(root)
templateApi.getNewRecordTemplate(parent)
const parent = templateApi.getNewModelTemplate(root)
templateApi.getNewModelTemplate(parent)
expect(root.children.length).toBe(1)
expect(parent.children.length).toBe(1)
@ -174,7 +174,7 @@ describe("hierarchy node creation", () => {
it("> getNewAggregateGroupTemplate > should add itself to index aggregateGroups", async () => {
const { templateApi } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewModelTemplate(root)
const index = templateApi.getNewIndexTemplate(record)
const aggregateGroup = templateApi.getNewAggregateGroupTemplate(index)
expect(index.aggregateGroups.length).toBe(1)

24
packages/core/test/templateApi.diffHierarchy.spec.js

@ -13,7 +13,7 @@ describe("diffHierarchy", () => {
it("should detect root record created", async () => {
const oldHierarchy = (await setup()).root;
const newSetup = await setup()
const opportunity = newSetup.templateApi.getNewRecordTemplate(newSetup.root, "opportunity", false)
const opportunity = newSetup.templateApi.getNewModelTemplate(newSetup.root, "opportunity", false)
const diff = diffHierarchy(oldHierarchy, newSetup.root)
expect(diff).toEqual([{
newNode: opportunity,
@ -25,8 +25,8 @@ describe("diffHierarchy", () => {
it("should only detect root record, when newly created root record has children ", async () => {
const oldHierarchy = (await setup()).root;
const newSetup = await setup()
const opportunity = newSetup.templateApi.getNewRecordTemplate(newSetup.root, "opportunity", false)
newSetup.templateApi.getNewRecordTemplate(opportunity, "invoice", true)
const opportunity = newSetup.templateApi.getNewModelTemplate(newSetup.root, "opportunity", false)
newSetup.templateApi.getNewModelTemplate(opportunity, "invoice", true)
const diff = diffHierarchy(oldHierarchy, newSetup.root)
expect(diff).toEqual([{
newNode: opportunity,
@ -38,7 +38,7 @@ describe("diffHierarchy", () => {
it("should detect child record created", async () => {
const oldHierarchy = (await setup()).root;
const newSetup = await setup()
const opportunity = newSetup.templateApi.getNewRecordTemplate(newSetup.contact, "opportunity", false)
const opportunity = newSetup.templateApi.getNewModelTemplate(newSetup.contact, "opportunity", false)
const diff = diffHierarchy(oldHierarchy, newSetup.root)
expect(diff).toEqual([{
newNode: opportunity,
@ -98,7 +98,7 @@ describe("diffHierarchy", () => {
it("should detect root record field removed", async () => {
const oldSetup = await setup()
const newSetup = await setup()
newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "name")
newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "name")
const diff = diffHierarchy(oldSetup.root, newSetup.root)
expect(diff).toEqual([{
newNode: newSetup.contact,
@ -110,7 +110,7 @@ describe("diffHierarchy", () => {
it("should detect child record field removed", async () => {
const oldSetup = await setup()
const newSetup = await setup()
newSetup.deal.fields = newSetup.deal.fields.filter(f => f.name !== "name")
newSetup.deal.fields = newSetup.deal.fields.filter(f => f.name !== "name")
const diff = diffHierarchy(oldSetup.root, newSetup.root)
expect(diff).toEqual([{
newNode: newSetup.deal,
@ -118,7 +118,7 @@ describe("diffHierarchy", () => {
type: HierarchyChangeTypes.recordFieldsChanged
}])
})
it("should detect record field added", async () => {
const oldSetup = await setup()
const newSetup = await setup()
@ -140,7 +140,7 @@ describe("diffHierarchy", () => {
const notesField = newSetup.templateApi.getNewField("string")
notesField.name = "notes"
newSetup.templateApi.addField(newSetup.contact, notesField)
newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "name")
newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "name")
const diff = diffHierarchy(oldSetup.root, newSetup.root)
expect(diff).toEqual([{
newNode: newSetup.contact,
@ -152,7 +152,7 @@ describe("diffHierarchy", () => {
it("should detect root record estimated record count changed", async () => {
const oldSetup = await setup()
const newSetup = await setup()
newSetup.contact.estimatedRecordCount = 987
newSetup.contact.estimatedRecordCount = 987
const diff = diffHierarchy(oldSetup.root, newSetup.root)
expect(diff).toEqual([{
newNode: newSetup.contact,
@ -164,7 +164,7 @@ describe("diffHierarchy", () => {
it("should detect root record estimated record count changed", async () => {
const oldSetup = await setup()
const newSetup = await setup()
newSetup.deal.estimatedRecordCount = 987
newSetup.deal.estimatedRecordCount = 987
const diff = diffHierarchy(oldSetup.root, newSetup.root)
expect(diff).toEqual([{
newNode: newSetup.deal,
@ -246,11 +246,11 @@ describe("diffHierarchy", () => {
}))
it("should detect root index allowedRecordIds changed", testIndexChanged("root", newSetup => {
newSetup.root.indexes[0].allowedRecordNodeIds.push(3)
newSetup.root.indexes[0].allowedModelNodeIds.push(3)
}))
it("should detect child index allowedRecordIds changed", testIndexChanged("contact", newSetup => {
newSetup.contact.indexes[0].allowedRecordNodeIds.push(3)
newSetup.contact.indexes[0].allowedModelNodeIds.push(3)
}))
it("should detect child index map changed", testIndexChanged("contact", newSetup => {

2
packages/core/test/templateApi.fields.spec.js

@ -3,7 +3,7 @@ import { getMemoryTemplateApi } from "./specHelpers"
import { fieldErrors } from "../src/templateApi/fields"
const getRecordTemplate = templateApi =>
$(templateApi.getNewRootLevel(), [templateApi.getNewRecordTemplate])
$(templateApi.getNewRootLevel(), [templateApi.getNewModelTemplate])
const getValidField = templateApi => {
const field = templateApi.getNewField("string")

5
packages/core/test/templateApi.heirarchyValidation.spec.js

@ -3,7 +3,6 @@ import createNodes from "../src/templateApi/createNodes"
import { some } from "lodash"
import { getNewField, addField } from "../src/templateApi/fields"
import {
getNewRecordValidationRule,
commonRecordValidationRules,
addRecordValidationRule,
} from "../src/templateApi/recordValidationRules"
@ -13,7 +12,7 @@ import { findCollectionDefaultIndex } from "./specHelpers"
const createValidHierarchy = () => {
const root = createNodes.getNewRootLevel()
const customerRecord = createNodes.getNewRecordTemplate(root, "customer")
const customerRecord = createNodes.getNewModelTemplate(root, "customer")
customerRecord.collectionName = "customers"
const customersDefaultIndex = findCollectionDefaultIndex(customerRecord)
@ -27,7 +26,7 @@ const createValidHierarchy = () => {
allCustomersOwedFunctions.aggregatedValue = "return record.owed"
allCustomersOwedFunctions.name = "all customers owed amount"
const partnerRecord = createNodes.getNewRecordTemplate(root, "partner")
const partnerRecord = createNodes.getNewModelTemplate(root, "partner")
partnerRecord.collectionName = "partners"
partnerRecord.name = "partner"
const businessName = getNewField("string")

2
packages/core/test/templateApi.loadSaveHeirarchy.spec.js

@ -3,7 +3,7 @@ import { permission } from "../src/authApi/permissions"
const saveThreeLevelHierarchy = async () => {
const { templateApi, app } = await getMemoryTemplateApi()
const root = templateApi.getNewRootLevel()
const record = templateApi.getNewRecordTemplate(root)
const record = templateApi.getNewModelTemplate(root)
record.name = "customer"
const surname = templateApi.getNewField("string")
surname.name = "surname"

30
packages/core/test/templateApi.upgradeData.spec.js

@ -1,4 +1,4 @@
import {
import {
getRecordApiFromTemplateApi,
getIndexApiFromTemplateApi,
} from "./specHelpers"
@ -24,7 +24,7 @@ describe("upgradeData", () => {
])
expect(remainingKeys.length).toBe(0)
})
it("should not delete other root record types, when root record node deleted", async () => {
@ -39,7 +39,7 @@ describe("upgradeData", () => {
])
expect(remainingKeys.length > 0).toBe(true)
})
it("should delete all child records, when child record node deleted", async () => {
@ -67,7 +67,7 @@ describe("upgradeData", () => {
const { oldSetup, newSetup } = await configure()
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.root)
newIndex.name = "more_contacts"
newIndex.allowedRecordNodeIds = [newSetup.contact.nodeId]
newIndex.allowedModelNodeIds = [newSetup.contact.nodeId]
await upgradeData(oldSetup.app)(newSetup.root)
@ -112,7 +112,7 @@ describe("upgradeData", () => {
const { oldSetup, newSetup, records } = await configure()
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.contact)
newIndex.name = "more_deals"
newIndex.allowedRecordNodeIds = [newSetup.deal.nodeId]
newIndex.allowedModelNodeIds = [newSetup.deal.nodeId]
await upgradeData(oldSetup.app)(newSetup.root)
@ -159,20 +159,20 @@ describe("upgradeData", () => {
const { oldSetup, newSetup, records, recordApi } = await configure()
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.lead)
newIndex.name = "contact_leads"
newIndex.allowedRecordNodeIds = [newSetup.lead.nodeId]
newIndex.allowedModelNodeIds = [newSetup.lead.nodeId]
newIndex.indexType = "reference"
const leadField = newSetup.templateApi.getNewField("string")
leadField.name = "lead"
leadField.type = "reference"
leadField.typeOptions = {
reverseIndexNodeKeys: [ newIndex.nodeKey() ],
reverseIndexNodeKeys: [newIndex.nodeKey()],
indexNodeKey: "/lead_index",
displayValue: "name"
}
newSetup.templateApi.addField(newSetup.contact, leadField)
await upgradeData(oldSetup.app)(newSetup.root)
const indexKey = `${records.lead1.key}/contact_leads`
@ -194,7 +194,7 @@ describe("upgradeData", () => {
it("should initialise a new root record", async () => {
const { oldSetup, newSetup } = await configure()
const invoice = newSetup.templateApi.getNewRecordTemplate(newSetup.root, "invoice", true)
const invoice = newSetup.templateApi.getNewModelTemplate(newSetup.root, "invoice", true)
invoice.collectionName = "invoices"
const nameField = newSetup.templateApi.getNewField("string")
@ -207,7 +207,7 @@ describe("upgradeData", () => {
expect(itemsInNewIndex.length).toBe(0)
const newInvoice = _getNew(invoice, "/invoices")
const newInvoice = _getNew(invoice, "/invoices")
await _save(newSetup.app, newInvoice)
itemsInNewIndex = await _listItems(newSetup.app, "/invoice_index")
@ -217,7 +217,7 @@ describe("upgradeData", () => {
it("should initialise a new child record", async () => {
const { oldSetup, newSetup, records } = await configure()
const invoice = newSetup.templateApi.getNewRecordTemplate(newSetup.contact, "invoice", true)
const invoice = newSetup.templateApi.getNewModelTemplate(newSetup.contact, "invoice", true)
invoice.collectionName = "invoices"
const nameField = newSetup.templateApi.getNewField("string")
@ -230,7 +230,7 @@ describe("upgradeData", () => {
expect(itemsInNewIndex.length).toBe(0)
const newInvoice = _getNew(invoice, `${records.contact1.key}/invoices`)
const newInvoice = _getNew(invoice, `${records.contact1.key}/invoices`)
await _save(newSetup.app, newInvoice)
itemsInNewIndex = await _listItems(newSetup.app, `${records.contact1.key}/invoice_index`)
@ -258,7 +258,7 @@ it("should rebuild affected index when field is removed", async () => {
it("should rebuild affected index when field is added", async () => {
const { oldSetup, newSetup, records } = await configure()
const aliveField = newSetup.templateApi.getNewField("string")
aliveField.name = "isalive"
newSetup.templateApi.addField(newSetup.contact, aliveField)
@ -276,10 +276,10 @@ it("should rebuild affected index when field is added", async () => {
const configure = async () => {
const oldSetup = await setup()
const recordApi = await getRecordApiFromTemplateApi(oldSetup.templateApi)
const indexApi = await getIndexApiFromTemplateApi(oldSetup.templateApi)
const newSetup = await setup(oldSetup.store)
const records = await createSomeRecords(recordApi)

6
packages/core/test/upgradeDataSetup.js

@ -5,7 +5,7 @@ import { initialiseData } from "../src/appInitialise/initialiseData"
export const setup = async store => {
const { templateApi } = await getMemoryTemplateApi(store)
const root = templateApi.getNewRootLevel()
const contact = templateApi.getNewRecordTemplate(root, "contact", true)
const contact = templateApi.getNewModelTemplate(root, "contact", true)
contact.collectionName = "contacts"
const nameField = templateApi.getNewField("string")
@ -16,9 +16,9 @@ export const setup = async store => {
templateApi.addField(contact, nameField)
templateApi.addField(contact, statusField)
const lead = templateApi.getNewRecordTemplate(root, "lead", true)
const lead = templateApi.getNewModelTemplate(root, "lead", true)
lead.collectionName = "leads"
const deal = templateApi.getNewRecordTemplate(contact, "deal", true)
const deal = templateApi.getNewModelTemplate(contact, "deal", true)
deal.collectionName = "deals"
templateApi.addField(deal, { ...nameField })

6
packages/datastores/tests/setup.js

@ -20,7 +20,7 @@ export default async datastore => {
const clients = templateApi.getNewCollectionTemplate(root)
clients.name = "clients"
const client = templateApi.getNewRecordTemplate(clients)
const client = templateApi.getNewModelTemplate(clients)
client.name = "client"
addStringField(client, "FamilyName")
addStringField(client, "Address1")
@ -33,7 +33,7 @@ export default async datastore => {
const children = templateApi.getNewCollectionTemplate(client)
children.name = "children"
const child = templateApi.getNewRecordTemplate(children)
const child = templateApi.getNewModelTemplate(children)
child.name = "child"
addStringField(child, "FirstName")
addStringField(child, "Surname")
@ -43,7 +43,7 @@ export default async datastore => {
const contacts = templateApi.getNewCollectionTemplate(client)
contacts.name = "contacts"
const contact = templateApi.getNewRecordTemplate(contacts)
const contact = templateApi.getNewModelTemplate(contacts)
contact.name = "contact"
addStringField(contact, "Name")
addStringField(contact, "relationship")

22
packages/server/appPackages/_master/appDefinition.json

@ -187,7 +187,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [],
"allowedModelNodeIds": [],
"nodeId": 15
}
],
@ -237,7 +237,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [],
"allowedModelNodeIds": [],
"nodeId": 9
},
{
@ -249,7 +249,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [],
"allowedModelNodeIds": [],
"nodeId": 10
},
{
@ -261,7 +261,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [],
"allowedModelNodeIds": [],
"nodeId": 28
}
],
@ -367,7 +367,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
2
],
"nodeId": 23
@ -381,7 +381,7 @@
"getShardName": "return record.username.substring(0,2)",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
16
],
"nodeId": 24
@ -395,7 +395,7 @@
"getShardName": "return record.name.substring(0,2)",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
8
],
"nodeId": 25
@ -409,7 +409,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
3
],
"nodeId": 26
@ -468,7 +468,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
1
],
"nodeId": 22
@ -482,7 +482,7 @@
"getShardName": "return record.username.substring(0,2)",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
17
],
"nodeId": 27
@ -524,4 +524,4 @@
"initialOptions": {}
}
]
}
}

8
packages/server/appPackages/testApp2/appDefinition.json

@ -166,7 +166,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
1
],
"nodeId": 2
@ -180,7 +180,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
3
],
"nodeId": 4
@ -194,7 +194,7 @@
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
"allowedModelNodeIds": [
7
],
"nodeId": 8
@ -1150,4 +1150,4 @@
"inputClass": ""
}
}
}
}

272
packages/server/yarn.lock

@ -131,33 +131,6 @@
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"
integrity sha512-B6DHlz/C/m3jrxHbImT4bphdJlL7r2qmGrmcVBSc9mGHvwcRh1xfFGrsPCOU2IEJow+DWD63BIjyHzLPI3cerQ==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3"
date-fns "^1.29.0"
lodash "^4.17.13"
lunr "^2.3.5"
safe-buffer "^5.1.2"
shortid "^2.2.8"
"@cnakazawa/watch@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
@ -326,11 +299,6 @@
path-to-regexp "^1.1.1"
urijs "^1.19.0"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
"@types/babel__core@^7.1.0":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
@ -678,11 +646,6 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
bcryptjs@^2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
binary-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
@ -1082,11 +1045,6 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
date-fns@^1.29.0:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -1125,24 +1083,6 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"
integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==
dependencies:
es-abstract "^1.16.3"
es-get-iterator "^1.0.1"
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
isarray "^2.0.5"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
side-channel "^1.0.1"
which-boxed-primitive "^1.0.1"
which-collection "^1.0.0"
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@ -1158,7 +1098,7 @@ deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
define-properties@^1.1.2, define-properties@^1.1.3:
define-properties@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
@ -1278,23 +1218,6 @@ 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.16.3, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4:
version "1.17.4"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
dependencies:
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
is-callable "^1.1.5"
is-regex "^1.0.5"
object-inspect "^1.7.0"
object-keys "^1.1.1"
object.assign "^4.1.0"
string.prototype.trimleft "^2.1.1"
string.prototype.trimright "^2.1.1"
es-abstract@^1.5.1:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
@ -1307,19 +1230,6 @@ es-abstract@^1.5.1:
is-regex "^1.0.4"
object-keys "^1.0.12"
es-get-iterator@^1.0.1:
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.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
@ -1329,15 +1239,6 @@ es-to-primitive@^1.2.0:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
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"
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
dependencies:
is-callable "^1.1.4"
is-date-object "^1.0.1"
is-symbol "^1.0.2"
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -1750,11 +1651,6 @@ has-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -1939,21 +1835,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"
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"
@ -1961,11 +1847,6 @@ 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"
@ -1976,11 +1857,6 @@ is-callable@^1.1.4:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
is-callable@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-ci@^1.0.10:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
@ -2091,21 +1967,11 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
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@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
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"
@ -2149,33 +2015,16 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
dependencies:
has "^1.0.3"
is-retry-allowed@^1.0.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.0.0, 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.2"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
@ -2197,16 +2046,6 @@ is-typedarray@~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"
@ -2227,11 +2066,6 @@ 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==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -2918,7 +2752,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15:
lodash@^4.17.11, lodash@^4.17.13:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -2943,11 +2777,6 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2"
yallist "^2.1.2"
lunr@^2.3.5:
version "2.3.8"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@ -3109,11 +2938,6 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nanoid@^2.1.0:
version "2.1.11"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -3309,17 +3133,7 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
object-inspect@^1.7.0:
version "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.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
object-keys@^1.0.12:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@ -3331,16 +3145,6 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
object.assign@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.1"
has-symbols "^1.0.0"
object-keys "^1.0.11"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
@ -3727,19 +3531,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
regexp.prototype.flags@^1.2.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==
registry-auth-token@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e"
@ -3982,21 +3773,6 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
dependencies:
nanoid "^2.1.0"
side-channel@^1.0.1:
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.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@ -4186,22 +3962,6 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string.prototype.trimleft@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
string.prototype.trimright@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@ -4290,11 +4050,6 @@ supports-color@^6.1.0:
dependencies:
has-flag "^3.0.0"
svelte@^3.9.2:
version "3.19.2"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.19.2.tgz#4b0169ee33b37399f08eb92163593a0a46c242c7"
integrity sha512-Jswg065u8R9QYcN0rdpTQSFIr0hFq7YUzcPpEY6ZpFSAWkJKZG9AJvHE1d8+NJDTfr7SzKrO6EYssYYkUmszpA==
symbol-tree@^3.2.2:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@ -4673,27 +4428,6 @@ 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.0:
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"

21270
packages/standard-components/public/bundle.js

File diff suppressed because it is too large

244
packages/standard-components/public/bundle.js.map

File diff suppressed because one or more lines are too long

6
packages/standard-components/public/clientAppDefinition.js

@ -59,7 +59,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [2],
allowedModelNodeIds: [2],
nodeId: 5,
},
],
@ -79,7 +79,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [1],
allowedModelNodeIds: [1],
nodeId: 4,
},
{
@ -91,7 +91,7 @@ window["##BUDIBASE_APPDEFINITION##"] = {
getShardName: "",
getSortKey: "record.id",
aggregateGroups: [],
allowedRecordNodeIds: [2],
allowedModelNodeIds: [2],
nodeId: 6,
},
],

Loading…
Cancel
Save